Swift中AVAudioRecorder录音文件最大限制设置及实时大小获取问题
为AVAudioRecorder设置最大文件大小及解决文件大小更新延迟问题
一、设置最大文件大小的实现方案
AVAudioRecorder没有原生的最大文件大小设置API,需要通过自定义逻辑实现:
方法1:通过比特率预估录制时长
先根据音频配置的比特率,计算达到目标文件大小对应的录制时长,到点自动停止录制:
- 从AVAudioRecorder的settings中提取比特率(
AVEncoderBitRateKey) - 计算目标时长:
目标时长(秒) = (目标文件大小(字节) * 8) / 比特率(比特/秒) - 启动定时器,到达时长后调用
stop()终止录制
代码示例:
// 示例:设置最大文件大小为10MB let maxFileSize: Int64 = 10 * 1024 * 1024 guard let bitRate = audioRecorder.settings[AVEncoderBitRateKey] as? Int else { return } let maxDuration = Double(maxFileSize * 8) / Double(bitRate) // 启动定时停止任务 Timer.scheduledTimer(withTimeInterval: maxDuration, repeats: false) { [weak self] _ in self?.audioRecorder.stop() }
方法2:实时监控数据量(更精准)
利用AVAudioRecorder的currentTime结合比特率计算实时文件大小,每秒检查一次,达到阈值就停止录制:
// 每秒执行一次大小检查 Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] timer in guard let self = self, self.audioRecorder.isRecording else { timer.invalidate() return } guard let bitRate = self.audioRecorder.settings[AVEncoderBitRateKey] as? Int else { return } // 实时大小计算:比特率(bit/s) * 录制时长(s) / 8 = 字节数 let realTimeSize = Int64(Double(bitRate) * self.audioRecorder.currentTime / 8) if realTimeSize >= maxFileSize { self.audioRecorder.stop() timer.invalidate() } }
二、解决FileManager获取文件大小延迟的问题
你之前用FileManager读取文件属性出现延迟,是因为AVAudioRecorder会先将录制数据缓存到内存,每隔2-3秒才批量写入磁盘,磁盘文件大小不会实时更新。
更可靠的方式是通过比特率+录制时长计算实时大小(如上方法2的代码),无需依赖磁盘文件的状态。如果一定要读取磁盘文件的实时大小,可以尝试强制刷新系统缓存:
func getRealTimeFileSize() throws -> Int64 { let fileURL = audioRecorder.url // 强制刷新文件属性缓存 try fileURL.resourceValues(forKeys: [.fileSizeKey]) let values = try fileURL.resourceValues(forKeys: [.fileSizeKey]) return values.fileSize ?? 0 }
不过这种方法仍可能受系统缓存影响,不如计算方式稳定。
内容的提问来源于stack exchange,提问作者lolCheck
相关产品推荐
相关产品推荐

