合并音频文件时 AVAssetExportSessionStatusFailed IOS 9
AVAssetExportSessionStatusFailed While Merging Audio files in IOS 9
我已经使用了这段代码,它在 IOS 9 的早期版本上工作得很好。但是在 IOS 9 版本上它总是会出现 AVAssetExportSessionStatusFailed
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:
returns 一个成功标志和一个错误!咨询他们!他们可能指出您的代码有问题!
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];
}
问题出在这里:
// [组合 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);
}
}];
我已经使用了这段代码,它在 IOS 9 的早期版本上工作得很好。但是在 IOS 9 版本上它总是会出现 AVAssetExportSessionStatusFailed
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:
returns 一个成功标志和一个错误!咨询他们!他们可能指出您的代码有问题!
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];
}
问题出在这里: // [组合 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);
}
}];