Objective c 使用AVPlayer循环播放视频片段

Objective c 使用AVPlayer循环播放视频片段,objective-c,cocoa,avfoundation,avplayer,nsnotificationcenter,Objective C,Cocoa,Avfoundation,Avplayer,Nsnotificationcenter,我尝试循环一段视频,给定两个帧标记(markIn和markOut)。选择“循环”选项后,播放机将循环此视频片段。目前,我已经为整个视频设置了一个循环,使用苹果的建议,即一旦到达终点,就发送avplayerItemDidPlaytoEndTime通知 我认为这是一个干净的实现方法,当到达标记点时发送一个通知,如果循环被激活,它会将玩家移回标记点。那么有没有办法按照playerItemDidReachMarkOut的思路创建一个通知呢 我对通知和AVPlayer还比较陌生,所以如果我遗漏了什么,请原

我尝试循环一段视频,给定两个帧标记(markIn和markOut)。选择“循环”选项后,播放机将循环此视频片段。目前,我已经为整个视频设置了一个循环,使用苹果的建议,即一旦到达终点,就发送avplayerItemDidPlaytoEndTime通知

我认为这是一个干净的实现方法,当到达标记点时发送一个通知,如果循环被激活,它会将玩家移回标记点。那么有没有办法按照playerItemDidReachMarkOut的思路创建一个通知呢


我对通知和AVPlayer还比较陌生,所以如果我遗漏了什么,请原谅。

您正在寻找的是所谓的边界时间观察者。你给你的AVPlayer一个
CMTime
s的列表,当播放器的
currentTime
大约是这些时间中的任何一个时,它会通知你

[m_player seekToTime:CMTimeMakeWithSeconds(5.0f, time.timescale) toleranceBefore: kCMTimeZero toleranceAfter: kCMTimeZero];
它的工作原理如下:

//Use an unretained reference in the block to break the retain cycle of the player retaining the block retaining the player retaining…
__unsafe_unretained AVPlayer *weakPlayer = _myPlayer;

_myObserver = [_myPlayer addBoundaryTimeObserverForTimes:@[ [NSValue valueWithCMTime:markOutTime] ]
    queue:dispatch_get_main_queue()
    usingBlock:^{
        [weakPlayer seekToTime:markInTime
            /*optional:
            toleranceBefore:kCMTimeZero
            toleranceAfter:kCMTimeZero
            */
            ];
    }
];
当然,稍后必须使用
removeTimeObserver:
通知AVPlayer停止此观察。将从
addBoundaryTimeObserver…:
获得的对象赋予它

注意事项/注意事项/警告
  • 尽管名称不同,但它们不必是“边界”时间。你可以只拥有一个时间,即使你没有,AVPlayer也不会推断任何时间是开始时间、结束时间、中点还是其他时间
  • 对于同一“边界”,可以多次调用同一块。确保你能恰当地处理这个问题(在我的例子中,我必须确保不让同一个副标题显示两次)
  • 寻找时不调用边界时间观察者(同样,从开始和结束的意义上来说,时间并没有真正解释为“边界”)。如果您直接寻找边界时间(或多或少见下一点),您应该得到通知,但寻找两个边界之间或多个边界之间的点不会引起观察
  • 我说的大概,我是认真的。我见过AVPlayer多次发出通知的主要情况是,AVPlayer提前一点发出通知,然后在(或至少更接近)准确时间再次发出通知。不要假设
    currentTime
    与您提供的任何时间完全相等

这只是问题的一半;提问者遗漏的部分是“到达标记点时的通知”。谢谢彼得,这似乎就是我要找的。发布问题后,我通过将结束时间更改为标记点来实现它。现在我可以使用PlayerItemDidReachen,玩家会认为标记点是终点,在这一点上它会“循环”回到给定的标记点。显然,这有一些限制,例如,将播放头移过新的“结束”将触发通知。为了避免这种情况,每当播放头移出循环边界时(在标记之前或标记之后),我就取消循环。由于这些限制,我将尝试您的解决方案,尽管我可以看到,在需要精度/一致性时,解决方案的近似性质是一个问题。