我正在研究视频的慢动作效果,一切都在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)"}}
有人知道这个的原因吗?
如果您需要更多详细信息,请告诉我们。我会相应地更新我的问题。
答案 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];
}