mirror of
https://github.com/ksyasuda/mpv-youtube-queue.git
synced 2024-11-22 03:19:54 -08:00
Compare commits
2 Commits
cfc4f94464
...
fa2014acd6
Author | SHA1 | Date | |
---|---|---|---|
|
fa2014acd6 | ||
|
7b9a061118 |
@ -81,6 +81,7 @@ This script requires the following software to be installed on the system
|
|||||||
- `font_size - 12`: Size of the font
|
- `font_size - 12`: Size of the font
|
||||||
- `marked_icon - ⇅`: The icon to use to mark a video as ready to be moved in
|
- `marked_icon - ⇅`: The icon to use to mark a video as ready to be moved in
|
||||||
the queue
|
the queue
|
||||||
|
- `menu_timeout - 5`: The number of seconds until the menu times out
|
||||||
- `show_errors - yes`: Show error messages on the OSD
|
- `show_errors - yes`: Show error messages on the OSD
|
||||||
- `ytdlp_file_format - mp4`: The preferred file format for downloaded videos
|
- `ytdlp_file_format - mp4`: The preferred file format for downloaded videos
|
||||||
- `ytdlp_output_template - %(uploader)s/%(title)s.%(ext)s`: The [yt-dlp output
|
- `ytdlp_output_template - %(uploader)s/%(title)s.%(ext)s`: The [yt-dlp output
|
||||||
|
@ -22,6 +22,7 @@ downloader=curl
|
|||||||
font_name=JetBrains Mono
|
font_name=JetBrains Mono
|
||||||
font_size=12
|
font_size=12
|
||||||
marked_icon=⇅
|
marked_icon=⇅
|
||||||
|
menu_timeout=5
|
||||||
show_errors=yes
|
show_errors=yes
|
||||||
ytdlp_file_format=mp4
|
ytdlp_file_format=mp4
|
||||||
ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s
|
ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s
|
||||||
|
@ -19,6 +19,16 @@ local utils = require 'mp.utils'
|
|||||||
local assdraw = require 'mp.assdraw'
|
local assdraw = require 'mp.assdraw'
|
||||||
local styleOn = mp.get_property("osd-ass-cc/0")
|
local styleOn = mp.get_property("osd-ass-cc/0")
|
||||||
local styleOff = mp.get_property("osd-ass-cc/1")
|
local styleOff = mp.get_property("osd-ass-cc/1")
|
||||||
|
local YouTubeQueue = {}
|
||||||
|
local video_queue = {}
|
||||||
|
local MSG_DURATION = 1.5
|
||||||
|
local index = 0
|
||||||
|
local selected_index = 1
|
||||||
|
local display_offset = 0
|
||||||
|
local marked_index = nil
|
||||||
|
local current_video = nil
|
||||||
|
local destroyer = nil
|
||||||
|
local timeout
|
||||||
|
|
||||||
local options = {
|
local options = {
|
||||||
add_to_queue = "ctrl+a",
|
add_to_queue = "ctrl+a",
|
||||||
@ -45,13 +55,21 @@ local options = {
|
|||||||
font_name = "JetBrains Mono",
|
font_name = "JetBrains Mono",
|
||||||
font_size = 12,
|
font_size = 12,
|
||||||
marked_icon = "⇅",
|
marked_icon = "⇅",
|
||||||
|
menu_timeout = 5,
|
||||||
show_errors = true,
|
show_errors = true,
|
||||||
ytdlp_file_format = "mp4",
|
ytdlp_file_format = "mp4",
|
||||||
ytdlp_output_template = "%(uploader)s/%(title)s.%(ext)s"
|
ytdlp_output_template = "%(uploader)s/%(title)s.%(ext)s"
|
||||||
}
|
}
|
||||||
|
|
||||||
mp.options.read_options(options, "mpv-youtube-queue")
|
mp.options.read_options(options, "mpv-youtube-queue")
|
||||||
|
|
||||||
|
local function destroy()
|
||||||
|
timeout:kill()
|
||||||
|
mp.set_osd_ass(0, 0, "")
|
||||||
|
destroyer = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
timeout = mp.add_periodic_timer(options.menu_timeout, destroy)
|
||||||
|
|
||||||
-- STYLE {{{
|
-- STYLE {{{
|
||||||
local colors = {
|
local colors = {
|
||||||
error = "676EFF",
|
error = "676EFF",
|
||||||
@ -83,26 +101,6 @@ local style = {
|
|||||||
}
|
}
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
local YouTubeQueue = {}
|
|
||||||
local video_queue = {}
|
|
||||||
local MSG_DURATION = 1.5
|
|
||||||
local display_limit = options.display_limit
|
|
||||||
local index = 0
|
|
||||||
local selected_index = 1
|
|
||||||
local display_offset = 0
|
|
||||||
local marked_index = nil
|
|
||||||
local current_video = nil
|
|
||||||
local destroyer = nil
|
|
||||||
local timeout
|
|
||||||
|
|
||||||
local function destroy()
|
|
||||||
timeout:kill()
|
|
||||||
mp.set_osd_ass(0, 0, "")
|
|
||||||
destroyer = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
timeout = mp.add_periodic_timer(5, destroy)
|
|
||||||
|
|
||||||
-- HELPERS {{{
|
-- HELPERS {{{
|
||||||
-- surround string with single quotes if it does not already have them
|
-- surround string with single quotes if it does not already have them
|
||||||
local function surround_with_quotes(s)
|
local function surround_with_quotes(s)
|
||||||
@ -215,25 +213,29 @@ function YouTubeQueue.get_clipboard_content()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function YouTubeQueue.get_video_info(url)
|
function YouTubeQueue.get_video_info(url)
|
||||||
local command =
|
local res = mp.command_native({
|
||||||
'yt-dlp --print channel_url --print uploader --print title --playlist-items 1 ' ..
|
name = "subprocess",
|
||||||
surround_with_quotes(url)
|
playback_only = false,
|
||||||
local handle = io.popen(command)
|
capture_stdout = true,
|
||||||
if handle == nil then return nil, nil, nil end
|
args = {
|
||||||
|
"yt-dlp", "--print", "channel_url", "--print", "uploader",
|
||||||
|
"--print", "title", "--playlist-items", "1", url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
local result = handle:read("*a")
|
if res.status ~= 0 then
|
||||||
handle:close()
|
print_osd_message("Failed to get video info", MSG_DURATION, style.error)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Split the result into URL, name, and video title
|
local channel_url, uploader, title = res.stdout:match("(.*)\n(.*)\n(.*)\n")
|
||||||
local channel_url, channel_name, video_name = result:match(
|
if channel_url == nil or uploader == nil or title == nil or channel_url ==
|
||||||
"(.-)\n(.-)\n(.*)")
|
"" or uploader == "" or title == "" then
|
||||||
|
print_osd_message("Failed to get video info", MSG_DURATION, style.error)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Remove trailing whitespace
|
return channel_url, uploader, title
|
||||||
if channel_url ~= nil then channel_url = channel_url:gsub("%s+$", "") end
|
|
||||||
if channel_name ~= nil then channel_name = channel_name:gsub("%s+$", "") end
|
|
||||||
if video_name ~= nil then video_name = video_name:gsub("%s+$", "") end
|
|
||||||
|
|
||||||
return channel_url, channel_name, video_name
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function YouTubeQueue.print_current_video()
|
function YouTubeQueue.print_current_video()
|
||||||
@ -343,9 +345,10 @@ function YouTubeQueue.print_queue(duration)
|
|||||||
local ass = assdraw.ass_new()
|
local ass = assdraw.ass_new()
|
||||||
local current_index = index
|
local current_index = index
|
||||||
if #video_queue > 0 then
|
if #video_queue > 0 then
|
||||||
local start_index = math.max(1, selected_index - display_limit / 2)
|
local start_index = math.max(1,
|
||||||
local end_index =
|
selected_index - options.display_limit / 2)
|
||||||
math.min(#video_queue, start_index + display_limit - 1)
|
local end_index = math.min(#video_queue,
|
||||||
|
start_index + options.display_limit - 1)
|
||||||
display_offset = start_index - 1
|
display_offset = start_index - 1
|
||||||
|
|
||||||
ass:append(
|
ass:append(
|
||||||
@ -405,7 +408,7 @@ function YouTubeQueue.move_cursor(amt)
|
|||||||
if amt == 1 and selected_index > 1 and selected_index < display_offset + 1 then
|
if amt == 1 and selected_index > 1 and selected_index < display_offset + 1 then
|
||||||
display_offset = display_offset - math.abs(selected_index - amt)
|
display_offset = display_offset - math.abs(selected_index - amt)
|
||||||
elseif amt == -1 and selected_index < #video_queue and selected_index >
|
elseif amt == -1 and selected_index < #video_queue and selected_index >
|
||||||
display_offset + display_limit then
|
display_offset + options.display_limit then
|
||||||
display_offset = display_offset + math.abs(selected_index - amt)
|
display_offset = display_offset + math.abs(selected_index - amt)
|
||||||
end
|
end
|
||||||
YouTubeQueue.print_queue()
|
YouTubeQueue.print_queue()
|
||||||
@ -475,6 +478,7 @@ function YouTubeQueue.add_to_queue(url, update_internal_playlist)
|
|||||||
(channel_url == "" or channel_name == "" or video_name == "") then
|
(channel_url == "" or channel_name == "" or video_name == "") then
|
||||||
print_osd_message("Error getting video info.", MSG_DURATION,
|
print_osd_message("Error getting video info.", MSG_DURATION,
|
||||||
style.error)
|
style.error)
|
||||||
|
return
|
||||||
else
|
else
|
||||||
video = {
|
video = {
|
||||||
video_url = url,
|
video_url = url,
|
||||||
@ -489,6 +493,7 @@ function YouTubeQueue.add_to_queue(url, update_internal_playlist)
|
|||||||
video_name == "" then
|
video_name == "" then
|
||||||
print_osd_message("Error getting video info.", MSG_DURATION,
|
print_osd_message("Error getting video info.", MSG_DURATION,
|
||||||
style.error)
|
style.error)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
video = {
|
video = {
|
||||||
video_url = url,
|
video_url = url,
|
||||||
@ -523,7 +528,6 @@ function YouTubeQueue.download_video_at(idx)
|
|||||||
|
|
||||||
print_osd_message("Downloading " .. v.video_name .. "...", MSG_DURATION)
|
print_osd_message("Downloading " .. v.video_name .. "...", MSG_DURATION)
|
||||||
-- Run the download command
|
-- Run the download command
|
||||||
-- local handle = io.popen(command)
|
|
||||||
mp.command_native_async({
|
mp.command_native_async({
|
||||||
name = "subprocess",
|
name = "subprocess",
|
||||||
capture_stderr = true,
|
capture_stderr = true,
|
||||||
@ -625,4 +629,5 @@ mp.register_event("playback-restart", on_playback_restart)
|
|||||||
|
|
||||||
mp.register_script_message("add_to_queue", YouTubeQueue.add_to_queue)
|
mp.register_script_message("add_to_queue", YouTubeQueue.add_to_queue)
|
||||||
mp.register_script_message("print_queue", YouTubeQueue.print_queue)
|
mp.register_script_message("print_queue", YouTubeQueue.print_queue)
|
||||||
|
mp.register_script_message("toggle_youtube_queue", toggle_print)
|
||||||
-- }}}
|
-- }}}
|
||||||
|
Loading…
Reference in New Issue
Block a user