diff --git a/public/js/components/VideoPlayer.js b/public/js/components/VideoPlayer.js
index 2577428..94ffcca 100644
--- a/public/js/components/VideoPlayer.js
+++ b/public/js/components/VideoPlayer.js
@@ -313,31 +313,37 @@ class VideoPlayer {
this.isUsingProxy = needsProxy;
const finalUrl = needsProxy ? this.getProxiedUrl(streamUrl) : streamUrl;
- // Detect if this is likely an HLS stream (vs direct video file like MP4)
- // Note: .ts files are raw MPEG-TS, NOT HLS manifests - exclude them
- const looksLikeHls = finalUrl.includes('.m3u8') ||
- finalUrl.includes('m3u8') ||
- (!finalUrl.includes('.mp4') && !finalUrl.includes('.mkv') &&
- !finalUrl.includes('.avi') && !finalUrl.includes('.ts'));
+ // Detect if this is likely an HLS stream (has .m3u8 in URL)
+ const looksLikeHls = finalUrl.includes('.m3u8') || finalUrl.includes('m3u8');
- // Check for raw TS streams that browsers can't play directly
+ // Check if this looks like a raw stream (no HLS manifest, no common video extensions)
+ // This includes .ts files AND extension-less URLs that might be TS streams
const isRawTs = finalUrl.includes('.ts') && !finalUrl.includes('.m3u8');
- if (isRawTs) {
- // If Force Remux is enabled, route through remux endpoint
- if (this.settings.forceRemux) {
- console.log('[Player] Raw TS stream detected. Using remux to convert to MP4...');
- const remuxUrl = this.getRemuxUrl(streamUrl);
- this.video.src = remuxUrl;
- this.video.play().catch(e => console.log('[Player] Autoplay prevented:', e));
+ const isExtensionless = !finalUrl.includes('.m3u8') &&
+ !finalUrl.includes('.mp4') &&
+ !finalUrl.includes('.mkv') &&
+ !finalUrl.includes('.avi') &&
+ !finalUrl.includes('.ts');
- // Update UI and dispatch events
- this.updateNowPlaying(channel);
- this.showNowPlayingOverlay();
- this.fetchEpgData(channel);
- window.dispatchEvent(new CustomEvent('channelChanged', { detail: channel }));
- return;
- }
+ // Force Remux: Route through FFmpeg for container conversion
+ // Applies to: 1) .ts streams when detected, or 2) ALL non-HLS streams when enabled
+ if (this.settings.forceRemux && (isRawTs || isExtensionless)) {
+ console.log('[Player] Force Remux enabled. Routing through FFmpeg remux...');
+ console.log('[Player] Stream type:', isRawTs ? 'Raw TS' : 'Extension-less (assumed TS)');
+ const remuxUrl = this.getRemuxUrl(streamUrl);
+ this.video.src = remuxUrl;
+ this.video.play().catch(e => console.log('[Player] Autoplay prevented:', e));
+ // Update UI and dispatch events
+ this.updateNowPlaying(channel);
+ this.showNowPlayingOverlay();
+ this.fetchEpgData(channel);
+ window.dispatchEvent(new CustomEvent('channelChanged', { detail: channel }));
+ return;
+ }
+
+ // If raw TS detected without Force Remux enabled, show error
+ if (isRawTs && !this.settings.forceRemux) {
console.warn('[Player] Raw MPEG-TS stream detected. Browsers cannot play .ts files directly.');
this.showError(
'This stream uses raw MPEG-TS format (.ts) which browsers cannot play directly.
' +