Ошибка AVAssetExportSessionStatusFailed при слиянии аудиофайлов в 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);
    }
}];

Я искал по всему Интернету, но не нашел решения, любая помощь будет оценена.


person Nitin    schedule 02.12.2015    source источник


Ответы (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 для получения дополнительной информации. 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];
}
person Rhythmic Fistman    schedule 02.12.2015
comment
Я также получаю одну проблему, пожалуйста, изучите это и сообщите: -com" title="error domain avfoundationerrordomain code 11800 операция не может быть выполнена com">stackoverflow.com/questions/51239586/ - person user2786; 09.07.2018

проблема была здесь: // [состав 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);
    }
}];
person Nitin    schedule 03.12.2015