mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +00:00
testing
This commit is contained in:
parent
2d3ece7dc4
commit
b21f13c283
6 changed files with 154 additions and 13 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit ff60b52232d79636656476b4057bbd7b479cd6c7
|
||||
Subproject commit cfd669df2258d217c90c58ce9455676c60abd1ac
|
||||
17
package-lock.json
generated
17
package-lock.json
generated
|
|
@ -21,7 +21,7 @@
|
|||
"@sentry/react-native": "^6.15.1",
|
||||
"@types/lodash": "^4.17.16",
|
||||
"@types/react-native-video": "^5.0.20",
|
||||
"axios": "^1.10.0",
|
||||
"axios": "^1.11.0",
|
||||
"axios-cookiejar-support": "^6.0.4",
|
||||
"cheerio-without-node-native": "^0.20.2",
|
||||
"date-fns": "^4.1.0",
|
||||
|
|
@ -5321,13 +5321,13 @@
|
|||
"optional": true
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
|
||||
"integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
|
||||
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"form-data": "^4.0.4",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -5386,14 +5386,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/axios/node_modules/form-data": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
|
||||
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
|
||||
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
"@sentry/react-native": "^6.15.1",
|
||||
"@types/lodash": "^4.17.16",
|
||||
"@types/react-native-video": "^5.0.20",
|
||||
"axios": "^1.10.0",
|
||||
"axios": "^1.11.0",
|
||||
"axios-cookiejar-support": "^6.0.4",
|
||||
"cheerio-without-node-native": "^0.20.2",
|
||||
"date-fns": "^4.1.0",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import { useTraktAutosync } from '../../hooks/useTraktAutosync';
|
|||
import { useTraktAutosyncSettings } from '../../hooks/useTraktAutosyncSettings';
|
||||
import { useMetadata } from '../../hooks/useMetadata';
|
||||
import { useSettings } from '../../hooks/useSettings';
|
||||
import { testVideoStreamUrl } from '../../utils/httpInterceptor';
|
||||
|
||||
import {
|
||||
DEFAULT_SUBTITLE_SIZE,
|
||||
|
|
@ -497,6 +498,17 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
|
||||
const onLoad = (data: any) => {
|
||||
try {
|
||||
// Enhanced HTTP response logging
|
||||
console.log('\n✅ [AndroidVideoPlayer] HTTP RESPONSE SUCCESS:');
|
||||
console.log('📍 URL:', currentStreamUrl);
|
||||
console.log('📊 Status: 200 OK (Video Stream Loaded)');
|
||||
console.log('📺 Duration:', data?.duration ? `${data.duration.toFixed(2)}s` : 'Unknown');
|
||||
console.log('📐 Resolution:', data?.naturalSize ? `${data.naturalSize.width}x${data.naturalSize.height}` : 'Unknown');
|
||||
console.log('🎵 Audio Tracks:', data?.audioTracks?.length || 0);
|
||||
console.log('📝 Text Tracks:', data?.textTracks?.length || 0);
|
||||
console.log('⏰ Response Time:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
logger.log('[AndroidVideoPlayer] Video loaded:', data);
|
||||
}
|
||||
|
|
@ -619,7 +631,7 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
NativeModules.StatusBarManager.setHidden(true);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Immersive mode error:', error);
|
||||
// Immersive mode error - silently handled
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -712,6 +724,16 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
|
||||
const handleError = (error: any) => {
|
||||
try {
|
||||
// Enhanced HTTP error response logging
|
||||
console.log('\n❌ [AndroidVideoPlayer] HTTP RESPONSE ERROR:');
|
||||
console.log('📍 URL:', currentStreamUrl);
|
||||
console.log('📊 Status:', error?.error?.code ? `${error.error.code} (${error.error.domain || 'Unknown Domain'})` : 'Unknown Error Code');
|
||||
console.log('💬 Error Message:', error?.error?.localizedDescription || error?.message || 'Unknown error');
|
||||
console.log('🔍 Error Type:', error?.error?.domain || 'Unknown');
|
||||
console.log('📋 Full Error Object:', JSON.stringify(error, null, 2));
|
||||
console.log('⏰ Error Time:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
logger.error('AndroidVideoPlayer error: ', error);
|
||||
|
||||
// Early return if component is unmounted to prevent iOS crashes
|
||||
|
|
@ -1046,6 +1068,24 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
}
|
||||
}, [pendingSeek, isPlayerReady, isVideoLoaded, duration]);
|
||||
|
||||
// HTTP stream testing with logging
|
||||
useEffect(() => {
|
||||
if (currentStreamUrl && currentStreamUrl.trim() !== '') {
|
||||
const testStream = async () => {
|
||||
try {
|
||||
console.log('\n🔍 [AndroidVideoPlayer] Testing video stream URL...');
|
||||
const isValid = await testVideoStreamUrl(currentStreamUrl, headers || {});
|
||||
console.log(`✅ [AndroidVideoPlayer] Stream test result: ${isValid ? 'VALID' : 'INVALID'}`);
|
||||
} catch (error) {
|
||||
console.log('❌ [AndroidVideoPlayer] Stream test failed:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Test the stream URL when it changes
|
||||
testStream();
|
||||
}
|
||||
}, [currentStreamUrl, headers]);
|
||||
|
||||
const handleSelectStream = async (newStream: any) => {
|
||||
if (newStream.url === currentStreamUrl) {
|
||||
setShowSourcesModal(false);
|
||||
|
|
@ -1247,7 +1287,16 @@ const AndroidVideoPlayer: React.FC = () => {
|
|||
headers: headers
|
||||
} : { uri: currentStreamUrl };
|
||||
|
||||
console.log('[AndroidVideoPlayer] FORCEFULLY using headers from route params:', headers);
|
||||
// Enhanced HTTP request logging
|
||||
console.log('\n🌐 [AndroidVideoPlayer] HTTP REQUEST DETAILS:');
|
||||
console.log('📍 URL:', currentStreamUrl);
|
||||
console.log('🔧 Method: GET (Video Stream)');
|
||||
console.log('📋 Headers:', headers ? JSON.stringify(headers, null, 2) : 'No headers');
|
||||
console.log('🎬 Stream Provider:', currentStreamProvider || 'Unknown');
|
||||
console.log('📺 Stream Name:', currentStreamName || 'Unknown');
|
||||
console.log('🎯 Quality:', currentQuality || 'Unknown');
|
||||
console.log('⏰ Timestamp:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
return sourceWithHeaders;
|
||||
})()}
|
||||
|
|
|
|||
|
|
@ -567,6 +567,7 @@ const VideoPlayer: React.FC = () => {
|
|||
|
||||
const onLoad = (data: any) => {
|
||||
try {
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
logger.log('[VideoPlayer] Video loaded:', data);
|
||||
}
|
||||
|
|
@ -796,6 +797,16 @@ const VideoPlayer: React.FC = () => {
|
|||
};
|
||||
|
||||
const handleError = (error: any) => {
|
||||
// Enhanced HTTP error response logging
|
||||
console.log('\n❌ [VideoPlayer] HTTP RESPONSE ERROR:');
|
||||
console.log('📍 URL:', currentStreamUrl);
|
||||
console.log('📊 Status:', error?.error?.code ? `${error.error.code} (${error.error.domain || 'Unknown Domain'})` : 'Unknown Error Code');
|
||||
console.log('💬 Error Message:', error?.error?.localizedDescription || error?.message || 'Unknown error');
|
||||
console.log('🔍 Error Type:', error?.error?.domain || 'Unknown');
|
||||
console.log('📋 Full Error Object:', JSON.stringify(error, null, 2));
|
||||
console.log('⏰ Error Time:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
logger.error('[VideoPlayer] Playback Error:', error);
|
||||
|
||||
// Format error details for user display
|
||||
|
|
@ -1270,7 +1281,16 @@ const VideoPlayer: React.FC = () => {
|
|||
headers: headers
|
||||
} : { uri: currentStreamUrl };
|
||||
|
||||
console.log('[VideoPlayer] FORCEFULLY using headers from route params:', headers);
|
||||
// Enhanced HTTP request logging
|
||||
console.log('\n🌐 [VideoPlayer] HTTP REQUEST DETAILS:');
|
||||
console.log('📍 URL:', currentStreamUrl);
|
||||
console.log('🔧 Method: GET (Video Stream)');
|
||||
console.log('📋 Headers:', headers ? JSON.stringify(headers, null, 2) : 'No headers');
|
||||
console.log('🎬 Stream Provider:', currentStreamProvider || streamProvider || 'Unknown');
|
||||
console.log('📺 Stream Name:', currentStreamName || streamName || 'Unknown');
|
||||
console.log('🎯 Quality:', currentQuality || quality || 'Unknown');
|
||||
console.log('⏰ Timestamp:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
return sourceWithHeaders;
|
||||
})()}
|
||||
|
|
|
|||
71
src/utils/httpInterceptor.ts
Normal file
71
src/utils/httpInterceptor.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import { logger } from './logger';
|
||||
|
||||
// Enhanced HTTP logging function specifically for AndroidVideoPlayer
|
||||
export const logHttpRequest = async (url: string, options: RequestInit = {}): Promise<Response> => {
|
||||
const method = options.method || 'GET';
|
||||
const headers = options.headers || {};
|
||||
|
||||
// Log HTTP request
|
||||
console.log('\n🌐 [AndroidVideoPlayer] HTTP REQUEST:');
|
||||
console.log('📍 URL:', url);
|
||||
console.log('🔧 Method:', method);
|
||||
console.log('📋 Headers:', JSON.stringify(headers, null, 2));
|
||||
console.log('⏰ Request Time:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// Make the actual request
|
||||
const response = await fetch(url, options);
|
||||
const endTime = Date.now();
|
||||
const duration = endTime - startTime;
|
||||
|
||||
// Log HTTP response success
|
||||
console.log('\n✅ [AndroidVideoPlayer] HTTP RESPONSE SUCCESS:');
|
||||
console.log('📍 URL:', url);
|
||||
console.log('📊 Status:', `${response.status} ${response.statusText}`);
|
||||
console.log('📋 Response Headers:', JSON.stringify(Object.fromEntries(response.headers.entries()), null, 2));
|
||||
console.log('⏱️ Duration:', `${duration}ms`);
|
||||
console.log('📦 Content-Type:', response.headers.get('content-type') || 'Unknown');
|
||||
console.log('📏 Content-Length:', response.headers.get('content-length') || 'Unknown');
|
||||
console.log('🔒 CORS:', response.headers.get('access-control-allow-origin') || 'Not specified');
|
||||
console.log('⏰ Response Time:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
return response;
|
||||
} catch (error: any) {
|
||||
const endTime = Date.now();
|
||||
const duration = endTime - startTime;
|
||||
|
||||
// Log HTTP response error
|
||||
console.log('\n❌ [AndroidVideoPlayer] HTTP RESPONSE ERROR:');
|
||||
console.log('📍 URL:', url);
|
||||
console.log('📊 Status: Network Error');
|
||||
console.log('💬 Error Message:', error.message || 'Unknown error');
|
||||
console.log('🔍 Error Type:', error.name || 'Unknown');
|
||||
console.log('⏱️ Duration:', `${duration}ms`);
|
||||
console.log('📋 Full Error:', JSON.stringify(error, null, 2));
|
||||
console.log('⏰ Error Time:', new Date().toISOString());
|
||||
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Test function to validate video stream URLs with HTTP logging
|
||||
export const testVideoStreamUrl = async (url: string, headers: Record<string, string> = {}): Promise<boolean> => {
|
||||
try {
|
||||
const response = await logHttpRequest(url, {
|
||||
method: 'HEAD',
|
||||
headers: {
|
||||
'Range': 'bytes=0-1',
|
||||
...headers
|
||||
}
|
||||
});
|
||||
|
||||
return response.ok || response.status === 206; // 206 for partial content
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
Loading…
Reference in a new issue