LoginSignup
8
9

More than 3 years have passed since last update.

【Swift5】動画をループ再生する

Posted at

環境

  • x-code10.2.1
  • Swift5

要件

  • 動画をループ再生する(動画終了時に巻き戻す)
  • 動画のアスペクト比は維持する
  • 動画の拡張子は、m4v、mp4、movのいずれかとする

実装

ViewController.swift

import UIKit
import AVFoundation

class ViewController: UIViewController {

    /// AVPlayerViewを乗せるView
    @IBOutlet weak var videoView: UIView!

    private let playerView = AVPlayerView()

    override func viewDidLoad() {
        super.viewDidLoad()

        // playerViewをUIViewに追加
        playerView.frame = CGRect(x: videoView.frame.origin.x ,
                                  y: videoView.frame.origin.y,
                                  width: videoView.frame.width,
                                  height: videoView.frame.height)
        // 動画の終了時に巻き戻し再生する
        NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd(_:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)

        if let playURL = URL(string: "hoge.mp4") {
            self.playerView.player = AVPlayer(url: playURL)
            self.playerView.player?.actionAtItemEnd = AVPlayer.ActionAtItemEnd.none
            // アスペクト比を維持
            self.playerView.setVideoFillMode(mode: AVLayerVideoGravity.resizeAspect.rawValue)
            self.videoView.addSubview(self.playerView)
            // 動画を再生
            self.playerView.player?.play()
        }
    }

    /// リピート
    @objc func endVideo() {
        playerView.player?.currentItem?.seek(to: CMTime.zero, completionHandler: nil)
    }

    /// 動画終了時
    ///
    /// - Parameter notification: Notification
    @objc private func playerItemDidReachEnd(_ notification: Notification) {
        // 動画を最初に巻き戻す
        self.playerView.player?.currentItem?.seek(to: CMTime.zero, completionHandler: nil)
    }
}

final class AVPlayerView: UIView {

    var player: AVPlayer? {
        get {
            let layer: AVPlayerLayer = self.layer as! AVPlayerLayer
            return layer.player
        }
        set(newValue) {
            let layer: AVPlayerLayer = self.layer as! AVPlayerLayer
            layer.player = newValue
        }
    }

    // MARK: - OverrideMethod

    override public class var layerClass: Swift.AnyClass {
        return AVPlayerLayer.self
    }

    // MARK: - Public Method

    /// アスペクト比を維持
    ///
    /// - Parameter mode: AVLayerVideoGravity
    func setVideoFillMode(mode: String) {
        let layer: AVPlayerLayer = self.layer as! AVPlayerLayer
        layer.videoGravity = AVLayerVideoGravity(rawValue: mode)
    }
}

参考

8
9
1

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
8
9