Browse Source

1

newdev_shunjiawei
fdp 1 year ago
parent
commit
6f90be1fcc
  1. BIN
      local_plugins/ble_service/android/libs/jl_audio_decode_V2.1.0_20013-release.aar
  2. 46
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/BleService.kt
  3. 35
      local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/OpusAudioManager.kt

BIN
local_plugins/ble_service/android/libs/jl_audio_decode_V2.1.0_20013-release.aar

Binary file not shown.

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

@ -856,15 +856,15 @@ object BleService {
//要先设置音频服务的通知,否则接收不到
// 设置音频服务的通知(如果存在)
if (audioChar != null) {
setupNotifications(g, audioChar)
Log.i(TAG, "音频服务特征找到并设置通知")
setupNotifications(g, audioChar)
Log.i(TAG, "音频服务特征找到并设置通知")
} else {
Log.w(TAG, "音频服务特征未找到")
}
// 设置主服务的通知
setupNotifications(g, notifyChar)
setupNotifications(g, notifyChar)
// 在服务发现完成后,请求最大MTU
requestMaxMtu(g)
@ -885,7 +885,7 @@ object BleService {
}
// 通知特征数据(命令和控制)
BleConst.NOTIFY_CHAR_UUID -> {
// Log.i(TAG, "收到通知特征数据(命令和控制)")
Log.i(TAG, "收到通知特征数据(命令和控制)")
// 判断数据类型
when {
// 设备响应 (0xBB开头)
@ -955,17 +955,41 @@ object BleService {
/**
* 设置特征的通知功能
* @param g BluetoothGatt实例
* @param characteristic 要设置通知的特征
*/
private fun setupNotifications(g: BluetoothGatt, characteristic: BluetoothGattCharacteristic?) {
private fun setupNotifications(g: BluetoothGatt, characteristic: BluetoothGattCharacteristic?) : Boolean{
if (characteristic == null || characteristic.properties.and(BluetoothGattCharacteristic.PROPERTY_NOTIFY) == 0) {
Log.w(TAG, "特征不支持通知功能: ${characteristic?.uuid}")
return
return false
}
// 在本地启用特征通知监听
val localResult = g.setCharacteristicNotification(characteristic, true)
if (!localResult) {
Log.e(TAG, "本地通知设置失败: ${characteristic.uuid}")
return false
}
Log.d(TAG, "本地通知设置成功: ${characteristic.uuid}")
g.setCharacteristicNotification(characteristic, true)
// 获取客户端特征配置描述符
val desc = characteristic.getDescriptor(BleConst.CLIENT_CHAR_CONFIG_UUID)
desc?.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
g.writeDescriptor(desc)
if (desc == null) {
Log.w(TAG, "未找到客户端配置描述符: ${characteristic.uuid}")
return false
}
// 设置描述符值为启用通知
desc.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
// 向远程设备写入描述符(异步操作,结果在onDescriptorWrite回调中处理)
val writeResult = g.writeDescriptor(desc)
if (writeResult) {
Log.d(TAG, "开始写入通知描述符: ${characteristic.uuid}")
} else {
Log.e(TAG, "通知描述符写入请求失败: ${characteristic.uuid}")
}
return true
}
/**

35
local_plugins/ble_service/android/src/main/kotlin/com/yunqiinnovation/ble_service/OpusAudioManager.kt

@ -84,6 +84,9 @@ class OpusAudioManager {
// Opus解码器实例
private var opusManager: OpusManager? = null
private var option: OpusOption? = null
private var opusManager1: OpusManager? = null
private var option1: OpusOption? = null
private val mainHandler = Handler(Looper.getMainLooper())
// 解码音频数据队列和处理线程
@ -124,6 +127,9 @@ class OpusAudioManager {
opusManager = OpusManager()
option = OpusOption()
opusManager1 = OpusManager()
option1 = OpusOption()
// 启动队列处理
startAudioQueueProcessing()
@ -174,6 +180,8 @@ class OpusAudioManager {
// 清理Opus相关资源
opusManager = null
option = null
opusManager1 = null
option1 = null
callback = null
isInitialized = false
@ -312,20 +320,27 @@ class OpusAudioManager {
* @return 是否成功开始编码
*/
fun startEncodeStream(): Boolean {
if (!isInitialized || opusManager == null) {
if (!isInitialized || opusManager1 == null) {
Log.e(TAG, "OpusManager未初始化,无法开始编码")
return false
}
// 如果已经在编码流,先停止
if (opusManager?.isEncodeStream == true) {
if (opusManager1?.isEncodeStream == true) {
Log.d(TAG, "Opus编码流已在运行")
return true
}
// 配置解码参数
option1?.apply {
setHasHead(false)
setChannel(1)
setSampleRate(16000)
setPacketSize(40)
}
try {
Log.d(TAG, "准备开始Opus数据流编码")
opusManager?.startEncodeStream(object : OnEncodeStreamCallback {
opusManager1?.startEncodeStream(object : OnEncodeStreamCallback {
override fun onEncodeStream(data: ByteArray?) {
Log.d(TAG, "Opus编码回调收到数据,大小: ${data?.size ?: 0} bytes")
if (data != null) {
@ -371,8 +386,8 @@ class OpusAudioManager {
* @return 是否成功停止编码
*/
fun stopEncodeStream(): Boolean {
if (opusManager?.isEncodeStream == true) {
opusManager?.stopEncodeStream()
if (opusManager1?.isEncodeStream == true) {
opusManager1?.stopEncodeStream()
stopAudioSendThread() // 停止音频发送线程
Log.i(TAG, "已停止Opus数据流编码")
callback?.onEncodeStreamStateChanged(false)
@ -389,16 +404,16 @@ class OpusAudioManager {
* @param data 音频数据字节数组,通常为PCM格式
*/
fun writeExternalAudioData(data: ByteArray) {
if (!isInitialized || opusManager == null) {
if (!isInitialized || opusManager1 == null) {
Log.e(TAG, "OpusManager未初始化")
return
}
// 如果已经在编码流中,直接写入数据
if (opusManager?.isEncodeStream == true) {
if (opusManager1?.isEncodeStream == true) {
Log.d(TAG, "正在进行Opus编码流,写入音频数据")
// 将外部音频数据写入编码流
opusManager?.writeEncodeStream(data)
opusManager1?.writeEncodeStream(data)
} else {
Log.w(TAG, "Opus编码流未启动,无法写入音频数据")
}
@ -421,7 +436,7 @@ class OpusAudioManager {
* @return 是否正在编码
*/
fun isEncoding(): Boolean {
return opusManager?.isEncodeStream == true
return opusManager1?.isEncodeStream == true
}
/**

Loading…
Cancel
Save