mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-03-11 17:45:38 +00:00
cleaned VLC
This commit is contained in:
parent
18815b8233
commit
688ea2b9d3
6 changed files with 65 additions and 172 deletions
105
package-lock.json
generated
105
package-lock.json
generated
|
|
@ -72,7 +72,6 @@
|
|||
"react-native-svg": "15.8.0",
|
||||
"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"
|
||||
},
|
||||
|
|
@ -12738,15 +12737,6 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-slider": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-slider/-/react-native-slider-0.11.0.tgz",
|
||||
"integrity": "sha512-jV9K87eu9uWr0uJIyrSpBLnCKvVlOySC2wynq9TFCdV9oGgjt7Niq8Q1A8R8v+5GHsuBw/s8vEj1AAkkUi+u+w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.6"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-svg": {
|
||||
"version": "15.8.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.8.0.tgz",
|
||||
|
|
@ -12898,91 +12888,6 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vector-icons": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-9.2.0.tgz",
|
||||
"integrity": "sha512-wKYLaFuQST/chH3AJRjmOLoLy3JEs1JR6zMNgTaemFpNoXs0ztRnTxcxFD9xhX7cJe1/zoN5BpQYe7kL0m5yyA==",
|
||||
"deprecated": "react-native-vector-icons package has moved to a new model of per-icon-family packages. See the https://github.com/oblador/react-native-vector-icons/blob/master/MIGRATION.md on how to migrate",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2",
|
||||
"yargs": "^16.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"fa5-upgrade": "bin/fa5-upgrade.sh",
|
||||
"generate-icon": "bin/generate-icon.js"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vector-icons/node_modules/cliui": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
|
||||
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vector-icons/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-native-vector-icons/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vector-icons/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vector-icons/node_modules/yargs": {
|
||||
"version": "16.2.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
|
||||
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^7.0.2",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vector-icons/node_modules/yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-video": {
|
||||
"version": "6.16.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-video/-/react-native-video-6.16.1.tgz",
|
||||
|
|
@ -12993,16 +12898,6 @@
|
|||
"react-native": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-vlc-media-player": {
|
||||
"version": "1.0.94",
|
||||
"resolved": "https://registry.npmjs.org/react-native-vlc-media-player/-/react-native-vlc-media-player-1.0.94.tgz",
|
||||
"integrity": "sha512-6Ee09NY3ir4UN7mSFv8N+4GBiUQzAyVWU54ilwBAOZO8ICU2aJJmOq9ptYxvswIiRcbSz8Z+aB7LnjIlMR6WoQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"react-native-slider": "^0.11.0",
|
||||
"react-native-vector-icons": "^9.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-web": {
|
||||
"version": "0.19.13",
|
||||
"resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.13.tgz",
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@
|
|||
"react-native-svg": "15.8.0",
|
||||
"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"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import * as Brightness from 'expo-brightness';
|
|||
const VideoPlayer: React.FC = () => {
|
||||
const insets = useSafeAreaInsets();
|
||||
const route = useRoute<RouteProp<RootStackParamList, 'Player'>>();
|
||||
const { uri, headers, forceVlc, streamProvider } = route.params as any;
|
||||
const { uri, headers, streamProvider } = route.params as any;
|
||||
|
||||
// Detect if stream is MKV format
|
||||
const isMkvFile = isMkvStream(uri, headers);
|
||||
|
|
@ -150,8 +150,8 @@ const VideoPlayer: React.FC = () => {
|
|||
const [isBackdropLoaded, setIsBackdropLoaded] = useState(false);
|
||||
const backdropImageOpacityAnim = useRef(new Animated.Value(0)).current;
|
||||
const [isBuffering, setIsBuffering] = useState(false);
|
||||
const [vlcAudioTracks, setVlcAudioTracks] = useState<Array<{ id: number, name: string, language?: string }>>([]);
|
||||
const [vlcTextTracks, setVlcTextTracks] = useState<Array<{ id: number, name: string, language?: string }>>([]);
|
||||
const [ksAudioTracks, setKsAudioTracks] = useState<Array<{ id: number, name: string, language?: string }>>([]);
|
||||
const [ksTextTracks, setKsTextTracks] = useState<Array<{ id: number, name: string, language?: string }>>([]);
|
||||
const [isPlayerReady, setIsPlayerReady] = useState(false);
|
||||
// Removed progressAnim and progressBarRef - no longer needed with React Native Community Slider
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
|
|
@ -193,10 +193,10 @@ const VideoPlayer: React.FC = () => {
|
|||
const [isLoadingSubtitleList, setIsLoadingSubtitleList] = useState<boolean>(false);
|
||||
const [showSourcesModal, setShowSourcesModal] = useState<boolean>(false);
|
||||
const [availableStreams, setAvailableStreams] = useState<{ [providerId: string]: { streams: any[]; addonName: string } }>(passedAvailableStreams || {});
|
||||
// Decode URLs for VLC compatibility - VLC has issues with encoded URLs
|
||||
const decodeUrlForVlc = (url: string): string => {
|
||||
// Decode URLs for KSPlayer compatibility - KSPlayer handles encoded URLs better
|
||||
const decodeUrlForKsPlayer = (url: string): string => {
|
||||
try {
|
||||
// Always decode URLs for VLC as it has trouble with encoded characters
|
||||
// KSPlayer handles encoded URLs well, but decode for consistency
|
||||
const decoded = decodeURIComponent(url);
|
||||
return decoded;
|
||||
} catch (e) {
|
||||
|
|
@ -205,7 +205,7 @@ const VideoPlayer: React.FC = () => {
|
|||
}
|
||||
};
|
||||
|
||||
const [currentStreamUrl, setCurrentStreamUrl] = useState<string>(decodeUrlForVlc(uri));
|
||||
const [currentStreamUrl, setCurrentStreamUrl] = useState<string>(decodeUrlForKsPlayer(uri));
|
||||
const [isChangingSource, setIsChangingSource] = useState<boolean>(false);
|
||||
const [showErrorModal, setShowErrorModal] = useState(false);
|
||||
const [errorDetails, setErrorDetails] = useState<string>('');
|
||||
|
|
@ -244,20 +244,20 @@ const VideoPlayer: React.FC = () => {
|
|||
const castDetailsScale = useRef(new Animated.Value(0.95)).current;
|
||||
|
||||
// Volume and brightness controls
|
||||
const [volume, setVolume] = useState(100); // VLC uses 0-100 range
|
||||
const [volume, setVolume] = useState(100); // KSPlayer uses 0-100 range
|
||||
const [brightness, setBrightness] = useState(1.0);
|
||||
const [showVolumeOverlay, setShowVolumeOverlay] = useState(false);
|
||||
const [showBrightnessOverlay, setShowBrightnessOverlay] = useState(false);
|
||||
const [showVlcVolumeWarning, setShowVlcVolumeWarning] = useState(false);
|
||||
const [hasShownVlcWarning, setHasShownVlcWarning] = useState(false);
|
||||
const [showKsVolumeWarning, setShowKsVolumeWarning] = useState(false);
|
||||
const [hasShownKsWarning, setHasShownKsWarning] = useState(false);
|
||||
|
||||
// Load VLC warning state from storage
|
||||
// Load KSPlayer warning state from storage
|
||||
useEffect(() => {
|
||||
const loadWarningState = async () => {
|
||||
try {
|
||||
const warningShown = await AsyncStorage.getItem('vlc_volume_warning_shown');
|
||||
const warningShown = await AsyncStorage.getItem('ks_volume_warning_shown');
|
||||
if (warningShown === 'true') {
|
||||
setHasShownVlcWarning(true);
|
||||
setHasShownKsWarning(true);
|
||||
}
|
||||
} catch (error) {
|
||||
// Ignore storage errors
|
||||
|
|
@ -428,17 +428,17 @@ const VideoPlayer: React.FC = () => {
|
|||
const { translationY, state } = event.nativeEvent;
|
||||
|
||||
if (state === State.ACTIVE) {
|
||||
// Show VLC volume warning only once per session
|
||||
if (!showVlcVolumeWarning && !hasShownVlcWarning) {
|
||||
setShowVlcVolumeWarning(true);
|
||||
setHasShownVlcWarning(true);
|
||||
// Show KSPlayer volume warning only once per session
|
||||
if (!showKsVolumeWarning && !hasShownKsWarning) {
|
||||
setShowKsVolumeWarning(true);
|
||||
setHasShownKsWarning(true);
|
||||
|
||||
// Save to storage that warning has been shown
|
||||
AsyncStorage.setItem('vlc_volume_warning_shown', 'true').catch(() => {});
|
||||
AsyncStorage.setItem('ks_volume_warning_shown', 'true').catch(() => {});
|
||||
|
||||
// Hide warning after 4 seconds
|
||||
setTimeout(() => {
|
||||
setShowVlcVolumeWarning(false);
|
||||
setShowKsVolumeWarning(false);
|
||||
}, 4000);
|
||||
}
|
||||
}
|
||||
|
|
@ -552,10 +552,10 @@ const VideoPlayer: React.FC = () => {
|
|||
startOpeningAnimation();
|
||||
|
||||
// Initialize current volume and brightness levels
|
||||
// Volume starts at 100 (full volume) for VLC
|
||||
// Volume starts at 100 (full volume) for KSPlayer
|
||||
setVolume(100);
|
||||
if (DEBUG_MODE) {
|
||||
logger.log(`[VideoPlayer] Initial volume: 100 (VLC native)`);
|
||||
logger.log(`[VideoPlayer] Initial volume: 100 (KSPlayer native)`);
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -901,11 +901,11 @@ const VideoPlayer: React.FC = () => {
|
|||
setLastAudioTrackCheck(now);
|
||||
|
||||
// Check if audio track is disabled (-1) and we have available tracks
|
||||
if (selectedAudioTrack === -1 && vlcAudioTracks.length > 1) {
|
||||
if (selectedAudioTrack === -1 && ksAudioTracks.length > 1) {
|
||||
logger.warn('[VideoPlayer] Detected disabled audio track, attempting fallback');
|
||||
|
||||
// Find a fallback audio track (prefer stereo/standard formats)
|
||||
const fallbackTrack = vlcAudioTracks.find((track, index) => {
|
||||
const fallbackTrack = ksAudioTracks.find((track, index) => {
|
||||
const trackName = (track.name || '').toLowerCase();
|
||||
const trackLang = (track.language || '').toLowerCase();
|
||||
// Prefer stereo, AAC, or standard audio formats, avoid heavy codecs
|
||||
|
|
@ -919,7 +919,7 @@ const VideoPlayer: React.FC = () => {
|
|||
});
|
||||
|
||||
if (fallbackTrack) {
|
||||
const fallbackIndex = vlcAudioTracks.indexOf(fallbackTrack);
|
||||
const fallbackIndex = ksAudioTracks.indexOf(fallbackTrack);
|
||||
logger.warn(`[VideoPlayer] Switching to fallback audio track: ${fallbackTrack.name || 'Unknown'} (index: ${fallbackIndex})`);
|
||||
|
||||
// Increment fallback attempts counter
|
||||
|
|
@ -1073,7 +1073,7 @@ const VideoPlayer: React.FC = () => {
|
|||
language: trackLanguage,
|
||||
};
|
||||
});
|
||||
setVlcAudioTracks(formattedAudioTracks);
|
||||
setKsAudioTracks(formattedAudioTracks);
|
||||
|
||||
// Auto-select English audio track if available, otherwise first track
|
||||
if (selectedAudioTrack === null && formattedAudioTracks.length > 0) {
|
||||
|
|
@ -1110,7 +1110,7 @@ const VideoPlayer: React.FC = () => {
|
|||
isImageSubtitle: track.isImageSubtitle || false
|
||||
}));
|
||||
|
||||
setVlcTextTracks(formattedTextTracks);
|
||||
setKsTextTracks(formattedTextTracks);
|
||||
|
||||
// Auto-select English subtitle track if available
|
||||
if (selectedTextTrack === -1 && !useCustomSubtitles && formattedTextTracks.length > 0) {
|
||||
|
|
@ -1351,11 +1351,11 @@ const VideoPlayer: React.FC = () => {
|
|||
(error?.title && /codec not supported/i.test(error.title));
|
||||
|
||||
// Handle audio codec errors with automatic fallback
|
||||
if (isAudioCodecError && vlcAudioTracks.length > 1) {
|
||||
if (isAudioCodecError && ksAudioTracks.length > 1) {
|
||||
logger.warn('[VideoPlayer] Audio codec error detected, attempting audio track fallback');
|
||||
|
||||
// Find a fallback audio track (prefer stereo/standard formats)
|
||||
const fallbackTrack = vlcAudioTracks.find((track, index) => {
|
||||
const fallbackTrack = ksAudioTracks.find((track, index) => {
|
||||
const trackName = (track.name || '').toLowerCase();
|
||||
const trackLang = (track.language || '').toLowerCase();
|
||||
// Prefer stereo, AAC, or standard audio formats, avoid heavy codecs
|
||||
|
|
@ -1369,7 +1369,7 @@ const VideoPlayer: React.FC = () => {
|
|||
});
|
||||
|
||||
if (fallbackTrack) {
|
||||
const fallbackIndex = vlcAudioTracks.indexOf(fallbackTrack);
|
||||
const fallbackIndex = ksAudioTracks.indexOf(fallbackTrack);
|
||||
logger.warn(`[VideoPlayer] Switching to fallback audio track: ${fallbackTrack.name || 'Unknown'} (index: ${fallbackIndex})`);
|
||||
|
||||
// Clear any existing error state
|
||||
|
|
@ -1478,18 +1478,18 @@ const VideoPlayer: React.FC = () => {
|
|||
const selectAudioTrack = (trackId: number) => {
|
||||
if (DEBUG_MODE) {
|
||||
logger.log(`[VideoPlayer] Selecting audio track: ${trackId}`);
|
||||
logger.log(`[VideoPlayer] Available tracks:`, vlcAudioTracks);
|
||||
logger.log(`[VideoPlayer] Available tracks:`, ksAudioTracks);
|
||||
}
|
||||
|
||||
// Validate that the track exists
|
||||
const trackExists = vlcAudioTracks.some(track => track.id === trackId);
|
||||
const trackExists = ksAudioTracks.some(track => track.id === trackId);
|
||||
if (!trackExists) {
|
||||
logger.error(`[VideoPlayer] Audio track ${trackId} not found in available tracks`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the selected track info for logging
|
||||
const selectedTrack = vlcAudioTracks.find(track => track.id === trackId);
|
||||
const selectedTrack = ksAudioTracks.find(track => track.id === trackId);
|
||||
if (selectedTrack && DEBUG_MODE) {
|
||||
logger.log(`[VideoPlayer] Switching to track: ${selectedTrack.name} (${selectedTrack.language})`);
|
||||
|
||||
|
|
@ -1541,12 +1541,12 @@ const VideoPlayer: React.FC = () => {
|
|||
}
|
||||
};
|
||||
|
||||
// Ensure native VLC text tracks are disabled when using custom (addon) subtitles
|
||||
// Ensure native KSPlayer text tracks are disabled when using custom (addon) subtitles
|
||||
// and re-applied when switching back to built-in tracks. This prevents double-rendering.
|
||||
useEffect(() => {
|
||||
try {
|
||||
if (useCustomSubtitles) {
|
||||
// -1 disables native subtitle rendering in VLC
|
||||
// -1 disables native subtitle rendering in KSPlayer
|
||||
setSelectedTextTrack(-1);
|
||||
} else if (typeof selectedTextTrack === 'number' && selectedTextTrack >= 0) {
|
||||
// KSPlayer picks it up via prop
|
||||
|
|
@ -1692,7 +1692,7 @@ const VideoPlayer: React.FC = () => {
|
|||
const parsedCues = parseSRT(srtContent);
|
||||
logger.log(`[VideoPlayer] Parsed cues count=${parsedCues.length}`);
|
||||
|
||||
// For VLC on iOS: stop spinner early, then clear-apply and micro-seek nudge
|
||||
// For KSPlayer on iOS: stop spinner early, then clear-apply and micro-seek nudge
|
||||
setIsLoadingSubtitles(false);
|
||||
logger.log('[VideoPlayer] isLoadingSubtitles -> false (early)');
|
||||
|
||||
|
|
@ -1825,7 +1825,6 @@ const VideoPlayer: React.FC = () => {
|
|||
streamProvider: addonName,
|
||||
streamName: bestStream.name || bestStream.title,
|
||||
headers: bestStream.headers || undefined,
|
||||
forceVlc: false,
|
||||
id,
|
||||
type: 'series',
|
||||
episodeId: nextEpisodeId,
|
||||
|
|
@ -2121,8 +2120,8 @@ const VideoPlayer: React.FC = () => {
|
|||
|
||||
// Handle audio track changes with proper logging
|
||||
useEffect(() => {
|
||||
if (selectedAudioTrack !== null && vlcAudioTracks.length > 0) {
|
||||
const selectedTrack = vlcAudioTracks.find(track => track.id === selectedAudioTrack);
|
||||
if (selectedAudioTrack !== null && ksAudioTracks.length > 0) {
|
||||
const selectedTrack = ksAudioTracks.find(track => track.id === selectedAudioTrack);
|
||||
if (selectedTrack) {
|
||||
if (DEBUG_MODE) {
|
||||
logger.log(`[VideoPlayer] Audio track selected: ${selectedTrack.name} (${selectedTrack.language}) - ID: ${selectedAudioTrack}`);
|
||||
|
|
@ -2131,7 +2130,7 @@ const VideoPlayer: React.FC = () => {
|
|||
logger.warn(`[VideoPlayer] Selected audio track ${selectedAudioTrack} not found in available tracks`);
|
||||
}
|
||||
}
|
||||
}, [selectedAudioTrack, vlcAudioTracks]);
|
||||
}, [selectedAudioTrack, ksAudioTracks]);
|
||||
|
||||
const increaseSubtitleSize = () => {
|
||||
const newSize = Math.min(subtitleSize + 2, 32);
|
||||
|
|
@ -2231,8 +2230,8 @@ const VideoPlayer: React.FC = () => {
|
|||
// Set pending seek state
|
||||
setPendingSeek({ position: savedPosition, shouldPlay: wasPlaying });
|
||||
|
||||
// Update the stream URL and details immediately (decode URL for VLC)
|
||||
setCurrentStreamUrl(decodeUrlForVlc(newStream.url));
|
||||
// Update the stream URL and details immediately (decode URL for KSPlayer)
|
||||
setCurrentStreamUrl(decodeUrlForKsPlayer(newStream.url));
|
||||
setCurrentQuality(newQuality);
|
||||
setCurrentStreamProvider(newProvider);
|
||||
setCurrentStreamName(newStreamName);
|
||||
|
|
@ -2559,7 +2558,7 @@ const VideoPlayer: React.FC = () => {
|
|||
currentTime={currentTime}
|
||||
duration={duration}
|
||||
zoomScale={zoomScale}
|
||||
vlcAudioTracks={vlcAudioTracks}
|
||||
ksAudioTracks={ksAudioTracks}
|
||||
selectedAudioTrack={selectedAudioTrack}
|
||||
availableStreams={availableStreams}
|
||||
togglePlayback={togglePlayback}
|
||||
|
|
@ -3148,8 +3147,8 @@ const VideoPlayer: React.FC = () => {
|
|||
</Animated.View>
|
||||
)}
|
||||
|
||||
{/* VLC Volume Warning Overlay */}
|
||||
{showVlcVolumeWarning && (
|
||||
{/* KSPlayer Volume Warning Overlay */}
|
||||
{showKsVolumeWarning && (
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
|
|
@ -3201,7 +3200,7 @@ const VideoPlayer: React.FC = () => {
|
|||
lineHeight: 18,
|
||||
marginBottom: 12,
|
||||
}}>
|
||||
VLC player doesn't support volume gestures.{'\n'}Use your device volume buttons instead.
|
||||
KSPlayer doesn't support volume gestures.{'\n'}Use your device volume buttons instead.
|
||||
</Text>
|
||||
|
||||
<Text style={{
|
||||
|
|
@ -3223,7 +3222,7 @@ const VideoPlayer: React.FC = () => {
|
|||
<AudioTrackModal
|
||||
showAudioModal={showAudioModal}
|
||||
setShowAudioModal={setShowAudioModal}
|
||||
vlcAudioTracks={vlcAudioTracks}
|
||||
ksAudioTracks={ksAudioTracks}
|
||||
selectedAudioTrack={selectedAudioTrack}
|
||||
selectAudioTrack={selectAudioTrack}
|
||||
/>
|
||||
|
|
@ -3236,7 +3235,7 @@ const VideoPlayer: React.FC = () => {
|
|||
isLoadingSubtitles={isLoadingSubtitles}
|
||||
customSubtitles={customSubtitles}
|
||||
availableSubtitles={availableSubtitles}
|
||||
vlcTextTracks={vlcTextTracks}
|
||||
ksTextTracks={ksTextTracks}
|
||||
selectedTextTrack={selectedTextTrack}
|
||||
useCustomSubtitles={useCustomSubtitles}
|
||||
subtitleSize={subtitleSize}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ interface PlayerControlsProps {
|
|||
duration: number;
|
||||
zoomScale: number;
|
||||
currentResizeMode?: string;
|
||||
vlcAudioTracks: Array<{id: number, name: string, language?: string}>;
|
||||
ksAudioTracks: Array<{id: number, name: string, language?: string}>;
|
||||
selectedAudioTrack: number | null;
|
||||
availableStreams?: { [providerId: string]: { streams: any[]; addonName: string } };
|
||||
togglePlayback: () => void;
|
||||
|
|
@ -58,7 +58,7 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
duration,
|
||||
zoomScale,
|
||||
currentResizeMode,
|
||||
vlcAudioTracks,
|
||||
ksAudioTracks,
|
||||
selectedAudioTrack,
|
||||
availableStreams,
|
||||
togglePlayback,
|
||||
|
|
@ -170,17 +170,17 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({
|
|||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* Audio Button - Updated to use vlcAudioTracks */}
|
||||
{/* Audio Button - Updated to use ksAudioTracks */}
|
||||
<TouchableOpacity
|
||||
style={styles.bottomButton}
|
||||
onPress={() => setShowAudioModal(true)}
|
||||
disabled={vlcAudioTracks.length <= 1}
|
||||
disabled={ksAudioTracks.length <= 1}
|
||||
>
|
||||
<Ionicons name="volume-high" size={20} color={vlcAudioTracks.length <= 1 ? 'grey' : 'white'} />
|
||||
<Text style={[styles.bottomButtonText, vlcAudioTracks.length <= 1 && {color: 'grey'}]} numberOfLines={1}>
|
||||
<Ionicons name="volume-high" size={20} color={ksAudioTracks.length <= 1 ? 'grey' : 'white'} />
|
||||
<Text style={[styles.bottomButtonText, ksAudioTracks.length <= 1 && {color: 'grey'}]} numberOfLines={1}>
|
||||
{(() => {
|
||||
const trackName = getTrackDisplayName(
|
||||
vlcAudioTracks.find(t => t.id === selectedAudioTrack) || { id: -1, name: 'Default' }
|
||||
ksAudioTracks.find(t => t.id === selectedAudioTrack) || { id: -1, name: 'Default' }
|
||||
);
|
||||
// Truncate long audio track names to prevent UI cramping
|
||||
const maxLength = 12; // Limit to 12 characters
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { logger } from '../../../utils/logger';
|
|||
interface AudioTrackModalProps {
|
||||
showAudioModal: boolean;
|
||||
setShowAudioModal: (show: boolean) => void;
|
||||
vlcAudioTracks: Array<{id: number, name: string, language?: string}>;
|
||||
ksAudioTracks: Array<{id: number, name: string, language?: string}>;
|
||||
selectedAudioTrack: number | null;
|
||||
selectAudioTrack: (trackId: number) => void;
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ const MENU_WIDTH = Math.min(width * 0.85, 400);
|
|||
export const AudioTrackModal: React.FC<AudioTrackModalProps> = ({
|
||||
showAudioModal,
|
||||
setShowAudioModal,
|
||||
vlcAudioTracks,
|
||||
ksAudioTracks,
|
||||
selectedAudioTrack,
|
||||
selectAudioTrack,
|
||||
}) => {
|
||||
|
|
@ -36,9 +36,9 @@ export const AudioTrackModal: React.FC<AudioTrackModalProps> = ({
|
|||
React.useEffect(() => {
|
||||
if (showAudioModal && DEBUG_MODE) {
|
||||
logger.log(`[AudioTrackModal] Modal opened with selectedAudioTrack:`, selectedAudioTrack);
|
||||
logger.log(`[AudioTrackModal] Available tracks:`, vlcAudioTracks);
|
||||
logger.log(`[AudioTrackModal] Available tracks:`, ksAudioTracks);
|
||||
if (typeof selectedAudioTrack === 'number') {
|
||||
const selectedTrack = vlcAudioTracks.find(track => track.id === selectedAudioTrack);
|
||||
const selectedTrack = ksAudioTracks.find(track => track.id === selectedAudioTrack);
|
||||
if (selectedTrack) {
|
||||
logger.log(`[AudioTrackModal] Selected track found: ${selectedTrack.name} (${selectedTrack.language})`);
|
||||
} else {
|
||||
|
|
@ -46,7 +46,7 @@ export const AudioTrackModal: React.FC<AudioTrackModalProps> = ({
|
|||
}
|
||||
}
|
||||
}
|
||||
}, [showAudioModal, selectedAudioTrack, vlcAudioTracks]);
|
||||
}, [showAudioModal, selectedAudioTrack, ksAudioTracks]);
|
||||
|
||||
if (!showAudioModal) return null;
|
||||
|
||||
|
|
@ -143,11 +143,11 @@ export const AudioTrackModal: React.FC<AudioTrackModalProps> = ({
|
|||
textTransform: 'uppercase',
|
||||
letterSpacing: 0.5,
|
||||
}}>
|
||||
Available Tracks ({vlcAudioTracks.length})
|
||||
Available Tracks ({ksAudioTracks.length})
|
||||
</Text>
|
||||
|
||||
<View style={{ gap: 8 }}>
|
||||
{vlcAudioTracks.map((track) => {
|
||||
{ksAudioTracks.map((track) => {
|
||||
// Determine if track is selected
|
||||
const isSelected = selectedAudioTrack === track.id;
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ export const AudioTrackModal: React.FC<AudioTrackModalProps> = ({
|
|||
})}
|
||||
</View>
|
||||
|
||||
{vlcAudioTracks.length === 0 && (
|
||||
{ksAudioTracks.length === 0 && (
|
||||
<View style={{
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.05)',
|
||||
borderRadius: 16,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ interface SubtitleModalsProps {
|
|||
isLoadingSubtitles: boolean;
|
||||
customSubtitles: SubtitleCue[];
|
||||
availableSubtitles: WyzieSubtitle[];
|
||||
vlcTextTracks: Array<{id: number, name: string, language?: string}>;
|
||||
ksTextTracks: Array<{id: number, name: string, language?: string}>;
|
||||
selectedTextTrack: number;
|
||||
useCustomSubtitles: boolean;
|
||||
subtitleSize: number;
|
||||
|
|
@ -68,7 +68,7 @@ export const SubtitleModals: React.FC<SubtitleModalsProps> = ({
|
|||
isLoadingSubtitles,
|
||||
customSubtitles,
|
||||
availableSubtitles,
|
||||
vlcTextTracks,
|
||||
ksTextTracks,
|
||||
selectedTextTrack,
|
||||
useCustomSubtitles,
|
||||
subtitleSize,
|
||||
|
|
@ -286,10 +286,10 @@ export const SubtitleModals: React.FC<SubtitleModalsProps> = ({
|
|||
</Text>
|
||||
|
||||
<View style={{ gap: 8 }}>
|
||||
{vlcTextTracks.map((track) => {
|
||||
{ksTextTracks.map((track) => {
|
||||
const isSelected = selectedTextTrack === track.id && !useCustomSubtitles;
|
||||
// Debug logging for subtitle selection
|
||||
if (__DEV__ && vlcTextTracks.length > 0) {
|
||||
if (__DEV__ && ksTextTracks.length > 0) {
|
||||
console.log('[SubtitleModals] Track:', track.id, track.name, 'Selected:', selectedTextTrack, 'isSelected:', isSelected, 'useCustom:', useCustomSubtitles);
|
||||
}
|
||||
return (
|
||||
|
|
|
|||
Loading…
Reference in a new issue