使用AudioQueueNewInput+WebSocket流式传录音丢失首段音频求助
音频流式传输开头数据包丢失的解决方案
问题根源
你当前的逻辑中,首次生成的音频数据包因为connected为false(还没收到服务器的就绪确认)被直接丢弃,同时currentPacket直接递增,导致这个数据包没有被保留等待后续发送,这就是开头约500ms音频丢失的核心原因。
具体解决建议
新增缓存队列暂存未就绪的音频数据
在录音相关类里新增一个数组或队列,用来临时存储还不能发送的音频数据包。修改readyRecordingData的逻辑:当不满足发送条件时,把音频数据加入缓存,而非直接返回。等connected变为true后,先发送缓存里的所有数据,再处理当前的数据包。
示例代码:// 在Recorder类中新增缓存队列 private var pendingAudioData: [Data] = [] func readyRecordingData(audio: Data) { if (!recordingStarted || !connected) { pendingAudioData.append(audio) return } // 先发送缓存中暂存的数据包 for cachedData in pendingAudioData { // 替换成你实际的WebSocket发送逻辑 webSocketTask?.send(cachedData) } pendingAudioData.removeAll() // 发送当前的音频数据包 webSocketTask?.send(audio) }修正currentPacket的递增时机
不要在生成数据包后立即递增currentPacket,而是等到数据包被成功加入缓存或发送后再递增,确保数据包序号和实际数据一一对应,避免序号跳变导致后续数据异常。
示例调整:// 原startStreaming中的代码 liveRecorder.delegate?.readyRecordingData(audio: audioData) // 移除这里的currentPacket递增,移到readyRecordingData里 // 在readyRecordingData的末尾添加: liveRecorder.currentPacket += Int64(inNumPackets)调整连接与录音的启动时序
当前点击录音按钮后,调用connect()就立即启动startStreaming,但WebSocket连接和服务器就绪确认是异步操作。可以改成等收到服务器的就绪确认后再启动录音,从根源上避免首次数据包无法发送的问题:func startRecording() { if !connected { connect() // 移除这里的startStreaming调用,改为在WebSocket收到就绪确认的回调中触发 // 比如在WebSocket的message回调中: // func webSocket(_ webSocket: URLSessionWebSocketTask, didReceive message: URLSessionWebSocketTask.Message) { // if message是服务器就绪信号 { // connected = true // startStreaming() // } // } } else { startStreaming() } }处理缓存的边界情况
当用户停止录音时,要确保缓存队列中剩余的数据包都被发送出去;如果遇到WebSocket断开重连的场景,根据业务需求决定是否重新发送缓存中的数据。
内容的提问来源于stack exchange,提问作者Ryan H
相关产品推荐
相关产品推荐

