Swift实现Picture in Picture(画中画)
在 Swift 中实现 Picture in Picture(画中画)功能,你可以使用 AVKit 框架提供的 AVPictureInPictureController 类。这个类允许你在 iOS 设备上播放视频并支持画中画模式。
下面是一个简单的示例代码,演示如何在 Swift 中使用 AVPictureInPictureController 实现 Picture in Picture 功能:
import AVKit
class ViewController: UIViewController, AVPictureInPictureControllerDelegate {
var playerViewController: AVPlayerViewController!
var player: AVPlayer!
var pipController: AVPictureInPictureController!
override func viewDidLoad() {
super.viewDidLoad()
// 创建 AVPlayer 对象
let videoURL = URL(string: "YOUR_VIDEO_URL")
player = AVPlayer(url: videoURL!)
// 创建 AVPlayerViewController 并设置 player
playerViewController = AVPlayerViewController()
playerViewController.player = player
// 设置 Picture in Picture 控制器并设置代理
pipController = AVPictureInPictureController(playerLayer: playerViewController.playerLayer)
pipController.delegate = self
// 添加 AVPlayerViewController 到当前视图控制器
addChild(playerViewController)
view.addSubview(playerViewController.view)
playerViewController.view.frame = view.bounds
playerViewController.didMove(toParent: self)
// 开始播放视频
player.play()
}
// 实现 AVPictureInPictureControllerDelegate 代理方法
func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
// Picture in Picture 模式已经开始
print("Picture in Picture 模式已经开始")
}
func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
// Picture in Picture 模式已经结束
print("Picture in Picture 模式已经结束")
}
// 添加按钮或手势来启动 Picture in Picture 模式
@IBAction func startPictureInPicture(_ sender: Any) {
if pipController.isPictureInPicturePossible {
pipController.startPictureInPicture()
}
}
}
在这个示例中,我们首先创建了一个 AVPlayer 对象来播放视频,并将其设置给一个 AVPlayerViewController 对象。然后,我们创建了一个 AVPictureInPictureController 对象,并将 AVPlayerViewController 的 playerLayer 设置给它。最后,我们实现了 AVPictureInPictureControllerDelegate 协议,并在代理方法中处理 Picture in Picture 模式的开始和结束。
请确保替换示例代码中的 "YOUR_VIDEO_URL" 为你自己的视频 URL。此外,你可以通过添加按钮或手势来启动 Picture in Picture 模式,以便用户可以在需要时手动启动。
下面是一个示例代码,演示了如何在 Swift 中使用 AVPlayer 和 AVPlayerLayer 实现视频播放,并结合画中画功能:
import UIKit
import AVKit
class ViewController: UIViewController {
var player: AVPlayer!
var playerLayer: AVPlayerLayer!
override func viewDidLoad() {
super.viewDidLoad()
// 设置音频会话
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Failed to configure audio session:", error)
}
// 创建 AVPlayer 对象
guard let videoURL = Bundle.main.url(forResource: "video", withExtension: "mp4") else { return }
player = AVPlayer(url: videoURL)
// 创建 AVPlayerLayer 并添加到视图层上
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = view.bounds
view.layer.addSublayer(playerLayer)
}
// 播放按钮点击事件
@IBAction func playButtonTapped(_ sender: Any) {
player.play()
}
// 进入画中画模式按钮点击事件
@IBAction func pipButtonTapped(_ sender: Any) {
let pipController = AVPictureInPictureController(playerLayer: playerLayer)
if pipController.isPictureInPicturePossible {
pipController.startPictureInPicture()
}
}
}
这个示例代码中,假设你的项目中有一个名为 video.mp4 的视频文件,代码会使用 AVPlayer 和 AVPlayerLayer 来播放该视频。当用户点击播放按钮时,视频会在当前视图中播放;当用户点击进入画中画模式按钮时,视频会自动进入画中画模式,继续在一个小窗口中播放。
要实现自定义播放器并支持画中画功能,你需要遵循以下步骤:
- 创建自定义播放器视图,并添加 AVPlayerLayer 用于显示视频。
- 添加画中画按钮,并在用户点击时启动画中画模式。
- 实现 AVPictureInPictureControllerDelegate 协议,以便处理画中画模式的状态变化。
- 将 AVPlayerLayer 添加到 AVPictureInPictureController 中,以便支持画中画功能。
下面是一个示例代码,演示了如何实现自定义播放器并支持画中画功能:
import UIKit
import AVKit
class CustomPlayerViewController: UIViewController, AVPictureInPictureControllerDelegate {
var player: AVPlayer!
var playerLayer: AVPlayerLayer!
var pipController: AVPictureInPictureController!
override func viewDidLoad() {
super.viewDidLoad()
// 创建 AVPlayer 对象
guard let videoURL = Bundle.main.url(forResource: "video", withExtension: "mp4") else { return }
player = AVPlayer(url: videoURL)
// 创建 AVPlayerLayer 并添加到视图层上
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = view.bounds
view.layer.addSublayer(playerLayer)
// 设置画中画控制器
pipController = AVPictureInPictureController(playerLayer: playerLayer)
pipController.delegate = self
// 添加画中画按钮
let pipButton = UIButton(type: .system)
pipButton.setTitle("画中画", for: .normal)
pipButton.addTarget(self, action: #selector(pipButtonTapped), for: .touchUpInside)
view.addSubview(pipButton)
pipButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
pipButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
pipButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20)
])
}
@objc func pipButtonTapped() {
if pipController.isPictureInPicturePossible {
pipController.startPictureInPicture()
}
}
// 实现 AVPictureInPictureControllerDelegate 协议方法
func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
print("画中画模式已经开始")
}
func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
print("画中画模式已经结束")
}
}
在这个示例中,我们创建了一个自定义播放器视图控制器 CustomPlayerViewController,其中包含一个自定义播放器和一个画中画按钮。当用户点击画中画按钮时,会启动画中画模式。我们还实现了 AVPictureInPictureControllerDelegate 协议来处理画中画模式的状态变化。最后,我们将 AVPlayerLayer 添加到 AVPictureInPictureController 中,以便支持画中画功能。
腾讯直播拉流播放器V2TXLivePlayer支持画中画
/**
* 开启画中画功能,仅支持直播和快直播播放
*
* @param enable YES: 开启画中画功能; NO: 关闭画中画功能。【默认值】: NO。
* @return 返回值 {@link V2TXLiveCode}。
* - V2TXLIVE_OK: 成功。
*/
- (V2TXLiveCode)enablePictureInPicture:(BOOL)enable;
// 开启画中画功能
let resCode = player.enablePicture(inPicture: true)
ZYLogUtil.zy_debug("画中画 resCode:\(resCode.rawValue)")
开启后台画中画权限,即可实现
// 设置音频会话
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print("Failed to configure audio session:", error)
}
image.png
IMG_0196.PNG