feat: add -seekable 0 to fix 405 errors and configurable User-Agent presets for stream requests
This commit is contained in:
+22
-2
@@ -67,10 +67,30 @@ function getDefaultSettings() {
|
||||
forceRemux: false,
|
||||
autoTranscode: true,
|
||||
streamFormat: 'm3u8',
|
||||
epgRefreshInterval: '24'
|
||||
epgRefreshInterval: '24',
|
||||
// User-Agent settings
|
||||
userAgentPreset: 'chrome', // chrome | vlc | tivimate | custom
|
||||
userAgentCustom: '', // Custom UA string when preset is 'custom'
|
||||
// Probe cache settings
|
||||
probeCacheTTL: 300, // 5 minutes for URL probe cache
|
||||
seriesProbeCacheDays: 7 // 7 days for series episode probe cache
|
||||
};
|
||||
}
|
||||
|
||||
// User-Agent presets
|
||||
const USER_AGENT_PRESETS = {
|
||||
chrome: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
|
||||
vlc: 'VLC/3.0.20 LibVLC/3.0.20',
|
||||
tivimate: 'TiviMate/4.7.0',
|
||||
};
|
||||
|
||||
function getUserAgent(settings) {
|
||||
if (settings.userAgentPreset === 'custom' && settings.userAgentCustom) {
|
||||
return settings.userAgentCustom;
|
||||
}
|
||||
return USER_AGENT_PRESETS[settings.userAgentPreset] || USER_AGENT_PRESETS.chrome;
|
||||
}
|
||||
|
||||
// Write lock to prevent concurrent writes from corrupting db.json
|
||||
let writeQueue = Promise.resolve();
|
||||
const tmpPath = dbPath + '.tmp';
|
||||
@@ -422,4 +442,4 @@ const users = {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { loadDb, saveDb, sources, hiddenItems, favorites, settings, users, getDefaultSettings };
|
||||
module.exports = { loadDb, saveDb, sources, hiddenItems, favorites, settings, users, getDefaultSettings, getUserAgent, USER_AGENT_PRESETS };
|
||||
|
||||
+11
-2
@@ -1,6 +1,7 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { spawn } = require('child_process');
|
||||
const db = require('../db');
|
||||
|
||||
/**
|
||||
* Remux stream (container conversion only)
|
||||
@@ -12,21 +13,27 @@ const { spawn } = require('child_process');
|
||||
*
|
||||
* Note: This does NOT fix Dolby/AC3 audio issues - use /api/transcode for that.
|
||||
*/
|
||||
router.get('/', (req, res) => {
|
||||
router.get('/', async (req, res) => {
|
||||
const { url } = req.query;
|
||||
if (!url) {
|
||||
return res.status(400).json({ error: 'URL parameter is required' });
|
||||
}
|
||||
|
||||
const ffmpegPath = req.app.locals.ffmpegPath || 'ffmpeg';
|
||||
|
||||
// Get User-Agent from settings
|
||||
const settings = await db.settings.get();
|
||||
const userAgent = db.getUserAgent(settings);
|
||||
|
||||
console.log(`[Remux] Starting remux for: ${url}`);
|
||||
console.log(`[Remux] Using User-Agent: ${settings.userAgentPreset}`);
|
||||
|
||||
// FFmpeg arguments for pure remux (no encoding)
|
||||
// Very lightweight - just changes container from TS to fragmented MP4
|
||||
const args = [
|
||||
'-hide_banner',
|
||||
'-loglevel', 'warning',
|
||||
'-user_agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
|
||||
'-user_agent', userAgent,
|
||||
// Low-latency startup: reduce probe/analyze time for faster first bytes
|
||||
'-probesize', '32768',
|
||||
'-analyzeduration', '500000', // 0.5 seconds - enough to detect audio
|
||||
@@ -40,6 +47,8 @@ router.get('/', (req, res) => {
|
||||
'-reconnect', '1',
|
||||
'-reconnect_streamed', '1',
|
||||
'-reconnect_delay_max', '5',
|
||||
// Prevent Range/HEAD requests that some providers reject with 405
|
||||
'-seekable', '0',
|
||||
'-i', url,
|
||||
// STRICT MAPPING: Only map video and audio, ignore subtitles/data/attachments
|
||||
// This prevents remux failure when source container has incompatible subtitle tracks (e.g. MKV -> MP4)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const { spawn } = require('child_process');
|
||||
const db = require('../db');
|
||||
|
||||
/**
|
||||
* Transcode stream
|
||||
@@ -9,14 +10,20 @@ const { spawn } = require('child_process');
|
||||
* Transcodes audio to AAC for browser compatibility while passing video through.
|
||||
* This fixes playback issues with Dolby/AC3/EAC3 audio that browsers can't decode.
|
||||
*/
|
||||
router.get('/', (req, res) => {
|
||||
router.get('/', async (req, res) => {
|
||||
const { url } = req.query;
|
||||
if (!url) {
|
||||
return res.status(400).json({ error: 'URL parameter is required' });
|
||||
}
|
||||
|
||||
const ffmpegPath = req.app.locals.ffmpegPath || 'ffmpeg';
|
||||
|
||||
// Get User-Agent from settings
|
||||
const settings = await db.settings.get();
|
||||
const userAgent = db.getUserAgent(settings);
|
||||
|
||||
console.log(`[Transcode] Starting transcoding for: ${url}`);
|
||||
console.log(`[Transcode] Using User-Agent: ${settings.userAgentPreset}`);
|
||||
console.log(`[Transcode] Using binary: ${ffmpegPath}`);
|
||||
|
||||
// FFmpeg arguments for transcoding
|
||||
@@ -25,7 +32,7 @@ router.get('/', (req, res) => {
|
||||
const args = [
|
||||
'-hide_banner',
|
||||
'-loglevel', 'warning',
|
||||
'-user_agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
|
||||
'-user_agent', userAgent,
|
||||
// Faster startup - reduced probe/analyze for quicker first bytes
|
||||
'-probesize', '2000000', // 2MB (reduced from 5MB)
|
||||
'-analyzeduration', '3000000', // 3 seconds (reduced from 10s)
|
||||
@@ -39,6 +46,8 @@ router.get('/', (req, res) => {
|
||||
'-reconnect', '1',
|
||||
'-reconnect_streamed', '1',
|
||||
'-reconnect_delay_max', '3',
|
||||
// Prevent Range/HEAD requests that some providers reject with 405
|
||||
'-seekable', '0',
|
||||
'-i', url,
|
||||
// Map only first video and audio stream (avoid subtitle streams causing issues)
|
||||
'-map', '0:v:0',
|
||||
|
||||
Reference in New Issue
Block a user