在appendSampleBuffer上,AVAssetWriter从AVAsset转换aac 5.1音轨失败

Gen*_*hin 7 objective-c avfoundation ios avassetwriter avassetwriterinput

我试图从提取音轨.mp4的视频文件,并转换成.m4a音频文件,这个outputSettings使用AVAssetWriter

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];
Run Code Online (Sandbox Code Playgroud)

案例1:带有音轨参数的.mp4视频文件(打印用CMFormatDescriptionRef):

mediaType:'soun'
mediaSubType:'aac '
mSampleRate: 44100.000000
mFormatID: 'aac '
mChannelsPerFrame: 2
ACL: {Stereo (L R)}
Run Code Online (Sandbox Code Playgroud)

结果:成功创建.m4a具有已定义输出参数的输出文件

案例2:带有音轨参数的.mp4视频文件(打印方式CMFormatDescriptionRef):

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

结果:当添加[AVAssetWriter appendSampleBuffer: ...]未知的样本缓冲区时,转换失败error:

Error Domain: NSOSStatusErrorDomain
code: -12780
description: The operation could not be completed
Run Code Online (Sandbox Code Playgroud)

要将视频转换为音频,我使用与其中描述的相同的算法:https://github.com/rs/SDAVAssetExportSession/blob/master/SDAVAssetExportSession.m

此外,我试图建立channelLayout.mChannelLayoutTagkAudioChannelLayoutTag_MPEG_5_1_D和更新AVNumberOfChannelsKey6价值,但它并没有为我工作.

谁能帮我理解我做错了什么?可能没有解决方案只使用iOS AVFoundation框架来执行此任务?我应该使用outputParams5.1 aac 6声道的音轨吗?

Rhy*_*man 0

我还没有尝试过使用 5.1 音频,但是当从视频中提取音频时,我喜欢在AVAssetExportSession纯音频上使用直通,AVMutableComposition因为这样可以避免转码,转码速度会很慢并且会降低音频质量。就像是:

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");
    }
}];
Run Code Online (Sandbox Code Playgroud)

我手头没有任何 5.1 文件,所以如果这不起作用,您可能需要更仔细地查看该行

AVAssetTrack*   srcTrack = [[srcAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)

ps 2012 年的这段代码“刚刚工作”,这很好。