|
|
@ -82,11 +82,13 @@ class OpusAudioManager { |
|
|
// ====================================================================================================== |
|
|
// ====================================================================================================== |
|
|
|
|
|
|
|
|
// Opus解码器实例 |
|
|
// Opus解码器实例 |
|
|
private var opusManager: OpusManager? = null |
|
|
//解码对象 |
|
|
private var option: OpusOption? = null |
|
|
private var decodeOpusManager: OpusManager? = null |
|
|
|
|
|
private var decodeOption: OpusOption? = null |
|
|
|
|
|
|
|
|
private var opusManager1: OpusManager? = null |
|
|
//编码对象 |
|
|
private var option1: OpusOption? = null |
|
|
private var encodeOpusManager: OpusManager? = null |
|
|
|
|
|
private var encodeOption: OpusOption? = null |
|
|
private val mainHandler = Handler(Looper.getMainLooper()) |
|
|
private val mainHandler = Handler(Looper.getMainLooper()) |
|
|
|
|
|
|
|
|
// 解码音频数据队列和处理线程 |
|
|
// 解码音频数据队列和处理线程 |
|
|
@ -124,11 +126,11 @@ class OpusAudioManager { |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
// 初始化OpusManager和OpusOption |
|
|
// 初始化OpusManager和OpusOption |
|
|
opusManager = OpusManager() |
|
|
decodeOpusManager = OpusManager() |
|
|
option = OpusOption() |
|
|
decodeOption = OpusOption() |
|
|
|
|
|
|
|
|
opusManager1 = OpusManager() |
|
|
encodeOpusManager = OpusManager() |
|
|
option1 = OpusOption() |
|
|
encodeOption = OpusOption() |
|
|
|
|
|
|
|
|
// 启动队列处理 |
|
|
// 启动队列处理 |
|
|
startAudioQueueProcessing() |
|
|
startAudioQueueProcessing() |
|
|
@ -178,10 +180,10 @@ class OpusAudioManager { |
|
|
audioSendQueue.clear() |
|
|
audioSendQueue.clear() |
|
|
|
|
|
|
|
|
// 清理Opus相关资源 |
|
|
// 清理Opus相关资源 |
|
|
opusManager = null |
|
|
decodeOpusManager = null |
|
|
option = null |
|
|
decodeOption = null |
|
|
opusManager1 = null |
|
|
encodeOpusManager = null |
|
|
option1 = null |
|
|
encodeOption = null |
|
|
callback = null |
|
|
callback = null |
|
|
|
|
|
|
|
|
isInitialized = false |
|
|
isInitialized = false |
|
|
@ -206,14 +208,14 @@ class OpusAudioManager { |
|
|
sampleRate: Int = 16000, |
|
|
sampleRate: Int = 16000, |
|
|
packetSize: Int = 40 |
|
|
packetSize: Int = 40 |
|
|
): Boolean { |
|
|
): Boolean { |
|
|
if (!isInitialized || opusManager == null) { |
|
|
if (!isInitialized || decodeOpusManager == null) { |
|
|
Log.e(TAG, "OpusManager未初始化,无法开始解码") |
|
|
Log.e(TAG, "OpusManager未初始化,无法开始解码") |
|
|
return false |
|
|
return false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 如果已经在解码流,先停止 |
|
|
// 如果已经在解码流,先停止 |
|
|
if (opusManager?.isDecodeStream == true) { |
|
|
if (decodeOpusManager?.isDecodeStream == true) { |
|
|
opusManager?.stopDecodeStream() |
|
|
decodeOpusManager?.stopDecodeStream() |
|
|
Log.d(TAG, "已停止正在进行的Opus解码流") |
|
|
Log.d(TAG, "已停止正在进行的Opus解码流") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -224,7 +226,7 @@ class OpusAudioManager { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 配置解码参数 |
|
|
// 配置解码参数 |
|
|
option?.apply { |
|
|
decodeOption?.apply { |
|
|
setHasHead(hasHeader) |
|
|
setHasHead(hasHeader) |
|
|
setChannel(channel) |
|
|
setChannel(channel) |
|
|
setSampleRate(sampleRate) |
|
|
setSampleRate(sampleRate) |
|
|
@ -234,10 +236,10 @@ class OpusAudioManager { |
|
|
Log.d(TAG, "准备开始Opus数据流解码, 参数: hasHeader=$hasHeader, channel=$channel, sampleRate=$sampleRate, packetSize=$packetSize") |
|
|
Log.d(TAG, "准备开始Opus数据流解码, 参数: hasHeader=$hasHeader, channel=$channel, sampleRate=$sampleRate, packetSize=$packetSize") |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
opusManager?.startDecodeStream(option, object : OnDecodeStreamCallback { |
|
|
decodeOpusManager?.startDecodeStream(decodeOption, object : OnDecodeStreamCallback { |
|
|
override fun onDecodeStream(data: ByteArray?) { |
|
|
override fun onDecodeStream(data: ByteArray?) { |
|
|
if (data != null) { |
|
|
if (data != null) { |
|
|
val channelCount = option?.getChannel() ?: 1 |
|
|
val channelCount = decodeOption?.getChannel() ?: 1 |
|
|
if (channelCount >= 1) { |
|
|
if (channelCount >= 1) { |
|
|
callback?.onAudioDataDecoded(data, channelCount) |
|
|
callback?.onAudioDataDecoded(data, channelCount) |
|
|
} else { |
|
|
} else { |
|
|
@ -276,8 +278,8 @@ class OpusAudioManager { |
|
|
* @return 是否成功停止解码 |
|
|
* @return 是否成功停止解码 |
|
|
*/ |
|
|
*/ |
|
|
fun stopDecodeStream(): Boolean { |
|
|
fun stopDecodeStream(): Boolean { |
|
|
if (opusManager?.isDecodeStream == true) { |
|
|
if (decodeOpusManager?.isDecodeStream == true) { |
|
|
opusManager?.stopDecodeStream() |
|
|
decodeOpusManager?.stopDecodeStream() |
|
|
|
|
|
|
|
|
// 清理音频数据缓存 |
|
|
// 清理音频数据缓存 |
|
|
synchronized(audioDataBuffer) { |
|
|
synchronized(audioDataBuffer) { |
|
|
@ -303,7 +305,7 @@ class OpusAudioManager { |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (opusManager?.isDecodeStream == true) { |
|
|
if (decodeOpusManager?.isDecodeStream == true) { |
|
|
// 将数据加入队列进行异步处理 |
|
|
// 将数据加入队列进行异步处理 |
|
|
audioDataQueue.offer(data) |
|
|
audioDataQueue.offer(data) |
|
|
} else { |
|
|
} else { |
|
|
@ -320,19 +322,19 @@ class OpusAudioManager { |
|
|
* @return 是否成功开始编码 |
|
|
* @return 是否成功开始编码 |
|
|
*/ |
|
|
*/ |
|
|
fun startEncodeStream(): Boolean { |
|
|
fun startEncodeStream(): Boolean { |
|
|
if (!isInitialized || opusManager1 == null) { |
|
|
if (!isInitialized || encodeOpusManager == null) { |
|
|
Log.e(TAG, "OpusManager未初始化,无法开始编码") |
|
|
Log.e(TAG, "OpusManager未初始化,无法开始编码") |
|
|
return false |
|
|
return false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 如果已经在编码流,先停止 |
|
|
// 如果已经在编码流,先停止 |
|
|
if (opusManager1?.isEncodeStream == true) { |
|
|
if (encodeOpusManager?.isEncodeStream == true) { |
|
|
Log.d(TAG, "Opus编码流已在运行") |
|
|
Log.d(TAG, "Opus编码流已在运行") |
|
|
return true |
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 配置解码参数 |
|
|
// 配置解码参数 |
|
|
option1?.apply { |
|
|
encodeOption?.apply { |
|
|
setHasHead(false) |
|
|
setHasHead(false) |
|
|
setChannel(1) |
|
|
setChannel(1) |
|
|
setSampleRate(16000) |
|
|
setSampleRate(16000) |
|
|
@ -340,7 +342,7 @@ class OpusAudioManager { |
|
|
} |
|
|
} |
|
|
try { |
|
|
try { |
|
|
Log.d(TAG, "准备开始Opus数据流编码") |
|
|
Log.d(TAG, "准备开始Opus数据流编码") |
|
|
opusManager1?.startEncodeStream(object : OnEncodeStreamCallback { |
|
|
encodeOpusManager?.startEncodeStream(object : OnEncodeStreamCallback { |
|
|
override fun onEncodeStream(data: ByteArray?) { |
|
|
override fun onEncodeStream(data: ByteArray?) { |
|
|
Log.d(TAG, "Opus编码回调收到数据,大小: ${data?.size ?: 0} bytes") |
|
|
Log.d(TAG, "Opus编码回调收到数据,大小: ${data?.size ?: 0} bytes") |
|
|
if (data != null) { |
|
|
if (data != null) { |
|
|
@ -386,8 +388,8 @@ class OpusAudioManager { |
|
|
* @return 是否成功停止编码 |
|
|
* @return 是否成功停止编码 |
|
|
*/ |
|
|
*/ |
|
|
fun stopEncodeStream(): Boolean { |
|
|
fun stopEncodeStream(): Boolean { |
|
|
if (opusManager1?.isEncodeStream == true) { |
|
|
if (encodeOpusManager?.isEncodeStream == true) { |
|
|
opusManager1?.stopEncodeStream() |
|
|
encodeOpusManager?.stopEncodeStream() |
|
|
stopAudioSendThread() // 停止音频发送线程 |
|
|
stopAudioSendThread() // 停止音频发送线程 |
|
|
Log.i(TAG, "已停止Opus数据流编码") |
|
|
Log.i(TAG, "已停止Opus数据流编码") |
|
|
callback?.onEncodeStreamStateChanged(false) |
|
|
callback?.onEncodeStreamStateChanged(false) |
|
|
@ -404,16 +406,16 @@ class OpusAudioManager { |
|
|
* @param data 音频数据字节数组,通常为PCM格式 |
|
|
* @param data 音频数据字节数组,通常为PCM格式 |
|
|
*/ |
|
|
*/ |
|
|
fun writeExternalAudioData(data: ByteArray) { |
|
|
fun writeExternalAudioData(data: ByteArray) { |
|
|
if (!isInitialized || opusManager1 == null) { |
|
|
if (!isInitialized || encodeOpusManager == null) { |
|
|
Log.e(TAG, "OpusManager未初始化") |
|
|
Log.e(TAG, "OpusManager未初始化") |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 如果已经在编码流中,直接写入数据 |
|
|
// 如果已经在编码流中,直接写入数据 |
|
|
if (opusManager1?.isEncodeStream == true) { |
|
|
if (encodeOpusManager?.isEncodeStream == true) { |
|
|
Log.d(TAG, "正在进行Opus编码流,写入音频数据") |
|
|
Log.d(TAG, "正在进行Opus编码流,写入音频数据") |
|
|
// 将外部音频数据写入编码流 |
|
|
// 将外部音频数据写入编码流 |
|
|
opusManager1?.writeEncodeStream(data) |
|
|
encodeOpusManager?.writeEncodeStream(data) |
|
|
} else { |
|
|
} else { |
|
|
Log.w(TAG, "Opus编码流未启动,无法写入音频数据") |
|
|
Log.w(TAG, "Opus编码流未启动,无法写入音频数据") |
|
|
} |
|
|
} |
|
|
@ -428,7 +430,7 @@ class OpusAudioManager { |
|
|
* @return 是否正在解码 |
|
|
* @return 是否正在解码 |
|
|
*/ |
|
|
*/ |
|
|
fun isDecoding(): Boolean { |
|
|
fun isDecoding(): Boolean { |
|
|
return opusManager?.isDecodeStream == true |
|
|
return decodeOpusManager?.isDecodeStream == true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -436,7 +438,7 @@ class OpusAudioManager { |
|
|
* @return 是否正在编码 |
|
|
* @return 是否正在编码 |
|
|
*/ |
|
|
*/ |
|
|
fun isEncoding(): Boolean { |
|
|
fun isEncoding(): Boolean { |
|
|
return opusManager1?.isEncodeStream == true |
|
|
return encodeOpusManager?.isEncodeStream == true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
@ -488,7 +490,7 @@ class OpusAudioManager { |
|
|
val audioData = audioDataQueue.take() // 阻塞等待 |
|
|
val audioData = audioDataQueue.take() // 阻塞等待 |
|
|
|
|
|
|
|
|
// 将音频数据写入Opus解码流 |
|
|
// 将音频数据写入Opus解码流 |
|
|
opusManager?.writeAudioStream(audioData) |
|
|
decodeOpusManager?.writeAudioStream(audioData) |
|
|
|
|
|
|
|
|
} catch (e: InterruptedException) { |
|
|
} catch (e: InterruptedException) { |
|
|
Log.d(TAG, "音频队列处理线程被中断") |
|
|
Log.d(TAG, "音频队列处理线程被中断") |
|
|
|