2015-12-02 172 views
1

我已經使用這個代碼是工作在以前版本的IOS 9.但IOS版本9完美的罰款它總是會AVAssetExportSessionStatusFailedAVAssetExportSessionStatusFailed雖然IOS合併的音頻文件9

AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/firstPart.caf",docsDir]] options:nil]; 
AVAsset *avAsset2 = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/New-Recording.caf",docsDir]] options:nil]; 

AVMutableComposition *composition = [[AVMutableComposition alloc] init]; 
[composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

AVMutableCompositionTrack *track = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

AVAssetTrack *assetTrack1; 
AVAssetTrack *assetTrack2; 

if ([avAsset1 tracksWithMediaType:AVMediaTypeAudio].count > 0) { 
    assetTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    assetTrack2 = [[avAsset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
} 

CMTime insertionPoint = kCMTimeZero; 
[track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset1.duration) ofTrack:assetTrack1 atTime:insertionPoint error:nil]; 
insertionPoint = CMTimeAdd(insertionPoint, avAsset1.duration); 
[track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset2.duration) ofTrack:assetTrack2 atTime:insertionPoint error:nil]; 

AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPresetAppleM4A]; 
exportSession.outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/mergedFilePart1.caf",documentsDirectory]]; 
exportSession.outputFileType = AVFileTypeAppleM4A; 

[exportSession exportAsynchronouslyWithCompletionHandler:^{ 
    if (AVAssetExportSessionStatusCompleted == exportSession.status) { 

     NSLog(@"AVAssetExportSessionStatusCompleted"); 

     [self mergeAudioPart2]; 

    } else if (AVAssetExportSessionStatusFailed == exportSession.status) { 
     NSLog(@"AVAssetExportSessionStatusFailed"); 
    } else { 
     NSLog(@"Export Session Status: %ld", (long)exportSession.status); 
    } 
}]; 

我找遍了互聯網但是,我沒有找到任何解決方案,任何幫助將不勝感激。

回答

2

你的代碼應該工作,但沒有看到你的輸入文件很難說。但是它仍然可以改進。

由於某種原因,您有一條未使用的可變軌道。你可以將其刪除:

AVMutableComposition *composition = [[AVMutableComposition alloc] init]; 
// This track is unused. Delete it! 
// [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

AVMutableCompositionTrack *track = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

當導出失敗(AVAssetExportSessionStatusFailed == exportSession.status)檢查exportSession.error以獲取更多信息。錯誤消息通常會留下很多不足之處,但您可能很幸運。

您正在導出m4a文件,但文件後綴爲.caf。將其更改爲.m4aAVAssetExportSession似乎不支持導出爲AVFileTypeCoreAudioFormat)。 確保出口之前總是去除輸出URL,你忘了這樣做:

NSURL *ouputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/mergedFilePart1.m4a",documentsDirectory]]; 
[[NSFileManager defaultManager] removeItemAtURL:ouputURL error:nil]; 

AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPresetAppleM4A]; 
exportSession.outputURL = ouputURL; 
exportSession.outputFileType = AVFileTypeAppleM4A; 

insertTimeRange:ofTrack:error:返回一個成功標誌和一個錯誤!請教他們!他們可能會指出你的代碼有問題!

NSError *error; 
if (![track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset1.duration) ofTrack:assetTrack1 atTime:insertionPoint error:&error]) { 
    NSLog(@"ERROR 1: %@", error); 
} 

這種情況很奇怪。你檢查音軌的存在,在一個資產,然後使用其他還有:

if ([avAsset1 tracksWithMediaType:AVMediaTypeAudio].count > 0) { 
    assetTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    assetTrack2 = [[avAsset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
} 
+0

謝謝@rhythmic你救了我..:D – Nitin

0

的問題在這裏: // [組成addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]。這條線增加了額外的軌道。現在這個代碼在IOS 9上也是非常完美的。

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 

NSString *path1 = [NSString stringWithFormat:@"%@/firstPart.caf",documentsDirectory]; 
NSString *path2 = [NSString stringWithFormat:@"%@/New-Recording.caf",documentsDirectory]; 

AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path1] options:nil]; 
AVAsset *avAsset2 = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path2] options:nil]; 

AVMutableComposition *composition = [[AVMutableComposition alloc] init]; 
// [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

AVMutableCompositionTrack *track = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 

AVAssetTrack *assetTrack1; 
AVAssetTrack *assetTrack2; 

if ([avAsset1 tracksWithMediaType:AVMediaTypeAudio].count > 0) { 
    assetTrack1 = [[avAsset1 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    assetTrack2 = [[avAsset2 tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
} 

NSError *error; 

CMTime insertionPoint = kCMTimeZero; 

[track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset1.duration) ofTrack:assetTrack1 atTime:insertionPoint error:nil]; 
insertionPoint = CMTimeAdd(insertionPoint, avAsset1.duration); 
[track insertTimeRange:CMTimeRangeMake(kCMTimeZero, avAsset2.duration) ofTrack:assetTrack2 atTime:insertionPoint error:nil]; 

NSURL *outPutUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/mergedFilePart1.caf",documentsDirectory]]; 


AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:composition presetName:AVAssetExportPresetAppleM4A]; 

exportSession.outputURL = outPutUrl; 

exportSession.outputFileType = AVFileTypeAppleM4A; 

[exportSession exportAsynchronouslyWithCompletionHandler:^{ 
    if (AVAssetExportSessionStatusCompleted == exportSession.status) { 

     NSLog(@"AVAssetExportSessionStatusCompleted"); 
     [self mergeAudioPart2]; 

    } else if (AVAssetExportSessionStatusFailed == exportSession.status) { 

     NSLog(@"%ld",(long)exportSession.status); 
     NSLog(@"AVAssetExportSessionStatusFailed"); 
    } else { 
     NSLog(@"Export Session Status: %ld", (long)exportSession.status); 
    } 
}];