You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中AVAudioRecorder录音文件最大限制设置及实时大小获取问题

为AVAudioRecorder设置最大文件大小及解决文件大小更新延迟问题

一、设置最大文件大小的实现方案

AVAudioRecorder没有原生的最大文件大小设置API,需要通过自定义逻辑实现:

方法1:通过比特率预估录制时长

先根据音频配置的比特率,计算达到目标文件大小对应的录制时长,到点自动停止录制:

  1. 从AVAudioRecorder的settings中提取比特率(AVEncoderBitRateKey)
  2. 计算目标时长:目标时长(秒) = (目标文件大小(字节) * 8) / 比特率(比特/秒)
  3. 启动定时器,到达时长后调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 08:33:35