AVAssetWriter转换AAC 5.1音频从AVAsset轨道上appendSampleBuffer

问题描述:

失败我试图从.mp4视频文件中提取音轨,并转换为.m4a音频文件,使用该outputSettingsAVAssetWriterAVAssetWriter转换AAC 5.1音频从AVAsset轨道上appendSampleBuffer

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]; 

案例1:。与音轨PARAMS MP4视频文件(CMFormatDescriptionRef打印):

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

结果:成功创建.m4a输出文件与定义的输出PARAMS

情况2: .mp4格式的视频与音频轨道PARAMS文件(带有CMFormatDescriptionRef打印):

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

结果:转换失败时,加入样品时缓冲[AVAssetWriter appendSampleBuffer: ...]未知error

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

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

我也试图建立channelLayout.mChannelLayoutTagkAudioChannelLayoutTag_MPEG_5_1_D,并与6值更新AVNumberOfChannelsKey,但它并没有为我工作。

任何人都可以帮助我了解我做错了什么吗?可能有没有解决方案只使用iOS AVFoundation框架来执行此任务?我应该使用不同的outputParams用于5.1 aac 6声道的音轨吗?

我还没有和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"); 
    } 
}]; 

我没有手头上的任何文件5.1,所以如果不工作,你可能需要在该行

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

附注:更密切地关注这个代码从2012年“刚刚工作”,这很好。