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

AVAssetWriter录制视频后播放无声音且AVPlayerItemDidPlayToEndTime通知不触发

问题排查与修复方案

一、回放无声音问题

核心原因

当前代码最核心的问题是音频采样的时间戳未做偏移对齐:
你创建AVAssetWriter时调用了writer.startSession(atSourceTime: .zero),写入视频帧时做了时间偏移CMTime(seconds: timestamp - _time, preferredTimescale: CMTimeScale(600)),但写入音频帧时直接使用了原始采集的sampleBuffer,原始sampleBuffer的时间戳是系统采集的绝对时间,和writer的起始时间轴完全不匹配,导致音频数据被判定为无效、不会被写入到最终文件中。

修复代码

在写入音频时,需要对音频sampleBuffer做时间戳偏移调整:

} else if output == _audioOutput {
    if _assetWriterAudioInput?.isReadyForMoreMediaData == true {
        // 调整音频时间戳
        let originalTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
        let adjustedTime = CMTime(seconds: originalTime.seconds - _time, preferredTimescale: originalTime.timescale)
        // 生成偏移后的新sampleBuffer
        var adjustedSampleBuffer: CMSampleBuffer?
        var timingInfo = CMSampleTimingInfo(duration: CMSampleBufferGetDuration(sampleBuffer), presentationTimeStamp: adjustedTime, decodeTimeStamp: CMSampleBufferGetDecodeTimeStamp(sampleBuffer))
        CMSampleBufferCreateCopyWithNewTiming(allocator: kCFAllocatorDefault, sampleBuffer: sampleBuffer, sampleTimingEntryCount: 1, sampleTimingArray: &timingInfo, sampleBufferOut: &adjustedSampleBuffer)
        if let adjustedBuffer = adjustedSampleBuffer {
            _assetWriterAudioInput?.append(adjustedBuffer)
        }
    }
}

其他注意事项

  • 建议去掉AVAssetWriter初始化的try!,添加异常捕获逻辑,避免因音频/视频配置无效导致写入失败
  • 写入完成后可以先校验输出文件的AVAsset是否包含音频轨道,排查是否在写入阶段就丢失了音频数据

二、.AVPlayerItemDidPlayToEndTime通知无法触发问题

常见原因及修复

  1. 观察者未在主线程添加:该通知默认在主线程分发,如果你在子线程添加观察者,会出现收不到通知的情况,添加观察者时需确保在主线程执行:
DispatchQueue.main.async {
    NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd), name: .AVPlayerItemDidPlayToEndTime, object: currentPlayerItem)
}
  1. 播放文件时长无效:如果之前音频时间戳异常导致输出文件的总时长计算错误,播放器无法正确判定播放结束节点,修复音频写入问题后该问题大概率会同步解决
  2. AVQueuePlayer配置问题:检查是否设置了player.actionAtItemEnd = .none,如果设置为.advance且队列中存在后续item,通知会被队列消费不会向外分发
  3. 观察者提前释放:确保持有通知观察者的对象未被提前释放,更换播放item时需先移除旧item的观察者,再给新item添加观察者

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:45:04