画中画(Picture-in-Picture, PiP)是一种多窗口模式,允许用户在屏幕一角的小窗口中观看视频,同时在主屏幕上继续与其他应用或内容进行交互。播放器 SDK 支持以下两种画中画实现模式,以适应不同的业务场景:
在集成画中画功能前,请确保您的项目满足对应平台的前提条件。
startPictureInPicture 接口,SDK 会自动跳转至系统授权页面。requestOverlayPermission 接口主动引导用户授权。为了提供更好的用户体验,建议您在用户点击画中画按钮前,通过引导流程主动申请悬浮窗权限,而不是在用户点击后被动触发。
import { requestOverlayPermission } from '@volcengine/react-native-vod-player'; // 调用后会跳转到系统设置页面引导用户进行手动授权 requestOverlayPermission();
建议在 App 初始化或播放页面挂载时设置监听,以便同步 App 内部的 UI 状态。
import { setPictureInPictureListener } from '@volcengine/react-native-vod-player'; setPictureInPictureListener({ onStartPictureInPicture() { console.log('画中画已开启'); }, onStopPictureInPicture() { console.log('画中画已关闭'); }, onError(code, extraData) { // 错误码 0:成功, 1:不支持, 2:参数错误, 3:已开启 console.log(`画中画开启失败: ${code}, ${extraData}`); }, onClickPictureInPictureRestoreBtn() { // 用户点击画中画窗口右上角的恢复按钮 console.log('正在从画中画恢复到应用'); }, });
在视频播放过程中,调用播放器实例的方法。
// 1. 判断当前环境是否支持画中画 import { isPictureInPictureSupported } from '@volcengine/react-native-vod-player'; const isSupport = isPictureInPictureSupported(); if (isSupport) { // 2. 开启画中画(仅播放时有效) player.startPictureInPicture(); } // 3. 停止画中画(或返回原页面) player.stopPictureInPicture();
注意
isPictureInPictureStarted() 随时判断当前是否处于画中画状态。本节介绍如何实现应用从前台切换到后台时,自动开启画中画的功能。该功能需要您结合 App 的生命周期事件进行开发。
在播放器创建后,调用以下接口允许 iOS 在后台触发画中画逻辑。
// 允许 iOS 应用进入后台后自动开启画中画 player.enableAutoStartPictureInPicture();
由于系统环境限制,SDK 无法直接感知应用切换至后台的动作。因此,实现自动开启画中画的关键在于,您需要通过 React Native 的 AppState 监听应用状态,在应用进入后台时主动调用开启画中画接口。
import { AppState } from 'react-native'; useEffect(() => { const subscription = AppState.addEventListener('change', nextAppState => { if (nextAppState === 'background') { // 应用进入后台,主动触发画中画 player.startPictureInPicture(); } else if (nextAppState === 'active') { // 应用返回前台,通常需关闭画中画以恢复全屏播放 player.stopPictureInPicture(); } }); return () => { subscription.remove(); }; }, []);
在 Feed 流(上下滑动切换视频)场景下,若想在画中画小窗内实现视频的无缝切集,参考以下步骤:
close 方法时,传入 {stopPip: false} 参数,销毁播放器实例但保持当前的画中画窗口不被关闭。startPictureInPicture 以接管现有窗口。// 1. 停止并销毁当前播放器实例,但保持画中画窗口开启 lastPlayer.close({ stopPip: false }); // 2. 立即让新播放器实例接管画中画窗口并播放 nextPlayer.startPictureInPicture(); nextPlayer.play();