Untitled

 avatar
unknown
plain_text
11 days ago
2.9 kB
4
Indexable
import {
  ActivityIndicator,
  StyleSheet,
  Text,
  View,
  FlatList,
  TouchableOpacity,
} from "react-native";
import React, { useState, useRef, useEffect } from "react";
import { Video, ResizeMode } from "expo-av";
import * as FileSystem from 'expo-file-system';

export default function VideoComponent({ videoArray }) {
  const [videoUri, setVideoUri] = useState(null);

  const downloadAndCacheVideo = async (videoUrl, videoName) => {
    try {
      // Define a local file path to store the cached video
      const localUri = FileSystem.documentDirectory + videoName;

      // Check if the video already exists locally
      const fileInfo = await FileSystem.getInfoAsync(localUri);

      if (!fileInfo.exists) {
        // If the video is not cached, download it and save it locally
        const downloadedFile = await FileSystem.downloadAsync(
          videoUrl,
          localUri
        );
        setVideoUri(downloadedFile.uri); // Update the URI state with the local file path
      } else {
        setVideoUri(localUri); // Set the local cached URI
      }
    } catch (error) {
      console.error('Error downloading video:', error);
       // Check for storage-related errors and inform the user
       if (error.message && error.message.includes('not enough space')) {
        Alert.alert('Error', 'Not enough storage space to download the video. Playing from the internet instead.');
        
        // If there's no space, fallback to streaming the video directly
        setVideoUri(videoUrl); // Stream the video from the URL
      } else {
        Alert.alert('Error', 'An unexpected error occurred while downloading the video.');
      }
    }
  }

  const video = useRef(null);

  const startVideo = async (videoUrl, videoName) => {
    await downloadAndCacheVideo(videoUrl, videoName);
    loadVideo(videoUri);
  };

  const loadVideo = async (videoUri) => {
    await video.current.loadAsync({uri: videoUri});
  };

  return (
    <View style={styles.container}>
      <Video
        ref={video}
        style={styles.video}
        useNativeControls
        resizeMode={ResizeMode.CONTAIN}
        isLooping
      >
        <ActivityIndicator size="small" />
      </Video>

      <FlatList
              data={videoArray}
              renderItem={({ item }) => (
                <TouchableOpacity style={styles.title} onPress={() => startVideo(item.source, item.title)}>
                  <Text style={styles.title}>{item.title}</Text>
                </TouchableOpacity>
              )}
              keyExtractor={(item) => item.key}
            />
    </View>
  );
}

const styles = StyleSheet.create({
  title: {
    borderColor: "black",
    alignSelf: "left",
    fontSize: 18,
    fontFamily: "Koulen Regular",
    marginRight: 20,
  },
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  video: {
    alignSelf: 'center',
    width: 320,
    height: 200,
  },
});
Leave a Comment