This commit is contained in:
tapframe 2025-07-30 00:09:25 +05:30
parent 9431f659d7
commit 93ddb029a0
6 changed files with 352 additions and 1568 deletions

@ -1 +1 @@
Subproject commit b9c6477161cd16f8c3b2c040252186adb73074f3
Subproject commit ea7009824e2a9e272520113d63b2d09d6cf8a0e8

1790
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,6 @@
"@expo/metro-runtime": "~4.0.1",
"@expo/vector-icons": "^14.1.0",
"@gorhom/bottom-sheet": "^5.1.2",
"@movie-web/providers": "^2.4.13",
"@react-native-async-storage/async-storage": "1.23.1",
"@react-native-community/blur": "^4.4.1",
"@react-native-community/slider": "^4.5.6",
@ -23,14 +22,12 @@
"@react-navigation/native-stack": "^7.3.10",
"@react-navigation/stack": "^7.2.10",
"@sentry/react-native": "^6.15.1",
"@shopify/flash-list": "1.7.3",
"@shopify/react-native-skia": "^1.12.4",
"@types/lodash": "^4.17.16",
"@types/react-native-video": "^5.0.20",
"axios": "^1.10.0",
"base64-js": "^1.5.1",
"axios-cookiejar-support": "^6.0.4",
"cheerio": "^1.1.2",
"cheerio-without-node-native": "^0.20.2",
"cors": "^2.8.5",
"date-fns": "^4.1.0",
"eventemitter3": "^5.0.1",
"expo": "~52.0.43",
@ -48,31 +45,20 @@
"expo-status-bar": "~2.0.1",
"expo-system-ui": "^4.0.9",
"expo-web-browser": "~14.0.2",
"express": "^5.1.0",
"lodash": "^4.17.21",
"node-fetch": "^2.6.7",
"puppeteer": "^24.10.1",
"node-fetch": "^3.3.2",
"react": "18.3.1",
"react-native": "0.76.9",
"react-native-awesome-slider": "^2.9.0",
"react-native-draggable-flatlist": "^4.0.2",
"react-native-gesture-handler": "~2.20.2",
"react-native-immersive-mode": "^2.0.2",
"react-native-modal": "^14.0.0-rc.1",
"react-native-orientation-locker": "^1.7.0",
"react-native-paper": "^5.13.1",
"react-native-reanimated": "^3.18.0",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "~4.4.0",
"react-native-svg": "^15.11.2",
"react-native-tab-view": "^4.0.10",
"react-native-url-polyfill": "^2.0.0",
"react-native-video": "^6.12.0",
"react-native-vlc-media-player": "^1.0.87",
"react-native-web": "~0.19.13",
"react-native-wheel-color-picker": "^1.3.1",
"react-navigation-shared-element": "^3.1.3",
"subsrt": "^1.1.1"
"react-native-wheel-color-picker": "^1.3.1"
},
"devDependencies": {
"@babel/core": "^7.25.2",

View file

@ -1128,7 +1128,43 @@ const AndroidVideoPlayer: React.FC = () => {
<Video
ref={videoRef}
style={[styles.video, customVideoStyles, { transform: [{ scale: zoomScale }] }]}
source={{ uri: currentStreamUrl }}
source={(() => {
// Add specific headers for Xprime streams
const isXprimeStream = currentStreamProvider === 'xprime' ||
currentStreamProvider === 'Xprime' ||
currentStreamUrl?.includes('xprime.tv');
// Debug logging for Xprime detection
console.log('[AndroidVideoPlayer] Xprime Detection Debug:');
console.log(' currentStreamProvider:', currentStreamProvider);
console.log(' currentStreamUrl:', currentStreamUrl);
console.log(' isXprimeStream:', isXprimeStream);
console.log(' URL includes xprime.tv:', currentStreamUrl?.includes('xprime.tv'));
const sourceWithHeaders = isXprimeStream ? {
uri: currentStreamUrl,
headers: {
'User-Agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36',
'Accept': 'video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'identity',
'Origin': 'https://xprime.tv',
'Referer': 'https://xprime.tv/',
'Sec-Fetch-Dest': 'video',
'Sec-Fetch-Mode': 'no-cors',
'Sec-Fetch-Site': 'cross-site',
'DNT': '1'
}
} : { uri: currentStreamUrl };
if (isXprimeStream) {
console.log('[AndroidVideoPlayer] Applying Xprime headers:', sourceWithHeaders.headers);
} else {
console.log('[AndroidVideoPlayer] No special headers applied');
}
return sourceWithHeaders;
})()}
paused={paused}
onProgress={handleProgress}
onLoad={onLoad}

View file

@ -39,23 +39,32 @@ import CustomSubtitles from './subtitles/CustomSubtitles';
import { SourcesModal } from './modals/SourcesModal';
const VideoPlayer: React.FC = () => {
// If on Android, use the AndroidVideoPlayer component
if (Platform.OS === 'android') {
const route = useRoute<RouteProp<RootStackParamList, 'Player'>>();
const { streamProvider, uri } = route.params;
// Check if the stream is from Xprime
const isXprimeStream = streamProvider === 'xprime' || streamProvider === 'Xprime';
// Check if the file format is MKV
const isMkvFile = uri && (uri.toLowerCase().includes('.mkv') || uri.toLowerCase().includes('mkv'));
// Use AndroidVideoPlayer for:
// - Android devices
// - Xprime streams on any platform
// - Non-MKV files on iOS
if (Platform.OS === 'android' || isXprimeStream || (Platform.OS === 'ios' && !isMkvFile)) {
return <AndroidVideoPlayer />;
}
const navigation = useNavigation<RootStackNavigationProp>();
const route = useRoute<RouteProp<RootStackParamList, 'Player'>>();
const {
uri,
title = 'Episode Name',
season,
episode,
episodeTitle,
quality,
year,
streamProvider,
streamName,
id,
type,
@ -1210,7 +1219,43 @@ const VideoPlayer: React.FC = () => {
<VLCPlayer
ref={vlcRef}
style={[styles.video, customVideoStyles, { transform: [{ scale: zoomScale }] }]}
source={{ uri: currentStreamUrl }}
source={(() => {
// Add specific headers for Xprime streams
const isXprimeStream = currentStreamProvider === 'xprime' ||
currentStreamProvider === 'Xprime' ||
currentStreamUrl?.includes('xprime.tv');
// Debug logging for Xprime detection
console.log('[VideoPlayer] Xprime Detection Debug:');
console.log(' currentStreamProvider:', currentStreamProvider);
console.log(' currentStreamUrl:', currentStreamUrl);
console.log(' isXprimeStream:', isXprimeStream);
console.log(' URL includes xprime.tv:', currentStreamUrl?.includes('xprime.tv'));
const sourceWithHeaders = isXprimeStream ? {
uri: currentStreamUrl,
headers: {
'User-Agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36',
'Accept': 'video/webm,video/ogg,video/*;q=0.9,application/ogg;q=0.7,audio/*;q=0.6,*/*;q=0.5',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'identity',
'Origin': 'https://xprime.tv',
'Referer': 'https://xprime.tv/',
'Sec-Fetch-Dest': 'video',
'Sec-Fetch-Mode': 'no-cors',
'Sec-Fetch-Site': 'cross-site',
'DNT': '1'
}
} : { uri: currentStreamUrl };
if (isXprimeStream) {
console.log('[VideoPlayer] Applying Xprime headers:', sourceWithHeaders.headers);
} else {
console.log('[VideoPlayer] No special headers applied');
}
return sourceWithHeaders;
})()}
paused={paused}
onProgress={handleProgress}
onLoad={onLoad}

View file

@ -650,6 +650,15 @@ export const StreamsScreen = () => {
// Determine the stream name using the same logic as StreamCard
const streamName = stream.name || stream.title || 'Unnamed Stream';
const streamProvider = stream.addonId || stream.addonName || stream.name;
// Debug logging for stream provider identification
console.log('[StreamsScreen] Stream Provider Debug:');
console.log(' stream.addonId:', stream.addonId);
console.log(' stream.addonName:', stream.addonName);
console.log(' stream.name:', stream.name);
console.log(' final streamProvider:', streamProvider);
console.log(' stream.url:', stream.url);
// Navigate to player immediately without waiting for orientation lock
// This prevents delay in player opening
@ -661,7 +670,7 @@ export const StreamsScreen = () => {
episode: type === 'series' ? currentEpisode?.episode_number : undefined,
quality: stream.title?.match(/(\d+)p/)?.[1] || undefined,
year: metadata?.year,
streamProvider: stream.name,
streamProvider: streamProvider,
streamName: streamName,
id,
type,