|
|
@ -26,22 +26,32 @@ class SwiftOpusAudioProcessor: NSObject { |
|
|
cleanup() |
|
|
cleanup() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 线程安全的解码器初始化 |
|
|
private func initializeOpusDecoder() -> Bool { |
|
|
private func initializeOpusDecoder() -> Bool { |
|
|
|
|
|
objc_sync_enter(self) |
|
|
|
|
|
defer { objc_sync_exit(self) } |
|
|
|
|
|
|
|
|
if decoder != nil { |
|
|
if decoder != nil { |
|
|
return true |
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var error: Int32 = 0 |
|
|
var error: Int32 = 0 |
|
|
decoder = opus_decoder_create(sampleRate, channels, &error) |
|
|
let newDecoder = opus_decoder_create(sampleRate, channels, &error) |
|
|
|
|
|
|
|
|
guard error == OPUS_OK, decoder != nil else { |
|
|
guard error == OPUS_OK, newDecoder != nil else { |
|
|
|
|
|
print("Opus解码器创建失败,错误代码: \(error)") |
|
|
return false |
|
|
return false |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
decoder = newDecoder |
|
|
return true |
|
|
return true |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 线程安全的解码器销毁 |
|
|
private func destroyOpusDecoder() { |
|
|
private func destroyOpusDecoder() { |
|
|
|
|
|
objc_sync_enter(self) |
|
|
|
|
|
defer { objc_sync_exit(self) } |
|
|
|
|
|
|
|
|
if let decoder = decoder { |
|
|
if let decoder = decoder { |
|
|
opus_decoder_destroy(decoder) |
|
|
opus_decoder_destroy(decoder) |
|
|
self.decoder = nil |
|
|
self.decoder = nil |
|
|
@ -112,23 +122,44 @@ class SwiftOpusAudioProcessor: NSObject { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 简化的 Opus 解码方法,重点是容错处理 |
|
|
/// 改进的 Opus 解码方法,增强容错和线程安全 |
|
|
private func decodeOpusPacket(_ packet: Data) { |
|
|
private func decodeOpusPacket(_ packet: Data) { |
|
|
guard let decoder = decoder else { return } |
|
|
// 添加线程安全锁 |
|
|
|
|
|
objc_sync_enter(self) |
|
|
|
|
|
defer { objc_sync_exit(self) } |
|
|
|
|
|
|
|
|
|
|
|
// 验证解码器状态 |
|
|
|
|
|
guard let decoder = decoder, isDecodingActive else { |
|
|
|
|
|
print("解码器未初始化或已停止") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
let maxSamples = Int(maxFrameSize) |
|
|
let maxSamples = Int(maxFrameSize) |
|
|
var pcmBuffer = [opus_int16](repeating: 0, count: maxSamples * Int(channels)) |
|
|
var pcmBuffer = [opus_int16](repeating: 0, count: maxSamples * Int(channels)) |
|
|
|
|
|
|
|
|
let decodedSamples = packet.withUnsafeBytes { packetPtr in |
|
|
let decodedSamples = packet.withUnsafeBytes { packetPtr in |
|
|
let uint8Ptr = packetPtr.bindMemory(to: UInt8.self).baseAddress |
|
|
// 确保指针有效 |
|
|
return opus_decode( |
|
|
guard let uint8Ptr = packetPtr.bindMemory(to: UInt8.self).baseAddress else { |
|
|
decoder, |
|
|
print("无法获取数据包指针") |
|
|
uint8Ptr, |
|
|
return opus_int32(-1) |
|
|
opus_int32(packet.count), |
|
|
} |
|
|
&pcmBuffer, |
|
|
|
|
|
Int32(maxSamples), |
|
|
// 添加异常捕获机制 |
|
|
0 |
|
|
var result: opus_int32 = -1 |
|
|
) |
|
|
|
|
|
|
|
|
// 使用 autoreleasepool 确保内存管理 |
|
|
|
|
|
autoreleasepool { |
|
|
|
|
|
result = opus_decode( |
|
|
|
|
|
decoder, |
|
|
|
|
|
uint8Ptr, |
|
|
|
|
|
opus_int32(packet.count), |
|
|
|
|
|
&pcmBuffer, |
|
|
|
|
|
Int32(maxSamples), |
|
|
|
|
|
0 |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return result |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 增强的错误处理:检查各种错误情况 |
|
|
// 增强的错误处理:检查各种错误情况 |
|
|
@ -237,4 +268,4 @@ class SwiftOpusAudioProcessor: NSObject { |
|
|
func getCurrentConfig() -> (sampleRate: Int32, channels: Int32) { |
|
|
func getCurrentConfig() -> (sampleRate: Int32, channels: Int32) { |
|
|
return (sampleRate, channels) |
|
|
return (sampleRate, channels) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|