local msg = require 'mp.msg' local url_headers = {} local function parse_m3u_content(content) local current_headers = {} for line in content:gmatch("[^\r\n]+") do local ref = line:match("^#EXTVLCOPT:http%%-referrer=(.+)") if ref then table.insert(current_headers, "Referer: " .. ref) end local ua = line:match("^#EXTVLCOPT:http%%-user%%-agent=(.+)") if ua then table.insert(current_headers, "User-Agent: " .. ua) end if line:match("^https?://") then if #current_headers > 0 then local base_url = line:gsub("%?.*", "") url_headers[base_url] = table.concat(current_headers, ",") current_headers = {} end end end end local function parse_local_m3u(path) local f = io.open(path, "r") if not f then return end local content = f:read("*a") f:close() if content then parse_m3u_content(content) end end local function parse_remote_m3u(url) local res = mp.command_native({ name = "subprocess", args = {"curl", "-s", "-L", url}, capture_stdout = true }) if res.status == 0 and res.stdout then parse_m3u_content(res.stdout) else msg.warn("Failed to fetch remote M3U: " .. url) end end mp.add_hook("on_load", 50, function() local path = mp.get_property("stream-open-filename", "") if path:match("%.m3u") or path:match("%.m3u8") then if path:match("^https?://") then parse_remote_m3u(path) else parse_local_m3u(path:gsub("^file://", "")) end end local base_path = path:gsub("%?.*", "") if url_headers[base_path] then msg.info("Applying custom headers for: " .. base_path) mp.set_property("file-local-options/http-header-fields", url_headers[base_path]) mp.set_property("file-local-options/ytdl", "no") end end)