ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

react-native-video v7 画中画、全屏与播放控制:基于 VideoView 的完整实战指南

react-native-video v7 画中画、全屏与播放控制:基于 VideoView 的完整实战指南 音视频移动开发【免费下载链接】react-native-videoA component for react-native项目地址https://gitcode.com/gh_mirrors/re/react-native-video点击查看免费下载导读在 react-native-video v7 中画中画Picture-in-Picture、全屏Fullscreen和原生播放控件不再挂在播放器上而是全部由VideoView组件props 命令式 ref承载——播放器VideoPlayer只负责播放状态与控制视图层则负责显示与系统级 UI 交互。本文以skills/react-native-video/references/v7/pip-fullscreen-controls.md为骨架结合仓库源码VideoView.tsx、VideoViewProps.ts 等与原生实现讲解如何在 v7 中开启原生控件、配置 PiP 与自动 PiP、通过 ref 命令式进入/退出全屏与 PiP以及如何监听六个视图生命周期事件读完即可在真实 iOS/Android 设备上落地完整的播放器 系统画中画 全屏体验。1. 先厘清 v7 的心智模型功能在 View状态在 Playerv7 与 v6 最大的区别是**播放器对象模型而非带 props 的组件模型**见 v7/README.mduseVideoPlayer(source, setup?)或new VideoPlayer(source)创建并拥有一个VideoPlayer所有播放状态与控制都落在这个实例上VideoView player{player} /是绑定到该播放器的可选显示表面纯音频播放甚至可以完全不渲染视图播放器事件是订阅式的useEvent/player.addEventListener而视图拥有自己的事件——也就是本文的主角全屏与 PiP 的生命周期事件。因此涉及控件显示、画中画、全屏的一切能力都应当去VideoView上寻找而不是去player上翻。下面先从最基础的原生控件说起。2. 原生播放控件一行controls属性在 v7 中原生播放控件播放/暂停、进度条、音量等系统级 UI由VideoView的controls属性控制VideoView player{player} controls / // controls 默认为 falsecontrols类型为boolean默认值为false传true时iOS 上渲染为系统AVPlayerViewController自带的控制条Android 上渲染为 ExoPlayer 的控制层不传时视频纯展示所有交互需要你自己实现可配合播放器订阅事件onPlaybackStateChange、onProgress等自行绘制 UI。从源码看VideoView在挂载时会把 props 同步给原生视图管理器updateProps 中的默认值处理如下manager.controls props.controls ?? false; manager.pictureInPicture props.pictureInPicture ?? false; manager.autoEnterPictureInPicture props.autoEnterPictureInPicture ?? false; manager.resizeMode props.resizeMode ?? none; manager.keepScreenAwake props.keepScreenAwake ?? true; manager.surfaceType props.surfaceType ?? surface;即controls、pictureInPicture、autoEnterPictureInPicture缺省均为falseresizeMode缺省为none约等于 containkeepScreenAwake缺省为true视图挂载期间屏幕常亮surfaceType仅 Android 生效、缺省为surfaceSurfaceView性能更佳但不可动画如需动画请改用texture见 VideoViewProps.ts。3. 画中画PiPprops 声明式 ref 命令式双通道3.1 声明式pictureInPicture与autoEnterPictureInPicture最简用法是在VideoView上声明 PiP 能力VideoView player{player} pictureInPicture autoEnterPictureInPicture /两个属性的语义见 VideoViewProps.ts 与 VideoView.tsxProp类型默认值作用pictureInPicturebooleanfalse是否启用并显示 PiP 按钮原生控件里的小窗按钮autoEnterPictureInPicturebooleanfalse播放中切后台时是否自动进入PiPpictureInPicture本身只是允许 PiP 显示按钮不代表会自动进入小窗自动进入需要autoEnterPictureInPicture。Android 端在PictureInPictureUtils.kt中对此有非常细致的处理自动进入只在用户意图播放时生效autoEnterPictureInPicture player.playWhenReady true并用playWhenReady而非isPlaying判断这样正在缓冲但即将播放的视频也能正确进入 PiP见 PictureInPictureUtils.kt。PiP 小窗的宽高比会优先取视频实际格式考虑 90°/270° 旋转并自动钳制在 Android 允许的 2.39:1 与 1:2.39 之间否则回退到视图尺寸同文件calculateAspectRatio。3.2 命令式通过 ref 精确控制需要由业务逻辑触发如点击小窗按钮、返回键处理等时使用命令式 refimport { useRef } from react; import type { VideoViewRef } from react-native-video; const ref useRefVideoViewRef(null); // ref.current?.canEnterPictureInPicture() // ref.current?.enterPictureInPicture() // ref.current?.exitPictureInPicture() VideoView ref{ref} player{player} pictureInPicture /VideoViewRef接口定义了 6 个方法见 VideoViewProps.ts方法返回说明enterFullscreen()void进入全屏exitFullscreen()void退出全屏enterPictureInPicture()void进入 PiPexitPictureInPicture()void退出 PiPcanEnterPictureInPicture()boolean查询当前设备/系统是否支持 PiPaddEventListener(event, cb)ListenerSubscription订阅视图事件返回带remove()的订阅对象VideoView通过useImperativeHandle将这些方法桥接到 Nitro 原生视图管理器VideoViewViewManager上VideoView.tsx所以调用ref.current?.enterPictureInPicture()最终走的是原生manager.enterPictureInPicture()。务必先调用canEnterPictureInPicture()再进入 PiPiOS 端通过AVPictureInPictureController.isPictureInPictureSupported()判断支持性不支持时会抛出pictureInPictureNotSupported错误见 AVPlayerViewControllerPictureInPicture.swiftAndroid 端则检查系统是否具备FEATURE_PICTURE_IN_PICTURE特性见 PictureInPictureUtils.kt。在真机上出现 PiP 按钮不显示或进入失败时用该方法定位是设备不支持还是原生配置缺失。3.3 原生前置条件iOS 与 Android 缺一不可PiP 是系统级能力光有 JS 配置不够还必须完成原生配置详见 platform-setup.mdiOS需要在Info.plist的UIBackgroundModes中加入audio后台音频模式。PiP 在 iOS 上受支持但建议与后台音频模式配合使用Android在AndroidManifest.xml中给activity添加android:supportsPictureInPicturetrue并且项目minSdkVersion必须 ≥ 26API 26 才有 PiP APIExpo使用 config plugin在app.json/app.config.js中配置enableAndroidPictureInPicture然后执行expo prebuild注意Expo Go 不支持{ plugins: [[react-native-video, { enableBackgroundAudio: true, enableAndroidPictureInPicture: true }]] }对应的 Expo 插件实现位于仓库 withAndroidPictureInPicture.ts它会自动为 activity 注入supportsPictureInPicture属性。3.4 PiP 测试环境模拟器 ≠ 真机PiP 测试提示iOS 模拟器不支持 PiP必须使用真实 iOS 设备测试Android 模拟器API 26、Google Play 镜像则支持PiP可以直接在模拟器上验证。这条经验与两端实现完全吻合iOS 依赖AVPictureInPictureController的系统级支持模拟器不提供该能力而 Android 的 PiP 依赖 API 26 的窗口机制API 26 的模拟器镜像具备该特性。4. 全屏Fullscreenref 命令式切换全屏同样通过VideoViewref 控制没有对应的 props 开关ref.current?.enterFullscreen(); ref.current?.exitFullscreen();iOS 端基于AVPlayerViewController的展开/收起能力实现AVPlayerViewControllerFullscreen.swiftAndroid 端通过独立的FullscreenVideoFragment承载全屏视图FullscreenVideoFragment.kt从源码结构看Android 的全屏是把同一个播放器内容挂载进一个全屏 Fragment来实现的与 PiP 不同全屏不要求额外的系统权限或后台模式配置只要视图已挂载即可调用。典型场景自定义控制条上的全屏按钮 →ref.current?.enterFullscreen()配合onFullscreenChange回调同步你的 UI 状态见下节。5. 生命周期事件6 个视图事件完整对照PiP 与全屏的状态变化通过视图事件暴露有两种订阅方式作为 props 传入或通过ref.addEventListener命令式订阅两者等效最终都注册到原生监听器上见 VideoView.tsx。事件清单类型定义见 Events.ts事件载荷触发时机onFullscreenChangefullscreen: boolean全屏状态发生变化进入/退出onPictureInPictureChangeisInPictureInPicture: booleanPiP 状态发生变化willEnterFullscreen—即将进入全屏willExitFullscreen—即将退出全屏willEnterPictureInPicture—即将进入 PiPwillExitPictureInPicture—即将退出 PiPprops 写法VideoView ref{ref} player{player} controls pictureInPicture onFullscreenChange{(full) {}} onPictureInPictureChange{(pip) {}} /命令式写法返回ListenerSubscription记得remove()const sub ref.current?.addEventListener(willEnterPictureInPicture, () { // 例如暂停视频流、收起自定义 UI }); // 不需要时 sub?.remove();v7 提醒全屏与 PiP在 v7 中依然可用——它们位于视图层请使用VideoView的 ref 与视图 props/事件本文所示 API而不是 v6 时代Video组件上的旧属性。如果你是从 v6 教程迁移过来的注意 v6 的Video source、ref.seek()与drmprop 在 v7 中均不存在请改用播放器 APImigration-v6-to-v7.md。6. Web 平台的边界native-only 能力在 Web 上是 no-opv7 的 Web 端是基于 video.js v10 的并行实现见 VideoView.web.tsx因此controls在 Web 上有效映射为 video.js 播放器自带控件PiP 与全屏属于 native-only 能力pictureInPicture、autoEnterPictureInPicture、enterFullscreen等在 Web 实现中为 no-opWeb 全屏走浏览器自身的requestFullscreen或 video.js 全屏插件与本文所述原生 API 不互通判断canEnterPictureInPicture()在 Web 上会返回不支持。如果你的应用需要跨端一致的 PiP/全屏行为建议按平台分流native 走VideoViewRefWeb 走浏览器的全屏/PiP API并在 UI 上做能力探测。7. 综合示例一个带控件、PiP 与全屏的播放器将上述能力组合一个完整的实战组件如下import { useRef } from react; import { useVideoPlayer, VideoView, useEvent } from react-native-video; import type { VideoViewRef } from react-native-video; export default function PlayerScreen({ uri }: { uri: string }) { const player useVideoPlayer({ uri }, (p) { p.loop false; p.volume 1; }); const viewRef useRefVideoViewRef(null); // 播放器事件走订阅与视图事件不同 useEvent(player, onPlaybackStateChange, ({ isPlaying }) { // 同步播放按钮状态 }); return ( VideoView ref{viewRef} player{player} controls pictureInPicture autoEnterPictureInPicture style{{ flex: 1 }} onFullscreenChange{(full) console.log(fullscreen:, full)} onPictureInPictureChange{(pip) console.log(pip:, pip)} / {/* 自定义控制逻辑示例先探测再进入 PiP */} Button title进入 PiP onPress{() { if (viewRef.current?.canEnterPictureInPicture()) { viewRef.current?.enterPictureInPicture(); } }} / Button title全屏 onPress{() viewRef.current?.enterFullscreen()} / / ); }关键实践要点初始配置放setup回调useVideoPlayer第二参它只在播放器开始加载时执行一次在组件体内直接改player.x会在每次渲染时执行视图事件用 props 或ref.addEventListener均可但订阅返回对象需调用remove()清理而 props 方式由VideoView内部在卸载时自动清理VideoView.tsx进入 PiP 前先canEnterPictureInPicture()避免在模拟器或不支持的设备上抛错真机验证iOS 模拟器不支持 PiP务必在真机上测试 PiP 全流程。8. 相关资源索引本文骨架来源pip-fullscreen-controls.md视图 props/ref 类型定义VideoViewProps.ts视图事件类型定义Events.tsVideoView桥接实现VideoView.tsxiOS PiP 原生实现AVPlayerViewControllerPictureInPicture.swiftAndroid PiP 工具类PictureInPictureUtils.kt原生平台配置iOS/Android/Expoplatform-setup.mdv7 播放器模型总览v7/README.md、player-model.mdv7 事件全览events.md赞分享音视频移动开发【免费下载链接】react-native-videoA component for react-native项目地址https://gitcode.com/gh_mirrors/re/react-native-video点击查看免费下载相关推荐react-native-video 的 VideoView 组件完全指南原生渲染、播放控制、全屏与画中画react native video 的 VideoView 组件完全指南原生渲染、播放控制、全屏与画中画 VideoView 是 react native音视频移动开发react-native-video 的 VideoView 命令式 API 指南Ref 方法控制全屏与画中画react native video 的 VideoView 命令式 API 指南Ref 方法控制全屏与画中画 VideoView 是 react nativ音视频移动开发react-native-video 的 VideoView 组件 Props 全解析播放器绑定、原生控件、画中画与画面适配react native video 的 VideoView 组件 Props 全解析播放器绑定、原生控件、画中画与画面适配 导读 VideoView 是 r音视频移动开发上一篇RevokeMsgPatcher免费强力防撤回工具完整使用指南下一篇图像去重终极指南使用imagededup快速清理重复图片的10个技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表