Enhance stream processing and logging in useMetadata and stremioService; improve stream filtering logic, consolidate behavior hints, and log raw and processed streams for better debugging and state management. Use received streams directly in state updates to streamline data handling.

This commit is contained in:
tapframe 2025-05-01 20:38:43 +05:30
parent b12f41d0ae
commit 1aebcf6c6c
2 changed files with 75 additions and 33 deletions

View file

@ -134,21 +134,21 @@ export const useMetadata = ({ id, type }: UseMetadataProps): UseMetadataReturn =
// For now, just log the error.
} else if (streams && addonId && addonName) {
logger.log(`✅ [${logPrefix}:${sourceName}] Received ${streams.length} streams from ${addonName} (${addonId}) after ${processTime}ms`);
// Log the raw streams received for this addon
logger.log(`📦 [${logPrefix}:${sourceName}] Raw streams for ${addonName} (${addonId}):`, JSON.stringify(streams.slice(0, 2), null, 2)); // Log first 2 raw streams
if (streams.length > 0) {
const streamsWithAddon = streams.map(stream => ({
...stream,
name: stream.name || stream.title || 'Unnamed Stream',
addonId: addonId,
addonName: addonName
}));
// Use the streams directly as they are already processed by stremioService
const updateState = (prevState: GroupedStreams): GroupedStreams => {
logger.log(`🔄 [${logPrefix}:${sourceName}] Updating state for addon ${addonName} (${addonId})`);
// Log the streams being added to state
logger.log(`💾 [${logPrefix}:${sourceName}] Adding processed streams for ${addonName} (${addonId}) to state:`, JSON.stringify(streams.slice(0, 2), null, 2)); // Log first 2 processed streams
return {
...prevState,
[addonId]: {
addonName: addonName,
streams: streamsWithAddon
streams: streams // Use the received streams directly
}
};
};

View file

@ -749,39 +749,81 @@ class StremioService {
private processStreams(streams: any[], addon: Manifest): Stream[] {
return streams
.filter(stream => {
const isTorrentioStream = stream.infoHash && stream.fileIdx !== undefined;
return stream && (stream.url || isTorrentioStream) && (stream.title || stream.name);
// Basic filtering - ensure there's a way to play (URL or infoHash) and identify (title/name)
const hasPlayableLink = !!(stream.url || stream.infoHash);
const hasIdentifier = !!(stream.title || stream.name);
return stream && hasPlayableLink && hasIdentifier;
})
.map(stream => {
const isDirectStreamingUrl = this.isDirectStreamingUrl(stream.url);
const streamUrl = this.getStreamUrl(stream);
const isDirectStreamingUrl = this.isDirectStreamingUrl(streamUrl);
const isMagnetStream = streamUrl?.startsWith('magnet:');
// Keep original stream data exactly as provided by the addon
return {
...stream,
url: streamUrl,
// Determine the best title: Prioritize description if it seems detailed,
// otherwise fall back to title or name.
let displayTitle = stream.title || stream.name || 'Unnamed Stream';
if (stream.description && stream.description.includes('\n') && stream.description.length > (stream.title?.length || 0)) {
// If description exists, contains newlines (likely formatted metadata),
// and is longer than the title, prefer it.
displayTitle = stream.description;
}
// Use the original name field for the primary identifier if available
const name = stream.name || stream.title || 'Unnamed Stream';
// Extract size: Prefer behaviorHints.videoSize, fallback to top-level size
const sizeInBytes = stream.behaviorHints?.videoSize || stream.size || undefined;
// Consolidate behavior hints, prioritizing specific data extraction
let behaviorHints: Stream['behaviorHints'] = {
...(stream.behaviorHints || {}), // Start with existing hints
notWebReady: !isDirectStreamingUrl,
isMagnetStream,
// Addon Info
addonName: addon.name,
addonId: addon.id,
// Preserve original stream metadata
name: stream.name,
title: stream.title,
behaviorHints: {
...stream.behaviorHints,
notWebReady: !isDirectStreamingUrl,
isMagnetStream,
...(isMagnetStream && {
infoHash: stream.infoHash || streamUrl?.match(/btih:([a-zA-Z0-9]+)/)?.[1],
fileIdx: stream.fileIdx,
magnetUrl: streamUrl,
type: 'torrent',
sources: stream.sources || [],
seeders: stream.seeders,
size: stream.size,
title: stream.title,
})
}
// Extracted data (provide defaults or undefined)
cached: stream.behaviorHints?.cached || undefined, // For RD/AD detection
filename: stream.behaviorHints?.filename || undefined, // Filename if available
bingeGroup: stream.behaviorHints?.bingeGroup || undefined,
// Add size here if extracted
size: sizeInBytes,
};
// Specific handling for magnet/torrent streams to extract more details
if (isMagnetStream) {
behaviorHints = {
...behaviorHints,
infoHash: stream.infoHash || streamUrl?.match(/btih:([a-zA-Z0-9]+)/)?.[1],
fileIdx: stream.fileIdx,
magnetUrl: streamUrl,
type: 'torrent',
sources: stream.sources || [],
seeders: stream.seeders, // Explicitly map seeders if present
size: sizeInBytes || stream.seeders, // Use extracted size, fallback for torrents
title: stream.title, // Torrent title might be different
};
}
// Explicitly construct the final Stream object
const processedStream: Stream = {
url: streamUrl,
name: name, // Use the original name/title for primary ID
title: displayTitle, // Use the potentially more detailed title from description
addonName: addon.name,
addonId: addon.id,
// Map other potential top-level fields if they exist
description: stream.description || undefined, // Keep original description too
infoHash: stream.infoHash || undefined,
fileIdx: stream.fileIdx,
size: sizeInBytes, // Assign the extracted size
isFree: stream.isFree,
isDebrid: !!(stream.behaviorHints?.cached), // Map debrid status more reliably
// Assign the consolidated behaviorHints
behaviorHints: behaviorHints,
};
return processedStream;
});
}