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

react native - EXPO-Video freez - Stack Overflow

programmeradmin0浏览0评论

Hi I'm encountering the problem where when i go from my app to other app, and go back not all the time but sometimes, it freezes and also it shows on the screen the icon that the video is not working, the funny thing is that i don't see any error or anything so, what should i do? Anyone with the same problem? I'm using latest expo-video, expo 52 and using flashlist. enter image description here

// video-players.state.ts

import { create } from 'zustand';
import { createVideoPlayer, VideoPlayer } from 'expo-video';

interface VideoPlayerEntry {
    player: VideoPlayer;
    source: string;
}

interface VideoPlayerMap extends Map<number, VideoPlayerEntry> {}

interface VideoPlayersState {
    videoPlayers: VideoPlayerMap;
    lastPlayed: number | null;
    initializePlayer: (index: number, videoSource: string) => void;
    getVideoData: (index: number) => VideoPlayerEntry | undefined;
    pauseAllVideos: () => void;
    releasePlayer: (index: number) => void;
    releaseAllPlayers: () => void;
    logAllPlayers: () => void;
    handleViewableItemsChanged: ({
        viewableItems,
    }: {
        viewableItems: Array<{ index: number | null }>;
    }) => void;
    setLastPlayed: (index: number) => void;
}

export const useVideoPlayersStore = create<VideoPlayersState>((set, get) => ({
    videoPlayers: new Map(),
    lastPlayed: null,

    initializePlayer: (index: number, videoSource: string) => {
        const videoPlayers = get().videoPlayers;
        if (!videoPlayers.has(index)) {
            const player = createVideoPlayer(videoSource);
            player.loop = true;
            player.generateThumbnailsAsync(1);
            videoPlayers.set(index, { player, source: videoSource });
            set({ videoPlayers: new Map(videoPlayers) });
        }
    },

    getVideoData: (index: number) => {
        return get().videoPlayers.get(index);
    },

    pauseAllVideos: () => {
        const videoPlayers = get().videoPlayers;
        videoPlayers.forEach((entry, index) => {
            if (entry.player.playing) {
                entry.player.pause();
                set({ lastPlayed: index });
            }
        });
    },

    releasePlayer: (index: number) => {
        const videoPlayers = get().videoPlayers;
        const entry = videoPlayers.get(index);
        if (entry) {
            if (entry.player.playing) {
                entry.player.pause();
            }
            entry.player.release();
            videoPlayers.delete(index);
            set({ videoPlayers: new Map(videoPlayers), lastPlayed: null });
        }
    },

    releaseAllPlayers: () => {
        const videoPlayers = get().videoPlayers;
        videoPlayers.forEach((entry) => {
            if (entry.player.playing) {
                entry.player.pause();
            }
            entry.player.release();
        });
        videoPlayers.clear();
        set({ videoPlayers: new Map(), lastPlayed: null });
    },

    logAllPlayers: () => {
        console.log('Logging players:');
        get().videoPlayers.forEach((entry, index) => {
            console.log(
                `Player at index ${index}: ${entry.player.playing ? 'Playing' : 'Paused'}, Source: ${entry.source}`,
            );
        });
    },

    handleViewableItemsChanged: ({ viewableItems }) => {
        const videoPlayers = get().videoPlayers;
        const visibleIndices = viewableItems
            .map((item) => item.index)
            .filter((i): i is number => i !== null);

        let played = false;
        videoPlayers.forEach((entry, index) => {
            if (visibleIndices.includes(index) && !played) {
                if (entry.player) {
                    entry.player.play();
                    played = true;
                }
            } else {
                if (entry.player.playing) {
                    entry.player.pause();
                }
            }
        });
    },

    setLastPlayed: (index: number) => {
        set({ lastPlayed: index });
    },
}));

Hi I'm encountering the problem where when i go from my app to other app, and go back not all the time but sometimes, it freezes and also it shows on the screen the icon that the video is not working, the funny thing is that i don't see any error or anything so, what should i do? Anyone with the same problem? I'm using latest expo-video, expo 52 and using flashlist. enter image description here

// video-players.state.ts

import { create } from 'zustand';
import { createVideoPlayer, VideoPlayer } from 'expo-video';

interface VideoPlayerEntry {
    player: VideoPlayer;
    source: string;
}

interface VideoPlayerMap extends Map<number, VideoPlayerEntry> {}

interface VideoPlayersState {
    videoPlayers: VideoPlayerMap;
    lastPlayed: number | null;
    initializePlayer: (index: number, videoSource: string) => void;
    getVideoData: (index: number) => VideoPlayerEntry | undefined;
    pauseAllVideos: () => void;
    releasePlayer: (index: number) => void;
    releaseAllPlayers: () => void;
    logAllPlayers: () => void;
    handleViewableItemsChanged: ({
        viewableItems,
    }: {
        viewableItems: Array<{ index: number | null }>;
    }) => void;
    setLastPlayed: (index: number) => void;
}

export const useVideoPlayersStore = create<VideoPlayersState>((set, get) => ({
    videoPlayers: new Map(),
    lastPlayed: null,

    initializePlayer: (index: number, videoSource: string) => {
        const videoPlayers = get().videoPlayers;
        if (!videoPlayers.has(index)) {
            const player = createVideoPlayer(videoSource);
            player.loop = true;
            player.generateThumbnailsAsync(1);
            videoPlayers.set(index, { player, source: videoSource });
            set({ videoPlayers: new Map(videoPlayers) });
        }
    },

    getVideoData: (index: number) => {
        return get().videoPlayers.get(index);
    },

    pauseAllVideos: () => {
        const videoPlayers = get().videoPlayers;
        videoPlayers.forEach((entry, index) => {
            if (entry.player.playing) {
                entry.player.pause();
                set({ lastPlayed: index });
            }
        });
    },

    releasePlayer: (index: number) => {
        const videoPlayers = get().videoPlayers;
        const entry = videoPlayers.get(index);
        if (entry) {
            if (entry.player.playing) {
                entry.player.pause();
            }
            entry.player.release();
            videoPlayers.delete(index);
            set({ videoPlayers: new Map(videoPlayers), lastPlayed: null });
        }
    },

    releaseAllPlayers: () => {
        const videoPlayers = get().videoPlayers;
        videoPlayers.forEach((entry) => {
            if (entry.player.playing) {
                entry.player.pause();
            }
            entry.player.release();
        });
        videoPlayers.clear();
        set({ videoPlayers: new Map(), lastPlayed: null });
    },

    logAllPlayers: () => {
        console.log('Logging players:');
        get().videoPlayers.forEach((entry, index) => {
            console.log(
                `Player at index ${index}: ${entry.player.playing ? 'Playing' : 'Paused'}, Source: ${entry.source}`,
            );
        });
    },

    handleViewableItemsChanged: ({ viewableItems }) => {
        const videoPlayers = get().videoPlayers;
        const visibleIndices = viewableItems
            .map((item) => item.index)
            .filter((i): i is number => i !== null);

        let played = false;
        videoPlayers.forEach((entry, index) => {
            if (visibleIndices.includes(index) && !played) {
                if (entry.player) {
                    entry.player.play();
                    played = true;
                }
            } else {
                if (entry.player.playing) {
                    entry.player.pause();
                }
            }
        });
    },

    setLastPlayed: (index: number) => {
        set({ lastPlayed: index });
    },
}));

Share Improve this question asked Feb 3 at 13:33 Filip ČorbaFilip Čorba 133 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

i've had the same issue. Tried a bunch of things and the only thing that helped is switching to expo-av.

Its not maintained anymore but it works for now. We should definitely raise this issue on expo github

发布评论

评论列表(0)

  1. 暂无评论