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?