【问题标题】:MP4 videos created with AVMutableComposition and AVAssetExportSession work in Quicktime, but appear corrupted in all other video tools使用 AVMutableComposition 和 AVAssetExportSession 创建的 MP4 视频在 Quicktime 中工作,但在所有其他视频工具中显示已损坏
【发布时间】:2018-12-16 21:16:10
【问题描述】:

我正在尝试在 macOS 上使用 Swift、AVFoundation 和 AVKit 将多部电影的片段一起编辑到一个剪辑中。以下 Swift 代码是我正在尝试做的一个很好的例子:

import AVFoundation
import AVKit

let source1 = AVAsset(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
let source2 = AVAsset(url: URL(string: "http://techslides.com/demos/sample-videos/small.mp4")!)

let comp = AVMutableComposition()

comp.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)
comp.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)

func cmtime(_ i: Double) -> CMTime {
    return CMTime(seconds: i, preferredTimescale: 600)
}

func insertSecond(into: AVMutableComposition, from: AVAsset, start: CMTime, at: CMTime) throws {
    let videoTrack = into.tracks(withMediaType: .video).first!
    let audioTrack = into.tracks(withMediaType: .audio).first!
    try videoTrack.insertTimeRange(
        CMTimeRange(start: start , duration: cmtime(1.0)),
        of: from.tracks(withMediaType: .video).first!,
        at: at
    )
    try audioTrack.insertTimeRange(
        CMTimeRange(start: start, duration: cmtime(1.0)),
        of: from.tracks(withMediaType: .audio).first!,
        at: at
    )
}

try insertSecond(into: comp, from: source1, start: cmtime(3.0), at: cmtime(0.0))
try insertSecond(into: comp, from: source2, start: cmtime(2.0), at: cmtime(1.0))
try insertSecond(into: comp, from: source1, start: cmtime(100.0), at: cmtime(2.0))
try insertSecond(into: comp, from: source2, start: cmtime(3.0), at: cmtime(3.0))
try insertSecond(into: comp, from: source1, start: cmtime(350.0), at: cmtime(4.0))


if let sess = AVAssetExportSession(asset: comp, presetName: "AVAssetExportPresetHighestQuality") {
    sess.outputURL = URL(fileURLWithPath: "/tmp/output.mp4")
    sess.outputFileType = .mp4
    sess.exportAsynchronously {
        print("done")
        print(sess.error ?? "success")
    }
}

运行此代码确实会成功生成output.mp4 文件,并且该文件可以在 Quicktime 中毫无问题地播放。您应该能够将上述代码粘贴到 Playground 中以重现视频(源视频都是托管在网络上的所有公开可用的示例视频)。我也有uploaded it to S3 here,所以你可以下载并分析它,而不必自己运行代码。

但是,尝试使用任何其他视频软件打开或处理它会导致错误。

VLC 将尝试播放该文件,但处理起来非常困难。视频冻结很多,与音频不同步,包含 Quicktime 根本不显示的帧,并且完全跳过了某些部分。

Firefox 也会尝试播放文件,但显然无法正确解码,并且视频输出有问题。 Chrome 在播放的第一秒后冻结。

我尝试使用ffprobeffmpeg 进一步诊断。

运行ffprobe -show_frames output.mp4 1>/dev/null 显示:

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fe841801800] DTS -24000 < 24000 out of order
[h264 @ 0x7fe843022800] reference count overflow
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] top block unavailable for requested intra mode -1
[h264 @ 0x7fe843022800] error while decoding MB 5 0, bytestream 947
[h264 @ 0x7fe843022800] concealing 3600 DC, 3600 AC, 3600 MV errors in P frame
[h264 @ 0x7fe843022800] mmco: unref short failure
[h264 @ 0x7fe843022800] cabac_init_idc 4 overflow
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!
[h264 @ 0x7fe843022800] deblocking filter parameters -43 0 out of range
[h264 @ 0x7fe843022800] decode_slice_header error
[h264 @ 0x7fe843022800] no frame!

尝试使用 ffmpeg (ffmpeg -i output.mp4 output.avi) 转码为另一种格式会出现很多警告和错误:

[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 73, current: 71; changing to 74. This may result in incorrect timestamps in the output file.
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fe1f4802800] DTS -24000 < 24000 out of order
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 74, current: 72; changing to 75. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 75, current: 73; changing to 76. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 76, current: 74; changing to 77. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 77, current: 75; changing to 78. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f4849600] reference count overflow
[h264 @ 0x7fe1f4849600] decode_slice_header error
[h264 @ 0x7fe1f4849600] no frame!
Error while decoding stream #0:1: Invalid data found when processing input
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 145, current: 143; changing to 146. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 146, current: 144; changing to 147. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 147, current: 145; changing to 148. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f483d800] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe1f483d800] decode_slice_header error
[h264 @ 0x7fe1f483d800] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 148, current: 146; changing to 149. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 149, current: 147; changing to 150. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f4849600] deblocking_filter_idc 6 out of range
[h264 @ 0x7fe1f4849600] decode_slice_header error
[h264 @ 0x7fe1f4849600] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 150, current: 148; changing to 151. This may result in incorrect timestamps in the output file.
Error while decoding stream #0:1: Invalid data found when processing input
    Last message repeated 1 times
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 151, current: 149; changing to 152. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 152, current: 150; changing to 153. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 153, current: 151; changing to 154. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 154, current: 152; changing to 155. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 155, current: 153; changing to 156. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 156, current: 154; changing to 157. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 157, current: 155; changing to 158. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 158, current: 156; changing to 159. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 159, current: 157; changing to 160. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 160, current: 158; changing to 161. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 161, current: 159; changing to 162. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 162, current: 160; changing to 163. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 163, current: 161; changing to 164. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 164, current: 162; changing to 165. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 165, current: 163; changing to 166. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 166, current: 164; changing to 167. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 167, current: 165; changing to 168. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 168, current: 166; changing to 169. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 169, current: 167; changing to 170. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 170, current: 168; changing to 171. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 171, current: 169; changing to 172. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 172, current: 170; changing to 173. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 173, current: 171; changing to 174. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 174, current: 172; changing to 175. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 175, current: 173; changing to 176. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 176, current: 174; changing to 177. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 177, current: 175; changing to 178. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 178, current: 176; changing to 179. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 179, current: 177; changing to 180. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 180, current: 178; changing to 181. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 181, current: 179; changing to 182. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 182, current: 180; changing to 183. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 183, current: 181; changing to 184. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 184, current: 182; changing to 185. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f483d800] top block unavailable for requested intra mode -1
[h264 @ 0x7fe1f483d800] error while decoding MB 5 0, bytestream 947
[h264 @ 0x7fe1f483d800] concealing 3600 DC, 3600 AC, 3600 MV errors in P frame
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 185, current: 183; changing to 186. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 186, current: 184; changing to 187. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f4849600] mmco: unref short failure
[h264 @ 0x7fe1f4849600] cabac_init_idc 4 overflow
[h264 @ 0x7fe1f4849600] decode_slice_header error
[h264 @ 0x7fe1f4849600] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 187, current: 185; changing to 188. This may result in incorrect timestamps in the output file.
[h264 @ 0x7fe1f485fa00] deblocking filter parameters -43 0 out of range
[h264 @ 0x7fe1f485fa00] decode_slice_header error
[h264 @ 0x7fe1f485fa00] no frame!
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 188, current: 186; changing to 189. This may result in incorrect timestamps in the output file.
Error while decoding stream #0:1: Invalid data found when processing input
    Last message repeated 1 times
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 189, current: 187; changing to 190. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 190, current: 188; changing to 191. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 191, current: 189; changing to 192. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 192, current: 190; changing to 193. This may result in incorrect timestamps in the output file.
[avi @ 0x7fe1f5804e00] Non-monotonous DTS in output stream 0:1; previous: 193, current: 191; changing to 194. This may result in incorrect timestamps in the output file.

上面的代码只是一个例子,我在这个代码的许多变体中看到了不同严重程度的类似问题。我尝试了很多方法,包括:

  • 使用本地文件网址而不是 HTTPS 网址
  • 使用.mov 而不是.mp4 文件
  • 使用AVMovieAVMutableMovie(以及各种设置调整,例如将AVURLAssetPreferPreciseDurationAndTimingKey 设置为true)而不是AVMutableComposition
  • AVAssetExportSession 上调整设置(预设等)
  • 以不同方式构造 CMTime 对象

但无济于事——我似乎无法让 AVFoundation 生成其他工具可以处理的视频文件。

如果您不能或不想运行上面的 Swift 代码来自己重现它,那么您可以提供任何帮助,甚至是关于输出文件编码异常之处的任何想法,you can download here

【问题讨论】:

    标签: swift ffmpeg avfoundation mp4 avmutablecomposition


    【解决方案1】:

    我同意其他播放器的播放问题源于每首曲目的格式描述不止一种。但实际上不需要在合成之前对音轨进行昂贵的转码,AVFoundation 可以为您做到这一点……如果您愿意跳过几圈。

    关键是AVMutableComposition 可以有多个特定媒体类型的轨道,而AVAssetExportSession 可以将此类组合“混合”为每种媒体类型只有一个轨道。 AVFoundation 通过提供mutableTrackCompatibleWithTrack: 来承认每个轨道有多种格式描述的问题。因此,当您想从给定的源轨道插入片段时,您可以向AVMutableComposition 询问合适的目标轨道,如果没有返回,则添加新的。

    如前所述,有几点需要牢记:

    • 您不能在当前结束后的“无效时间”中的某处插入给定的目标轨道。要解决此问题,请记下目标轨道的当前结束时间,附加该时间段,然后在此之后在前一个轨道结束时插入一个正确持续时间的空段。下面的示例显示了这一点,在简化的假设下,您总是在附加。如果您想在现有音轨中的任何位置插入,则需要在此处进行更精细的逻辑。

    • 要真正让AVAssetExportSession 将所有内容混合到每种媒体类型只有一个轨道,您必须在导出会话上设置一个 AVAudioMix 和一个 AVVideoComposition。

    下面的示例代码基于您的原始示例,生成了一个 output.mp4,它可以在 VLC、Chrome 和 Firefox 中正确播放,并且在使用 ffmpeg 检查时不会引发任何错误。

    import AVFoundation
    import Foundation
    
    let source0 = AVAsset(url: URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")!)
    let source1 = AVAsset(url: URL(string: "http://techslides.com/demos/sample-videos/small.mp4")!)
    
    let comp = AVMutableComposition()
    
    func cmtime(_ i: Double) -> CMTime {
        return CMTime(seconds: i, preferredTimescale: 600)
    }
    
    func insertTrackSecond( srcAsset: AVAsset, dstComp: AVMutableComposition, mediaType: AVMediaType, start: CMTime, at: CMTime) throws {
        let srcTrack: AVAssetTrack = srcAsset.tracks(withMediaType: mediaType).first!
    
        // get a compatible destination track or, if not available, create a new one
        let dstTrack: AVMutableCompositionTrack = dstComp.mutableTrack(compatibleWith: srcTrack) ?? dstComp.addMutableTrack(withMediaType: mediaType, preferredTrackID: kCMPersistentTrackID_Invalid)!
    
        // can't insert into "void" time beyond the current end of track. Instead, note current end time, append there, and *after* appending, insert empty range
        var dstTrackEnd: CMTime = CMTimeRangeGetEnd( dstTrack.timeRange)
        if CMTIME_IS_INVALID( dstTrackEnd) {
            dstTrackEnd = kCMTimeZero
        }
    
        try dstTrack.insertTimeRange( CMTimeRangeMake( start, cmtime( 1.0)), of: srcTrack, at: dstTrackEnd)
    
        // now add empty range, if necessary
        if CMTimeCompare( dstTrackEnd, at) == -1 {
            dstTrack.insertEmptyTimeRange( CMTimeRangeFromTimeToTime( dstTrackEnd, at))
        }
    }
    
    func insertSecond( srcAsset: AVAsset, dstComp: AVMutableComposition, start: CMTime, at: CMTime) throws
    {
        try insertTrackSecond(srcAsset: srcAsset, dstComp: dstComp, mediaType: .video, start: start, at: at)
        try insertTrackSecond(srcAsset: srcAsset, dstComp: dstComp, mediaType: .audio, start: start, at: at)
    }
    
    try insertSecond( srcAsset: source0, dstComp: comp, start: cmtime(3.0), at: cmtime(0.0))
    try insertSecond( srcAsset: source1, dstComp: comp, start: cmtime(2.0), at: cmtime(1.0))
    try insertSecond( srcAsset: source0, dstComp: comp, start: cmtime(100.0), at: cmtime(2.0))
    try insertSecond( srcAsset: source1, dstComp: comp, start: cmtime(3.0), at: cmtime(3.0))
    try insertSecond( srcAsset: source0, dstComp: comp, start: cmtime(350.0), at: cmtime(4.0))
    
    
    if let sess = AVAssetExportSession(asset: comp, presetName: "AVAssetExportPresetHighestQuality") {
        sess.outputURL = URL(fileURLWithPath: "/tmp/output.mp4")
        sess.outputFileType = .mp4
    
        // this leaves smaller videotracks at the origin, in their "natural" size. Manipulate the "preferredTransform" property of the mutable composition tracks for nicer results
        sess.videoComposition = AVVideoComposition.init(propertiesOf: comp)
    
        // not assigning an audio mix results in an output with multiple audio tracks
        var inputParameters = [AVAudioMixInputParameters]()
        for audioTrack: AVAssetTrack in comp.tracks(withMediaType:.audio) {
            inputParameters.append( AVMutableAudioMixInputParameters.init(track:audioTrack))
        }
        let audioMix: AVMutableAudioMix = AVMutableAudioMix();
        audioMix.inputParameters = inputParameters;
        sess.audioMix = audioMix;
    
        let semaphore: DispatchSemaphore = DispatchSemaphore(value:0);
    
        sess.exportAsynchronously {
            print("done")
            print(sess.error ?? "success")
            semaphore.signal()
        }
    
        semaphore.wait()
    }
    

    【讨论】:

    • 这太棒了
    • 哇,谢谢,这太棒了!我现在比较忙,但我会详细阅读以尝试了解发生了什么,并在我有空闲时间时试一试(很可能会接受您的回答)。
    • 这确实有效,非常感谢!但是,让我非常困惑的是,您必须额外调用 insertEmptyTimeRange 才能正确附加到合成。在我看来,我无法从文档中推断出这一点,而且我的直觉会让我相信这样的代码会导致视频和空虚的交替出现。我很想阅读更多有关此内容的信息,或阅读有关 AVFoundation 或这些格式的任何其他资源,这将使我对此类事情有更好的直觉。你知道我能读到什么吗?
    • 令人沮丧的是,不,我不知道。在过去的十年里,我主要通过反复试验来学习这些东西,因为我不得不这样做。当时的 QuickTime 文档 iirc 中有“没有插入无效时间”。使用 AVFoundation,恕我直言,情况更糟:过度设计的 API、不完整的文档、缺少的功能以及似乎从未引起任何关注的错误报告。不过,与其他任何框架相比,我更倾向于查看 AVFoundation 的 ObjC 头文件;那里的 cmets 通常比 API 文档更准确(有时甚至与 API 文档相矛盾)......
    • 有趣 是的,我发现查看源 cmets 是学习其他工具的好方法,我以后会尝试做更多。感谢所有的建议!不幸的是——AVFoundation 似乎是一个非常强大的工具,可惜文档太差了。
    【解决方案2】:

    正如@RhythmicFistman 所说,您的视频流是多个具有不同属性的 H264 流的集合。 H264 流的参数通常可以存储在带内(称为附件 B)或存储在 MP4 之类的容器(stsd)中时的全局元数据中。 AVF 在这里所做的是添加多个 stsd 条目。

    stsd: s=       326 (0x00000146), o=   1982552 (0x001e4058)
                          version: 0
                          flags: 0x000000
                          sample_descriptions (0x00000002):
                            size: 0000009b
                            data_format: avc1 (61 76 63 31)
                            ...
                            size: 0000009b
                            data_format: avc1 (61 76 63 31)
                            ...
    

    大多数播放器会忽略额外的条目,但解码器需要此比特流配置来(重新)初始化。

    有两种前进方式。

    使用相同的编码属性重新编码每个单独的段,以便在连接后,缺少解码器重新初始化实际上不是问题,

    获取 AVF 或其他工具(如 mp4box)将流连接为 avc3 流,从而比特流参数也存储在带内。解码器应该遇到新的参数集并重新初始化。

    【讨论】:

    • 我刚刚添加了一条评论,我认为它重申了您在 AVFoundation 方面的第一种前进方式。
    【解决方案3】:

    这个问题几乎可以肯定是因为视频和音频的剪辑格式不匹配:

    AVAssetExportSession 可以做很多事情,但它似乎选择了在那里转储所有格式,这可能解释了您的兼容性问题。我明白为什么播放器会感到困惑,这两种视频格式甚至没有相同的宽高比。也许这种行为是一个错误,或者在某些情况下它是完全有意义的。我不知道。

    所以你可以:

    1. 确保您的所有剪辑都具有匹配的格式(我喜欢这个,也许您不希望剪辑混搭在信箱样式/纵横比变化之间跳跃)
    2. 使用AVMutableVideoCompositionLayerInstruction + AVAssetExportSessionAVAssetReader + AVAssetWriter 使格式匹配

    附言我怀疑在这里视频不匹配比音频更重要,所以也许测试会表明您可以忽略音频?

    【讨论】:

    • 啊,谢谢,很有帮助!!我尝试通过仅使用来自单一来源的剪辑来创建视频,以保持格式不变。这在一定程度上有所帮助,但生成的文件(您可以在此处找到:s3.amazonaws.com/avfoundation-video-problem-demo/…)仍未被所有玩家正确处理。 Quicktime 和 Chrome 处理得很好,但 Firefox 和 VLC 仍然有类似的问题,虽然不太严重。 ffmpeg 报告的错误比以前少,尽管它仍然警告[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f9d92801800] DTS -30000 &lt; 24000 out of order
    • 我还尝试了两个不同的视频,每个视频格式相同(H246、720p、AAC 44k Hz 立体声),得到this output,得到的结果与我的原始视频相似。除了 Quicktime 没有其他播放器可以处理视频,ffmpeg 在重新编码时会产生很多错误和损坏的输出(results)供参考,the other source movie I used
    • 啊,抱歉 - 我没有用 ffmpeg 进行测试,当我只看到一种格式时就停止了!谷歌搜索各种 ffmpeg 警告会发现有人使用通过AVAssetReaderAVAssetWriter 有效转码/重新编码AVComposition 的工具。 github.com/rFlex/SCRecorder/issues/105 stackoverflow.com/q/32287059/22147 这很有趣,因为直接读取远程资产不起作用,但将其包装在 AVComposition 中!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    相关资源
    最近更新 更多