如何自定义expo-av Video的useNativeControls并添加倍速、分辨率调节按钮
实现自定义播放器控制按钮的方案
你当前代码中启用了useNativeControls属性,调用的是系统原生播放控件,不支持插入自定义按钮,要实现倍速调节、分辨率切换的需求,关闭原生控件后自行封装自定义控制层即可,具体实现步骤如下:
第一步:新增状态管理并调整Video组件配置
首先添加对应状态变量管理播放速率、控制栏显隐、当前分辨率,再修改Video组件的属性配置:
// 新增状态 const [rate, setRate] = useState(1.0); const [showControls, setShowControls] = useState(false); const [currentResolution, setCurrentResolution] = useState("720p");
修改后的Video组件代码:
<Video key={videoId} ref={video} style={styles.videoPlayer} source={{ uri: videofiles?.link, }} rate={rate} posterSource={{ uri: thumbnail }} usePoster={!isActivity} useNativeControls={false} // 关闭原生控件 resizeMode={Video.RESIZE_MODE_CONTAIN} isLooping onPlaybackStatusUpdate={status => { statusChangeEvent(status); }} onFullscreenUpdate={onFullscreenUpdate} onPress={() => setShowControls(prev => !prev)} // 点击视频切换控制栏显隐 />
第二步:叠加自定义控制层UI
给Video组件外层套一个相对定位的容器,同层级绝对定位叠加自定义控制栏,放入你需要的三个按钮:
<View style={styles.videoWrapper}> {/* 上述Video组件放在此处 */} {showControls && <View style={styles.controlsBar}> {/* 降低倍速按钮 */} <TouchableOpacity onPress={() => setRate(prev => Math.max(0.5, prev - 0.25))} style={styles.controlBtn} > <Text style={{color: '#fff'}}>-0.25x</Text> </TouchableOpacity> {/* 显示当前倍速 */} <Text style={styles.rateText}>{rate}x</Text> {/* 升高倍速按钮 */} <TouchableOpacity onPress={() => setRate(prev => Math.min(2.0, prev + 0.25))} style={styles.controlBtn} > <Text style={{color: '#fff'}}>+0.25x</Text> </TouchableOpacity> {/* 分辨率切换按钮 */} <TouchableOpacity onPress={async () => { // 切换分辨率逻辑,可根据自己的业务调整分辨率选项 const newRes = currentResolution === "720p" ? "1080p" : "720p"; const status = await video.current.getStatusAsync(); let currentPosition = 0; if(status.isLoaded) currentPosition = status.positionMillis; // 替换为对应分辨率的视频地址,getResUrl为你自己实现的地址映射方法 videofiles.link = getResUrl(newRes); setCurrentResolution(newRes); // 切换后回到之前的播放进度 setTimeout(() => { video.current.setPositionAsync(currentPosition); }, 100) }} style={styles.controlBtn} > <Text style={{color: '#fff'}}>{currentResolution}</Text> </TouchableOpacity> {/* 可自行补充播放/暂停、进度条、全屏等其他控制功能 */} </View>} </View>
第三步:补充对应样式
const styles = StyleSheet.create({ videoWrapper: { position: 'relative', width: '100%', aspectRatio: 16/9 }, videoPlayer: { width: '100%', height: '100%' }, controlsBar: { position: 'absolute', bottom: 0, left: 0, right: 0, height: 50, backgroundColor: 'rgba(0,0,0,0.7)', flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, gap: 16 }, controlBtn: { paddingHorizontal: 8, paddingVertical: 4, backgroundColor: '#333', borderRadius: 4 }, rateText: { color: '#fff', minWidth: 40, textAlign: 'center' } })
注意事项
- 可给控制栏添加自动隐藏逻辑,用户操作后3秒无交互自动隐藏,提升使用体验
- 提前做好不同分辨率的视频地址映射,避免切换时请求失败
- 可根据业务需求调整倍速可选区间,示例中设置的是0.5x到2x的范围
内容的提问来源于stack exchange,提问作者Younis Rahman
相关产品推荐
相关产品推荐

