【问题标题】:Add a chapter track while creating a video with AVFoundation使用 AVFoundation 创建视频时添加章节轨道
【发布时间】:2017-08-15 22:30:35
【问题描述】:

我正在从一堆静止图像中创建一个视频(QuickTime .mov 格式,H.264 编码),并且我想在此过程中添加一个章节轨道。视频制作良好,我没有检测到任何错误,但 QuickTime Player 没有显示任何章节。我知道this question,但它不能解决我的问题。

旧版 QuickTime Player 7 与最近的版本不同,它可以显示有关电影曲目的信息。当我打开带有工作章节的电影(使用旧的 QuickTime 代码创建)时,我看到一个视频轨道和一个文本轨道,并且视频轨道知道文本轨道正在为视频提供章节。然而,如果我检查由我的新代码创建的电影,则会有一个元数据轨道和视频轨道,但 QuickTime 不知道元数据轨道应该提供章节。我读过的东西让我相信应该为章节使用元数据,但有没有人真正做到这一点?文本轨道有用吗?

以下是我为元数据创建 AVAssetWriterInput 的方法。

// Make dummy AVMetadataItem to get its format
AVMutableMetadataItem* dummyMetaItem = [AVMutableMetadataItem metadataItem];
dummyMetaItem.identifier = AVMetadataIdentifierQuickTimeUserDataChapter;
dummyMetaItem.dataType = (NSString*) kCMMetadataBaseDataType_UTF8;
dummyMetaItem.value = @"foo";
AVTimedMetadataGroup* dummyGroup = [[[AVTimedMetadataGroup alloc]
    initWithItems: @[dummyMetaItem]
    timeRange: CMTimeRangeMake( kCMTimeZero, kCMTimeInvalid )] autorelease];
CMMetadataFormatDescriptionRef metaFmt = [dummyGroup copyFormatDescription];

// Make the input
AVAssetWriterInput* metaWriterInput = [AVAssetWriterInput
    assetWriterInputWithMediaType: AVMediaTypeMetadata
    outputSettings: nil
    sourceFormatHint: metaFmt];
CFRelease( metaFmt );

// Associate metadata input with video input
[videoInput addTrackAssociationWithTrackOfInput: metaWriterInput
    type: AVTrackAssociationTypeChapterList];

// Associate metadata input with AVAssetWriter
[writer addInput: metaWriterInput];

// Create a metadata adaptor
AVAssetWriterInputMetadataAdaptor* metaAdaptor = [AVAssetWriterInputMetadataAdaptor
    assetWriterInputMetadataAdaptorWithAssetWriterInput: metaWriterInput];

附:我尝试改用文本轨道(AVMediaTypeText 类型的 AVAssetWriterInput),QuickTime Player 说结果“不是电影”。不知道我做错了什么。

【问题讨论】:

    标签: macos video avfoundation metadata


    【解决方案1】:

    我设法使用文本轨道来提供章节。我处理了一次 Apple 开发人员技术支持事件,并被告知这是正确的做法。

    设置:

    我假设 AVAssetWriter 已创建,并且视频轨道的 AVAssetWriterInput 已分配给它。

    这里最棘手的部分是创建文本格式描述。文档说CMTextFormatDescriptionCreateFromBigEndianTextDescriptionDataTextDescription 结构作为输入,但忽略了该结构的定义位置。它在 Movies.h 中,它在 QuickTime.framework 中,它不再是 Mac OS SDK 的一部分。谢谢,苹果。

    // Create AVAssetWriterInput
    AVAssetWriterInput* textWriterInput = [AVAssetWriterInput
        assetWriterInputWithMediaType: AVMediaTypeText
        outputSettings: nil ];
    textWriterInput.marksOutputTrackAsEnabled = NO;
    
    // Connect input to writer
    [writer addInput: textWriterInput];
    
    // Mark the text track as providing chapter for the video
    [videoWriterInput addTrackAssociationWithTrackOfInput: textWriterInput
        type: AVTrackAssociationTypeChapterList];
    
    // Create the text format description, which we will need
    // when creating each sample.
    CMFormatDescriptionRef textFmt = NULL;
    TextDescription textDesc;
    memset( &textDesc, 0, sizeof(textDesc) );
    textDesc.descSize = OSSwapHostToBigInt32( sizeof(textDesc) );
    textDesc.dataFormat = OSSwapHostToBigInt32( 'text' );
    CMTextFormatDescriptionCreateFromBigEndianTextDescriptionData( NULL,
        (const uint8_t*)&textDesc, sizeof(textDesc), NULL, kCMMediaType_Text,
        &textFmt );
    

    编写示例:

    CMSampleTimingInfo timing =
    {
        CMTimeMakeWithSeconds( endTime - startTime, timeScale ),    // duration
        CMTimeMakeWithSeconds( startTime, timeScale ),
        kCMTimeInvalid
    };
    CMSampleBufferRef textSample = NULL;
    CMPSampleBufferCreateWithText( NULL, (CFStringRef)theTitle, true, NULL, NULL,
        textFmt, &timing, &textSample );
    [textWriterInput appendSampleBuffer: textSample];
    

    函数CMPSampleBufferCreateWithText取自开源CoreMediaPlus

    【讨论】:

    • 这段代码真的适合你吗?当我尝试使用它(macOS 10.14)时,对CMTextFormatDescriptionCreateFromBigEndianTextDescriptionData 的调用给了我错误消息copyTextExtensions signalled err=-12717 (kFigBridgeUnsupportedSampleDescriptionFlavorErr) (unrecognized text format) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/CoreMedia_frameworks/CoreMedia-2288.33/Sources/Core/FigFormatDescription/TextDescriptionBridge.c:1681 随后对appendSampleBuffer 的调用然后失败并出现类似的错误。
    猜你喜欢
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2017-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多