From e2d608c91014da3fd2ac08a4919738523e975c38 Mon Sep 17 00:00:00 2001 From: Nulo Date: Tue, 3 May 2022 10:36:17 -0300 Subject: [PATCH] mpv: sponsorblock_minimal --- .config/mpv/scripts/sponsorblock_minimal.lua | 131 +++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 .config/mpv/scripts/sponsorblock_minimal.lua diff --git a/.config/mpv/scripts/sponsorblock_minimal.lua b/.config/mpv/scripts/sponsorblock_minimal.lua new file mode 100644 index 0000000..7c9f0d6 --- /dev/null +++ b/.config/mpv/scripts/sponsorblock_minimal.lua @@ -0,0 +1,131 @@ +-- sponsorblock_minimal.lua +-- +-- This script skips sponsored segments of YouTube videos +-- using data from https://github.com/ajayyy/SponsorBlock + +-- From https://codeberg.org/jouni/mpv_sponsorblock_minimal/src/commit/b71beb60eb71eb7df1266abfccd14c8cc451c643/sponsorblock_minimal.lua + +local options = { + server = "https://sponsor.ajay.app/api/skipSegments", + + -- Categories to fetch and skip + categories = '"sponsor","interaction","outro"' +} + +function getranges() + local luacurl_available, cURL = pcall(require,'cURL') + + local cstr = ("categories=[%s]"):format(options.categories) + local vstr = ("videoID=%s"):format(youtube_id) + + if not(luacurl_available) then -- if Lua-cURL is not available on this system + local curl_cmd = { + "curl", + "-L", + "-s", + "-G", + "-d", cstr, + "-d", vstr, + options.server + } + local sponsors = mp.command_native{ + name = "subprocess", + capture_stdout = true, + playback_only = false, + args = curl_cmd + } + res = sponsors.stdout + else -- otherwise use Lua-cURL (binding to libcurl) + local API = ("%s?%s&%s"):format(options.server, cstr, vstr) + local buf={} + local c = cURL.easy_init() + c:setopt_followlocation(1) + c:setopt_url(API) + c:setopt_writefunction(function(chunk) table.insert(buf,chunk); return true; end) + c:perform() + res = table.concat(buf) + end + + if string.match(res,"%[(.-)%]") then + ranges = {} + for i in string.gmatch(string.sub(res,2,-2),"%[(.-)%]") do + k,v = string.match(i,"(%d+.?%d*),(%d+.?%d*)") + ranges[k] = v + end + end + return +end + +function skip_ads(name,pos) + if pos ~= nil then + for k,v in pairs(ranges) do + k = tonumber(k) + v = tonumber(v) + if k <= pos and v > pos then + --this message may sometimes be wrong + --it only seems to be a visual thing though + mp.osd_message(("[sponsorblock] skipping forward %ds"):format(math.floor(v-mp.get_property("time-pos")))) + --need to do the +0.01 otherwise mpv will start spamming skip sometimes + --example: https://www.youtube.com/watch?v=4ypMJzeNooo + mp.set_property("time-pos",v+0.01) + return + end + end + end + return +end + +function file_loaded() + local video_path = mp.get_property("path", "") + local video_referer = string.match(mp.get_property("http-header-fields", ""), "Referer:([^,]+)") or "" + + local urls = { + "ytdl://youtu%.be/([%w-_]+).*", + "ytdl://w?w?w?%.?youtube%.com/v/([%w-_]+).*", + "https?://youtu%.be/([%w-_]+).*", + "https?://w?w?w?%.?youtube%.com/v/([%w-_]+).*", + "/watch.*[?&]v=([%w-_]+).*", + "/embed/([%w-_]+).*", + "^ytdl://([%w-_]+)$", + "-([%w-_]+)%." + } + youtube_id = nil + local purl = mp.get_property("metadata/by-key/PURL", "") + for i,url in ipairs(urls) do + youtube_id = youtube_id or string.match(video_path, url) or string.match(video_referer, url) or string.match(purl, url) + end + + if not youtube_id or string.len(youtube_id) < 11 then return end + youtube_id = string.sub(youtube_id, 1, 11) + + getranges() + if ranges then + ON = true + mp.add_key_binding("b","sponsorblock",toggle) + mp.observe_property("time-pos", "native", skip_ads) + end + return +end + +function end_file() + if not ON then return end + mp.unobserve_property(skip_ads) + ranges = nil + ON = false +end + +function toggle() + if ON then + mp.unobserve_property(skip_ads) + mp.osd_message("[sponsorblock] off") + ON = false + return + end + mp.observe_property("time-pos", "native", skip_ads) + mp.osd_message("[sponsorblock] on") + ON = true + return +end + +mp.register_event("file-loaded", file_loaded) +mp.register_event("end-file", end_file)