diff options
| author | ilotterytea <ilotterytea@proton.me> | 2024-05-26 20:10:26 +0500 |
|---|---|---|
| committer | ilotterytea <ilotterytea@proton.me> | 2024-05-26 20:10:26 +0500 |
| commit | 036c889c4a4f7f59d1e1a592586b54c5c5e93005 (patch) | |
| tree | aa76d678790abc79f24edf83c17a564eb2c6f65d /mpv/scripts/youtube-serarch.lua | |
Diffstat (limited to 'mpv/scripts/youtube-serarch.lua')
| -rw-r--r-- | mpv/scripts/youtube-serarch.lua | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/mpv/scripts/youtube-serarch.lua b/mpv/scripts/youtube-serarch.lua new file mode 100644 index 0000000..dfe04c6 --- /dev/null +++ b/mpv/scripts/youtube-serarch.lua @@ -0,0 +1,149 @@ +--[[ + This script allows users to search and open youtube results from within mpv. + Available at: https://github.com/CogentRedTester/mpv-scripts + Users can open the search page with Y, and use Y again to open a search. + Alternatively, Ctrl+y can be used at any time to open a search. + Esc can be used to close the page. + Enter will open the selected item, Shift+Enter will append the item to the playlist. + This script requires that my other scripts `scroll-list` and `user-input` be installed. + scroll-list.lua and user-input-module.lua must be in the ~~/script-modules/ directory, + while user-input.lua should be loaded by mpv normally. + https://github.com/CogentRedTester/mpv-scroll-list + https://github.com/CogentRedTester/mpv-user-input + This script also requires a youtube API key to be entered. + The API key must be passed to the `API_key` script-opt. + A personal API key is free and can be created from: + https://console.developers.google.com/apis/api/youtube.googleapis.com/ + The script also requires that curl be in the system path. +]]-- + +local mp = require "mp" +local msg = require "mp.msg" +local utils = require "mp.utils" +local opts = require "mp.options" + +package.path = mp.command_native({"expand-path", "~~/lua-modules/?.lua;"}) .. package.path +local ui = require "user-input-module" +local list = require "scroll-list" + +list.header = "Youtube Search Results\\N-----------------------------" +list.num_entries = 18 +list.list_style = [[{\fs10}\N{\q2\fs25\c&Hffffff&}]] + +local o = { + API_key = "AIzaSyB3IuyFp8C5SYEgJ0BSGgKZZjfUtuVGl44", + num_results = 40 +} + +opts.read_options(o) + +local ass_escape = list.ass_escape + +--taken from: https://gist.github.com/liukun/f9ce7d6d14fa45fe9b924a3eed5c3d99 +local function urlencode(url) + if type(url) ~= "string" then return url end + url = url:gsub("\n", "\r\n") + url = url:gsub("([^%w ])", function (c) string.format("%%%02X", string.byte(c)) end) + url = url:gsub(" ", "+") + return url +end + +--sends an API request +local function send_request(type, queries) + local url = "https://www.googleapis.com/youtube/v3/"..type + + url = url.."?key="..o.API_key + + for key, value in pairs(queries) do + url = url.."&"..key.."="..urlencode(value) + end + + + local request = mp.command_native({ + name = "subprocess", + capture_stdout = true, + capture_stderr = true, + playback_only = false, + args = {"curl", url} + }) + + local response = utils.parse_json(request.stdout) + if request.status ~= 0 then msg.error(request.stderr) ; return nil end + return response +end + +local function insert_video(item) + list:insert({ + ass = ("%s {\\c&aaaaaa&}%s"):format(ass_escape(item.snippet.title), ass_escape(item.snippet.channelTitle)), + url = "https://www.youtube.com/watch?v="..item.id.videoId + }) +end + +local function insert_playlist(item) + list:insert({ + ass = ("🖿 %s {\\c&aaaaaa&}%s"):format(ass_escape(item.snippet.title), ass_escape(item.snippet.channelTitle)), + url = "https://www.youtube.com/playlist?list="..item.id.playlistId + }) +end + +local function insert_channel(item) + list:insert({ + ass = ("👤 %s"):format(ass_escape(item.snippet.title)), + url = "https://www.youtube.com/channel/"..item.id.channelId + }) +end + +local function reset_list() + list.selected = 1 + list:clear() +end + +local function search(query) + local response = send_request("search", { + q = query, + part = "id,snippet", + maxResults = o.num_results + }) + + if not response then return end + reset_list() + + for _, item in ipairs(response.items) do + if item.id.kind == "youtube#video" then + insert_video(item) + elseif item.id.kind == "youtube#playlist" then + insert_playlist(item) + elseif item.id.kind == "youtube#channel" then + insert_channel(item) + end + end + list.header = "Youtube Search: "..ass_escape(query).."\\N-------------------------------------------------" + list:update() + list:open() +end + +local function play_result(flag) + if not list[list.selected] then return end + if flag == "new_window" then mp.commandv("run", "mpv", list[list.selected].url) ; return end + + mp.commandv("loadfile", list[list.selected].url, flag) + if flag == "replace" then list:close() end +end + +table.insert(list.keybinds, {"ENTER", "play", function() play_result("replace") end, {}}) +table.insert(list.keybinds, {"Shift+ENTER", "play_append", function() play_result("append-play") end, {}}) +table.insert(list.keybinds, {"Ctrl+ENTER", "play_new_window", function() play_result("new_window") end, {}}) + +local function open_search_input() + ui.get_user_input(function(input) + if not input then return end + search( input ) + end) +end + +mp.add_key_binding("Ctrl+y", "yt", open_search_input) + +mp.add_key_binding("Y", "youtube-search", function() + if not list.hidden then open_search_input() + else list:open() end +end) |
