我在AVAssetExportSession上遇到了一个问题,进程停止增加,但状态仍然显示它正在导出。这实际上是一个相当罕见的情况,它在99.99%的时间内都能完美地工作,但我还是想解决这个问题。
所以我开始导出:
exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality];
exportSession.videoComposition = videoComposition;
exportSession.outputFileType = @"com.apple.quicktime-movie";
exportSession.outputURL = outputURL;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
...
}];然后使用计时器检查进度:
AVAssetExportSessionStatus status = [exportSession status];
float progress = 0;
if (status == AVAssetExportSessionStatusExporting) {
progress = [exportSession progress];
} else if (status == AVAssetExportSessionStatusCompleted) {
progress = 1;
}
NSLog(@"%d %f", status, progress);
[delegate processor:self didProgress:progress];输出结果如下所示:
2012-05-23 14:28:59.494 **********[1899:707] 2 0.125991
2012-05-23 14:28:59.994 **********[1899:707] 2 0.185280
2012-05-23 14:29:00.494 **********[1899:707] 2 0.259393
2012-05-23 14:29:00.994 **********[1899:707] 2 0.326093
2012-05-23 14:29:01.494 **********[1899:707] 2 0.400206
2012-05-23 14:29:01.995 **********[1899:707] 2 0.481729
2012-05-23 14:29:02.495 **********[1899:707] 2 0.541019
2012-05-23 14:29:02.997 **********[1899:707] 2 0.622542
2012-05-23 14:29:03.493 **********[1899:707] 2 0.681832
2012-05-23 14:29:03.995 **********[1899:707] 2 0.763355
2012-05-23 14:29:04.494 **********[1899:707] 2 0.822645
2012-05-23 14:29:04.994 **********[1899:707] 2 0.880082
2012-05-23 14:29:05.493 **********[1899:707] 2 0.880082
2012-05-23 14:29:05.994 **********[1899:707] 2 0.880082
...
2012-05-23 14:43:22.994 **********[1899:707] 2 0.880082
2012-05-23 14:43:23.493 **********[1899:707] 2 0.880082
2012-05-23 14:43:23.994 **********[1899:707] 2 0.880082
2012-05-23 14:43:24.494 **********[1899:707] 2 0.880082(注意:它并不是每次都以相同的百分比停止,它完全是随机的)
正如你从时间戳中看到的,它花了5秒完成前88%,然后我让它再运行13分钟(完整的视频处理通常不会超过10秒),进度没有变化。
目前,我唯一的选择是检查进度是否在过去X秒内没有改变,然后告诉用户失败,然后重试。
有谁有什么想法吗?
发布于 2014-02-10 11:29:51
在我的例子中,这个问题源于使用不寻常的配置编码的mp4s。但最终导致这个问题的是苹果代码中的一个bug。
具体地说,我在Facebook上和mp4s一起工作。似乎facebook在对视频进行编码时,会丢弃或移动视频轨道的第一帧。使用ffprobe查看视频显示:
"r_frame_rate": "722/25",
"avg_frame_rate": "722/25",
"time_base": "1/28880",
"start_pts": 1000,
"start_time": "0.034626",不幸的是,苹果的API不能正确地报告曲目的开始时间。在从AVAsset获取AVAssetTrack并检查其timeRange之后,它报告开始时间为0。我可能误解了赛道和资产计时的本质,但这似乎是一个错误。
当然,在为导出会话构建视频合成时,我使用了不正确的跟踪时间范围。我怀疑,当导出会话在时间0查找磁道中的数据时,它会感到困惑,然后就像我们看到的那样,只是挂起,甚至没有报告错误-另一个错误。即使使用videoCompositionWithPropertiesOfAsset:创建组合也没有帮助。
我还没有尝试使用AVAssetReader和AVAssetWriter来代替AVAssetExportSession,所以我不知道您是否会遇到同样的情况。直到我有更多的时间来探索,我已经想出了这个hack作为解决方案:
将用于曲目插入和视频指令的时间范围重置为从1帧或2帧开始:
CMTimeRange videoTimeRange = videoTrack.timeRange;
videoTimeRange.start = CMTimeMake(1, ceil(videoTrack.nominalFrameRate));显然,该hack仅适用于视频轨道开始时间不为0的特定情况。我猜测,一般来说,这个bug是由AVAssetExportSession及其相关类所不期望的不寻常的媒体编码引起的。
发布于 2013-02-18 04:47:06
我已经找到了!
您需要设置正确的layerInstructions:
AVMutableCompositionTrack *track = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVMutableVideoCompositionLayerInstruction * layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:track];
AVMutableVideoCompositionInstruction * MainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
MainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, allTime);
MainInstruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];否则它就会卡住。
发布于 2013-02-23 13:46:06
我想知道这是不是线程的问题-如果计时器和导出器在不同的线程中结束。( AVFoundation指南指出,不能保证导出器在任何特定线程上运行。)
您是否尝试过使用键值观察而不是计时器?
基本框架示例:
// register for the notification
[exportSession addObserver:someProcessor forKeyPath:@"progress" options:NSKeyValueObservingOptionNew context:NULL];然后在你的处理器中:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
// add some checks here
NSNumber *processNumber = [change objectForKey:NSKeyValueChangeNewKey];
float process = [processNumber floatValue];
[delegate processor:self didProgress:progress];
}https://stackoverflow.com/questions/10727530
复制相似问题