Egi*_*gil 102 iphone objective-c avfoundation ios avplayer
有没有办法知道AVPlayer
播放是否已经停止或到达终点?
maz*_*maz 325
你可以告诉它正在使用:
AVPlayer *player = ...
if ((player.rate != 0) && (player.error == nil)) {
// player is playing
}
Run Code Online (Sandbox Code Playgroud)
Swift 3扩展:
extension AVPlayer {
var isPlaying: Bool {
return rate != 0 && error == nil
}
}
Run Code Online (Sandbox Code Playgroud)
Tod*_*son 58
要获得到达项目结尾的通知(通过Apple):
[[NSNotificationCenter defaultCenter]
addObserver:<self>
selector:@selector(<#The selector name#>)
name:AVPlayerItemDidPlayToEndTimeNotification
object:<#A player item#>];
Run Code Online (Sandbox Code Playgroud)
跟踪比赛你可以:
"通过使用addPeriodicTimeObserverForInterval:queue:usingBlock:或addBoundaryTimeObserverForTimes:queue:usingBlock: "跟踪AVPlayer对象中播放头位置的变化" .
示例来自Apple:
// Assume a property: @property (retain) id playerObserver;
Float64 durationSeconds = CMTimeGetSeconds([<#An asset#> duration]);
CMTime firstThird = CMTimeMakeWithSeconds(durationSeconds/3.0, 1);
CMTime secondThird = CMTimeMakeWithSeconds(durationSeconds*2.0/3.0, 1);
NSArray *times = [NSArray arrayWithObjects:[NSValue valueWithCMTime:firstThird], [NSValue valueWithCMTime:secondThird], nil];
self.playerObserver = [<#A player#> addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{
// Passing NULL for the queue specifies the main queue.
NSString *timeDescription = (NSString *)CMTimeCopyDescription(NULL, [self.player currentTime]);
NSLog(@"Passed a boundary at %@", timeDescription);
[timeDescription release];
}];
Run Code Online (Sandbox Code Playgroud)
Tra*_* M. 39
在iOS10中,现在有一个内置属性:timeControlStatus
例如,此功能根据其状态播放或暂停avPlayer,并相应地更新播放/暂停按钮.
@IBAction func btnPlayPauseTap(_ sender: Any) {
if aPlayer.timeControlStatus == .playing {
aPlayer.pause()
btnPlay.setImage(UIImage(named: "control-play"), for: .normal)
} else if aPlayer.timeControlStatus == .paused {
aPlayer.play()
btnPlay.setImage(UIImage(named: "control-pause"), for: .normal)
}
}
Run Code Online (Sandbox Code Playgroud)
至于你的第二个问题,要知道avPlayer是否到达终点,最简单的方法是设置通知.
NotificationCenter.default.addObserver(self, selector: #selector(self.didPlayToEnd), name: .AVPlayerItemDidPlayToEndTime, object: nil)
Run Code Online (Sandbox Code Playgroud)
例如,当它结束时,您可以将其倒回到视频的开头并将"暂停"按钮重置为"播放".
@objc func didPlayToEnd() {
aPlayer.seek(to: CMTimeMakeWithSeconds(0, 1))
btnPlay.setImage(UIImage(named: "control-play"), for: .normal)
}
Run Code Online (Sandbox Code Playgroud)
如果您正在创建自己的控件,这些示例很有用,但如果您使用AVPlayerViewController,则内置控件.
kga*_*dis 20
rate
是不是要检查视频是否是这样打(这可能停滞不前).来自以下文件rate
:
表示所需的播放速率; 0.0表示"暂停",1.0表示希望以当前项目的自然速率进行游戏.
关键词"游戏欲望" - 速度1.0
并不意味着视频正在播放.
自iOS 10.0以来的解决方案是使用AVPlayerTimeControlStatus
可以在AVPlayer
timeControlStatus
属性上观察到的解决方案.
iOS 10.0(9.0,8.0等)之前的解决方案是推出自己的解决方案.视频暂停的平均速率0.0
.当rate != 0.0
它意味着视频正在播放或停转.
您可以通过以下方式观察球员时间来找出差异: func addPeriodicTimeObserver(forInterval interval: CMTime, queue: DispatchQueue?, using block: @escaping (CMTime) -> Void) -> Any
该块返回当前播放器的时间CMTime
,因此比较lastTime
(从块上次收到currentTime
的时间)和(刚刚报告的块的时间)将判断播放器是在播放还是停止播放.例如,如果lastTime == currentTime
和rate != 0.0
,则播放器已经停止.
正如其他人所指出的那样,确定回放是否已经完成AVPlayerItemDidPlayToEndTimeNotification
.
max*_*lov 18
一个更可靠的替代方案NSNotification
是将自己添加为玩家rate
财产的观察者.
[self.player addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionNew
context:NULL];
Run Code Online (Sandbox Code Playgroud)
然后检查观察到的速率的新值是否为零,这意味着由于某种原因播放已停止,例如由于空缓冲区而到达结束或停止.
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context {
if ([keyPath isEqualToString:@"rate"]) {
float rate = [change[NSKeyValueChangeNewKey] floatValue];
if (rate == 0.0) {
// Playback stopped
} else if (rate == 1.0) {
// Normal playback
} else if (rate == -1.0) {
// Reverse playback
}
}
}
Run Code Online (Sandbox Code Playgroud)
例如rate == 0.0
,要知道究竟是什么原因导致播放停止,您可以执行以下检查:
if (self.player.error != nil) {
// Playback failed
}
if (CMTimeGetSeconds(self.player.currentTime) >=
CMTimeGetSeconds(self.player.currentItem.duration)) {
// Playback reached end
} else if (!self.player.currentItem.playbackLikelyToKeepUp) {
// Not ready to play, wait until enough data is loaded
}
Run Code Online (Sandbox Code Playgroud)
并且不要忘记让玩家到达终点时停止:
self.player.actionAtItemEnd = AVPlayerActionAtItemEndPause;
Aks*_*Aks 17
对于Swift:
AVPlayer:
let player = AVPlayer(URL: NSURL(string: "http://www.sample.com/movie.mov"))
if (player.rate != 0 && player.error == nil) {
println("playing")
}
Run Code Online (Sandbox Code Playgroud)
更新:
player.rate > 0
条件已更改为player.rate != 0
因为如果视频正在反向播放,则感谢Julian指出,这可能是负面的.
注意:这可能与上面(Maz的)答案相同,但是在Swift'中!player.error'给了我一个编译错误,所以你必须在Swift中使用'player.error == nil'检查错误.(因为错误属性不是'Bool'类型)
AVAudioPlayer:
if let theAudioPlayer = appDelegate.audioPlayer {
if (theAudioPlayer.playing) {
// playing
}
}
Run Code Online (Sandbox Code Playgroud)
AVQueuePlayer:
if let theAudioQueuePlayer = appDelegate.audioPlayerQueue {
if (theAudioQueuePlayer.rate != 0 && theAudioQueuePlayer.error == nil) {
// playing
}
}
Run Code Online (Sandbox Code Playgroud)
Swift扩展基于maz的答案
extension AVPlayer {
var isPlaying: Bool {
return ((rate != 0) && (error == nil))
}
}
Run Code Online (Sandbox Code Playgroud)
目前使用 swift 5 检查播放器是否正在播放或暂停的最简单方法是检查.timeControlStatus变量。
player.timeControlStatus == .paused
player.timeControlStatus == .playing
Run Code Online (Sandbox Code Playgroud)
Objective C 中的答案
if (player.timeControlStatus == AVPlayerTimeControlStatusPlaying) {
//player is playing
}
else if (player.timeControlStatus == AVPlayerTimeControlStatusPaused) {
//player is pause
}
else if (player.timeControlStatus == AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate) {
//player is waiting to play
}
Run Code Online (Sandbox Code Playgroud)
Swink版本的maxkonovalov的答案是这样的:
player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.New, context: nil)
Run Code Online (Sandbox Code Playgroud)
和
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "rate" {
if let rate = change?[NSKeyValueChangeNewKey] as? Float {
if rate == 0.0 {
print("playback stopped")
}
if rate == 1.0 {
print("normal playback")
}
if rate == -1.0 {
print("reverse playback")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢maxkonovalov!
小智 5
player.timeControlStatus == AVPlayer.TimeControlStatus.playing
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
89939 次 |
最近记录: |