AVAssetExportSessionStatusFailed:视频导出失败,错误为-16364

时间:2017-11-01 11:58:24

标签: ios objective-c avfoundation avasset avassetexportsession

我正在研究视频的慢动作效果,一切都在iOS 11下工作正常但我在iOS 11上遇到以下错误:

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-16364), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x608000456620 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}}

我试图找出有关此问题但尚未找到任何确切的解决方法。

以下是我的参考代码:

    - (void)applySlowMoOnAsset:(NSURL *)assetURL {
    AVAsset *videoAsset = [[AVURLAsset alloc] initWithURL:assetURL options:nil];

    AVMutableComposition *mixComposition = [AVMutableComposition composition];
    AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                                   preferredTrackID:kCMPersistentTrackID_Invalid];

    AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

    AVAssetTrack *videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

    NSError *videoInsertError = nil;

    BOOL videoInsertResult = [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                                                            ofTrack: videoAssetTrack
                                                             atTime:kCMTimeZero
                                                              error:&videoInsertError];

    if (!videoInsertResult || nil != videoInsertError) {
        NSLog(@"VideoInsertError %@",videoInsertError);
        return;
    }

    if ([[videoAsset tracksWithMediaType:AVMediaTypeAudio] count] > 0) {
        AVAssetTrack *audioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

        if (audioTrack != nil) {

            NSError *error;
            BOOL audioInsertResult = [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [videoAsset duration]) ofTrack:audioTrack atTime:kCMTimeZero error:&error];

            NSLog(@"audioInsertResult %d with error description %@", audioInsertResult, [error description]);
        }
    }

    compositionVideoTrack.preferredTransform = videoAssetTrack.preferredTransform;

    double videoScaleFactor = 4.0;

    CMTime videoDuration = videoAsset.duration;

    NSLog(@"slo-Mo begin time %f slo-Mo endTime %f Actual Video duration %f", CMTimeGetSeconds(self.sloMoStartHead), CMTimeGetSeconds(self.sloMoEndHead), CMTimeGetSeconds(videoDuration));

    CMTime scaledDuration = CMTimeSubtract(self.sloMoEndHead, self.sloMoStartHead);

    CMTime normalDuration = CMTimeSubtract(videoDuration, scaledDuration);

    NSLog(@"Slow-Mo duration %f Normal Video Duration %f scaled slo-mo duration %f ", CMTimeGetSeconds(scaledDuration), CMTimeGetSeconds(CMTimeMake(normalDuration.value, normalDuration.timescale)), CMTimeGetSeconds(CMTimeMake(scaledDuration.value * videoScaleFactor, scaledDuration.timescale)));

    CMTime newTime = CMTimeAdd(CMTimeMake(self.sloMoStartHead.value, self.sloMoStartHead.timescale), CMTimeMake(scaledDuration.value * videoScaleFactor, scaledDuration.timescale));

    CMTime exportedTime = CMTimeAdd(newTime, CMTimeMake(normalDuration.value, normalDuration.timescale));

    NSLog(@"FinalTime for slowMo video %f", CMTimeGetSeconds(exportedTime));

    [compositionVideoTrack scaleTimeRange:CMTimeRangeMake(self.sloMoStartHead, self.sloMoEndHead) toDuration:newTime];

    [compositionAudioTrack scaleTimeRange:CMTimeRangeMake(self.sloMoStartHead, self.sloMoEndHead) toDuration:newTime];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDirectory = paths[0];
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager createDirectoryAtPath:documentDirectory withIntermediateDirectories:YES attributes:nil error:nil];
    NSString *outputStr = [documentDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4",@"exportedVideo"]];
    // Remove Existing File
    [manager removeItemAtPath:outputStr error:nil];

    NSLog(@"outputStr = %@",outputStr);

    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality];

    exportSession.outputURL = [NSURL fileURLWithPath:outputStr]; // output path;

    exportSession.outputFileType = AVFileTypeMPEG4;

    [AVAssetExportSession determineCompatibilityOfExportPreset:AVAssetExportPresetMediumQuality
                                                     withAsset:mixComposition
                                                outputFileType:AVFileTypeMPEG4
                                             completionHandler:^(BOOL compatible) {

                                                 DLog(@"compatible = %d",compatible);

                                                 if (compatible) {

                                                     [exportSession determineCompatibleFileTypesWithCompletionHandler:^(NSArray<AVFileType> * _Nonnull compatibleFileTypes) {

                                                         DLog(@"compatibleFileTypes = %@",compatibleFileTypes);

                                                         [exportSession exportAsynchronouslyWithCompletionHandler:^(void) {

                                                             switch (exportSession.status) {
                                                                 case AVAssetExportSessionStatusCompleted:

                                                                     NSLog(@"AVAssetExportSessionStatusCompleted");
                                                                     NSLog(@"slow-mo video saved with path url %@", exportSession.outputURL);
                                                                     break;

                                                                     case AVAssetExportSessionStatusFailed:

                                                                     NSLog(@"AVAssetExportSessionStatusFailed");
                                                                     NSLog(@"exportSession.error = &@",exportSession.error);
                                                                     break;

                                                                 case AVAssetExportSessionStatusCancelled:

                                                                     NSLog(@"AVAssetExportSessionStatusCancelled");
                                                                     NSLog(@"exportSession.error = &@",exportSession.error);
                                                                     break;

                                                                 default:
                                                                     break;
                                                             }
                                                         }];
                                                     }];
                                                 }
                                             }];
    }

打印日志如下:

audioInsertResult 1 with error description (null)

slo-Mo begin time 2.476292 slo-Mo endTime 4.666674 Actual Video duration 11.033333

Slow-Mo duration 2.190382 Normal Video Duration 8.842951 scaled slo-mo duration 8.761529

FinalTime for slowMo video 20.080772

outputURL = /Users/xyz/Library/Developer/CoreSimulator/Devices/92F3DB9A-A923-4CDA-9941-190AED9D844F/data/Containers/Data/Application/1B9A30B4-B14B-483B-91B6-D965C4366A53/Documents/exportedVideo.mp4

compatible = 1

compatibleFileTypes = (
    "com.apple.m4v-video",
    "com.apple.quicktime-movie",
    "public.mpeg-4"
)

AVAssetExportSessionStatusFailed

exportSession.error = Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-16364), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x608000456620 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}}

有人知道这个的原因吗?

如果您需要更多详细信息,请告诉我们。我会相应地更新我的问题。

1 个答案:

答案 0 :(得分:3)

尝试更改 AVExportSession presetName ,可能更改为AVAssetExportPresetHEVCHighestQuality或其他 HEVC预设。由于AVAssetExportPresetHEVCHighestQuality在&gt; = iOS 11.0上可用,因此不要忘记进行@available检查。

AVAssetExportSession *exportSession = nil;

if (@available(iOS 11.0, *)) {
    exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHEVCHighestQuality];
} else {
    exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName: AVAssetExportPresetMediumQuality];
}