AvassetExportSessionStatus在IOS 9中合并音频文件时失败

AvassetExportSessionStatus在IOS 9中合并音频文件时失败,ios,objective-c,avassetexportsession,Ios,Objective C,Avassetexportsession,我已经使用了这段代码,它在以前版本的iOS9上运行得非常好。但在IOS 9版本上,它总是运行AvassetExportSessionStatus失败 AVAsset *avAsset1 = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/firstPart.caf",docsDir]] options:nil]; AVAsset *avAsset2 = [AVURLAsset U

我已经使用了这段代码,它在以前版本的iOS9上运行得非常好。但在IOS 9版本上,它总是运行AvassetExportSessionStatus失败

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);
    }
}];
我搜索了整个互联网,但没有找到任何解决方案。我们将感谢您的帮助。

您的代码应该可以工作,但如果没有看到您的输入文件,就很难判断。然而,它仍然可以改进

由于某种原因,您有一个未使用的可变轨迹。您可以删除它:

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
,了解更多信息
AVFoundation
错误消息通常会留下很多不尽如人意的地方,但您可能很幸运

您正在导出m4a文件,但文件后缀为
.caf
。将其更改为
.m4a
AVAssetExportSession
似乎不支持导出为
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];
}
问题是: //[composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_无效];这条线增加了额外的轨道。现在,这段代码在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);
    }
}];

我还遇到一个问题,请对此进行调查并提出建议: