在iOS開發(fā)視頻播放畫中畫(PiP)最簡單的方法是使用AVPlayerViewController
實(shí)現(xiàn)現(xiàn)標(biāo)準(zhǔn)播放器幽崩,實(shí)際上使用AVPlayerViewController
播放器時(shí)將自動(dòng)支持畫中畫(PiP)功能。
實(shí)現(xiàn)代碼
- 配置Audio Playback Behavior绢淀,需要設(shè)置App 的AVAudioSession的Category為playback模式
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback, options: [])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("無法設(shè)置音頻會(huì)話類別: \(error)")
}
import UIKit
import AVKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .black
}
func initPlayer() {
let _videoURL = "***播放地址***"
let _player = AVPlayer(url:_videoURL)
let _playerVC = AVPlayerViewController()
_playerVC.delegate = self
if AVPictureInPictureController.isPictureInPictureSupported() {
_playerVC.allowsPictureInPicturePlayback = true
if #available(iOS 14.2, *) {
_playerVC.canStartPictureInPictureAutomaticallyFromInline = true
}
}
_playerVC.player = _player
self.present(playerViewController, animated: true) {
_player.play()
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.initPlayer()
}
}
PiP代理方法
// 通知代理 AVPlayerViewController 即將開始全屏顯示其內(nèi)容
func playerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
print("")
}
// 通知代理 AVPlayerViewController 將停止全屏顯示其內(nèi)容
func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
print("")
}
// 即將啟動(dòng)畫中畫(Picture in Picture, PiP)模式時(shí)調(diào)用此方法
// 可以在此方法中設(shè)置或更新一些相關(guān)的 UI 元素或狀態(tài)土铺,以反映視頻即將進(jìn)入畫中畫模式胶滋。
func playerViewControllerWillStartPictureInPicture(_ playerViewController: AVPlayerViewController) {
print("")
}
// 已經(jīng)進(jìn)入畫中畫模式時(shí)調(diào)用此方法
// 用法:用于更新 UI 或進(jìn)行其他準(zhǔn)備工作板鬓,以支持畫中畫模式。
func playerViewControllerDidStartPictureInPicture(_ playerViewController: AVPlayerViewController) {
print("")
}
// 當(dāng)畫中畫模式啟動(dòng)失敗時(shí)調(diào)用此方法
// 用法:處理畫中畫模式啟動(dòng)失敗時(shí)的錯(cuò)誤究恤。
func playerViewController(_ playerViewController: AVPlayerViewController, failedToStartPictureInPictureWithError error: Error) {
print("")
}
// 即將結(jié)束畫中畫模式時(shí)調(diào)用此方法
// 用法:在視頻退出畫中畫模式前進(jìn)行收尾工作俭令,更新 UI 或做一些清理
func playerViewControllerWillStopPictureInPicture(_ playerViewController: AVPlayerViewController) {
print("")
}
// 已經(jīng)結(jié)束畫中畫模式時(shí)調(diào)用此方法
// 用法:用于恢復(fù)正常播放狀態(tài),或者處理畫中畫模式結(jié)束后的邏輯
func playerViewControllerDidStopPictureInPicture(_ playerViewController: AVPlayerViewController) {
print("PiPVC:playerViewControllerDidStopPictureInPicture")
}
// 返回 true 或 false部宿,指示在啟動(dòng)畫中畫時(shí)播放器是否應(yīng)自動(dòng)關(guān)閉抄腔。
// 用法:如果希望在進(jìn)入畫中畫模式時(shí)關(guān)閉 AVPlayerViewController,則返回 true理张,否則返回 false赫蛇。
func playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart(_ playerViewController: AVPlayerViewController) -> Bool {
return true
}
// 當(dāng)畫中畫模式結(jié)束時(shí),恢復(fù)用戶界面雾叭。如果 AVPlayerViewController 在啟動(dòng)畫中畫后關(guān)閉悟耘,該方法可用于恢復(fù) UI。
// 用法:用于確保在結(jié)束畫中畫后织狐,用戶界面恢復(fù)到正確的狀態(tài)暂幼。確保調(diào)用 completionHandler 來表示恢復(fù)工作已經(jīng)完成。
func playerViewController(_ playerViewController: AVPlayerViewController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
completionHandler(true)
}
PS1:從iOS 14開始赚瘦,畫中畫用戶界面提供了允許用戶在視頻中向前和向后跳轉(zhuǎn)的控件粟誓。默認(rèn)情況下,系統(tǒng)為iOS14或更高版本中鏈接的應(yīng)用程序啟用這些控件起意。如果您需要限制跳過內(nèi)容以獲得法律免責(zé)聲明或廣告鹰服,請?jiān)谝曨l的所需部分使用requiresLinearPlayback。一旦您可以再次允許seek揽咕,請將此屬性設(shè)置為false悲酷。
PS2:當(dāng)用戶在播放器界面中選擇PiP按鈕時(shí),PiP播放開始亲善。在iOS和iPadOS中设易,如果您的視頻以全屏模式播放,并且用戶退出應(yīng)用程序蛹头,則PiP播放會(huì)自動(dòng)開始顿肺。當(dāng)視頻的寬度沒有填滿整個(gè)屏幕時(shí),請使用canStartPictureInPictureAutomaticyFromInline來指示視頻是主要焦點(diǎn)渣蜗。在任何一種情況下屠尊,播放器窗口都會(huì)最小化為可移動(dòng)的浮動(dòng)窗口。
通常情況下耕拷,系統(tǒng)會(huì)自動(dòng)暫停視頻的場景下讼昆,因此您不需要根據(jù)激活狀態(tài)暫停視頻。