- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在录制小视频剪辑(大约一秒左右,同时使用前置和后置摄像头,方向可能不同)。然后尝试使用 AVAssetExportSession 合并它们。我基本上使用适当的转换和音频和视频轨道制作合成和视频合成。
问题是在 iOS 5 上,如果您有超过 4 个视频剪辑,它会失败,而在 iOS 6 上,限制似乎是 16 个剪辑。
这对我来说似乎真的很费解。 AVAssetExportSession 是否在做一些奇怪的事情,或者它是否对可以传递给它的剪辑数量有一些未记录的限制?以下是我的代码的一些摘录:
-(void)exportVideo
{
AVMutableComposition *composition = video.composition;
AVMutableVideoComposition *videoComposition = video.videoComposition;
NSString * presetName = AVAssetExportPresetMediumQuality;
AVAssetExportSession *_assetExport = [[AVAssetExportSession alloc] initWithAsset:composition presetName:presetName];
self.exportSession = _assetExport;
videoComposition.renderSize = CGSizeMake(640, 480);
_assetExport.videoComposition = videoComposition;
NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent: @"export.mov"];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
// Delete the currently exported files if it exists
if([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
_assetExport.outputFileType = AVFileTypeQuickTimeMovie;
_assetExport.outputURL = exportUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
[_assetExport exportAsynchronouslyWithCompletionHandler:^{
switch (_assetExport.status)
{
case AVAssetExportSessionStatusCompleted:
NSLog(@"Completed exporting!");
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"Failed:%@", _assetExport.error.description);
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"Canceled:%@", _assetExport.error);
break;
default:
break;
}
}];
}
下面是组合的制作方法:
-(void)setVideoAndExport
{
video = nil;
video = [[VideoComposition alloc] initVideoTracks];
CMTime localTimeline = kCMTimeZero;
// Create the composition of all videofiles
for (NSURL *url in outputFileUrlArray) {
AVAsset *asset = [[AVURLAsset alloc]initWithURL:url options:nil];
[video setVideo:url at:localTimeline];
localTimeline = CMTimeAdd(localTimeline, asset.duration); // Increment the timeline
}
[self exportVideo];
}
这是 VideoComposition 类的主要内容:
-(id)initVideoTracks
{
if((self = [super init]))
{
composition = [[AVMutableComposition alloc] init];
addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instructions = [[NSMutableArray alloc] init];
videoComposition = [AVMutableVideoComposition videoComposition];
}
return self;
}
-(void)setVideo:(NSURL*) url at:(CMTime)to
{
asset = [[AVURLAsset alloc]initWithURL:url options:nil];
AVAssetTrack *assetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableCompositionTrack *compositionTrackVideo = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionTrackVideo insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack: assetTrack atTime:to error:nil];
AVMutableCompositionTrack *compositionTrackAudio = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionTrackAudio insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:[[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:to error:nil];
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeAdd(to, asset.duration));
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionTrackVideo];
[layerInstruction setTransform: assetTrack.preferredTransform atTime: kCMTimeZero];
[layerInstruction setOpacity:0.0 atTime:CMTimeAdd(to, asset.duration)];
[instructions addObject:layerInstruction];
mainInstruction.layerInstructions = instructions;
videoComposition.instructions = [NSArray arrayWithObject:mainInstruction];
videoComposition.frameDuration = CMTimeMake(1, 30);
}
最佳答案
好的,这个问题我也联系了苹果,他们给了回复:
“这是已知情况。您正在达到 AVFoundation 中设置的解码器限制。”
他们还要求我就此问题提交错误报告,因为 AVAssetExportSession 给出的错误消息含糊不清且具有误导性。所以我向苹果公司提交了一份错误报告,提示错误信息是错误的。
所以 AVAssetExportSession 中的这些限制被确认。在 iOS 5 中,解码器限制为 4,在 iOS 6 中提高到 16。这里的主要问题是 AVAssetExportSession 报告的错误很糟糕,因为它只报告:11820“无法完成导出”而不是实际告诉我们我们有达到极限。
关于objective-c - exportAsynchronouslyWithCompletionHandler 因多个视频文件而失败(代码=-11820),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14081186/
我想从 iPod-Library 导出和压缩视频,但是“exportAsynchronouslyWithCompletionHandler”可以对某些视频正常工作,但对某些视频不起作用。它不起作用并且
我正在实现 AVAssetExportSession 来在线修剪视频,但总是返回失败。 这是我的实现: NSString *url = @"http://www.ebookfrenzy.com/ios
我正在创建视频剪辑并将其导出到文档目录中的新文件。它工作正常视频总时长的一半。但是如果我选择后半段的剪辑时间,它不会执行 [export exportAsynchronouslyWithComplet
我正在开发一个 iOS 应用程序,使用带有后台配置的 NSURLSession 从相机胶卷上传视频。用户可以将多个视频排队上传(队列是串行执行的)。 单次上传包括: 使用 PHImageManager
我正在将两个录音(使用 AVAudioRecorder 录制)合并到一个文件中。第一次使用 AVAssetExportSession 导出组合文件时效果很好(即只要我在当前 View Controll
我正在使用以下代码将 .mp4 和 .caf 组合成 .mov。 (注意:我知道如何播放视频所以不要为此提供代码) AVAssetExportSession* _assetExport = [[AV
我正在录制小视频剪辑(大约一秒左右,同时使用前置和后置摄像头,方向可能不同)。然后尝试使用 AVAssetExportSession 合并它们。我基本上使用适当的转换和音频和视频轨道制作合成和视频合成
当播放从 AVAssetExportSession 导出的视频时,您会在看到视频之前很久就听到音频。音频立即播放,但视频仅在录制循环多次(即开始和结束)后出现。换句话说,您会在看到任何图像之前多次听到
我正在使用 AVAssetExportSession 导出从库中选择的视频。它适用于所有类型的所有视频,除了横向录制的屏幕录制(使用 iOS 11 中的屏幕录制功能)。奇怪的是,它适用于其他横向视频,
我是一名优秀的程序员,十分优秀!