diff --git a/index.js b/index.js index 483872c..dd72e51 100644 --- a/index.js +++ b/index.js @@ -228,10 +228,44 @@ app.get('/stream/:channelId', async (req, res) => { const hlsMedia = media.find(m => m.mediaId === 'HLS' || m.mediaId === 'LLHLS'); if (hlsMedia && hlsMedia.path) { - // Redirect Jellyfin to our proxy endpoint to intercept keys + // Serve HLS master playlist directly (no redirect) so ffmpeg/Jellyfin + // doesn't need to follow a redirect chain which can cause code 8 errors const host = req.get('host'); const protocol = req.protocol; - res.redirect(302, `${protocol}://${host}/m3u8?url=${encodeURIComponent(hlsMedia.path)}`); + const baseUrl = `${protocol}://${host}`; + const m3u8Url = hlsMedia.path; + + const m3u8Res = await axios.get(m3u8Url); + let m3u8Data = m3u8Res.data; + + const lines = m3u8Data.split('\n'); + const processedLines = lines.map(line => { + let processed = line.trim(); + if (!processed) return processed; + + if (processed.startsWith('#EXT-X-KEY:')) { + processed = processed.replace(/URI="(https?:\/\/[^"]+)"/, (match, keyUrl) => { + return `URI="${baseUrl}/key?url=${encodeURIComponent(keyUrl)}"`; + }); + return processed; + } + + if (!processed.startsWith('#')) { + let uri = processed; + if (!uri.startsWith('http')) { + uri = new URL(uri, m3u8Url).toString(); + } + if (uri.includes('.m3u8')) { + uri = `${baseUrl}/m3u8?url=${encodeURIComponent(uri)}`; + } + return uri; + } + + return processed; + }); + + res.header('Content-Type', 'application/vnd.apple.mpegurl'); + res.send(processedLines.join('\n')); } else { res.status(404).send('HLS stream not found in playback info'); }