对于视频:
AVPlayer有一个被称为的参数rate (Float),如果rate大于0.0,则有一个当前播放的视频.
您可以检查是否rate是!=0:(速率可以是负的,如果玩家会倒流)
if vidPlayer != nil && vidPlayer.rate != 0 {
println("playing")
}
Run Code Online (Sandbox Code Playgroud)
据我所知,我同意你的看法,在play()调用函数和实际播放视频之间会有一点延迟(换句话说,视频的第一帧被渲染的时间).延迟取决于一些标准,如视频类型(视频点播或直播),网络条件......但幸运的是,我们能够知道视频的第一帧渲染,我的意思是视频实际播放的时间.
通过观察status当前AVPlayerItem和无论何时AVPlayerItemStatusReadyToPlay,都应该是第一帧被渲染.
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];
-(void)observeValueForKeyPath:(NSString*)path ofObject:(id)object change:(NSDictionary*)change context:(void*) context {
if([self.playerItem status] == AVPlayerStatusReadyToPlay){
NSLog(@"The video actually plays")
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下,还有另一种解决方案,我们观察readyForDisplay状态AVPlayerLayer,它还表示视频呈现的时间.但是,该解决方案具有Apple文档中提到的缺点
/*!
@property readyForDisplay
@abstract Boolean indicating that the first video frame has been made ready for display for the current item of the associated AVPlayer.
@discusssion Use this property as an indicator of when best to show or animate-in an AVPlayerLayer into view.
An AVPlayerLayer may be displayed, or made visible, while this propoerty is NO, however the layer will not have any
user-visible content until the value becomes YES.
This property remains NO for an AVPlayer currentItem whose AVAsset contains no enabled video tracks.
*/
@property(nonatomic, readonly, getter=isReadyForDisplay) BOOL readyForDisplay;
Run Code Online (Sandbox Code Playgroud)
这是示例代码
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
[self.playerLayer addObserver:self forKeyPath:@"readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];
-(void)observeValueForKeyPath:(NSString*)path ofObject:(id)object change:(NSDictionary*)change context:(void*) context {
if([self.playerLayer isReadyForDisplay]){
NSLog(@"Ready to display");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,[self.playerLayer isReadyForDisplay]应该返回YES,但是,作为文件,它不能保证.
我希望这会有所帮助.
斯威夫特 4
方法一
var rateObserver: NSKeyValueObservation?
self.rateObserver = myPlayer.observe(\.rate, options: [.new, .old], changeHandler: { (player, change) in
if player.rate == 1 {
print("Playing")
}else{
print("Stop")
}
})
// Later You Can Remove Observer
self.rateObserver?.invalidate()
Run Code Online (Sandbox Code Playgroud)
方法二
myPlayer.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions(rawValue: NSKeyValueObservingOptions.new.rawValue | NSKeyValueObservingOptions.old.rawValue), context: nil)
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "rate" {
if player.rate == 1 {
print("Playing")
}else{
print("Stop")
}
}
}
Run Code Online (Sandbox Code Playgroud)