AVAssetExportSession fails every time (error -12780)

pinki picture pinki · Feb 1, 2013 · Viewed 9.3k times · Source

I'm trying to merge some audio files (picked via MPMediaPickerController), but the export always fails with error code -12780.

When I try to play my composition with an AVPlayer object, it plays correctly. Just the export fails.

What am I doing wrong?

This is my code:

AVAssetExportSession *exportSession;
AVPlayer *player;

- (void)mergeAudiofiles {
    // self.mediaItems is an NSArray of MPMediaItems
    if (self.mediaItems.count == 0) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                        message:@"No Tracks selected."
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
        return;
    }

    // Configure audio session
    NSError *sessionError;
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryAudioProcessing error:nil];
    [session setActive:YES error:&sessionError];
    if (sessionError) NSLog(@"Session-Error: %@", sessionError.localizedDescription);

    // Create composition
    AVMutableComposition *composition = [AVMutableComposition composition];
    AVMutableCompositionTrack *track = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    CMTime position = kCMTimeZero;

    for (MPMediaItem *item in self.mediaItems) {
        NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
        AVAsset *asset  = [AVAsset assetWithURL:assetURL];

        CMTimeRange duration = CMTimeRangeMake(kCMTimeZero, asset.duration);
        //        duration = CMTimeRangeMake(kCMTimeZero, CMTimeMake(5, 1));    // For player test

        NSError *error;
        [track insertTimeRange:duration ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] lastObject] atTime:position error:&error];
        if (error) NSLog(@"ERROR! :(");

        position = CMTimeAdd(position, duration.duration);
    }

    // Path to output file
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSURL *exportUrl = [NSURL URLWithString:[documentsDirectory stringByAppendingPathComponent:@"export.m4a"]];

    NSLog(@"Export URL = %@", exportUrl.description);

    //    Playing works!
    //    """"""""""""""
    //    AVPlayerItem *pitem = [[AVPlayerItem alloc] initWithAsset:composition];
    //    player = [[AVPlayer alloc] initWithPlayerItem:pitem];
    //    [player play];
    //
    //    return;

    // Export
    exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetAppleM4A];
    exportSession.outputURL = exportUrl;
    exportSession.outputFileType = AVFileTypeAppleM4A;

    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        switch (exportSession.status) {
            case AVAssetExportSessionStatusFailed:
                NSLog(@"Export failed -> Reason: %@, User Info: %@",
                      exportSession.error.localizedDescription,
                      exportSession.error.userInfo.description);
                break;

            case AVAssetExportSessionStatusCancelled:
                NSLog(@"Export cancelled");
                break;

            case AVAssetExportSessionStatusCompleted:
                NSLog(@"Export finished");
                break;

            default:
                break;
        }
    }];
}

Answer

ucangetit picture ucangetit · Dec 27, 2013

Need to change your export URL to:

    NSURL *exportUrl = [NSURL fileURLWithPath:[documentsDirectory stringByAppendingPathComponent:@"export.m4a"]];

You must use fileURLWithPath when referring to file paths. I got hung up by this too until I read this: AVAssetExportSession outputfile