feat: 添加发送语音相关逻辑
This commit is contained in:
parent
88b512aa7f
commit
6356b071ac
2
App.vue
2
App.vue
@ -31,7 +31,7 @@
|
||||
return 'XHJ'
|
||||
}
|
||||
// #endif
|
||||
return 'XHJ'
|
||||
return 'DEV'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@ -89,7 +89,10 @@
|
||||
"<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.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" : {
|
||||
|
||||
@ -187,7 +187,14 @@
|
||||
// #endif
|
||||
|
||||
// #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
|
||||
|
||||
const $bluetooth = useBluetoothStore()
|
||||
@ -223,6 +230,8 @@
|
||||
onMounted(async () => {
|
||||
// #ifdef APP-PLUS
|
||||
isApp.value = true
|
||||
// 初始化录音管理器
|
||||
initRecorder()
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
@ -268,6 +277,11 @@
|
||||
})
|
||||
if (urlResult.code === 0) {
|
||||
url.value = urlResult.data.url
|
||||
runSendService(
|
||||
`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`,
|
||||
'channel=0',
|
||||
true
|
||||
)
|
||||
handlePlaySuccess()
|
||||
} else {
|
||||
$basic.backAndToast(message)
|
||||
@ -284,6 +298,12 @@
|
||||
|
||||
onUnload(() => {
|
||||
// #ifdef APP-PLUS
|
||||
// 停止录音
|
||||
if (isVoice.value && recorderManager.value) {
|
||||
stopRecording()
|
||||
}
|
||||
|
||||
stopSendService(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`)
|
||||
stopService({
|
||||
id: `${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`
|
||||
})
|
||||
@ -460,6 +480,103 @@
|
||||
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 = () => {
|
||||
// #ifdef MP-WEIXIN
|
||||
if (isVoice.value) {
|
||||
@ -479,7 +596,18 @@
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
console.log(1111)
|
||||
// #ifdef APP-PLUS
|
||||
if (isVoice.value) {
|
||||
isVoice.value = false
|
||||
|
||||
stopRecording()
|
||||
} else {
|
||||
uni.vibrateLong()
|
||||
isVoice.value = true
|
||||
// 初始化并开始录音
|
||||
startRecording()
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
const handlePlaySuccess = () => {
|
||||
|
||||
@ -77,3 +77,84 @@ export const stopService = async function (params: IdParams): Promise<Result> {
|
||||
// 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