iOS视频播放&画中画
2021-08-20 本文已影响0人
CocoaJason
//
// ViewController.swift
// Palyer
//
// Created by HuangZhen on 2021/8/20.
//
import UIKit
import AVKit
class ViewController: UIViewController, AVPlayerViewControllerDelegate {
var playerItem: AVPlayerItem?
var playerController: AVPlayerViewController!
var picVC : AVPictureInPictureController!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
guard let url = URL(string: "https://xxxxx.mp4") else {
return
}
playerController = AVPlayerViewController()
playerController.showsPlaybackControls = true
playerController.allowsPictureInPicturePlayback = true
// if #available(iOS 14.2, *) {
// playerController.canStartPictureInPictureAutomaticallyFromInline = true
// } else {
// // Fallback on earlier versions
// }
playerController.delegate = self
playerItem = AVPlayerItem(url: url)
playerItem?.automaticallyPreservesTimeOffsetFromLive = true
playerController.player = AVPlayer(playerItem: playerItem)
playerController.videoGravity = .resizeAspectFill
playerController.view.frame = CGRect(x: 0, y: 100, width: view.frame.width, height: 300)
view.addSubview(playerController.view)
// 监听loadedTimeRanges属性来监听缓冲进度更新
playerItem?.addObserver(self,
forKeyPath: "loadedTimeRanges",
options: .new,
context: nil)
// 监听status属性进行播放
playerItem?.addObserver(self,
forKeyPath: "status",
options: .new,
context: nil)
if AVPictureInPictureController.isPictureInPictureSupported() {
try! AVAudioSession.sharedInstance().setCategory(.playback)
}
}
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
guard let object = object as? AVPlayerItem else { return }
guard let keyPath = keyPath else { return }
if keyPath == "status" {
if object.status == .readyToPlay { //当资源准备好播放,那么开始播放视频
playerController?.player?.play()
print("正在播放...,视频总长度:\(formatPlayTime(seconds: CMTimeGetSeconds(object.duration)))")
} else if object.status == .failed || object.status == .unknown {
print("播放出错")
}
} else if keyPath == "loadedTimeRanges" {
let loadedTime = availableDurationWithplayerItem()
print("当前加载进度\(loadedTime)")
}
}
// 将秒转成时间字符串的方法,因为我们将得到秒。
func formatPlayTime(seconds: Float64) -> String {
let min = Int(seconds / 60)
let sec = Int(seconds.truncatingRemainder(dividingBy: 60))
return String(format: "%02d:%02d", min, sec)
}
// 计算当前的缓冲进度
func availableDurationWithplayerItem() -> TimeInterval {
guard let loadedTimeRanges = playerController.player?.currentItem?.loadedTimeRanges,
let first = loadedTimeRanges.first else {
fatalError()
}
let timeRange = first.timeRangeValue
let startSeconds = CMTimeGetSeconds(timeRange.start) // 本次缓冲起始时间
let durationSecound = CMTimeGetSeconds(timeRange.duration)// 缓冲时间
let result = startSeconds + durationSecound// 缓冲总长度
return result
}
}