Browse Source

加入opus压缩,回传设备端

weicu
fdp 1 year ago
parent
commit
62110f1c8b
  1. 89
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

89
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt

@ -12,6 +12,7 @@ import java.util.concurrent.CopyOnWriteArrayList
// Import Jieli Opus SDK classes
import com.jieli.jl_audio_decode.opus.model.OpusOption
import com.jieli.jl_audio_decode.callback.OnDecodeStreamCallback
import com.jieli.jl_audio_decode.callback.OnEncodeStreamCallback
import com.jieli.jl_audio_decode.opus.OpusManager
import com.jieli.jl_audio_decode.exceptions.OpusException
@ -78,6 +79,7 @@ object BleService {
private var audioChar: BluetoothGattCharacteristic? = null
private var writeChar1: BluetoothGattCharacteristic? = null
var recordfile: RecordingFile? = null
var recordfile1: RecordingFile? = null
// 扫描相关
private lateinit var scanHandler: Handler
private val scanResults = ArrayList<ScanResult>()
@ -173,6 +175,7 @@ object BleService {
try {
opusManager = OpusManager()
startOpusStreamDecoding()
startEncodeStream()
Log.d(TAG, "OpusManager初始化成功")
} catch (e: OpusException) {
Log.e(TAG, "OpusManager初始化失败: ${e.message}", e)
@ -180,6 +183,9 @@ object BleService {
}
recordfile = RecordingFile(this.context)
recordfile!!.fileName = "不拆分"
recordfile1 = RecordingFile(this.context)
recordfile1!!.fileName = "重新压缩"
isInitialized = true
Log.d(TAG, "BLE服务初始化成功")
return true
@ -953,11 +959,13 @@ object BleService {
codecStatus == BleConst.CODEC_CONTROL_A2DP_PLAY ||
codecStatus == BleConst.CODEC_CONTROL_ENCODE_ON
) {
recordfile1!!.closeFile()
recordfile1!!.creatingFiles()
recordfile!!.closeFile()
recordfile!!.creatingFiles()
} else if (codecStatus == BleConst.CODEC_CONTROL_CLOSE) {
recordfile!!.closeFile()
recordfile1!!.closeFile()
}
// 声道模式描述
val channelDesc = when (channelMode) {
@ -1152,7 +1160,31 @@ object BleService {
override fun onDecodeStream(data: ByteArray?) {
if (data != null) {
// Log.d(TAG, "Opus解码数据: ${data.size} bytes")
notifyAudioDataReceived(data)
//解码数据再重新编码回去
val sampleCount = data.size / 4 // 每个样本4字节(左右声道各2字节)
val leftBuffer = ByteArray(sampleCount * 2) // 左声道缓冲区
val rightBuffer = ByteArray(sampleCount * 2) // 右声道缓冲区
// 拆分交错的左右声道数据
for (i in 0 until sampleCount) {
val stereoIndex = i * 4
val monoIndex = i * 2
// 左声道(低位字节在前,高位字节在后)
leftBuffer[monoIndex] = data[stereoIndex]
leftBuffer[monoIndex + 1] = data[stereoIndex + 1]
// 右声道
rightBuffer[monoIndex] = data[stereoIndex + 2]
rightBuffer[monoIndex + 1] = data[stereoIndex + 3]
}
// // 将左右声道数据分别放入队列
// leftChannelQueue.offer(leftBuffer)
// rightChannelQueue.offer(rightBuffer)
opusManager?.writeEncodeStream(rightBuffer)
notifyAudioDataReceived(rightBuffer)
}
}
@ -1194,7 +1226,60 @@ object BleService {
return false
}
// ======================================================================================================
// Opus 编码相关
// ======================================================================================================
private fun startEncodeStream(
hasHeader: Boolean = false, // 通常BLE传输的Opus没有文件头
channel: Int = 1,
sampleRate: Int = 16000, // 确认设备端Opus编码采样率
packetSize: Int = 40 // 确认设备端Opus编码帧长,必须与iOS版本frameSize保持一致
): Boolean {
if (opusManager == null) {
Log.e(TAG, "OpusManager未初始化,无法开始编码")
return false
}
// 如果已经在解码流,先停止
if (opusManager?.isEncodeStream == true) {
opusManager?.stopEncodeStream()
Log.d(TAG, "已停止正在进行的Opus编码流")
}
var streamStartedSuccessfully = false
opusManager?.startEncodeStream(object : OnEncodeStreamCallback {
override fun onEncodeStream(data: ByteArray?) {
if (data != null) {
// Log.d(TAG, "Opus解码数据: ${data.size} bytes")
//notifyAudioDataReceived(data)
writeChar1!!.value=data
recordfile1!!.saveAudioDataToWav(data)
val isSuccess = bluetoothGatt?.writeCharacteristic(writeChar1)
if (isSuccess == true) {
Log.d(TAG, "发送opus数据")
}
}
}
override fun onStart() {
streamStartedSuccessfully = true
Log.i(TAG, "Opus数据流编码已开始")
// 可以通过回调通知上层解码已开始
}
override fun onComplete(outPath: String?) {
Log.i(TAG, "Opus数据流编码完成: $outPath (通常流式编码不会调用此方法)")
}
override fun onError(code: Int, message: String?) {
Log.e(TAG, "Opus数据流编码错误: [$code] $message")
// 可以通过回调通知上层解码错误
}
})
return true // 暂定为调用即成功
}
// ======================================================================================================
// 公开的命令接口
// ======================================================================================================

Loading…
Cancel
Save