简体   繁体   中英

AVAssetWriter convert aac 5.1 audio track from AVAsset fail on appendSampleBuffer

I am trying to extract audio track from .mp4 video file and convert to .m4a audio file with this outputSettings using AVAssetWriter class

AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;

NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                [NSNumber numberWithFloat:44100.0], AVSampleRateKey,
                                [NSNumber numberWithInt:2], AVNumberOfChannelsKey,
                                [NSNumber numberWithInt:128000], AVEncoderBitRateKey, // 128 kbps
                                [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,
                                nil];

Case 1: .mp4 video file with audio track params (print with CMFormatDescriptionRef ):

mediaType:'soun'
mediaSubType:'aac '
mSampleRate: 44100.000000
mFormatID: 'aac '
mChannelsPerFrame: 2
ACL: {Stereo (L R)}

result: successfully create .m4a output file with defined output params

Case 2: .mp4 video file with audio track params(print with CMFormatDescriptionRef ):

mediaType:'soun'
mediaSubType:'aac ' 
mSampleRate: 48000.000000
mFormatID: 'aac '
mChannelsPerFrame: 6
ACL: {5.1 (C L R Ls Rs LFE)}

result: convert fails, when adding sample buffer [AVAssetWriter appendSampleBuffer: ...] with unknown error :

Error Domain: NSOSStatusErrorDomain
code: -12780
description: The operation could not be completed

To convert video to audio I use the same algorithm as described there: https://github.com/rs/SDAVAssetExportSession/blob/master/SDAVAssetExportSession.m

Also I tried to setup channelLayout.mChannelLayoutTag with kAudioChannelLayoutTag_MPEG_5_1_D , and update AVNumberOfChannelsKey with 6 value, but it doesn't work for me.

Can anyone help me to understand what I am doing wrong? May be there are no solution to perform this task using only iOS AVFoundation framework? Should I use different outputParams for audio track with 5.1 aac 6 channels?

I haven't tried this with 5.1 audio, but when extracting audio from video I like to use a passthrough AVAssetExportSession on an audio-only AVMutableComposition as this avoids transcoding which would be slow and throw away audio quality. Something like:

AVMutableComposition*       newAudioAsset = [AVMutableComposition composition];
AVMutableCompositionTrack*  dstCompositionTrack;

dstCompositionTrack = [newAudioAsset addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];


AVAsset*        srcAsset = [AVURLAsset URLAssetWithURL:srcURL options:nil];
AVAssetTrack*   srcTrack = [[srcAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];


CMTimeRange timeRange = srcTrack.timeRange;//CMTimeRangeMake(kCMTimeZero, srcAsset.duration);

NSError*    error;

if(NO == [dstCompositionTrack insertTimeRange:timeRange ofTrack:srcTrack atTime:kCMTimeZero error:&error]) {
    NSLog(@"track insert failed: %@\n", error);
    return 1;
}


__block AVAssetExportSession*   exportSesh = [[AVAssetExportSession alloc] initWithAsset:newAudioAsset presetName:AVAssetExportPresetPassthrough];

exportSesh.outputFileType = AVFileTypeAppleM4A;
exportSesh.outputURL = dstURL;

[exportSesh exportAsynchronouslyWithCompletionHandler:^{
    AVAssetExportSessionStatus  status = exportSesh.status;
    NSLog(@"exportAsynchronouslyWithCompletionHandler: %i\n", status);

    if(AVAssetExportSessionStatusFailed == status) {
        NSLog(@"FAILURE: %@\n", exportSesh.error);
    } else if(AVAssetExportSessionStatusCompleted == status) {
        NSLog(@"SUCCESS!\n");
    }
}];

I don't have any 5.1 files on hand, so if that doesn't work you may need to look more closely at the line

AVAssetTrack*   srcTrack = [[srcAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

ps this code from 2012 "just worked", which was nice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM