概要
UIKit x Combineでプロジェクトに保存している動画を再生停止する時のメモです。
動画はPixabayより引用
環境
Xcode14.2
iOS 16.2
完成形

大まかな手順
- 動画を再生するための
UIView
実装 - 動画の再生・停止を親ViewControllerで管理
UIView
の実装
実装は以下です。
特徴的なのはCombineを使って、動画終了のタイミングを親クラスに知らせている箇所です。
VideoPlayUIView.swift
class VideoPlayUIView: UIView {
....
private func subscribeDidFinishVideoPlay() {
NotificationCenter
.default
.publisher(for: NSNotification.Name.AVPlayerItemDidPlayToEndTime)
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let self = self else { return }
self.didFinishVideoPlay.send()
}
.store(in: &cancellables)
}
....
}
ViewController
で動画の再生・停止を管理する
今回はプロジェクトに動画が保存されているので、遅延読み込みしてメモリに保存します。
先程の手順で再生終了のタイミングは取得できるので、取得できしだい動画を停止しリセットします。
VideoViewController.swift
class VideoViewController: UIViewController {
@IBOutlet weak var videoPlayUIView: VideoPlayUIView!
private var cancellables: Set<AnyCancellable> = []
private lazy var player: AVPlayer = {
let url = Bundle.main.url(forResource: "video", withExtension: "mp4")!
return AVPlayer(url: url)
}()
override func viewDidLoad() {
super.viewDidLoad()
subscribeDidFinishVideoPlay()
setup()
}
deinit {
cancellables.forEach { $0.cancel() }
}
}
// MARK: - SETUP
extension VideoViewController {
private func setup() {
videoPlayUIView.player = player
player.play()
}
}
// MARK: - SUBSCRIBE
extension VideoViewController {
private func subscribeDidFinishVideoPlay() {
videoPlayUIView
.didFinishVideoPlay
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let self = self else { return }
self.player.pause()
self.player.seek(to: .zero)
}
.store(in: &cancellables)
}
}
今後の課題
今回はプロジェクトに保存されてましたが、ネットワークから取得した場合や、ストリーミングなど技術的にチャレンジしたい分野です。
今後もこの分野は特に記事を上げたいと思ってます。
全体のソースコードはこちらです。
参考