Reputation: 13
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 });
},
}));
Upvotes: 1
Views: 42
Reputation: 1
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
Upvotes: 0