react-native-expo-video-player
v0.1.1
Published
基于 expo-video 的功能丰富的 React Native 视频播放器组件,内置自定义控制栏、全屏手势、倍速切换等功能。
Maintainers
Readme
react-native-expo-video-player
基于 expo-video 构建的功能丰富的 React Native 视频播放器组件,开箱即用的自定义控制栏、全屏手势和倍速切换。
功能特性
- 🎬 自定义浮层控制栏(播放/暂停、进度条、倍速切换、全屏)
- 🖐️ 全屏手势:左侧上下滑 = 音量,右侧上下滑 = 亮度,水平滑 = 快进快退
- ⏩ 倍速选择器(0.5x – 2x)
- 🎞️ 画质选择器(通过不同 URL 切换画质,自动保持播放进度)
- 📱 控制栏自动隐藏,超时可配置
- 🔄 全屏管理 Hook(屏幕方向锁定 & 状态栏隐藏)
- 🎨 支持主题色自定义
- 🍎 iOS 滑块缩略图优化(内置 14px 小圆点图片)
- 🤖 Android 返回键自动退出全屏
- 🔀 完整透传
VideoView原生属性(contentFit、allowsPictureInPicture等)
安装
npx expo install react-native-expo-video-player expo-video expo-brightness expo-screen-orientation react-native-safe-area-context @react-native-community/slider快速开始
import { useVideoPlayer } from 'expo-video';
import { ExpoVideoPlayer, useFullscreen } from 'react-native-expo-video-player';
export default function Player() {
const player = useVideoPlayer(null);
const { isFullscreen, toggleFullscreen } = useFullscreen();
useEffect(() => {
player.replaceAsync('https://example.com/video.mp4').then(() => player.play());
}, []);
return (
<ExpoVideoPlayer
player={player}
isFullscreen={isFullscreen}
onToggleFullscreen={toggleFullscreen}
onBack={() => navigation.goBack()}
theme={{ primary: '#FF6B00' }}
/>
);
}组件
<ExpoVideoPlayer>
主组件,渲染 expo-video 的 VideoView 并叠加自定义控制栏。
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| player | VideoPlayer | 必填 | expo-video 播放器实例 |
| theme | VideoPlayerTheme | { primary: '#2979FF' } | 主题色配置 |
| isFullscreen | boolean | false | 当前是否全屏 |
| onToggleFullscreen | () => void | () => {} | 全屏切换回调 |
| onBack | () => void | () => {} | 返回按钮回调 |
| speedOptions | number[] | [0.5, 0.75, 1, 1.25, 1.5, 2] | 可选倍速 |
| speedLabel | string | '倍速' | 1x 速度时显示的文字 |
| autoHideTimeout | number | 3000 | 控制栏自动隐藏时间(毫秒) |
| enableGestures | boolean | true | 是否启用全屏手势 |
| showSpeedPicker | boolean | true | 是否显示倍速按钮 |
| showFullscreenButton | boolean | true | 是否显示全屏按钮 |
| showQualityPicker | boolean | false | 是否显示画质选择按钮 |
| qualityLabel | string | '画质' | "自动"画质时按钮上显示的文字 |
| qualityOptions | Array<{ label, url }> | [] | 画质选项列表,如 [{ label: '1080p', url: '...' }] |
| onQualityChange | (quality \| null) => void | () => {} | 画质切换回调,null 表示选了"自动" |
| thumbImage | ImageSource | 内置 14px 圆点 | 自定义滑块拇指图片 |
| width | number | 窗口宽度 | 视频容器宽度 |
| height | number | width × 9/16 | 视频容器高度 |
| ...videoViewProps | VideoViewProps | - | 所有原生 VideoView 属性均会透传 |
透传的 VideoView 属性
所有 expo-video 的 VideoView 原生属性均会透传到底层组件,包括但不限于:
| 属性 | 说明 |
|------|------|
| contentFit | 'contain' / 'cover' / 'fill' — 视频缩放模式 |
| contentPosition | { dx, dy } — 视频位置偏移(iOS) |
| allowsPictureInPicture | 启用画中画模式 |
| startsPictureInPictureAutomatically | 后台自动进入画中画 |
| allowsVideoFrameAnalysis | 视频中的实况文本(iOS 16+) |
| requiresLinearPlayback | 禁止用户拖拽进度 |
| showsTimecodes | 显示/隐藏时间码(iOS) |
| surfaceType | 'surfaceView' / 'textureView'(Android) |
| useExoShutter | ExoPlayer 快门(Android) |
| onFirstFrameRender | 首帧渲染回调 |
| onPictureInPictureStart | 画中画开始回调 |
| onPictureInPictureStop | 画中画结束回调 |
<VideoControls>
控制栏浮层组件,如果你想配合自己的 VideoView 单独使用。
<PlayerIcon>
基于 Unicode 的轻量级图标组件,内部使用。可用图标:play、pause、arrow-left、fullscreen、fullscreen-exit、fast-forward、rewind、volume-off、volume-medium、volume-high、brightness-6。
Hooks
useFullscreen(initialFullscreen?: boolean)
管理全屏状态,包括屏幕方向锁定、状态栏显隐和 Android 返回键处理。
const { isFullscreen, enterFullscreen, exitFullscreen, toggleFullscreen } = useFullscreen();全屏手势
全屏模式下且 enableGestures 开启时:
| 手势 | 操作 | |------|------| | 左侧上下滑动 | 调节音量 | | 右侧上下滑动 | 调节亮度 | | 水平滑动 | 快进/快退 | | 单击 | 显示/隐藏控制栏 | | 双击 | 播放/暂停 |
主题定制
<ExpoVideoPlayer
player={player}
theme={{
primary: '#FF6B00', // 滑块颜色、选中状态
text: '#ffffff', // (预留)
textSecondary: '#aaa', // (预留)
}}
/>画质切换
画质切换通过不同 URL 实现,适配国内大部分视频平台的分发方式:
<ExpoVideoPlayer
player={player}
showQualityPicker
qualityOptions={[
{ label: '1080p', url: 'https://cdn.example.com/video_1080p.mp4' },
{ label: '720p', url: 'https://cdn.example.com/video_720p.mp4' },
{ label: '480p', url: 'https://cdn.example.com/video_480p.mp4' },
]}
onQualityChange={(quality) => {
console.log('切换画质:', quality?.label ?? '自动');
}}
/>切换时会自动记住当前播放进度,通过 replaceAsync 加载新 URL 后恢复到之前的位置继续播放。选择"自动"时使用列表中第一个 URL。
从 expo-video 重新导出
为方便使用,以下常用符号从 expo-video 重新导出:
// 组件和 hooks
import { useVideoPlayer, VideoView, createVideoPlayer, isPictureInPictureSupported } from 'react-native-expo-video-player';
// 类型
import type { VideoSource, VideoPlayer, VideoPlayerStatus, VideoContentFit, DRMOptions, BufferOptions, VideoMetadata } from 'react-native-expo-video-player';Peer Dependencies
| 依赖 | 最低版本 |
|------|----------|
| expo | >= 51 |
| expo-video | >= 2 |
| expo-brightness | >= 12 |
| expo-screen-orientation | >= 7 |
| react | >= 18 |
| react-native | >= 0.75 |
| react-native-safe-area-context | >= 4 |
| @react-native-community/slider | >= 4 |
所有 expo 相关依赖均声明为
peerDependencies,不会与宿主项目的版本冲突。
兼容性
| 平台 | 支持情况 | |------|----------| | iOS | ✅ | | Android | ✅ | | Web | ❌(expo-video 暂不支持 Web) |
参与贡献
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'feat: 添加新功能') - 推送到分支 (
git push origin feature/amazing-feature) - 提交 Pull Request
致谢
- expo-video — Expo 官方视频播放模块
- expo-brightness — 亮度调节
- expo-screen-orientation — 屏幕方向控制
- @react-native-community/slider — 进度条滑块组件
技术交流
欢迎加入 QQ 技术交流群:1048378204,一起讨论 React Native、Expo 和移动端开发。
