0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

UIKitで動画を再生・停止・シークする

Posted at

概要

UIKit x Combineでプロジェクトに保存している動画を再生停止する時のメモです。
動画はPixabayより引用

環境

Xcode14.2
iOS 16.2

完成形

大まかな手順

  1. 動画を再生するためのUIView実装
  2. 動画の再生・停止を親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)
    }
}

今後の課題

今回はプロジェクトに保存されてましたが、ネットワークから取得した場合や、ストリーミングなど技術的にチャレンジしたい分野です。
今後もこの分野は特に記事を上げたいと思ってます。

全体のソースコードはこちらです。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?