Files
yt-dlp4vlc/youtube.lua

129 lines
4.0 KiB
Lua

-- YouTube Link Resolver for VLC with Separate Video and Audio URLs
-- Place this script in VLC's lua/playlist directory
local yt_dlp_path = 'yt-dlp.exe';
local yt_dlp_silent_path = 'ytdlp-silent-xp.exe';
function sleep(s)
local ntime = os.time() + s
repeat until os.time() > ntime
end
function probe()
-- Check if the input is a YouTube link
return vlc.access == "http" or vlc.access == "https" and
(string.match(vlc.path, "youtube%.com") or string.match(vlc.path, "youtu%.be"))
end
function parse()
-- Construct the full YouTube URL
local youtube_url = vlc.access .. "://" .. vlc.path
-- Extract "quality" query parameter if present
local quality = youtube_url:match("[&?]quality=(%d+)[pP]?")
youtube_url = youtube_url:gsub("[&?]quality=%d+[pP]?", ""):gsub("[&?]$", "") -- Remove trailing ? or &
local allowed_qualities = {
["360"] = true,
["480"] = true,
["720"] = true,
["1080"] = true,
["2160"] = true
}
local format_string = "bestvideo+bestaudio" -- Default to highest available
if quality and allowed_qualities[quality] then
format_string = string.format("bestvideo[height=%s]+bestaudio", quality)
vlc.msg.info("Using requested quality: " .. quality .. "p")
else
vlc.msg.info("No valid quality specified. Defaulting to best available.")
end
local cmd_hidden = yt_dlp_silent_path
local video_url = ''
local audio_url = ''
local yt_dlp_silent_exists = io.open(yt_dlp_silent_path, "r") ~= nil
if not yt_dlp_silent_exists then
vlc.msg.info(yt_dlp_silent_path .. " not found. Falling back to " .. yt_dlp_path)
cmd_hidden = 'PowerShell.exe -windowstyle hidden cmd /c &'
local cmd = string.format(
'%s "%s" -f \"%s\" -g --no-warnings %s',
cmd_hidden,
yt_dlp_path,
format_string,
youtube_url
)
local handle = io.popen(cmd)
video_url = handle:read("*l")
audio_url = handle:read("*l")
handle:close()
else
vlc.msg.info(yt_dlp_silent_path .. " found. Running program")
local cmd = string.format(
'%s -s "%s -f \"%s\" -g --no-warnings %s"',
cmd_hidden,
yt_dlp_path,
format_string,
youtube_url
)
local process = io.popen("start /B " .. cmd)
process:close()
local output_file = "yt-dlp-output.txt"
local file_exists = false
local timeout = 0
local timeout_limit = 10
while not file_exists do
local file_test = os.rename(output_file, output_file)
if file_test then
file_exists = true
else
vlc.msg.info("Waiting for output file...")
sleep(1)
timeout = timeout + 1
if timeout > timeout_limit then
vlc.msg.warn("Timeout reached. The output file was not created.")
break
end
end
end
vlc.msg.info("File found")
local file = io.open(output_file, "r")
video_url = file:read("*l")
audio_url = file:read("*l")
file:close()
os.remove(output_file)
end
video_url = video_url and video_url:gsub("^%s+", ""):gsub("%s+$", "") or ""
audio_url = audio_url and audio_url:gsub("^%s+", ""):gsub("%s+$", "") or ""
vlc.msg.info("[YouTube Resolver] Original URL: " .. youtube_url)
vlc.msg.info("[YouTube Resolver] Video URL: " .. video_url)
if audio_url and audio_url ~= "" then
return {
{
path = video_url,
name = vlc.path .. " (Video)",
options = {
":input-slave=" .. audio_url
}
}
}
else
return {
{
path = video_url,
name = vlc.path .. " (Video + Audio)"
}
}
end
end