Cocoa: AVAsset loaded from file has 0 tracks
audio, avfoundation, cocoa, macos, objective-c
Solution
As you've already found, you need to use `fileURLWithPath:`, not `URLWithString:`, to create your URLs.
`URLWithString:` expects a string that describes a URL, such as `@"file:///path/to/file"` or `@"http://example.com/"`. When your string describes a path alone, such as `@"/path/to/file"`, you must use `fileURLWithPath:`, which will fill in the missing pieces correctly.
More technically, `URLWithString:` will interpret a path as simply a URL with only a path but no particular scheme, which you could go on to use relative to a base URL in any file-oriented scheme, such as HTTP (`GET /path/to/file`). `fileURLWithPath:` will interpret a path as a local file path, and return a `file:` URL accordingly.
Problem
I'm attempting to concatenate some audio files using the technique shown here. My audio files are .m4a and I can verify that they play fine in Quicktime. Here's the code I'm trying to use to concatenate them: ``` [currFile.audioContent writeToFile:tempOldFilePath atomically:NO]; AVURLAsset *oldAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempOldFilePath] options:nil]; AVURLAsset *newAudioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:tempInputFilePath] options:nil]; NSLog(@"oldAsset num tracks = %lu",(unsigned long)oldAudioAsset.tracks.count); NSLog(@"newAsset num tracks = %lu",(unsigned long)newAudioAsset.tracks.count); AVAssetTrack *oldTrack = [[oldAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; AVAssetTrack *newTrack = [[newAudioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; AVMutableComposition *mutableComposition = [AVMutableComposition composition]; AVMutableCompositionTrack *compTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; NSError *error=nil; [compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, oldTrack.timeRange.duration) ofTrack:oldTrack atTime:kCMTimeZero error:&error]; if (error) { NSLog(@"%@",error.localizedDescription); error=nil; } [compTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, newTrack.timeRange.duration) ofTrack:newTrack atTime:oldTrack.timeRange.duration error:&error]; if (error) { NSLog(@"%@",error.localizedDescription); error=nil; } exporter = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetAppleM4A]; exporter.outputURL = [NSURL URLWithString:tempCompFilePath]; exporter.outputFileType = AVFileTypeAppleM4A; [exporter exportAsynchronouslyWithCompletionHandler:^{ NSLog(@"handller"); NSError *error=nil; NSData *newData = [NSData dataWithContentsOfFile:tempCompFilePath options:0 error:&error]; NSLog(@"%lu",(unsigned long)newData.length); if (error) { NSLog(@"%@",error.localizedDescription); } currFile.audioContent = newData; [[AppDelegate sharedDelegate] saveAction:nil]; }]; ``` The first problem I noticed is that the exporter's handler method is never called. I'm guessing the reason for this is the other problem I noticed: After created my AVAssets from URL, log statements show that they contain 0 tracks. Apple's example doesn't exactly show how the AVAssets are loaded. Any advice on how to get this working?