diff --git a/uni_modules/xhj-record/utssdk/app-android/index.uts b/uni_modules/xhj-record/utssdk/app-android/index.uts index c6deb72..2ee70b0 100644 --- a/uni_modules/xhj-record/utssdk/app-android/index.uts +++ b/uni_modules/xhj-record/utssdk/app-android/index.uts @@ -11,7 +11,6 @@ import 'android.media.MediaFormat' import 'java.lang.Thread' import { UTSAndroid } from 'io.dcloud.uts' import { Result } from '../interface.uts' -// @ts-ignore-end import { FLVPacker, FLVListener } from 'com.tencent.iot.thirdparty.flv' let recorder: AudioRecord | null = null @@ -142,121 +141,115 @@ export const initAudio = async function (): Promise { } } -export async function onStartRecord(callback: (data: Array) => void): Promise { - try { - await stopRecord() +// Final version based on the naming convention from the documentation. +// This function intentionally returns void. The caller on the JS side +// must NOT use `await` on it, otherwise a ClassCastException will occur. +export function onStartRecord(callback: (data: Array) => void) { + stopRecord() + .then(() => { + const currentRecorder = recorder + if (currentRecorder == null) { + console.log('Error: Recorder not initialized.') + return + } - const currentRecorder = recorder - if (currentRecorder == null) { - return { code: -1, data: {}, message: '录音尚未初始化' } - } + const listener = new MyFLVListener(callback) + flvPacker = new FLVPacker(listener, true, false) - const listener = new MyFLVListener(callback) - flvPacker = new FLVPacker(listener, true, false) + const sampleRateInHz = 16000 + const channelCount = 1 + const bitRate = 96000 + aacEncoder = MediaCodec.createEncoderByType('audio/mp4a-latm') + const mediaFormat = MediaFormat.createAudioFormat( + 'audio/mp4a-latm', + sampleRateInHz.toInt(), + channelCount.toInt() + ) + mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate.toInt()) + mediaFormat.setInteger( + MediaFormat.KEY_AAC_PROFILE, + MediaCodecInfo.CodecProfileLevel.AACObjectLC + ) + mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1024 * 1024) + aacEncoder!!.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) - const sampleRateInHz = 16000 - const channelCount = 1 - const bitRate = 96000 - aacEncoder = MediaCodec.createEncoderByType('audio/mp4a-latm') - const mediaFormat = MediaFormat.createAudioFormat( - 'audio/mp4a-latm', - sampleRateInHz.toInt(), - channelCount.toInt() - ) - mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate.toInt()) - mediaFormat.setInteger( - MediaFormat.KEY_AAC_PROFILE, - MediaCodecInfo.CodecProfileLevel.AACObjectLC - ) - mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1024 * 1024) - aacEncoder!!.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) - - recordThread = new Thread(() => { - try { - if (aacEncoder == null || currentRecorder == null || flvPacker == null) { - return - } - - currentRecorder.startRecording() - aacEncoder!!.start() - isRecording = true - - const audioInfo = new MediaCodec.BufferInfo() - while (isRecording) { - // Feed encoder - const inputBufferId = aacEncoder!!.dequeueInputBuffer(10000) - if (inputBufferId >= 0) { - const inputBuffer = aacEncoder!!.getInputBuffer(inputBufferId)!! - const readSize = currentRecorder.read(inputBuffer, bufferSizeInBytes) - if (readSize > 0 && isRecording) { - aacEncoder!!.queueInputBuffer( - inputBufferId, - 0, - readSize, - (Date.now() * 1000).toLong(), - 0 - ) - } + recordThread = new Thread(() => { + try { + if (aacEncoder == null || currentRecorder == null || flvPacker == null) { + return } - // Drain encoder - var outputBufferId = aacEncoder!!.dequeueOutputBuffer(audioInfo, 10000) - while (outputBufferId >= 0 && isRecording) { - const outputBuffer = aacEncoder!!.getOutputBuffer(outputBufferId)!! - if (audioInfo.size > 0 && flvPacker != null) { - const outDataSize = audioInfo.size - const packetLen = outDataSize + 7 - const aacPacket = ByteArray(packetLen) + currentRecorder.startRecording() + aacEncoder!!.start() + isRecording = true - addADTStoPacket(aacPacket, packetLen) - - outputBuffer.position(audioInfo.offset) - outputBuffer.limit(audioInfo.offset + outDataSize) - outputBuffer.get(aacPacket, 7, outDataSize) - outputBuffer.position(audioInfo.offset) - - if (flvPacker != null && isRecording) { - flvPacker!!.encodeFlv(aacPacket, FLVPacker.TYPE_AUDIO, Date.now().toLong()) + const audioInfo = new MediaCodec.BufferInfo() + while (isRecording) { + const inputBufferId = aacEncoder!!.dequeueInputBuffer(10000) + if (inputBufferId >= 0) { + const inputBuffer = aacEncoder!!.getInputBuffer(inputBufferId)!! + const readSize = currentRecorder.read(inputBuffer, bufferSizeInBytes) + if (readSize > 0 && isRecording) { + aacEncoder!!.queueInputBuffer( + inputBufferId, + 0, + readSize, + (Date.now() * 1000).toLong(), + 0 + ) } } - aacEncoder!!.releaseOutputBuffer(outputBufferId, false) - outputBufferId = aacEncoder!!.dequeueOutputBuffer(audioInfo, 0) + + var outputBufferId = aacEncoder!!.dequeueOutputBuffer(audioInfo, 10000) + while (outputBufferId >= 0 && isRecording) { + const outputBuffer = aacEncoder!!.getOutputBuffer(outputBufferId)!! + if (audioInfo.size > 0 && flvPacker != null) { + const outDataSize = audioInfo.size + const aacPacketWithAdts = ByteArray(outDataSize + 7) + + addADTStoPacket(aacPacketWithAdts, outDataSize + 7) + + outputBuffer.position(audioInfo.offset) + outputBuffer.limit(audioInfo.offset + outDataSize) + outputBuffer.get(aacPacketWithAdts, 7, outDataSize) + + if (flvPacker != null && isRecording) { + flvPacker!!.encodeFlv( + aacPacketWithAdts, + FLVPacker.TYPE_AUDIO, + Date.now().toLong() + ) + } + } + aacEncoder!!.releaseOutputBuffer(outputBufferId, false) + outputBufferId = aacEncoder!!.dequeueOutputBuffer(audioInfo, 0) + } } + } catch (error) { + console.log('Record thread error: ' + error.toString()) + } finally { + try { + currentRecorder?.stop() + } catch (e) {} + try { + aacEncoder?.stop() + aacEncoder?.release() + } catch (e) {} + try { + flvPacker?.release() + } catch (e) {} + + aacEncoder = null + flvPacker = null + isRecording = false } - } catch (error) { - // Log error - } finally { - try { - currentRecorder?.stop() - } catch (e) {} - try { - aacEncoder?.stop() - aacEncoder?.release() - } catch (e) {} - try { - flvPacker?.release() - } catch (e) {} + }) - aacEncoder = null - flvPacker = null - isRecording = false - } + recordThread!!.start() + }) + .catch(error => { + console.log('Error in stopRecord(): ' + error.toString()) }) - - recordThread!!.start() - - return { - code: 0, - data: {}, - message: '成功' - } - } catch (error) { - return { - code: -1, - data: {}, - message: error.toString() - } - } } export const stopRecord = async function (): Promise { @@ -322,5 +315,3 @@ export const releaseRecord = async function (): Promise { } } } - -// @ts-ignore-end