feat: 添加发送语音相关逻辑
This commit is contained in:
parent
88b512aa7f
commit
6356b071ac
2
App.vue
2
App.vue
@ -31,7 +31,7 @@
|
|||||||
return 'XHJ'
|
return 'XHJ'
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
return 'XHJ'
|
return 'DEV'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
211
manifest.json
211
manifest.json
@ -1,110 +1,113 @@
|
|||||||
{
|
{
|
||||||
"name": "星星锁Lite",
|
"name" : "星星锁Lite",
|
||||||
"appid": "__UNI__933D519",
|
"appid" : "__UNI__933D519",
|
||||||
"description": "",
|
"description" : "",
|
||||||
"versionName": "1.3.0",
|
"versionName" : "1.3.0",
|
||||||
"versionCode": "37",
|
"versionCode" : "37",
|
||||||
"mp-weixin": {
|
"mp-weixin" : {
|
||||||
"appid": "wx9829a39e65550757",
|
"appid" : "wx9829a39e65550757",
|
||||||
"setting": {
|
"setting" : {
|
||||||
"urlCheck": true,
|
"urlCheck" : true,
|
||||||
"minified": true
|
"minified" : true
|
||||||
},
|
|
||||||
"permission": {
|
|
||||||
"scope.bluetooth": {
|
|
||||||
"desc": "蓝牙将用于控制和管理您的智能门锁"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"usingComponents": true,
|
|
||||||
"lazyCodeLoading": "requiredComponents",
|
|
||||||
"optimization": {
|
|
||||||
"subPackages": true
|
|
||||||
},
|
|
||||||
"plugins": {
|
|
||||||
"wmpf-voip": {
|
|
||||||
"version": "latest",
|
|
||||||
"provider": "wxf830863afde621eb",
|
|
||||||
"genericsImplementation": {
|
|
||||||
"call-page-plugin": {
|
|
||||||
"custombox": "pages/main/customBox"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"vueVersion": "3",
|
|
||||||
"app-plus": {
|
|
||||||
"distribute": {
|
|
||||||
"icons": {
|
|
||||||
"android": {
|
|
||||||
"hdpi": "unpackage/res/icons/72x72.png",
|
|
||||||
"xhdpi": "unpackage/res/icons/96x96.png",
|
|
||||||
"xxhdpi": "unpackage/res/icons/144x144.png",
|
|
||||||
"xxxhdpi": "unpackage/res/icons/192x192.png"
|
|
||||||
},
|
},
|
||||||
"ios": {
|
"permission" : {
|
||||||
"appstore": "unpackage/res/icons/1024x1024.png",
|
"scope.bluetooth" : {
|
||||||
"ipad": {
|
"desc" : "蓝牙将用于控制和管理您的智能门锁"
|
||||||
"app": "unpackage/res/icons/76x76.png",
|
}
|
||||||
"app@2x": "unpackage/res/icons/152x152.png",
|
},
|
||||||
"notification": "unpackage/res/icons/20x20.png",
|
"usingComponents" : true,
|
||||||
"notification@2x": "unpackage/res/icons/40x40.png",
|
"lazyCodeLoading" : "requiredComponents",
|
||||||
"proapp@2x": "unpackage/res/icons/167x167.png",
|
"optimization" : {
|
||||||
"settings": "unpackage/res/icons/29x29.png",
|
"subPackages" : true
|
||||||
"settings@2x": "unpackage/res/icons/58x58.png",
|
},
|
||||||
"spotlight": "unpackage/res/icons/40x40.png",
|
"plugins" : {
|
||||||
"spotlight@2x": "unpackage/res/icons/80x80.png"
|
"wmpf-voip" : {
|
||||||
},
|
"version" : "latest",
|
||||||
"iphone": {
|
"provider" : "wxf830863afde621eb",
|
||||||
"app@2x": "unpackage/res/icons/120x120.png",
|
"genericsImplementation" : {
|
||||||
"app@3x": "unpackage/res/icons/180x180.png",
|
"call-page-plugin" : {
|
||||||
"notification@2x": "unpackage/res/icons/40x40.png",
|
"custombox" : "pages/main/customBox"
|
||||||
"notification@3x": "unpackage/res/icons/60x60.png",
|
}
|
||||||
"settings@2x": "unpackage/res/icons/58x58.png",
|
}
|
||||||
"settings@3x": "unpackage/res/icons/87x87.png",
|
}
|
||||||
"spotlight@2x": "unpackage/res/icons/80x80.png",
|
|
||||||
"spotlight@3x": "unpackage/res/icons/120x120.png"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"android": {
|
|
||||||
"permissions": [
|
|
||||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
|
||||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
|
||||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
|
||||||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />",
|
|
||||||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
|
|
||||||
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\" />",
|
|
||||||
"<uses-permission android:name=\"android.permission.BLUETOOTH\" />",
|
|
||||||
"<uses-permission android:name=\"android.permission.BLUETOOTH_SCAN\" />",
|
|
||||||
"<uses-permission android:name=\"android.permission.BLUETOOTH_CONNECT\" />"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ios": {
|
|
||||||
"dSYMs": false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"modules": {
|
"vueVersion" : "3",
|
||||||
"Bluetooth": {},
|
"app-plus" : {
|
||||||
"VideoPlayer": {},
|
"distribute" : {
|
||||||
"LivePusher": {},
|
"icons" : {
|
||||||
"Camera": {},
|
"android" : {
|
||||||
"Record": {}
|
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||||
},
|
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||||
"splashscreen": {
|
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||||
"waiting": false
|
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||||
|
},
|
||||||
|
"ios" : {
|
||||||
|
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||||
|
"ipad" : {
|
||||||
|
"app" : "unpackage/res/icons/76x76.png",
|
||||||
|
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||||
|
"notification" : "unpackage/res/icons/20x20.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||||
|
"settings" : "unpackage/res/icons/29x29.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||||
|
},
|
||||||
|
"iphone" : {
|
||||||
|
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||||
|
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||||
|
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"android" : {
|
||||||
|
"permissions" : [
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
|
||||||
|
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\" />",
|
||||||
|
"<uses-permission android:name=\"android.permission.BLUETOOTH\" />",
|
||||||
|
"<uses-permission android:name=\"android.permission.BLUETOOTH_SCAN\" />",
|
||||||
|
"<uses-permission android:name=\"android.permission.BLUETOOTH_CONNECT\" />",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"/>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ios" : {
|
||||||
|
"dSYMs" : false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"modules" : {
|
||||||
|
"Bluetooth" : {},
|
||||||
|
"VideoPlayer" : {},
|
||||||
|
"LivePusher" : {},
|
||||||
|
"Camera" : {},
|
||||||
|
"Record" : {}
|
||||||
|
},
|
||||||
|
"splashscreen" : {
|
||||||
|
"waiting" : false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -187,7 +187,14 @@
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
import { startService, getLiveUrl, stopService } from '@/uni_modules/xhj-tencent-xp2p'
|
import {
|
||||||
|
startService,
|
||||||
|
getLiveUrl,
|
||||||
|
stopService,
|
||||||
|
runSendService,
|
||||||
|
stopSendService,
|
||||||
|
dataSend
|
||||||
|
} from '@/uni_modules/xhj-tencent-xp2p'
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
const $bluetooth = useBluetoothStore()
|
const $bluetooth = useBluetoothStore()
|
||||||
@ -223,6 +230,8 @@
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
isApp.value = true
|
isApp.value = true
|
||||||
|
// 初始化录音管理器
|
||||||
|
initRecorder()
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
@ -268,6 +277,11 @@
|
|||||||
})
|
})
|
||||||
if (urlResult.code === 0) {
|
if (urlResult.code === 0) {
|
||||||
url.value = urlResult.data.url
|
url.value = urlResult.data.url
|
||||||
|
runSendService(
|
||||||
|
`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`,
|
||||||
|
'channel=0',
|
||||||
|
true
|
||||||
|
)
|
||||||
handlePlaySuccess()
|
handlePlaySuccess()
|
||||||
} else {
|
} else {
|
||||||
$basic.backAndToast(message)
|
$basic.backAndToast(message)
|
||||||
@ -284,6 +298,12 @@
|
|||||||
|
|
||||||
onUnload(() => {
|
onUnload(() => {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
|
// 停止录音
|
||||||
|
if (isVoice.value && recorderManager.value) {
|
||||||
|
stopRecording()
|
||||||
|
}
|
||||||
|
|
||||||
|
stopSendService(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`)
|
||||||
stopService({
|
stopService({
|
||||||
id: `${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`
|
id: `${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`
|
||||||
})
|
})
|
||||||
@ -460,6 +480,103 @@
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
const recorderManager = ref(null)
|
||||||
|
const recordingFilePath = ref('')
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
const convertAudioFileToUint8Array = filePath => {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
try {
|
||||||
|
plus.io.resolveLocalFileSystemURL(filePath, entry => {
|
||||||
|
entry.file(
|
||||||
|
file => {
|
||||||
|
console.log(11111, file)
|
||||||
|
if (file.size === 0) return
|
||||||
|
|
||||||
|
const fileReader = new plus.io.FileReader()
|
||||||
|
|
||||||
|
fileReader.onloadend = async evt => {
|
||||||
|
try {
|
||||||
|
const base64 = evt.target.result.split(',')[1]
|
||||||
|
|
||||||
|
const binaryString = atob(base64)
|
||||||
|
const byteArray = []
|
||||||
|
|
||||||
|
for (let i = 0; i < binaryString.length; i++) {
|
||||||
|
byteArray[i] = binaryString.charCodeAt(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = `${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`
|
||||||
|
|
||||||
|
await dataSend(id, byteArray)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('音频数据转换失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileReader.onerror = () => {
|
||||||
|
console.error('音频文件读取失败')
|
||||||
|
}
|
||||||
|
|
||||||
|
fileReader.readAsDataURL(file)
|
||||||
|
},
|
||||||
|
error => console.error('获取文件对象失败:', error)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('音频文件处理异常:', error)
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const initRecorder = () => {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
recorderManager.value = uni.getRecorderManager()
|
||||||
|
|
||||||
|
recorderManager.value.onStart(() => {
|
||||||
|
console.log('录音开始')
|
||||||
|
})
|
||||||
|
|
||||||
|
recorderManager.value.onError(error => {
|
||||||
|
console.error('录音出错:', error)
|
||||||
|
})
|
||||||
|
|
||||||
|
recorderManager.value.onStop(res => {
|
||||||
|
console.log('录音结束:', res)
|
||||||
|
recordingFilePath.value = res.tempFilePath
|
||||||
|
|
||||||
|
convertAudioFileToUint8Array(res.tempFilePath)
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始录音
|
||||||
|
const startRecording = () => {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
if (!recorderManager.value) {
|
||||||
|
initRecorder()
|
||||||
|
}
|
||||||
|
|
||||||
|
recorderManager.value.start({
|
||||||
|
duration: 60000,
|
||||||
|
sampleRate: 16000,
|
||||||
|
format: 'aac'
|
||||||
|
})
|
||||||
|
console.log('开始录音')
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止录音
|
||||||
|
const stopRecording = () => {
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
if (recorderManager.value) {
|
||||||
|
recorderManager.value.stop()
|
||||||
|
console.log('停止录音')
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
const toggleVoice = () => {
|
const toggleVoice = () => {
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
if (isVoice.value) {
|
if (isVoice.value) {
|
||||||
@ -479,7 +596,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
console.log(1111)
|
// #ifdef APP-PLUS
|
||||||
|
if (isVoice.value) {
|
||||||
|
isVoice.value = false
|
||||||
|
|
||||||
|
stopRecording()
|
||||||
|
} else {
|
||||||
|
uni.vibrateLong()
|
||||||
|
isVoice.value = true
|
||||||
|
// 初始化并开始录音
|
||||||
|
startRecording()
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePlaySuccess = () => {
|
const handlePlaySuccess = () => {
|
||||||
|
|||||||
@ -77,3 +77,84 @@ export const stopService = async function (params: IdParams): Promise<Result> {
|
|||||||
// console.log(2, error)
|
// console.log(2, error)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
export const runSendService = async function (
|
||||||
|
id: string,
|
||||||
|
cmd: string,
|
||||||
|
crypto: boolean
|
||||||
|
): Promise<Result> {
|
||||||
|
try {
|
||||||
|
await XP2P.runSendService(id, cmd, crypto)
|
||||||
|
console.log('开始发送服务')
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
data: {},
|
||||||
|
message: '成功'
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
data: {},
|
||||||
|
message: error.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const stopSendService = async function (id: string): Promise<Result> {
|
||||||
|
try {
|
||||||
|
await XP2P.stopSendService(id, null)
|
||||||
|
console.log('停止发送服务')
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
data: {},
|
||||||
|
message: '成功'
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
data: {},
|
||||||
|
message: error.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dataSend = async function (id: string, data: Array<number>): Promise<Result> {
|
||||||
|
try {
|
||||||
|
let byteTest = new ByteArray((data.length + 7).toInt())
|
||||||
|
byteTest.set(0, (0xff).toByte())
|
||||||
|
byteTest.set(1, (0xf9).toByte())
|
||||||
|
|
||||||
|
let profile = 2
|
||||||
|
let freqIdx = 8
|
||||||
|
let chanCfg = 1
|
||||||
|
let packetLen = data.length + 7
|
||||||
|
|
||||||
|
byteTest.set(2, (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2)).toByte())
|
||||||
|
byteTest.set(3, (((chanCfg & 3) << 6) + (packetLen >> 11)).toByte())
|
||||||
|
byteTest.set(4, ((packetLen & 0x7ff) >> 3).toByte())
|
||||||
|
byteTest.set(5, (((packetLen & 7) << 5) + 0x1f).toByte())
|
||||||
|
byteTest.set(6, (0xfc).toByte())
|
||||||
|
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
byteTest.set((i + 7).toInt(), data[i].toByte())
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(byteTest)
|
||||||
|
console.log(1, id, byteTest[0], byteTest[1], (data.length + 7).toInt())
|
||||||
|
|
||||||
|
const result = await XP2P.dataSend(id, byteTest, (data.length + 7).toInt())
|
||||||
|
|
||||||
|
console.log('发送数据', result)
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
data: {},
|
||||||
|
message: '成功'
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
data: {},
|
||||||
|
message: error.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user