7

失敗我試圖從.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聲道的音軌嗎?

回答

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"); 
    } 
}]; 

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

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

附註:更密切地關注這個代碼從2012年「剛剛工作」,這很好。