在 ARC 中异步生成 CGImagesForTimes

发布于 2024-12-28 02:29:23 字数 1028 浏览 4 评论 0原文

如果我在启用了 ARC 的项目中运行以下命令,则完成处理程序永远不会触发。但如果没有 ARC,它会按预期工作。我在这里缺少什么?

NSURL *url = [NSURL URLWithString:@"http://media.w3.org/2010/05/sintel/trailer.mp4"];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = YES;
CMTime thumbTime = CMTimeMakeWithSeconds(5,30);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, 
                                                   CGImageRef im, 
                                                   CMTime actualTime, 
                                                   AVAssetImageGeneratorResult result, 
                                                   NSError *error){
    NSLog(@"completion handler");
};

generator.maximumSize = CGSizeMake(320, 180);
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];

If I run the following in a project where ARC is enabled the completion handler never fires. But without ARC it works as expected. What am I missing here?

NSURL *url = [NSURL URLWithString:@"http://media.w3.org/2010/05/sintel/trailer.mp4"];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = YES;
CMTime thumbTime = CMTimeMakeWithSeconds(5,30);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, 
                                                   CGImageRef im, 
                                                   CMTime actualTime, 
                                                   AVAssetImageGeneratorResult result, 
                                                   NSError *error){
    NSLog(@"completion handler");
};

generator.maximumSize = CGSizeMake(320, 180);
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

偷得浮生 2025-01-04 02:29:23

根据 Michael 指出,生成器不会被保留,如果您只是在完成块中“使用”生成器 var,一切都会正常。

所以我想答案是...

NSURL *url = [NSURL URLWithString:@"http://media.w3.org/2010/05/sintel/trailer.mp4"];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = YES;
CMTime thumbTime = CMTimeMakeWithSeconds(5,30);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, 
                                                   CGImageRef im, 
                                                   CMTime actualTime, 
                                                   AVAssetImageGeneratorResult result, 
                                                   NSError *error){
    NSLog(@"make sure generator is used in this block and it'll work %@", generator);
};

generator.maximumSize = CGSizeMake(320, 180);
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];

Based on Michael pointing out that generator doesn't get retained, if you simply 'use' the generator var inside the completion block, everything will work.

So I guess the answer is...

NSURL *url = [NSURL URLWithString:@"http://media.w3.org/2010/05/sintel/trailer.mp4"];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = YES;
CMTime thumbTime = CMTimeMakeWithSeconds(5,30);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, 
                                                   CGImageRef im, 
                                                   CMTime actualTime, 
                                                   AVAssetImageGeneratorResult result, 
                                                   NSError *error){
    NSLog(@"make sure generator is used in this block and it'll work %@", generator);
};

generator.maximumSize = CGSizeMake(320, 180);
[generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];
若沐 2025-01-04 02:29:23

看起来generateCGImagesAsynchronouslyForTimes不保留生成器。使生成器成为实例的成员变量并分配给它。我一这样做,它就开始工作了。代码看起来像这样:

NSURL *url = [NSURL URLWithString:@"http://media.w3.org/2010/05/sintel/trailer.mp4"];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
[generator_ cancelAllCGImageGeneration];
generator_ = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator_.appliesPreferredTrackTransform = YES;
CMTime thumbTime = CMTimeMakeWithSeconds(5,30);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, 
                                                   CGImageRef im, 
                                                   CMTime actualTime, 
                                                   AVAssetImageGeneratorResult result, 
                                                   NSError *error){
    NSLog(@"completion handler");
};

generator_.maximumSize = CGSizeMake(320, 180);
[generator_ generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];

Looks like generateCGImagesAsynchronouslyForTimes does not retain the generator. Make generator a member variable of your instance and assign to it. As soon as I did that, it started working. The code will look something like this:

NSURL *url = [NSURL URLWithString:@"http://media.w3.org/2010/05/sintel/trailer.mp4"];
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
[generator_ cancelAllCGImageGeneration];
generator_ = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator_.appliesPreferredTrackTransform = YES;
CMTime thumbTime = CMTimeMakeWithSeconds(5,30);

AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, 
                                                   CGImageRef im, 
                                                   CMTime actualTime, 
                                                   AVAssetImageGeneratorResult result, 
                                                   NSError *error){
    NSLog(@"completion handler");
};

generator_.maximumSize = CGSizeMake(320, 180);
[generator_ generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];
南…巷孤猫 2025-01-04 02:29:23

图像生成器肯定不会被框架保留。不确定 Apple 编程指南的更新频率,但您可以在 AV Foundation Prog 中阅读该指南。指南,位于 生成图像序列非常清楚:

<块引用>

此外,您必须确保保留图像生成器
直到完成图像创建。

The image generator definitely does not get retained by the framework. Not sure how often Apple Programming Guide gets updated, but you can read that in AV Foundation Prog. Guide, in Generating a Sequence of Images quite clearly:

In addition, you must ensure that you retain the image generator
until it has finished creating the images.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文