Czy istnieje stosunkowo łatwy sposób zapętlenia wideo w programie AVFoundation?
Stworzyłem mój AVPlayer i AVPlayerLayer w ten sposób:
avPlayer = [[AVPlayer playerWithURL:videoUrl] retain];
avPlayerLayer = [[AVPlayerLayer playerLayerWithPlayer:avPlayer] retain];
avPlayerLayer.frame = contentView.layer.bounds;
[contentView.layer addSublayer: avPlayerLayer];
a potem odtwarzam wideo za pomocą:
[avPlayer play];
Film odtwarza się dobrze, ale na końcu się zatrzymuje. Z MPMoviePlayerController wszystko, co musisz zrobić, to ustawić jego repeatMode
właściwość na odpowiednią wartość. Wygląda na to, że w programie AVPlayer nie ma podobnej właściwości. Wygląda na to, że nie ma też wywołania zwrotnego, które powie mi, kiedy film się skończy, więc mogę odszukać początek i odtworzyć go ponownie.
Nie używam MPMoviePlayerController, ponieważ ma on poważne ograniczenia. Chcę mieć możliwość jednoczesnego odtwarzania wielu strumieni wideo.
Odpowiedzi:
Możesz otrzymać powiadomienie, gdy gracz się skończy. Czek
AVPlayerItemDidPlayToEndTimeNotification
Podczas konfigurowania odtwarzacza:
ObjC
Zapobiegnie to zatrzymaniu gracza na końcu.
w zgłoszeniu:
spowoduje to przewinięcie filmu do tyłu.
Nie zapomnij wyrejestrować powiadomienia przy zwalnianiu odtwarzacza.
Szybki
Swift 4+
źródło
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
, nie zatrzyma się, więc nie ma potrzeby ustawiania go na ponowne odtwarzanie[player play];
po przewinięciu.[[NSNotificationCenter defaultCenter] removeObserver:self];
na przykład, gdyself
słuchasz powiadomień.Jeśli to pomoże, w iOS / tvOS 10 dostępna jest nowa funkcja AVPlayerLooper (), której możesz użyć do tworzenia płynnej pętli wideo (Swift):
Zostało to zaprezentowane na WWDC 2016 w „Advances in AVFoundation Playback”: https://developer.apple.com/videos/play/wwdc2016/503/
Nawet używając tego kodu, miałem czkawkę, dopóki nie złożyłem raportu o błędzie w Apple i nie otrzymałem tej odpowiedzi:
Okazuje się, że Premiere eksportowało pliki ze ścieżką dźwiękową o nieco innej długości niż wideo. W moim przypadku całkowite usunięcie dźwięku było w porządku i to rozwiązało problem.
źródło
W Swift :
Możesz otrzymać powiadomienie, gdy odtwarzacz się skończy ... sprawdź AVPlayerItemDidPlayToEndTimeNotification
podczas konfigurowania odtwarzacza:
Zapobiegnie to zatrzymaniu gracza na końcu.
w zgłoszeniu:
Swift3
spowoduje to przewinięcie filmu do tyłu.
Nie zapomnij wyrejestrować powiadomienia przy zwalnianiu odtwarzacza.
źródło
Oto, co ostatecznie zrobiłem, aby zapobiec problemowi z przerwami:
Szybki:
Cel C:
UWAGA: nie używałem,
avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone
ponieważ nie jest potrzebne.źródło
[weakSelf.avPlayer seekToTime:kCMTimeZero]; [weakSelf.avPlayer play];
liniami - kiedy je komentuję, nie ma już wycieku pamięci. Sprofilowałem to w instrumentach.Zalecam używanie AVQueuePlayer do płynnego zapętlania filmów. Dodaj obserwatora powiadomień
i w jego selektorze zapętl wideo
źródło
Aby uniknąć przerwy podczas przewijania wideo, dobrze działało użycie wielu kopii tego samego zasobu w kompozycji. Znalazłem to tutaj:
www.developers-life.com/avplayer-looping-video-without-hiccupdelays.html(link niedziała).źródło
to działało dla mnie bez problemów z czkawką, chodzi o wstrzymanie odtwarzacza przed wywołaniem metody seekToTime:
init AVPlayer
zgłoszenie rejestracji
funkcja videoLoop
źródło
Dla Swift 3 i 4
źródło
moje rozwiązanie w objective-c z AVQueuePlayer - wydaje się, że musisz zduplikować AVPlayerItem i po zakończeniu odtwarzania pierwszego elementu natychmiast dodać kolejną kopię. „Kind of” ma sens i działa dla mnie bez żadnych problemów
https://gist.github.com/neonm3/06c3b5c911fdd3ca7c7800dccf7202ad
źródło
Swift 5:
Dokonałem niewielkich zmian w stosunku do poprzednich odpowiedzi, takich jak dodanie elementu playerItem do kolejki przed dodaniem go do warstwy playerLayer.
I ustaw playerLooper jako właściwość Twojego UIViewController, w przeciwnym razie wideo może zostać odtworzone tylko raz.
źródło
Po załadowaniu wideo do AVPlayera (oczywiście przez jego AVPlayerItem):
Metoda addDidPlayToEndTimeNotificationForPlayerItem:
W Twoim widoku metoda WillDisappear:
W Twoim widoku deklaracja interfejsu kontrolera w pliku implementacji:
Chcesz zobaczyć, jak działa, zanim spróbujesz? Pobierz i uruchom tę przykładową aplikację:
https://developer.apple.com/library/prerelease/ios/samplecode/AVBasicVideoOutput/Listings/AVBasicVideoOutput_APLViewController_m.html#//apple_ref/doc/uid/DTS40013109-AVBasicVideoOutput_APLViewController_APLViewController
W mojej aplikacji, która używa tego właśnie kodu, nie ma żadnej przerwy między końcem filmu a początkiem. W rzeczywistości, w zależności od wideo, nie mogę stwierdzić, że wideo jest ponownie na początku, zapisz wyświetlanie kodu czasowego.
źródło
możesz dodać obserwatora AVPlayerItemDidPlayToEndTimeNotification i odtworzyć wideo od początku w selektorze, kod jak poniżej
źródło
Poniższe działa dla mnie w WKWebView w Swift 4.1 Główna część WKWebView w WKwebviewConfiguration
źródło
Zrobiłem to, aby odtwarzać w pętli, jak mój kod poniżej:
źródło
Swift 4.2 w Xcode 10.1.
Tak , istnieje stosunkowo łatwy sposób na zapętlenie wideo w
AVKit
/AVFoundation
za pomocąAVQueuePlayer()
techniki obserwacji klucz-wartość (KVO) i jej tokena.To zdecydowanie działa w przypadku kilku filmów H.264 / HEVC przy minimalnym obciążeniu procesora.
Oto kod:
źródło
użyj poniższego kodu AVPlayerViewController, działa dla mnie
Wszystkie kontrolki do pokazania, mam nadzieję, że będą pomocne
źródło
Ta właściwość jest już zdefiniowana w środku
AVAudioPlayer
. Mam nadzieję, że to może ci pomóc. Używam Xcode 6.3.źródło