diff --git a/.env b/.env index acd5d00..25f4748 100644 --- a/.env +++ b/.env @@ -8,3 +8,7 @@ CHANNELS=4df4756104a54e28e967bff6dc08e319:KBS2,8ecd602c251f30fd7f09463e9f55609f: # To get these, log in to Chzzk/Naver in your browser, open Developer Tools -> Application -> Cookies. # NID_AUT= # NID_SES= + +# Optional: Limit maximum quality (e.g. 720p or 1080p). +# Useful if 1080p causes transcoding lag or errors on Jellyfin. +MAX_QUALITY=720p diff --git a/index.js b/index.js index 363ca66..f2c59ef 100644 --- a/index.js +++ b/index.js @@ -264,9 +264,34 @@ const filterMasterPlaylist = async (m3u8Data, m3u8Url) => { if (variants.length === 0) return m3u8Data; + // Filter variants based on MAX_QUALITY env variable if specified + let filteredVariants = variants; + const maxQualityStr = process.env.MAX_QUALITY; + if (maxQualityStr) { + const maxQuality = parseInt(maxQualityStr, 10); + if (!isNaN(maxQuality)) { + filteredVariants = variants.filter(v => { + const streamInf = v.headers.find(h => h.startsWith('#EXT-X-STREAM-INF')); + let height = 0; + if (streamInf) { + const match = streamInf.match(/RESOLUTION=\d+x(\d+)/); + if (match) height = parseInt(match[1], 10); + } + if (!height) { + const uriMatch = v.uri.match(/\/(\d+)p\//); + if (uriMatch) height = parseInt(uriMatch[1], 10); + } + return !height || height <= maxQuality; + }); + if (filteredVariants.length === 0) { + filteredVariants = variants; + } + } + } + // Test playability of each variant in parallel const checkedVariants = await Promise.all( - variants.map(async (v) => { + filteredVariants.map(async (v) => { try { await axios.get(v.uri, { headers: buildHeaders(), @@ -282,7 +307,7 @@ const filterMasterPlaylist = async (m3u8Data, m3u8Url) => { ); const playableVariants = checkedVariants.filter(v => v.playable); - const finalVariants = playableVariants.length > 0 ? playableVariants : variants; + const finalVariants = playableVariants.length > 0 ? playableVariants : filteredVariants; let output = '#EXTM3U\n#EXT-X-VERSION:7\n#EXT-X-INDEPENDENT-SEGMENTS\n'; finalVariants.forEach(v => {