如何处理expo-video中的timeUpdate事件?
解决expo-video中timeUpdate事件仅触发一次且currentTime始终为0的问题
问题原因分析
- 缺失类型导入:代码中使用
TimeUpdateEventPayload但未从expo-video导入,可能引发类型错误干扰事件处理逻辑。 - 事件绑定时机不当:直接在组件顶层绑定事件,可能在
player未完全初始化时就完成绑定,导致监听失效。 - 播放时机过早:在
useVideoPlayer的初始化回调中立即调用play(),此时视频资源尚未加载完成,播放器无法正常触发时间更新事件。
修复后的代码
import { useEventListener } from 'expo'; import { useVideoPlayer, VideoView, TimeUpdateEventPayload } from 'expo-video'; // 导入缺失的类型 import { StyleSheet, useEffect } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; const videoSource = 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'; export default function Player() { const player = useVideoPlayer(videoSource); useEffect(() => { if (!player) return; player.loop = true; // 监听视频加载完成事件,确保资源就绪后再播放 const loadListener = useEventListener(player, 'load', () => { player.play(); console.log('视频加载完成,初始currentTime:', player.currentTime); }); // 绑定timeUpdate事件 const timeUpdateListener = useEventListener(player, 'timeUpdate', (timeUpdate: TimeUpdateEventPayload) => { console.log('当前播放时间: ', timeUpdate.currentTime); }); // 组件卸载时清理事件监听,避免内存泄漏 return () => { loadListener?.remove(); timeUpdateListener?.remove(); }; }, [player]); return ( <SafeAreaView edges={['left', 'right']} style={styles.contentContainer}> <VideoView style={styles.video} player={player} allowsFullscreen={false} allowsPictureInPicture={false} contentFit='fill' nativeControls={false} /> </SafeAreaView> ); } // 补充样式定义,避免代码报错 const styles = StyleSheet.create({ contentContainer: { flex: 1, }, video: { flex: 1, }, });
关键修复点
- 补全
TimeUpdateEventPayload类型导入,消除类型错误隐患。 - 将播放逻辑延迟到
load事件触发后执行,确保视频资源加载完成再启动播放,此时播放器能正常触发时间更新。 - 将事件监听逻辑放入
useEffect中,依赖player变量,确保仅在player初始化完成后绑定事件,同时在组件卸载时清理监听。
内容的提问来源于stack exchange,提问作者Ricardodnr
相关产品推荐
相关产品推荐

