mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
embed stream fetch critical bug fix
This commit is contained in:
parent
ff2bca18a5
commit
b4b8648e25
2 changed files with 75 additions and 25 deletions
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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 ||
|
||||
|
|
|
|||
Loading…
Reference in a new issue