iOS/AVFoundation:将图像阵列转换为曲目,然后转换为单个视频时,异步处理程序的设计模式?
你能告诉我设计模式指南,使我的风格适应AVFoundation的异步方法吗 在应用程序中创建图像并将音频放置到热点上。我正在实现导出到一部电影,该电影是在音频下播放的带有效果(热点的辉光)的图像 我能可靠地创建视频和音频曲目,并能正确地将音频转换成AVMUTABLE合成并播放。问题在于视频。我已经把范围缩小到我已经为一个需要使用AVFoundation异步编写方法的问题编写了一个同步解决方案 当前方法及其失败之处(每个步骤都是自己的方法):iOS/AVFoundation:将图像阵列转换为曲目,然后转换为单个视频时,异步处理程序的设计模式?,ios,objective-c,design-patterns,avfoundation,Ios,Objective C,Design Patterns,Avfoundation,你能告诉我设计模式指南,使我的风格适应AVFoundation的异步方法吗 在应用程序中创建图像并将音频放置到热点上。我正在实现导出到一部电影,该电影是在音频下播放的带有效果(热点的辉光)的图像 我能可靠地创建视频和音频曲目,并能正确地将音频转换成AVMUTABLE合成并播放。问题在于视频。我已经把范围缩小到我已经为一个需要使用AVFoundation异步编写方法的问题编写了一个同步解决方案 当前方法及其失败之处(每个步骤都是自己的方法): 创建字典数组。字典中有2个对象。一个字典对象是表示关键
从文档中: 分组块允许聚合同步。你的申请 可以在全部完成时提交多个区块并跟踪,甚至 尽管它们可能在不同的队列上运行。这种行为可以是 在完成所有指定任务后才能取得进展时,此功能非常有用 这些都是完整的 基本思想是,为每个异步任务调用。在任务的完成处理程序中,调用 调度组的工作类似于计算信号量。启动任务时递增计数器(使用dipsatch_group_wait),任务完成时递减计数器。 用于为组安装完成处理程序块。当计数器达到0时,执行此块
这篇博文提供了一个很好的概述和完整的代码示例:@weichsel非常感谢。这似乎应该行得通。但是,我正在使用dispatch_group_wait,它似乎没有等待。自从你第一次回复以来,我一直在敲它好几个小时,但现在运气好了。以下是我所做的:
- 添加了一个属性,该属性是一个调度组,称为videoDispatchGroup,并在执行视频处理的类的init中调用dispatch_group_create
- 在创建视频曲目的方法中,使用dispatch_group_async(VideoDispatch group,dispatch_get_global_queue(dispatch_queue_PRIORITY_DEFAULT,0))^{[videoWriter finishWritingWithCompletionHandler:^{
- 视频曲目写入方法是从一个链接各个步骤的方法调用的。在该方法中,在调用写入曲目后,我调用dispatch_group_wait(videoProcessingGroup,dispatch_TIME_FOREVER)
- 在dealloc中,调用dispatch_release(videoDispatchGroup)
下面是代码——dispatch_group_wait似乎从未启动过,但电影本身是制作的。为了简洁起见,代码略去了一点,但没有删除任何在没有GCD代码的情况下不起作用的代码
@implementation MovieMaker
// This is the dispatch group
@synthesize videoProcessingGroup = _videoProcessingGroup;
-(id)init {
self = [super init];
if (self) {
_videoProcessingGroup = dispatch_group_create();
}
return self;
}
-(void)dealloc {
dispatch_release(self.videoProcessingGroup);
}
-(id)convert:(MTCanvasElementViewController *)sourceObject {
// code fails in same way with or without this line
dispatch_group_enter(self.videoProcessingGroup);
// This method works its way down to writeImageArrayToMovie
_tracksData = [self collectTracks:sourceObject];
NSString *fileName = @"";
// The following seems to never stop waiting, the movies themselves get made though
// Wait until dispatch group finishes processing temp tracks
dispatch_group_wait(self.videoProcessingGroup, DISPATCH_TIME_FOREVER);
// never gets to here
fileName = [self writeTracksToMovie:_tracksData];
// Wait until dispatch group finishes processing final track
dispatch_group_wait(self.videoProcessingGroup, DISPATCH_TIME_FOREVER);
return fileName;
}
// @param videoFrames should be NSArray of UIImage, all of same size
// @return path to temp file
-(NSString *)writeImageArrayToMovie:(NSArray *)videoFrames usingDispatchGroup:(dispatch_group_t)dispatchGroup {
// elided a bunch of stuff, but it all works
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:result]
fileType:AVFileTypeMPEG4
error:&error];
//elided stuff
//Finish the session:
[writerInput markAsFinished];
dispatch_group_async(dispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[videoWriter finishWritingWithCompletionHandler:^{
dispatch_group_leave(dispatchGroup);
// not sure I ever get here? NSLogs don't write out.
CVPixelBufferPoolRelease(adaptor.pixelBufferPool);
}];
});
return result;
}
非常感谢您的帮助。但我无法让dispatch\u group\u wait实际等待。由于此评论部分的格式问题,我在下面的新答案中添加了一个说明。Hi Rod-很抱歉回复太晚:)我没有看到您的答案,因为我只收到评论通知。您似乎从未呼叫dispatch\u group\u enter-这非常重要,因为它会增加等待计数器。如果您从未“输入”组,dispatch\u group\u wait将不起作用。我不确定您的dispatch\u group\u wait呼叫是否位于正确的位置。或许您可以更新您的答案(或原问题)带代码。