url passing correctly

This commit is contained in:
tejaspanchall
2025-06-18 18:46:16 +05:30
parent f8631b4ef7
commit de1b0a0363
3 changed files with 84 additions and 44 deletions

View File

@@ -178,8 +178,28 @@ export default function WatchPage() {
} }
// Set subtitles if available in the sources response // Set subtitles if available in the sources response
if (data.subtitles && data.subtitles.length > 0) { // Check both subtitles and tracks fields since API might return either
setSubtitles(data.subtitles); const subtitleData = data.subtitles || data.tracks || [];
if (subtitleData.length > 0) {
// Filter out thumbnails from subtitles array
const filteredSubtitles = subtitleData.filter(sub =>
sub.lang && sub.lang.toLowerCase() !== 'thumbnails'
);
// Look for thumbnails separately
const thumbnailTrack = subtitleData.find(sub =>
sub.lang && sub.lang.toLowerCase() === 'thumbnails'
);
if (thumbnailTrack && thumbnailTrack.url) {
console.log('[Watch] Found thumbnails track:', thumbnailTrack.url);
setThumbnails(thumbnailTrack.url);
}
if (filteredSubtitles.length > 0) {
console.log('[Watch] Found subtitles:', filteredSubtitles.length);
setSubtitles(filteredSubtitles);
}
} }
// Try to find the best source in order of preference // Try to find the best source in order of preference
@@ -421,8 +441,8 @@ export default function WatchPage() {
subtitles={subtitles} subtitles={subtitles}
thumbnails={thumbnails} thumbnails={thumbnails}
category={isDub ? 'dub' : 'sub'} category={isDub ? 'dub' : 'sub'}
intro={episodeData?.intro} intro={episodeData?.intro || null}
outro={episodeData?.outro} outro={episodeData?.outro || null}
autoSkipIntro={autoSkip} autoSkipIntro={autoSkip}
autoSkipOutro={autoSkip} autoSkipOutro={autoSkip}
episodeId={currentEpisodeId} episodeId={currentEpisodeId}

View File

@@ -2,7 +2,7 @@
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import Hls from 'hls.js'; import Hls from 'hls.js';
import Image from 'next/image'; import NextImage from 'next/image';
// Get the M3U8 Proxy URL from environment variables // Get the M3U8 Proxy URL from environment variables
const CORSPROXY_URL = process.env.NEXT_PUBLIC_CORSPROXY_URL; const CORSPROXY_URL = process.env.NEXT_PUBLIC_CORSPROXY_URL;
@@ -99,11 +99,22 @@ export default function VideoPlayer({ src, poster, headers = {}, subtitles = [],
const getProxiedUrl = (url) => { const getProxiedUrl = (url) => {
if (!url) return url; if (!url) return url;
// Log the original URL for debugging
console.log('[VideoPlayer] Original URL:', url);
// Check if the URL is an M3U8 URL // Check if the URL is an M3U8 URL
if (url.includes('.m3u8') || url.includes('application/vnd.apple.mpegurl')) { if (url.includes('.m3u8') || url.includes('application/vnd.apple.mpegurl')) {
// Check if we have a CORS proxy URL configured
if (!CORSPROXY_URL) {
console.warn('[VideoPlayer] No CORS proxy URL configured, using original URL');
return url;
}
// Route through the external M3U8 proxy server // Route through the external M3U8 proxy server
const encodedUrl = encodeURIComponent(url); const encodedUrl = encodeURIComponent(url);
return `${CORSPROXY_URL}/m3u8-proxy?url=${encodedUrl}`; const proxiedUrl = `${CORSPROXY_URL}/m3u8-proxy?url=${encodedUrl}`;
console.log('[VideoPlayer] Using proxied URL:', proxiedUrl);
return proxiedUrl;
} }
return url; return url;
@@ -259,7 +270,14 @@ export default function VideoPlayer({ src, poster, headers = {}, subtitles = [],
maxMaxBufferLength: 60, maxMaxBufferLength: 60,
startLevel: -1, // Auto level selection startLevel: -1, // Auto level selection
capLevelToPlayerSize: true, // Limit quality based on player size capLevelToPlayerSize: true, // Limit quality based on player size
debug: false debug: false,
// Add more robust error recovery
fragLoadingMaxRetry: 5,
manifestLoadingMaxRetry: 5,
levelLoadingMaxRetry: 5,
fragLoadingRetryDelay: 1000,
manifestLoadingRetryDelay: 1000,
levelLoadingRetryDelay: 1000
}); });
window.hls = hls; // Save reference for debugging window.hls = hls; // Save reference for debugging
@@ -294,26 +312,28 @@ export default function VideoPlayer({ src, poster, headers = {}, subtitles = [],
}); });
hls.on(Hls.Events.ERROR, (event, data) => { hls.on(Hls.Events.ERROR, (event, data) => {
console.error('[VideoPlayer] HLS error:', event, data);
if (data.fatal) { if (data.fatal) {
switch (data.type) { switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR: case Hls.ErrorTypes.NETWORK_ERROR:
console.error('HLS network error'); console.error('[VideoPlayer] HLS network error, attempting recovery');
hls.startLoad(); hls.startLoad();
break; break;
case Hls.ErrorTypes.MEDIA_ERROR: case Hls.ErrorTypes.MEDIA_ERROR:
console.error('HLS media error'); console.error('[VideoPlayer] HLS media error, attempting recovery');
hls.recoverMediaError(); hls.recoverMediaError();
break; break;
default: default:
console.error('HLS fatal error'); console.error('[VideoPlayer] HLS fatal error, cannot recover');
setError('Failed to load video'); setError('Failed to load video - please try another server');
break; break;
} }
} }
}); });
} else { } else {
// For non-HLS streams, use native video player // For non-HLS streams, use native video player
video.src = src; console.log('[VideoPlayer] Using native player for source:', src);
// Set headers for direct video requests // Set headers for direct video requests
const fetchOptions = { const fetchOptions = {
@@ -322,7 +342,10 @@ export default function VideoPlayer({ src, poster, headers = {}, subtitles = [],
try { try {
const response = await fetch(src, fetchOptions); const response = await fetch(src, fetchOptions);
if (!response.ok) throw new Error('Failed to load video'); if (!response.ok) {
console.error('[VideoPlayer] Failed to fetch video:', response.status, response.statusText);
throw new Error('Failed to load video');
}
const blob = await response.blob(); const blob = await response.blob();
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
@@ -330,18 +353,20 @@ export default function VideoPlayer({ src, poster, headers = {}, subtitles = [],
// Auto-play when ready // Auto-play when ready
if (isPlaying) { if (isPlaying) {
video.play().catch(console.error); video.play().catch(err => {
console.error('[VideoPlayer] Autoplay error:', err);
});
} }
} catch (error) { } catch (error) {
console.error('Error loading video:', error); console.error('[VideoPlayer] Error loading video:', error);
setError('Failed to load video'); setError('Failed to load video - please try another server');
} }
} }
setIsLoading(false); setIsLoading(false);
} catch (error) { } catch (error) {
console.error('Error setting up video:', error); console.error('[VideoPlayer] Error setting up video:', error);
setError('Failed to load video'); setError('Failed to load video - please try another server');
setIsLoading(false); setIsLoading(false);
} }
}; };
@@ -562,18 +587,6 @@ export default function VideoPlayer({ src, poster, headers = {}, subtitles = [],
}; };
}, []); }, []);
// Setup thumbnails for scrubbing preview
useEffect(() => {
if (thumbnails) {
console.log('Thumbnails URL available:', thumbnails);
const video = videoRef.current;
if (video) {
// Add data attribute for custom video player to use
video.setAttribute('data-thumbnails', thumbnails);
}
}
}, [thumbnails]);
// Toggle fullscreen // Toggle fullscreen
const toggleFullscreen = () => { const toggleFullscreen = () => {
const container = videoRef.current?.parentElement; const container = videoRef.current?.parentElement;
@@ -1045,14 +1058,13 @@ export default function VideoPlayer({ src, poster, headers = {}, subtitles = [],
// Load and verify thumbnails // Load and verify thumbnails
useEffect(() => { useEffect(() => {
if (thumbnails) { if (thumbnails) {
const img = new Image(); const img = new window.Image();
img.onload = () => { img.onload = () => {
setThumbnailsLoaded(true); setThumbnailsLoaded(true);
console.log('Thumbnails loaded successfully'); console.log('Thumbnails loaded successfully');
}; };
img.onerror = () => { img.onerror = (err) => {
console.error('Failed to load thumbnails'); console.error('Error loading thumbnails:', err);
setThumbnailsLoaded(false);
}; };
img.src = thumbnails; img.src = thumbnails;
} }

View File

@@ -586,33 +586,41 @@ export const fetchEpisodeSources = async (episodeId, dub = false, server = 'hd-2
return { sources: [] }; return { sources: [] };
} }
if (!data.success) { // Check if response is valid (status 200 or success flag)
console.error('[API Error] Response indicates failure - success flag is false'); // Some API responses use success flag, others use status code
const isValidResponse = (data.success === true) || (data.status === 200);
if (!isValidResponse) {
console.error('[API Error] Response indicates failure - invalid status or success flag');
return { sources: [] }; return { sources: [] };
} }
if (!data.data) { // Get the data object from either data.data (new format) or data (old format)
const responseData = data.data || data;
if (!responseData) {
console.error('[API Error] Empty data object in response'); console.error('[API Error] Empty data object in response');
return { sources: [] }; return { sources: [] };
} }
if (!data.data.sources || data.data.sources.length === 0) { if (!responseData.sources || responseData.sources.length === 0) {
console.error('[API Error] No sources found in response data'); console.error('[API Error] No sources found in response data');
return { sources: [] }; return { sources: [] };
} }
console.log('[API Success] Found sources:', data.data.sources.map(s => ({ console.log('[API Success] Found sources:', responseData.sources.map(s => ({
url: s.url.substring(0, 50) + '...', url: s.url.substring(0, 50) + '...',
quality: s.quality, quality: s.quality,
isM3U8: s.isM3U8 isM3U8: s.isM3U8
}))); })));
return { return {
sources: data.data.sources || [], sources: responseData.sources || [],
headers: data.data.headers || { "Referer": "https://hianime.to/" }, headers: responseData.headers || { "Referer": "https://hianime.to/" },
subtitles: data.data.subtitles || [], subtitles: responseData.tracks || responseData.subtitles || [],
anilistID: data.data.anilistID || null, anilistID: responseData.anilistID || null,
malID: data.data.malID || null malID: responseData.malID || null,
intro: responseData.intro || null,
outro: responseData.outro || null
}; };
} catch (error) { } catch (error) {
console.error('Error fetching episode sources:', error); console.error('Error fetching episode sources:', error);