最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - How to render multiple expo-video VideoView with the same VideoPlayer instance? - Stack Overflow

programmeradmin1浏览0评论

Video component from expo-av is deprecated in favor of expo-video.

On the other hand, mounting multiple VideoView components (from expo-video) at the same time with the same VideoPlayer instance does not work due to an Android platform limitation.

Given that, what's the recommended approach for rendering VideoCard components within a FlatList, where each VideoCard includes a VideoView?

This is described as an Android platform limitation, yet expo-av appears to support it. Could you clarify this discrepancy? Are you familiar with a fix in the next Expo SDK release?

Home Screen

<FlatList
   data={videoItems}
   keyExtractor={(item) => item.id}
   renderItem={({ item }) => <VideoCard videoItem={item} />}
   ...
/>

VideoCard Component (example code)

import { useEvent } from 'expo';
import { useVideoPlayer, VideoView } from 'expo-video';
import { StyleSheet, View, Button } from 'react-native';
  
const VideoCard = ({ 
        videoItem: { creator, videoUrl }
}) => {
  const player = useVideoPlayer(videoUrl, player => {
    player.loop = false;
    player.play();
  });

  const { isPlaying } = useEvent(player, 'playingChange', { isPlaying: player.playing });
  ...

  return (
     <View style={styles.contentContainer}>
      <VideoView 
          style={styles.video} 
          player={player} 
          allowsFullscreen={false} 
          allowsPictureInPicture={false}
      />
      ...
    </View>
  );
}

Video component from expo-av is deprecated in favor of expo-video.

On the other hand, mounting multiple VideoView components (from expo-video) at the same time with the same VideoPlayer instance does not work due to an Android platform limitation.

Given that, what's the recommended approach for rendering VideoCard components within a FlatList, where each VideoCard includes a VideoView?

This is described as an Android platform limitation, yet expo-av appears to support it. Could you clarify this discrepancy? Are you familiar with a fix in the next Expo SDK release?

Home Screen

<FlatList
   data={videoItems}
   keyExtractor={(item) => item.id}
   renderItem={({ item }) => <VideoCard videoItem={item} />}
   ...
/>

VideoCard Component (example code)

import { useEvent } from 'expo';
import { useVideoPlayer, VideoView } from 'expo-video';
import { StyleSheet, View, Button } from 'react-native';
  
const VideoCard = ({ 
        videoItem: { creator, videoUrl }
}) => {
  const player = useVideoPlayer(videoUrl, player => {
    player.loop = false;
    player.play();
  });

  const { isPlaying } = useEvent(player, 'playingChange', { isPlaying: player.playing });
  ...

  return (
     <View style={styles.contentContainer}>
      <VideoView 
          style={styles.video} 
          player={player} 
          allowsFullscreen={false} 
          allowsPictureInPicture={false}
      />
      ...
    </View>
  );
}
Share Improve this question asked yesterday NirNir 1132 silver badges6 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Here is the one approach where you can use

Single VideoPlayer: Create one VideoPlayer in the parent compnent.

Single VideoView: Render one VideoView and update its source (videoUrl) using Flatlist’s onViewableItemsChanged.

Placeholder in VideoCard: Show a thumnail in each VideoCard instead of a VideoView.

// State and player setup
const [currentVideoUrl, setCurrentVideoUrl] = useState(videoItems[0]?.videoUrl);
const player = useVideoPlayer(currentVideoUrl, (player) => {
  player.loop = false;
  player.play();
});

// Detect visible item in FlatList
const viewabilityConfig = { itemVisiblePercentThreshold: 50 };
const onViewableItemsChanged = useRef(({ viewableItems }) => {
  if (viewableItems.length > 0) {
    const visibleItem = viewableItems[0].item;
    if (visibleItem.videoUrl !== currentVideoUrl) {
      setCurrentVideoUrl(visibleItem.videoUrl);
      player.source = { uri: visibleItem.videoUrl }; // Update video source
      player.play();
    }
  }
});

// Render the VideoView and FlatList
return (
  <View>
    <VideoView
      style={{ width: '100%', height: 200 }}
      player={player}
      allowsFullscreen={false}
      allowsPictureInPicture={false}
    />
    <FlatList
      data={videoItems}
      keyExtractor={(item) => item.id}
      renderItem={({ item }) => (
        <VideoCard videoItem={item} isPlaying={item.videoUrl === currentVideoUrl} />
      )}
      onViewableItemsChanged={onViewableItemsChanged.current}
      viewabilityConfig={viewabilityConfig}
    />
  </View>
);
发布评论

评论列表(0)

  1. 暂无评论