如何实现类似TikTok的多视频同时播放效果,修复FlatList仅单视频播放问题
多视频同时播放实现问题修复
问题背景
需要实现列表内多个视频同时播放的效果,参考效果如下:
现有代码渲染水平滚动的FlatList视频列表,运行后可正常展示所有视频,但仅有1个视频能正常播放。
现有代码
<FlatList data={data.vidSlide} horizontal={true} renderItem={({ item }) => ( <Pressable onPress={() => navigation.navigate('Video', { Video: item })}> <View key={item.id} style={{ flexDirection: 'row', paddingRight: 5 }}> <Video source={{ uri: item.video }} ref={lo} style={{ borderRadius: 7, width: 115, height: 175 }} onPlaybackStatusUpdate={status => setStatus(() => status)} onLoad={() => lo.current.playAsync()} resizeMode="cover" isLooping > </Video> </View> </Pressable> )} />
修复方案
问题确实出在ref属性上:所有Video组件共用了同一个lo引用,每渲染一个新的视频,ref就会被覆盖为当前最新的视频实例,最终只有最后一个渲染的视频能触发播放。
具体修改步骤
- 改用对象格式的ref存储所有视频实例,以视频id作为唯一标识区分每个实例:
// 组件顶部声明ref const videoRefs = useRef({}); // 如果需要存储多个视频的播放状态,也改用对象存储 const playbackStatus = useRef({});
- 修改FlatList内Video组件的ref绑定和播放逻辑:
<FlatList data={data.vidSlide} horizontal={true} renderItem={({ item }) => ( <Pressable onPress={() => navigation.navigate('Video', { Video: item })}> <View key={item.id} style={{ flexDirection: 'row', paddingRight: 5 }}> <Video source={{ uri: item.video }} // 绑定每个视频的独立ref ref={el => videoRefs.current[item.id] = el} style={{ borderRadius: 7, width: 115, height: 175 }} onPlaybackStatusUpdate={status => { playbackStatus.current[item.id] = status; }} // 调用对应id的视频实例触发播放 onLoad={() => videoRefs.current[item.id]?.playAsync()} resizeMode="cover" isLooping /> </View> </Pressable> )} // 可选优化:回收滑出可视区的组件,降低内存占用 removeClippedSubviews={true} />
额外优化建议
如果列表视频数量较多,建议增加可视区域判断逻辑,仅让处于屏幕可视范围内的视频播放,避免同时播放过多视频导致设备卡顿、发热。
内容的提问来源于stack exchange,提问作者zeke1
相关产品推荐
相关产品推荐

