embed stream fetch critical bug fix

This commit is contained in:
tapframe 2025-12-29 01:03:06 +05:30
parent ff2bca18a5
commit b4b8648e25
2 changed files with 75 additions and 25 deletions

View file

@ -1364,7 +1364,7 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
};
// Extract embedded streams from metadata videos (used by PPV-style addons)
const extractEmbeddedStreams = useCallback(() => {
const extractEmbeddedStreams = useCallback((episodeIdOverride?: string) => {
if (!metadata?.videos) return;
// Check if any video has embedded streams
@ -1378,11 +1378,11 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
const addonId = (metadata as any).addonId || 'embedded';
const addonName = (metadata as any).addonName || metadata.name || 'Embedded Streams';
// Extract all streams from videos
const embeddedStreams: Stream[] = [];
// 1. Extract all streams for groupedStreams (legacy/movies behavior, or flat list)
const allEmbeddedStreams: Stream[] = [];
for (const video of videosWithStreams) {
for (const stream of video.streams) {
embeddedStreams.push({
allEmbeddedStreams.push({
...stream,
name: stream.name || stream.title || video.title,
title: stream.title || video.title,
@ -1392,15 +1392,15 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
}
}
if (embeddedStreams.length > 0) {
if (__DEV__) console.log(`✅ [extractEmbeddedStreams] Found ${embeddedStreams.length} embedded streams from ${addonName}`);
if (allEmbeddedStreams.length > 0) {
if (__DEV__) console.log(`✅ [extractEmbeddedStreams] Found ${allEmbeddedStreams.length} embedded streams from ${addonName}`);
// Add to grouped streams
setGroupedStreams(prevStreams => ({
...prevStreams,
[addonId]: {
addonName,
streams: embeddedStreams,
streams: allEmbeddedStreams,
},
}));
@ -1412,10 +1412,44 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
return prevOrder;
});
// Mark loading as complete since we have streams
setLoadingStreams(false);
// If we are not waiting for episode streams, we can stop loading
if (!loadingEpisodeStreams) {
setLoadingStreams(false);
}
}
}, [metadata]);
// 2. Extract streams specifically for the selected episode
const episodeToUse = episodeIdOverride || selectedEpisode;
if (episodeToUse) {
const episodeVideo = videosWithStreams.find(
v => v.id === episodeToUse ||
v.id === episodeToUse.split(':').pop() || // Handle cases where ID might have prefix
(v.season === 0 && v.episode === 1 && videosWithStreams.length === 1) // Single item PPV edge case
);
if (episodeVideo && episodeVideo.streams && episodeVideo.streams.length > 0) {
if (__DEV__) console.log(`✅ [extractEmbeddedStreams] Found embedded streams for episode ${episodeToUse}`);
const episodeStreamsList: Stream[] = episodeVideo.streams.map((stream: any) => ({
...stream,
name: stream.name || stream.title || episodeVideo.title,
title: stream.title || episodeVideo.title,
addonId,
addonName,
}));
setEpisodeStreams(prevStreams => ({
...prevStreams,
[addonId]: {
addonName,
streams: episodeStreamsList,
},
}));
setLoadingEpisodeStreams(false);
}
}
}, [metadata, selectedEpisode, loadingEpisodeStreams]);
const loadStreams = async () => {
const startTime = Date.now();
@ -1822,11 +1856,24 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
if (__DEV__) console.log('✅ [loadEpisodeStreams] Converted to TMDB ID:', tmdbId);
// Ensure consistent format
stremioEpisodeId = `${id}:${seasonNum}:${episodeNum}`;
// Ensure consistent format or fallback to episodeId if parsing failed
// This handles cases where 'tt' is used for a unique episode ID directly
if (!seasonNum && !episodeNum) {
stremioEpisodeId = episodeId;
} else {
stremioEpisodeId = `${id}:${seasonNum}:${episodeNum}`;
}
if (__DEV__) console.log('🔧 [loadEpisodeStreams] Normalized episode ID for addons:', stremioEpisodeId);
} else {
tmdbId = id;
stremioEpisodeId = `${id}:${seasonNum}:${episodeNum}`;
// If season/episode parsing failed (empty strings), use the raw episode ID
// This handles custom IDs like "ppv-event-name" that don't follow "id:s:e" format
if (!seasonNum && !episodeNum) {
// Remove 'series:' prefix if present to be safe, though parsing logic above usually handles it
stremioEpisodeId = episodeId.replace(/^series:/, '');
} else {
stremioEpisodeId = `${id}:${seasonNum}:${episodeNum}`;
}
if (__DEV__) console.log(' [loadEpisodeStreams] Using ID as both TMDB and Stremio ID:', tmdbId);
}
@ -1840,11 +1887,16 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat
if (__DEV__) console.log('🎬 [loadEpisodeStreams] Using episode ID for Stremio addons:', stremioEpisodeId);
// For collections, treat episodes as individual movies, not series
const contentType = isCollection ? 'movie' : 'series';
if (__DEV__) console.log(`🎬 [loadEpisodeStreams] Using content type: ${contentType} for ${isCollection ? 'collection' : 'series'}`);
// For other types (e.g. StreamsPPV), preserve the original type unless it's explicitly 'series' logic we want
const contentType = isCollection ? 'movie' : type;
if (__DEV__) console.log(`🎬 [loadEpisodeStreams] Using content type: ${contentType} for ${isCollection ? 'collection' : type}`);
processStremioSource(contentType, stremioEpisodeId, true);
// Also extract any embedded streams from metadata for this episode
// Also extract any embedded streams from metadata for this episode
extractEmbeddedStreams(episodeId);
// Monitor scraper completion status instead of using fixed timeout
const checkEpisodeScrapersCompletion = () => {
setScraperStatuses(currentStatuses => {

View file

@ -357,7 +357,7 @@ export const useStreamsScreen = () => {
async (stream: Stream, options?: { headers?: Record<string, string> }) => {
const finalHeaders = filterHeadersForVidrock(options?.headers || (stream.headers as any));
const streamsToPass = type === 'series' || (type === 'other' && selectedEpisode) ? episodeStreams : groupedStreams;
const streamsToPass = selectedEpisode ? episodeStreams : groupedStreams;
const streamName = stream.name || stream.title || 'Unnamed Stream';
const streamProvider = stream.addonId || stream.addonName || stream.name;
@ -545,8 +545,7 @@ export const useStreamsScreen = () => {
useEffect(() => {
if (!isMounted.current) return;
const currentStreamsData =
metadata?.videos && metadata.videos.length > 1 && selectedEpisode ? episodeStreams : groupedStreams;
const currentStreamsData = selectedEpisode ? episodeStreams : groupedStreams;
const providersWithStreams = Object.entries(currentStreamsData)
.filter(([_, data]) => data.streams && data.streams.length > 0)
@ -592,8 +591,7 @@ export const useStreamsScreen = () => {
const isSpecialFilter = selectedProvider === 'all' || selectedProvider === 'grouped-plugins';
if (isSpecialFilter) return;
const currentStreamsData =
metadata?.videos && metadata.videos.length > 1 && selectedEpisode ? episodeStreams : groupedStreams;
const currentStreamsData = selectedEpisode ? episodeStreams : groupedStreams;
const hasStreamsForProvider =
currentStreamsData[selectedProvider] &&
currentStreamsData[selectedProvider].streams &&
@ -675,8 +673,7 @@ export const useStreamsScreen = () => {
// Autoplay effect
useEffect(() => {
if (settings.autoplayBestStream && !autoplayTriggered && isAutoplayWaiting) {
const streams =
metadata?.videos && metadata.videos.length > 1 && selectedEpisode ? episodeStreams : groupedStreams;
const streams = selectedEpisode ? episodeStreams : groupedStreams;
if (Object.keys(streams).length > 0) {
const bestStream = getBestStream(streams);
@ -716,7 +713,7 @@ export const useStreamsScreen = () => {
// Filter items for provider selector
const filterItems = useMemo((): FilterItem[] => {
const installedAddons = stremioService.getInstalledAddons();
const streams = metadata?.videos && metadata.videos.length > 1 && selectedEpisode ? episodeStreams : groupedStreams;
const streams = selectedEpisode ? episodeStreams : groupedStreams;
const providersWithStreams = Object.keys(streams).filter(key => {
const providerData = streams[key];
@ -787,7 +784,7 @@ export const useStreamsScreen = () => {
// Sections for stream list
const sections = useMemo((): StreamSection[] => {
const streams = metadata?.videos && metadata.videos.length > 1 && selectedEpisode ? episodeStreams : groupedStreams;
const streams = selectedEpisode ? episodeStreams : groupedStreams;
const installedAddons = stremioService.getInstalledAddons();
const filteredEntries = Object.entries(streams).filter(([addonId]) => {
@ -1014,8 +1011,9 @@ export const useStreamsScreen = () => {
const gradientColors = useMemo(() => createGradientColors(dominantColor), [dominantColor, createGradientColors]);
// Loading states
const isLoading = metadata?.videos && metadata.videos.length > 1 && selectedEpisode ? loadingEpisodeStreams : loadingStreams;
const streams = metadata?.videos && metadata.videos.length > 1 && selectedEpisode ? episodeStreams : groupedStreams;
// Loading states
const isLoading = selectedEpisode ? loadingEpisodeStreams : loadingStreams;
const streams = selectedEpisode ? episodeStreams : groupedStreams;
const streamsEmpty =
Object.keys(streams).length === 0 ||