feat: Add FFmpeg audio transcoding for Dolby/AC3/EAC3 compatibility
- Add /api/transcode endpoint for audio-only transcoding - Video passthrough (no re-encoding) for fast performance - Audio transcode to AAC for browser compatibility - Add 'Force Audio Transcode' setting toggle in UI - Add ffmpeg-static as optional dependency - Handle Electron asar.unpacked path for packaged apps
This commit is contained in:
@@ -343,6 +343,17 @@
|
||||
directly.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<label class="setting-toggle">
|
||||
<input type="checkbox" id="setting-force-transcode">
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
<div class="setting-info">
|
||||
<span class="setting-label">Force Audio Transcode</span>
|
||||
<span class="setting-hint">Transcode audio to AAC for browser compatibility. Enable if you get video
|
||||
but no audio (fixes Dolby/AC3/EAC3). Requires ffmpeg-static.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="setting-info" style="flex: 1;">
|
||||
<span class="setting-label">Stream Output Format</span>
|
||||
|
||||
@@ -33,7 +33,8 @@ class VideoPlayer {
|
||||
rememberVolume: true, // Persist volume between sessions
|
||||
lastVolume: 80, // Last used volume (if rememberVolume is true)
|
||||
autoPlayNextEpisode: false, // Auto-play next episode in series
|
||||
forceProxy: false // Force all streams through backend proxy
|
||||
forceProxy: false, // Force all streams through backend proxy
|
||||
forceTranscode: false // Force audio transcoding (fixes Dolby/AC3 audio)
|
||||
};
|
||||
try {
|
||||
const saved = localStorage.getItem('nodecast_tv_player_settings');
|
||||
@@ -202,6 +203,25 @@ class VideoPlayer {
|
||||
// Determine if HLS or direct stream
|
||||
this.currentUrl = streamUrl;
|
||||
|
||||
// CHECK: Force Transcode Priority - transcoded streams bypass HLS.js
|
||||
if (this.settings.forceTranscode) {
|
||||
console.log('[Player] Force Transcode enabled. Routing through ffmpeg...');
|
||||
const transcodeUrl = this.getTranscodeUrl(streamUrl);
|
||||
this.currentUrl = transcodeUrl;
|
||||
|
||||
// Transcoded streams are fragmented MP4 - play directly with <video> element
|
||||
console.log('[Player] Playing transcoded stream directly:', transcodeUrl);
|
||||
this.video.src = transcodeUrl;
|
||||
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; // Exit early - don't use HLS.js path
|
||||
}
|
||||
|
||||
// Proactively use proxy for:
|
||||
// 1. User enabled "Force Proxy" in settings
|
||||
// 2. Known CORS-restricted domains (like Pluto TV)
|
||||
@@ -377,6 +397,13 @@ class VideoPlayer {
|
||||
return `/api/proxy/stream?url=${encodeURIComponent(url)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transcoded URL for a stream (audio transcoding for browser compatibility)
|
||||
*/
|
||||
getTranscodeUrl(url) {
|
||||
return `/api/transcode?url=${encodeURIComponent(url)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode base64 EPG data
|
||||
*/
|
||||
|
||||
@@ -29,6 +29,7 @@ class SettingsPage {
|
||||
const rememberVolumeToggle = document.getElementById('setting-remember-volume');
|
||||
const autoPlayNextToggle = document.getElementById('setting-autoplay-next');
|
||||
const forceProxyToggle = document.getElementById('setting-force-proxy');
|
||||
const forceTranscodeToggle = document.getElementById('setting-force-transcode');
|
||||
|
||||
// Load current settings
|
||||
if (this.app.player?.settings) {
|
||||
@@ -41,6 +42,9 @@ class SettingsPage {
|
||||
if (forceProxyToggle) {
|
||||
forceProxyToggle.checked = this.app.player.settings.forceProxy || false;
|
||||
}
|
||||
if (forceTranscodeToggle) {
|
||||
forceTranscodeToggle.checked = this.app.player.settings.forceTranscode || false;
|
||||
}
|
||||
}
|
||||
|
||||
// Arrow keys toggle
|
||||
@@ -83,6 +87,12 @@ class SettingsPage {
|
||||
this.app.player.saveSettings();
|
||||
});
|
||||
|
||||
// Force transcode toggle
|
||||
forceTranscodeToggle?.addEventListener('change', () => {
|
||||
this.app.player.settings.forceTranscode = forceTranscodeToggle.checked;
|
||||
this.app.player.saveSettings();
|
||||
});
|
||||
|
||||
// EPG refresh interval
|
||||
const epgRefreshSelect = document.getElementById('epg-refresh-interval');
|
||||
if (epgRefreshSelect) {
|
||||
|
||||
Reference in New Issue
Block a user