AVQueuePlayerとは
AVFoundationのAVPlayerを継承している。複数のAVPlayerItemを連続再生できるクラスです。
複数の動画を連続再生するときはAVQueuePlayerというクラスを使うといいらしい
let items = [AVPlayerItem(), AVPlayerItem(), AVPlayerItem()]
let queuePlayer = AVQueuePlayer(items: items)
queuePlayer.play()
ってやると配列の順番通りに動画が再生される
AVQueuePlayerでリピート再生を実現させる(間違ってる例)
僕は最後のAVPlayerItemが再生し終わったらseekを0にしてまた再生しとけばいいと思ってた
普通に
func setupObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(self.endPlaying), name: .AVPlayerItemDidPlayToEndTime, object: items.last)
}
func endPlaying() {
queuePlayer.seek(to: kCMTimeZero)
queuePlayer.play()
}
RxSwift使用
NotificationCenter.default.rx.notification(.AVPlayerItemDidPlayToEndTime, object: items.last).subscribe(onNext: { [weak self] _ in
guard let `self` = self else { return }
self.queuePlayer.seek(to: kCMTimeZero)
self.queuePlayer.play()
}).disposed(by: disposeBag)
けどできませんでした、、、
できない理由はよくわからないんで知ってる人がいたら教えて欲しいです。
AVQueuePlayerでリピート再生を実現させる(できた)
正しいリピート再生のアプローチは
「1つめのAVPlayerItemが再生し終わる」
↓
「1つめのAVPlayerItemのseekを0にする」
↓
「次のAVPlayerItemを再生する」
↓
「1つめのAVPlayerItemをAVQueuePlayerのitemsの後ろにinsertする」
↓
「2つめのAVPlayerItemが再生し終わる」
↓
「2つめのAVPlayerItemのseekを0にする」
↓
以下同様
って方法だとリピートを実現することができた!
普通に
func setupObserver() {
for item in items {
NotificationCenter.default.addObserver(self, selector: #selector(self.endPlaying), name: .AVPlayerItemDidPlayToEndTime, object: item)
}
}
func endPlaying(_ notification: Notification) {
let item = notification.userInfo?["object"] as! AVPlayerItem
// 再生し終わったらseekを0にして
item.seek(to: kCMTimeZero)
// 次を再生して
queuePlayer.advanceToNextItem()
// 後ろにinsert
queuePlayer.insert(item, after: nil)
}
RxSwift使用
for item in items {
NotificationCenter.default.rx.notification(.AVPlayerItemDidPlayToEndTime, object: item).subscribe(onNext: { [weak self] _ in
guard let `self` = self else { return }
// 再生し終わったらseekを0にして
item.seek(to: kCMTimeZero)
// 次を再生して
self.player.advanceToNextItem()
// 後ろにinsert
self.player.insert(item, after: nil)
}).disposed(by: disposeBag)
}
最後に
やー、はまりまくった。
RxSwiftじゃない方は文法間違いあっても知りません