Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cocoa: AVAsset loaded from file has 0 tracks

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?

like image 579
James Harpe Avatar asked Jan 30 '14 17:01

James Harpe


2 Answers

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.

like image 84
Peter Hosey Avatar answered Oct 20 '22 01:10

Peter Hosey


I found the reason why this error was occurred and eventually solve it.

Originally I had set the source file path as ".mp4". But the type of recorded video file was MOV so I changed as ".mov".

NSString *source_file_path = @"temp_video.mov"

instead of

NSString *source_file_path = @"temp_video.mp4"

The problem was fixed and it is working well now.

Hope to be helpful for all.

like image 29
user3704354 Avatar answered Oct 20 '22 01:10

user3704354