Sprawdź stan odtwarzania AVPlayer
Czy istnieje sposób, aby dowiedzieć się, czy odtwarzanie AVPlayer
zatrzymało się, czy dotarło do końca?
8 answers
Aby otrzymać powiadomienie o dotarciu do końca artykułu (przez Apple):
[[NSNotificationCenter defaultCenter]
addObserver:<self>
selector:@selector(<#The selector name#>)
name:AVPlayerItemDidPlayToEndTimeNotification
object:<#A player item#>];
A do śledzenia gry Można:
"Śledź zmiany położenia głowicy odtwarzania w obiekcie AVPlayer" za pomocą addPeriodicTimeObserverForInterval:queue:usingBlock: lub addBoundaryTimeObserverForTimes:queue:usingBlock:.
Przykład pochodzi z 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];
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-13 23:03:33
Możesz powiedzieć, że gra używając:
AVPlayer *player = ...
if ((player.rate != 0) && (player.error == nil)) {
// player is playing
}
Swift 3 extension:
extension AVPlayer {
var isPlaying: Bool {
return rate != 0 && error == nil
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-02 11:34:29
W iOS10 jest teraz wbudowana właściwość: timeControlStatus
Na przykład ta funkcja odtwarza lub wstrzymuje avplayera w zależności od jego statusu i odpowiednio aktualizuje przycisk odtwarzania / pauzy.
@IBAction func btnPlayTap(_ 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)
}
}
Jeśli chodzi o drugie pytanie, aby wiedzieć, czy avPlayer dotarł do końca, najprostszą rzeczą do zrobienia byłoby skonfigurowanie powiadomienia.
NotificationCenter.default.addObserver(self, selector: #selector(self.didPlayToEnd), name: .AVPlayerItemDidPlayToEndTime, object: nil)
Kiedy dotrze do końca, na przykład, możesz cofnąć go do początku wideo i zresetować Przycisk pauzy do gry.
func didPlayToEnd() {
aPlayer.seek(to: CMTimeMakeWithSeconds(0, 1))
btnPlay.setImage(UIImage(named: "control-play"), for: .normal)
}
Te przykłady są przydatne, jeśli tworzysz własne kontrolki, ale jeśli używasz kontrolki AVPlayerViewController, to kontrolki są wbudowane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-23 15:20:36
Bardziej niezawodną alternatywą dla NSNotification
jest dodanie siebie jako obserwatora do właściwości gracza rate
.
[self.player addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionNew
context:NULL];
Następnie sprawdź, czy nowa wartość obserwowanej szybkości wynosi zero, co oznacza, że odtwarzanie zostało zatrzymane z jakiegoś powodu, na przykład dotarcie do końca lub opóźnienie z powodu pustego bufora.
- (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
}
}
}
W przypadku rate == 0.0
, aby dowiedzieć się, co dokładnie spowodowało zatrzymanie odtwarzania, możesz wykonać następujące kontrole:
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
}
I nie zapomnij, aby twój gracz zatrzymał się, gdy dotrze do end:
self.player.actionAtItemEnd = AVPlayerActionAtItemEndPause;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 14:54:02
Dla :
AVPlayer :
let player = AVPlayer(URL: NSURL(string: "http://www.sample.com/movie.mov"))
if (player.rate != 0 && player.error == nil) {
println("playing")
}
Aktualizacja:player.rate > 0
warunek zmieniony na player.rate != 0
, ponieważ jeśli film jest odtwarzany w odwrotnej kolejności, to może być ujemny dzięki Julianowi za wskazanie.
Uwaga: to może wyglądać tak samo jak powyżej(Maz) odpowiedź, ale w Swift '!gracz.error 'dawał mi błąd kompilatora, więc musisz sprawdzić błąd za pomocą' player.error = = nil' in Swift.(ponieważ właściwość error nie jest 'Bool' typ)
AVAudioPlayer:
if let theAudioPlayer = appDelegate.audioPlayer {
if (theAudioPlayer.playing) {
// playing
}
}
AVQueuePlayer:
if let theAudioQueuePlayer = appDelegate.audioPlayerQueue {
if (theAudioQueuePlayer.rate != 0 && theAudioQueuePlayer.error == nil) {
// playing
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-24 06:35:02
rate
czy Nie jest sposobem sprawdzenia, czy film jest odtwarzany (może zostać zablokowany). Z dokumentacji rate
:
Wskazuje pożądaną szybkość odtwarzania; 0.0 oznacza "wstrzymane", 1.0 oznacza chęć odtwarzania z naturalną szybkością bieżącego elementu.
Słowa kluczowe "chęć gry" - szybkość 1.0
nie oznacza, że wideo jest odtwarzane.
Rozwiązaniem od iOS 10.0 jest użycie AVPlayerTimeControlStatus
, które można zaobserwować na AVPlayer
timeControlStatus
własność.
Rozwiązanie przed iOS 10.0 (9.0, 8.0 itd.) jest zrolowanie własnego rozwiązania. szybkość 0.0
oznacza, że film jest wstrzymywany. Gdy rate != 0.0
oznacza to, że wideo jest odtwarzane lub jest zablokowane.
Możesz sprawdzić różnicę obserwując czas gracza poprzez: func addPeriodicTimeObserver(forInterval interval: CMTime, queue: DispatchQueue?, using block: @escaping (CMTime) -> Void) -> Any
Blok zwraca bieżący czas gracza w CMTime
, więc porównanie lastTime
(czasu, który został ostatnio odebrany z bloku) i currentTime
(czasu, który blok tylko zgłoszone) powie, czy gracz gra lub jest zablokowany. Na przykład, jeśli lastTime == currentTime
i rate != 0.0
, to gracz stoi w miejscu.
Jak zauważyli inni, sprawdzenie, czy odtwarzanie zostało zakończone, wskazuje AVPlayerItemDidPlayToEndTimeNotification
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-18 15:40:47
Rozszerzenie Swift na podstawie odpowiedzi maz
extension AVPlayer {
var isPlaying: Bool {
return ((rate != 0) && (error == nil))
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-05 12:23:08
Szybka wersja odpowiedzi maxkonovalova jest taka:
player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.New, context: nil)
I
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")
}
}
}
}
Dziękuję maxkonovalov!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 19:40:29