- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
EXPORT STATUS 4 Error Domain=AVFoundationErrorDomain Code=-11820 "Cannot Complete Export" UserInfo={NSLocalizedDescription=Cannot Complete Export, NSLocalizedRecoverySuggestion=Try exporting again.}
尝试导出包含 AVMutableVideoCompositionLayerInstruction
的 AVMutableComposition
和使用 的
.AVMutableVideoComposition
时遇到间歇性错误AVAssetExportSession
目标是合并无限数量的视频并使用 layerInstructions 在剪辑之间应用过渡。
附言错误不一致。它在尝试合并 5 个剪辑和 18 个剪辑时有效,但在尝试合并 17 个剪辑时无效。
我已经在下面发布了我的代码。非常感谢任何帮助。
编辑:问题似乎与多个 AVMutableCompositionTrack(s) 的创建有关。如果创建超过 15 或 16 个,则会发生错误。但是,我认为创建多个 AVMutableCompositionTrack 是重叠所有视频和创建重叠过渡的必要条件。
编辑 2:选择较短的视频时,会在发生错误之前处理更多的视频。因此,它看起来像是一个内存问题,轨道正在被释放。但是,基于内存管理工具似乎没有内存泄漏。
-(void)prepareMutableCompositionForPlayback{
AVMutableComposition *mutableComposition = [[AVMutableComposition alloc] init];
AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
mainInstruction.backgroundColor = [[UIColor blackColor] CGColor];
NSMutableArray *instructionsArray = [[NSMutableArray alloc] init];
videoStartTime = kCMTimeZero;
for(int i = 0; i < videoAssetsArray.count; i++){
AVAsset *videoAsset = [videoAssetsArray objectAtIndex:i];
CMTime currentVideoDuration = [videoAsset duration];
AVMutableCompositionTrack *videoTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, currentVideoDuration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:videoStartTime error:nil];
CGSize videoSize = [videoTrack naturalSize];
if([videoAsset tracksWithMediaType:AVMediaTypeAudio].count > 0){
AVMutableCompositionTrack *audioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, currentVideoDuration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:videoStartTime error:nil];
}
//INSTRUCTIONS - TRANSITIONS
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
int transitionNumber = [[videoTransitionsArray objectAtIndex:i] intValue];
float transitionDuration = [[videoTransitionsDurationArray objectAtIndex:i] floatValue];
if(i == 0){
[layerInstruction setOpacityRampFromStartOpacity:1.0 toEndOpacity:0.0 timeRange:CMTimeRangeMake(CMTimeSubtract(currentVideoDuration, CMTimeMakeWithSeconds(transitionDuration, 600)), CMTimeMakeWithSeconds(transitionDuration, 600))];
}
else{
int previousTransitionNumber = [[videoTransitionsArray objectAtIndex:i - 1] intValue];
float previousTransitionDuration = [[videoTransitionsDurationArray objectAtIndex:i - 1] floatValue];
if(i < videoAssetsArray.count - 1){
[layerInstruction setOpacityRampFromStartOpacity:1.0 toEndOpacity:1.0 timeRange:CMTimeRangeMake(videoStartTime, CMTimeMakeWithSeconds(previousTransitionDuration, 600))];
[layerInstruction setOpacityRampFromStartOpacity:1.0 toEndOpacity:0.0 timeRange:CMTimeRangeMake(CMTimeAdd(videoStartTime, CMTimeSubtract(currentVideoDuration, CMTimeMakeWithSeconds(transitionDuration, 600))), CMTimeMakeWithSeconds(transitionDuration, 600))];
}
else{
[layerInstruction setOpacityRampFromStartOpacity:1.0 toEndOpacity:1.0 timeRange:CMTimeRangeMake(videoStartTime, CMTimeMakeWithSeconds(previousTransitionDuration, 600))];
}
}
[instructionsArray addObject:layerInstruction];
if(i < videoAssetsArray.count - 1){
//TAKING INTO ACCOUNT THE TRANSITION DURATION TO OVERLAP VIDEOS
videoStartTime = CMTimeAdd(videoStartTime, CMTimeSubtract(currentVideoDuration, CMTimeMakeWithSeconds(transitionDuration, 600)));
}
else{
//TRANSITION NOT APPLIED TO THE END OF THE LAST CLIP
videoStartTime = CMTimeAdd(videoStartTime, currentVideoDuration);
}
}
mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,videoStartTime);
mainInstruction.layerInstructions = instructionsArray;
AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.instructions = [NSArray arrayWithObjects:mainInstruction,nil];
videoComposition.frameDuration = CMTimeMake(1, 30);
videoComposition.renderSize = CGSizeMake(1920, 1080);
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *videoOutputPath = [documentsDirectory stringByAppendingPathComponent:@"videoRecordingFinalOutput.mov"];
NSURL *videoOutputURL = [[NSURL alloc] initFileURLWithPath:videoOutputPath];
AVAssetExportSession *videoExportSession = [[AVAssetExportSession alloc] initWithAsset:mutableComposition presetName:AVAssetExportPresetHighestQuality];
videoExportSession.outputURL = videoOutputURL;
videoExportSession.videoComposition = videoComposition;
videoExportSession.outputFileType = AVFileTypeQuickTimeMovie;
[videoExportSession exportAsynchronouslyWithCompletionHandler:^{
NSLog(@"EXPORT STATUS %ld %@", (long)videoExportSession.status, videoExportSession.error);
if(videoExportSession.error == NULL){
NSLog(@"EXPORT SUCCESSFUL");
[library writeVideoAtPathToSavedPhotosAlbum:videoOutputURL
completionBlock:^(NSURL *assetURL, NSError *error) {
if(error) {
NSError *error = nil;
if([[NSFileManager defaultManager] fileExistsAtPath:videoOutputPath]){
[[NSFileManager defaultManager] removeItemAtPath:videoOutputPath error:&error];
if(error){
NSLog(@"VIDEO FILE DELETE FAILED");
}
else{
NSLog(@"VIDEO FILE DELETED");
}
}
}
else{
NSError *error = nil;
if([[NSFileManager defaultManager] fileExistsAtPath:videoOutputPath]){
[[NSFileManager defaultManager] removeItemAtPath:videoOutputPath error:&error];
if(error){
NSLog(@"VIDEO FILE DELETE FAILED");
}
else{
NSLog(@"VIDEO FILE DELETED");
}
}
}
}];
}
else{
NSError *error = nil;
if([[NSFileManager defaultManager] fileExistsAtPath:videoOutputPath]){
[[NSFileManager defaultManager] removeItemAtPath:videoOutputPath error:&error];
if(error){
NSLog(@"VIDEO FILE DELETE FAILED");
}
else{
NSLog(@"VIDEO FILE DELETED");
}
}
}
}];
}
最佳答案
与其为每个剪辑创建新的 videoTracks,不如尝试仅使用 2 个 videoTracks 并在这 2 个中插入 timeRanges。并在 2 个轨道之间进行过渡
所以第一个视频将被插入到 videoTrack1 中,第二个视频将被插入到 videoTrack2 中,这样就可以应用过渡,然后再次将第三个剪辑插入到轨道 1 中,依此类推。
关于ios - AVAssetExportSession 间歇性错误 11820 "Cannot Complete Export"Suggestion=再次尝试导出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35170799/
在我的项目代码优化期间,我替换了 var 的所有实例关键词 let因为我认为 var 没有特别的用途.为此,我在所有文件中执行了“查找和替换”操作。 在一些自定义模块中,我使用了如下语句: var e
我遇到过使用“双”导出来创建当前组件的情况。您能否解释一下它是否有真正的用途,或者只是作者的偏好? import React from 'react' import DuckImage from '.
我编写了一个简单的脚本来创建用户 (TestV100)、在该架构中创建表 (Xy100) 并将制表符分隔的平面文件从 hadoop 导出到此 Oracle 表。 这是 shell 脚本:-Export
我真的很困惑: export const foo 导出默认 foo module.exports = foo; 我知道这些是非常基本的,但有人可以区分并向我解释这些。我真的很想明白。 最佳答案 让我们
今天我在我的 AngularJS 项目中采用了 Browserify,但是我还不清楚。在所有示例和博客文章中,我都看到了这样的东西: /app.js: require('./messages'); a
我正在寻找一种方法: 隐藏 HTML 页面结果上的标题 导出时在 highcharts 图表上显示标题(PDF、PNG、JPEG 或打印) 我不知道如何继续。有人可以帮助我吗? 最佳答案 您可以在导出
在我的应用程序的首选项中,我调用以特殊方式处理某些参数的 Activity 。到目前为止它运作良好。但是,为了创建试用版和专业版,我刚刚创建了一个包含所有代码的库和一个调用该库的新演示应用程序。除了由
pentaho cde 导出组件正在为我工作,它导出表数据,文件名为 cda-export.csv,我可以自动设置文件名吗? 最佳答案 尝试使用参数 {filename : 'myfilename
我想从 Gephi 的预览选项卡中导出 SVG/PDF/PNG。导出的网络包括所有节点,但切断了左右两侧的节点标签。如何获得不切断标签的导出 pdf? 最佳答案 您必须通过控制选项 来调整输出的大小。
如标题所述,我在尝试使用我的 perl 模块时遇到此错误,但我不知道它是什么意思,而且我似乎无法在 Internet 上找到任何明确的结果。我的代码由 3 个文件组成:一个脚本 (myApp.pl),
我曾经每天下载一个 firebase 实时数据库的节点,通过导出该节点的 .JSON 文件来监控一些输出。 JSON 文件本身大约 8MB。 最近,我开始收到一个错误: “导出 JSON 无法导出在单
之间有什么区别 export * as bar from 'foo' 和 export { default as bar } from 'foo' 在我的特殊情况下,我尝试了以下两种方法,它们都有效,
我想我要求的是不可能的OOB,但我想确认一下。 我们正在升级到 ES6(使用 Babel)。项目是一个网站,使用 AMD (requirejs)。我想将实用程序模块 (foolib) 转换为 ES6,
我一直在我的 React 中广泛使用命名导出和默认导出,我遇到了这 2 个相似的语法。 从'./Button'导出默认值; export { default } from './Button'; 有人
在此页面 ( http://docs.nodejitsu.com/articles/getting-started/what-is-require ) 上,它指出“如果要将导出对象设置为函数或新对象,
在此页面 ( http://docs.nodejitsu.com/articles/getting-started/what-is-require ) 上,它指出“如果要将导出对象设置为函数或新对象,
我在运行 flow check 时收到此错误,但我不确定这是什么意思。 Cannot use exports as a type because exports is a value. To get
module.export和export有什么区别? 如果module.export对象中有一些属性怎么办?export.xx 会无效吗? 最佳答案 首先是 exports 和 module.expo
我正在学习 typescript 。在研究一些源文件时,我发现声明文件 .d 中有时有 export declare ... 有时只有 export ... .ts. 经过一些测试,在我看来它们是等价
假设我有一个要导出的变量。有什么区别 export const a = 1; 对比 export let a = 1; 我理解const 和let 之间的区别,但是当你导出它们时,有什么区别? 最佳答
我是一名优秀的程序员,十分优秀!