I am trying to add chapter information to a QuickTime movie file which has an audio track and possibly also a video track. Using AVAssetWriter to write the file works great, but I cannot figure out how to add chapter information. (I really want "markers", not "regions", but chapters may still be the most appropriate mechanism for that, please correct me if I'm wrong.) I also want this to be as portable as possible (note that this is for macOS, not iOS).
I tried two approaches. The first is to simply add one metadata item per chapter, which I would create like so:
AVMutableMetadataItem* item = [AVMutableMetadataItem metadataItem]; item.keySpace = AVMetadataKeySpaceQuickTimeUserData; item.key = AVMetadataQuickTimeUserDataKeyChapter; item.value = marker.name; item.time = CMTimeMake(marker.position, sampleRate); item.duration = CMTimeMake(sampleRate, sampleRate);
This almost works in the sense that these metadata items do show up when I subsequently read the file, but their time and duration would always be set to (0,0).
The other approach I tried is to create an additional AVAssetWriterInput of type AVMediaTypeText and to associate that text track to the audio track via
[audioWriterInput addTrackAssociationWithTrackOfInput:textWriterInput type: AVTrackAssociationTypeChapterList];
The problem then is that I do not know how to create a CMSampleBufferRef to hold a chapter information that I can feed to appendSampleBuffer:. The only information I found about this online is https://stackoverflow.com/questions/45702521/add-a-chapter-track-while-creating-a-video-with-avfoundation?rq=1, but the call to CMTextFormatDescriptionCreateFromBigEndianTextDescriptionData always fails for me with the message
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
For what it's worth, here is the code leading to the error
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 );
(I had to hunt around to find a definition for the long-deprecated TextDescription data structure and to copy it into my source file, so it's quite possible I'm doing something wrong here.) Any hints are greatly appreciated!