如何在iOS应用内直接启动画中画(Picture-in-Picture)功能?
在应用内指定视图出现时启动画中画功能
当然可以实现,核心是把画中画相关实例(AVPlayer、AVPlayerViewController、AVPictureInPictureController)作为视图控制器的属性持有,在指定视图的生命周期方法(比如viewDidAppear)中完成初始化、播放启动和画中画触发,同时确保满足画中画的启动条件。
关键修改点
- 将播放器、播放器控制器、画中画控制器声明为视图控制器属性,避免局部变量被提前释放
- 在目标视图的
viewDidAppear中执行初始化逻辑,确保视图已加载完成 - 提前检查设备是否支持画中画功能,避免无效调用
- 保留你已在AppDelegate中配置的音频会话设置
修改后的代码示例
class TargetViewController: UIViewController { // 声明为属性持有,防止被提前释放 private var player: AVPlayer? private var avPlayerController: AVPlayerViewController? private var pipController: AVPictureInPictureController? override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 视图出现时启动视频和画中画 setupAndLaunchPIP() } private func setupAndLaunchPIP() { // 检查设备是否支持画中画 guard AVPictureInPictureController.isPictureInPictureSupported() else { print("当前设备不支持画中画功能") return } guard let videoURL = Bundle.main.url(forResource: "video", withExtension: "mp4") else { print("未找到目标视频文件") return } // 初始化播放器与控制器 player = AVPlayer(url: videoURL) avPlayerController = AVPlayerViewController() avPlayerController?.player = player avPlayerController?.canStartPictureInPictureAutomaticallyFromInline = true // 可选:如果不需要显示完整播放器界面,可隐藏控制器视图 if let playerView = avPlayerController?.view { playerView.frame = .zero playerView.isHidden = true view.addSubview(playerView) } else { // 或直接present播放器控制器,根据需求选择 present(avPlayerController!, animated: true) } // 启动视频播放 player?.play() // 初始化并启动画中画 guard let player = player else { return } let playerLayer = AVPlayerLayer(player: player) pipController = AVPictureInPictureController(playerLayer: playerLayer) pipController?.canStartPictureInPictureAutomaticallyFromInline = true pipController?.delegate = self // 可选:设置代理处理画中画状态变化 pipController?.startPictureInPicture() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 视图消失时清理资源,避免内存泄漏 player?.pause() pipController?.stopPictureInPicture() pipController = nil player = nil avPlayerController?.dismiss(animated: false) avPlayerController = nil } } // 可选:实现画中画代理方法,处理状态回调 extension TargetViewController: AVPictureInPictureControllerDelegate { func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) { print("画中画已启动") } func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) { print("画中画已停止") } }
注意事项
- 若不需要显示完整播放器界面,可将
AVPlayerViewController的视图添加到当前视图并隐藏,避免启动画中画时弹出播放器窗口 - 必须确保在调用
startPictureInPicture()前,播放器已经开始播放(即player?.play()已执行),否则可能启动失败 - 部分iOS版本可能要求画中画启动关联用户交互,但在
viewDidAppear中触发属于合法场景,建议测试不同系统版本的表现
内容的提问来源于stack exchange,提问作者Another Dude
相关产品推荐
相关产品推荐

