Mohd Haider
Mohd Haider

Reputation: 703

AVAssetExportSessionStatusFailed: Video exporting failed with error -16364

I am working on slow motion effect on video and everything is working fine below iOS 11 but I am getting following error on 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)"}}

I have tried to find out regarding this issue but didn't find any exact solution for this.

Below if my code for reference:

    - (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;
                                                             }
                                                         }];
                                                     }];
                                                 }
                                             }];
    }

The print logs are as below:

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)"}}

Does anyone know any reason about this?

If you need more details about this, then let me know. I will update my questions accordingly.

Upvotes: 3

Views: 1541

Answers (1)

rajugautam
rajugautam

Reputation: 78

Try changing AVExportSession presetName, maybe to AVAssetExportPresetHEVCHighestQuality or other HEVC presets. Since AVAssetExportPresetHEVCHighestQuality is available on >=iOS 11.0, don't forget to have an @available check.

AVAssetExportSession *exportSession = nil;

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

Upvotes: 5

Related Questions