美文网首页
Swift实现Picture in Picture(画中画)

Swift实现Picture in Picture(画中画)

作者: Hengry | 来源:发表于2024-04-08 09:47 被阅读0次

    在 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

    相关文章

      网友评论

          本文标题:Swift实现Picture in Picture(画中画)

          本文链接:https://www.haomeiwen.com/subject/qvztxjtx.html