環境
- 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)
}
}