首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >macruby AVPlayer addBoundaryTimeObserverForTimes

macruby AVPlayer addBoundaryTimeObserverForTimes
EN

Stack Overflow用户
提问于 2013-02-22 19:44:07
回答 3查看 2.5K关注 0票数 2

我在使用AVFoundation AVPlayer为边界时间添加观察者时遇到了一个奇怪的问题。

代码语言:javascript
复制
 player = AVPlayer.playerWithURL(NSURL.URLWithString(someurl))
 player.play()
 player.addBoundaryTimeObserverForTimes([NSValue.valueWithCMTime(CMTimeMake(1,1))], queue: nil, usingBlock: -> { puts 'success' } )

当在XCode中执行此代码时,它落在添加观察者的调试汇编程序代码上,而控制台中没有错误。有没有人遇到过这样的问题?

EN

回答 3

Stack Overflow用户

发布于 2014-08-20 23:05:56

我像这样使用它,它是有效的:

代码语言:javascript
复制
__block AVPlayer* blockPlayer = self.player;        //player is already initialised and set up; 
__block id obs;

// Setup boundary time observer to trigger when audio really begins,
// specifically after 1/3 of a second playback

obs = [self.player addBoundaryTimeObserverForTimes: @[[NSValue valueWithCMTime:CMTimeMake(1, 10)]]
                                             queue:NULL
                                        usingBlock:^{

                                           // Raise a notificaiton when playback has started
                                           [[NSNotificationCenter defaultCenter] postNotificationName:PLAYBACK_STARTED_NOTIFICATION object:nil];

                                           // Remove the boundary time observer
                                           [blockPlayer removeTimeObserver:obs];
                                       }];
票数 1
EN

Stack Overflow用户

发布于 2015-08-16 13:32:30

如果您仔细阅读文档,您将看到此方法返回:

返回值:作为参数传递给removeTimeObserver:以停止观察的不透明对象。

然后就是:

只要希望播放器调用时间观察器,就必须保留返回值。每次调用此方法时,都需要与相应的removeTimeObserver调用配对:

您的问题是您没有保留该方法的返回值,您只是调用了该方法,因此时间观察器不会被播放器调用。

使用__block变量实际上应该可以在这里工作

代码语言:javascript
复制
player = AVPlayer.playerWithURL(NSURL.URLWithString(someurl))
player.play()

__block id observer = player.addBoundaryTimeObserverForTimes([NSValue.valueWithCMTime(CMTimeMake(1,1))], queue: nil, usingBlock: ->
{
    puts 'success'
    player.removeTimeObserver(observer) // IMPORTANT, but careful. Read below*
} )

低于 *:正如苹果强调的那样,你需要调用removeTimeObserver,对我来说最有意义的地方应该是完成块,但至少在Obj和Swift以及大多数其他语言中,这会导致保留循环。在Obj和Swift中,你可以通过将观察者和播放器声明为block variables来绕过这个问题,这样你就可以从块内部安全地引用它们。

如果您能找到其他地方安全地调用removeTimeObserver方法,那么您不必担心这一点。

无论如何,上面的代码将在播放器进入歌曲/视频的1秒时执行该块。

另请注意:

AV基础不保证为通过的每个间隔或边界调用您的块。如果先前调用的块的执行尚未完成,则AV Foundation不会调用块。因此,您必须确保在块中执行的工作不会对系统造成过重的负担。

我认为这不适用于你,但可能适用于添加了多个时间间隔/界限的其他人。

票数 0
EN

Stack Overflow用户

发布于 2013-02-28 07:05:23

也许它真的需要一些队列作为参数进行传递

试试这个:

代码语言:javascript
复制
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

[player addBoundaryTimeObserverForTimes:[NSValue.valueWithCMTime(CMTimeMake(1,1))]
                                  queue: myQueue
                             usingBlock: -> { puts 'success' }];
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15023451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档