Read Chapters From MOV file

I'm trying to read the chapter list from an mov file I exported from FCP (Final Cut Pro). If I load the mov file into QT, it displays the chapter list just fine. When I load the mov file in my app with AVAsset, I cannot find the chapter metadata. I've tried various posted suggestions and defined workflows without success:


Searching AVAssetTracks:

------------------------------------

-(void)readMetadataFromTrack:(NSString*)filename {

NSString* videoPath = [[NSBundle mainBundle] pathForResource:filename ofType:@"mov"];

self.videoAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:videoPath]];

NSArray* tracks = [self.videoAsset tracksWithMediaType:AVMediaTypeMetadata];

AVAssetTrack* chapterTrack = nil;

for (AVAssetTrack* track in tracks) { // <-- tracks is always a 0 length array

for (id formatDescription in [track formatDescriptions]) {

CFArrayRef identifiers = CMMetadataFormatDescriptionGetIdentifiers((CMMetadataFormatDescriptionRef)formatDescription);

CFIndex cfSize = CFArrayGetCount(identifiers);

CFRange range = CFRangeMake(0, cfSize);

if (CFArrayContainsValue(identifiers, range, <Doesn't matter, tracks count is always 0>)) {

chapterTrack = track;

break;

}

}

}

if (chapterTrack != nil) {

AVAssetReaderTrackOutput* trackOutput = [[AVAssetReaderTrackOutput new] initWithTrack:chapterTrack outputSettings:nil];

AVAssetReaderOutputMetadataAdaptor* metaDataAdaptor = [[AVAssetReaderOutputMetadataAdaptor new] initWithAssetReaderTrackOutput:trackOutput];

AVTimedMetadataGroup* metaDataGroup = nil;

do {

metaDataGroup = [metaDataAdaptor nextTimedMetadataGroup];

} while (metaDataGroup != nil);

}

}


Async Key Search:

--------------------------

-(void)readChapterList:(NSString*)filename {

NSArray* chapterTitles = [NSArray new];

NSString* videoPath = [[NSBundle mainBundle] pathForResource:filename ofType:@"mov"];

self.videoAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:videoPath]];

NSString* key = @"availableChapterLocales";

[self.videoAsset loadValuesAsynchronouslyForKeys:@[key] completionHandler:^{

NSError* error;

AVKeyValueStatus status = [self.videoAsset statusOfValueForKey:key error:&error];

if (status == AVKeyValueStatusLoaded) {

[chapterTitles arrayByAddingObjectsFromArray:[self chaptersForAsset:self.videoAsset]];

for (NSString* title in chapterTitles) {

NSLog(@"Found Chapter: %@", title);

}

}

}];

}


Access Chapter Metadata Groups ( shortened the code for brevity):

------------------------------------------------------------------------------------------

NSLocale * locale = [NSLocale currentLocale];

NSArray *keys = @[AVMetadataCommonKeyTitle, AVMetadataCommonKeyArtwork, AVMetadataQuickTimeUserDataKeyChapter]; // <-- Tried various keys.

NSArray *chapters = [self.videoAsset chapterMetadataGroupsWithTitleLocale:locale containingItemsWithCommonKeys:keys];

for (AVTimedMetadataGroup * metadataGroup in chapters) {

NSArray * items = metadataGroup.items;

CMTimeRange timeRange = metadataGroup.timeRange;

NSLog(@"time: %@", CMTimeCopyDescription(NULL, timeRange.start));

for (AVMetadataItem * metadataItem in items) {

NSLog(@"key: %@", metadataItem.commonKey);

NSLog(@"value: %@", metadataItem.value);

}

}


So the question is, how does one read the chapter list metadata from an "ISO Media, Apple QuickTime movie, Apple QuickTime (.MOV/QT)" file? In this case, specifically from a mov created from Final Cut Pro?

Replies

This document describes how you can retrieve the movie’s chapter list using Apple’s AVFoundation API’s:

https://developer.apple.com/documentation/avfoundation/avasset/presenting_chapter_markers


Make sure that you use an AVAsset or AVMovie instance when intializing the movie from the file URL (in contrast, an instance of AVMutableMovie does not contain values for title and image - they are not loaded for some unknown reason).