feat: 添加发送语音相关逻辑

This commit is contained in:
fanpeng 2025-06-19 10:18:09 +08:00
parent 88b512aa7f
commit 6356b071ac
4 changed files with 319 additions and 107 deletions

View File

@ -31,7 +31,7 @@
return 'XHJ' return 'XHJ'
} }
// #endif // #endif
return 'XHJ' return 'DEV'
} }
}, },
computed: { computed: {

View File

@ -1,74 +1,74 @@
{ {
"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": { "permission" : {
"scope.bluetooth": { "scope.bluetooth" : {
"desc": "蓝牙将用于控制和管理您的智能门锁" "desc" : "蓝牙将用于控制和管理您的智能门锁"
} }
}, },
"usingComponents": true, "usingComponents" : true,
"lazyCodeLoading": "requiredComponents", "lazyCodeLoading" : "requiredComponents",
"optimization": { "optimization" : {
"subPackages": true "subPackages" : true
}, },
"plugins": { "plugins" : {
"wmpf-voip": { "wmpf-voip" : {
"version": "latest", "version" : "latest",
"provider": "wxf830863afde621eb", "provider" : "wxf830863afde621eb",
"genericsImplementation": { "genericsImplementation" : {
"call-page-plugin": { "call-page-plugin" : {
"custombox": "pages/main/customBox" "custombox" : "pages/main/customBox"
} }
} }
} }
} }
}, },
"vueVersion": "3", "vueVersion" : "3",
"app-plus": { "app-plus" : {
"distribute": { "distribute" : {
"icons": { "icons" : {
"android": { "android" : {
"hdpi": "unpackage/res/icons/72x72.png", "hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi": "unpackage/res/icons/96x96.png", "xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi": "unpackage/res/icons/144x144.png", "xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi": "unpackage/res/icons/192x192.png" "xxxhdpi" : "unpackage/res/icons/192x192.png"
}, },
"ios": { "ios" : {
"appstore": "unpackage/res/icons/1024x1024.png", "appstore" : "unpackage/res/icons/1024x1024.png",
"ipad": { "ipad" : {
"app": "unpackage/res/icons/76x76.png", "app" : "unpackage/res/icons/76x76.png",
"app@2x": "unpackage/res/icons/152x152.png", "app@2x" : "unpackage/res/icons/152x152.png",
"notification": "unpackage/res/icons/20x20.png", "notification" : "unpackage/res/icons/20x20.png",
"notification@2x": "unpackage/res/icons/40x40.png", "notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x": "unpackage/res/icons/167x167.png", "proapp@2x" : "unpackage/res/icons/167x167.png",
"settings": "unpackage/res/icons/29x29.png", "settings" : "unpackage/res/icons/29x29.png",
"settings@2x": "unpackage/res/icons/58x58.png", "settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight": "unpackage/res/icons/40x40.png", "spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x": "unpackage/res/icons/80x80.png" "spotlight@2x" : "unpackage/res/icons/80x80.png"
}, },
"iphone": { "iphone" : {
"app@2x": "unpackage/res/icons/120x120.png", "app@2x" : "unpackage/res/icons/120x120.png",
"app@3x": "unpackage/res/icons/180x180.png", "app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x": "unpackage/res/icons/40x40.png", "notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x": "unpackage/res/icons/60x60.png", "notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x": "unpackage/res/icons/58x58.png", "settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x": "unpackage/res/icons/87x87.png", "settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x": "unpackage/res/icons/80x80.png", "spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x": "unpackage/res/icons/120x120.png" "spotlight@3x" : "unpackage/res/icons/120x120.png"
} }
} }
}, },
"android": { "android" : {
"permissions": [ "permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
@ -89,22 +89,25 @@
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\" />", "<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\" />",
"<uses-permission android:name=\"android.permission.BLUETOOTH\" />", "<uses-permission android:name=\"android.permission.BLUETOOTH\" />",
"<uses-permission android:name=\"android.permission.BLUETOOTH_SCAN\" />", "<uses-permission android:name=\"android.permission.BLUETOOTH_SCAN\" />",
"<uses-permission android:name=\"android.permission.BLUETOOTH_CONNECT\" />" "<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": { "ios" : {
"dSYMs": false "dSYMs" : false
} }
}, },
"modules": { "modules" : {
"Bluetooth": {}, "Bluetooth" : {},
"VideoPlayer": {}, "VideoPlayer" : {},
"LivePusher": {}, "LivePusher" : {},
"Camera": {}, "Camera" : {},
"Record": {} "Record" : {}
}, },
"splashscreen": { "splashscreen" : {
"waiting": false "waiting" : false
} }
} }
} }

View File

@ -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 = () => {

View File

@ -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()
}
}
}