From 4ade691441822e9e4ff11c1cb3aae801bb00ebc3 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Mon, 5 Apr 2021 15:45:05 +0200 Subject: [PATCH] mpv: Replace sponsorblock with minimal version Use a more minimal version of sponsorblock which neither caches the results locally, nor allows many of the fancy things that the python plugin allows. On the other hand, it is lua-only and does not depend on python, and fulfills the same basic functionality: skipping sponsorship segments. You can toggle the plugin on and off by pressing `b`. Additionally, it also works on files played locally, if those carry a yt identifier in their filename. --- mpv/.config/mpv/scripts/sponsorblock/main.lua | 506 ------------------ .../sponsorblock/shared/sponsorblock.py | 110 ---- .../mpv/scripts/sponsorblock_legacy.lua | 3 - .../mpv/scripts/sponsorblock_minimal.lua | 88 +++ mpv/README.md | 10 +- 5 files changed, 91 insertions(+), 626 deletions(-) delete mode 100644 mpv/.config/mpv/scripts/sponsorblock/main.lua delete mode 100644 mpv/.config/mpv/scripts/sponsorblock/shared/sponsorblock.py delete mode 100644 mpv/.config/mpv/scripts/sponsorblock_legacy.lua create mode 100644 mpv/.config/mpv/scripts/sponsorblock_minimal.lua diff --git a/mpv/.config/mpv/scripts/sponsorblock/main.lua b/mpv/.config/mpv/scripts/sponsorblock/main.lua deleted file mode 100644 index f89c83a..0000000 --- a/mpv/.config/mpv/scripts/sponsorblock/main.lua +++ /dev/null @@ -1,506 +0,0 @@ --- sponsorblock.lua --- --- This script skips sponsored segments of YouTube videos --- using data from https://github.com/ajayyy/SponsorBlock -local ON_WINDOWS = package.config:sub(1, 1) ~= '/' - -local options = { - server_address = "https://sponsor.ajay.app", - - python_path = ON_WINDOWS and "python" or "python3", - - -- Whether or not to automatically skip sponsors - skip = true, - - -- If true, sponsored segments will only be skipped once - skip_once = true, - - -- Note that sponsored segments may ocasionally be inaccurate if this is turned off - -- see https://blog.ajay.app/voting-and-pseudo-randomness-or-sponsorblock-or-youtube-sponsorship-segment-blocker - local_database = true, - - -- Update database on first run, does nothing if local_database is false - auto_update = true, - - -- User ID used to submit sponsored segments, leave blank for random - user_id = "", - - -- Name to display on the stats page https://sponsor.ajay.app/stats/ leave blank to keep current name - display_name = "", - - -- Tell the server when a skip happens - report_views = true, - - -- Auto upvote skipped sponsors - auto_upvote = true, - - -- Use sponsor times from server if they're more up to date than our local database - server_fallback = true, - - -- Create chapters at sponsor boundaries for OSC display and manual skipping with skip=false - make_chapters = true, - - -- Minimum duration for sponsors (in seconds), segments under that threshold will be ignored - min_duration = 1, - - -- Fade audio for smoother transitions - audio_fade = false, - - -- Audio fade step, applied once every 100ms until cap is reached - audio_fade_step = 10, - - -- Audio fade cap - audio_fade_cap = 0, - - -- Fast forward through sponsors instead of skipping - fast_forward = false, - - -- Playback speed modifier when fast forwarding, applied once every second until cap is reached - fast_forward_increase = .2, - - -- Playback speed cap - fast_forward_cap = 2, - - -- Pattern for video id in local files, ignored if blank - -- Recommended value for base youtube-dl is "-([%a%d%-_]+)%.[mw][kpe][v4b][m]?$" - local_pattern = "" -} - -mp.options = require "mp.options" -mp.options.read_options(options, "sponsorblock") - -local legacy = mp.command_native_async == nil -if legacy then options.local_database = false end - -local utils = require "mp.utils" -if mp.get_script_directory == nil then - scripts_dir = mp.find_config_file("scripts/sponsorblock") -else - scripts_dir = mp.get_script_directory() -end -local sponsorblock = utils.join_path(scripts_dir, "shared/sponsorblock.py") -local uid_path = utils.join_path(scripts_dir, "shared/sponsorblock.txt") -local database_file = options.local_database and - utils.join_path(scripts_dir, "shared/sponsorblock.db") or - "" -local youtube_id = nil -local ranges = {} -local init = false -local segment = {a = 0, b = 0, progress = 0, first = true} -local retrying = false -local last_skip = {uuid = "", dir = nil} -local speed_timer = nil -local fade_timer = nil -local fade_dir = nil -local volume_before = mp.get_property_number("volume") - -function file_exists(name) - local f = io.open(name, "r") - if f ~= nil then - io.close(f) - return true - else - return false - end -end - -function t_count(t) - local count = 0 - for _ in pairs(t) do count = count + 1 end - return count -end - -function time_sort(a, b) return a.time < b.time end - -function clean_chapters() - local chapters = mp.get_property_native("chapter-list") - local new_chapters = {} - for _, chapter in pairs(chapters) do - if chapter.title ~= "Preview segment start" and chapter.title ~= - "Preview segment end" then - table.insert(new_chapters, chapter) - end - end - mp.set_property_native("chapter-list", new_chapters) -end - -function create_chapter(chapter_title, chapter_time) - local chapters = mp.get_property_native("chapter-list") - local duration = mp.get_property_native("duration") - table.insert(chapters, { - title = chapter_title, - time = (duration == nil or duration > chapter_time) and chapter_time or - duration - .001 - }) - table.sort(chapters, time_sort) - mp.set_property_native("chapter-list", chapters) -end - -function getranges(_, exists, db, more) - if type(exists) == "table" and exists["status"] == "1" then - if options.server_fallback then - mp.add_timeout(0, function() getranges(true, true, "") end) - else - return mp.osd_message( - "[sponsorblock] database update failed, gave up") - end - end - if db ~= "" and db ~= database_file then db = database_file end - if exists ~= true and not file_exists(db) then - if not retrying then - mp.osd_message("[sponsorblock] database update failed, retrying...") - retrying = true - end - return update() - end - if retrying then - mp.osd_message("[sponsorblock] database update succeeded") - retrying = false - end - local sponsors - local args = { - options.python_path, sponsorblock, "ranges", db, options.server_address, - youtube_id - } - if not legacy then - sponsors = mp.command_native({ - name = "subprocess", - capture_stdout = true, - playback_only = false, - args = args - }) - else - sponsors = utils.subprocess({args = args}) - end - if not string.match(sponsors.stdout, "^%s*(.*%S)") then return end - if string.match(sponsors.stdout, "error") then - return getranges(true, true) - end - local new_ranges = {} - local r_count = 0 - if more then r_count = -1 end - for t in string.gmatch(sponsors.stdout, "[^:%s]+") do - uuid = string.match(t, '[^,]+$') - if ranges[uuid] then - new_ranges[uuid] = ranges[uuid] - else - start_time = tonumber(string.match(t, '[^,]+')) - end_time = tonumber(string.sub(string.match(t, ',[^,]+'), 2)) - for o_uuid, o_t in pairs(ranges) do - if (start_time >= o_t.start_time and start_time <= o_t.end_time) or - (o_t.start_time >= start_time and o_t.start_time <= end_time) then - new_ranges[o_uuid] = o_t - goto continue - end - end - if end_time - start_time >= options.min_duration then - new_ranges[uuid] = { - start_time = start_time, - end_time = end_time, - skipped = false - } - end - if options.make_chapters then - create_chapter("Sponsor start (" .. string.sub(uuid, 1, 6) .. - ")", start_time) - create_chapter("Sponsor end (" .. string.sub(uuid, 1, 6) .. ")", - end_time) - end - end - ::continue:: - r_count = r_count + 1 - end - local c_count = t_count(ranges) - if c_count == 0 or r_count >= c_count then ranges = new_ranges end -end - -function fast_forward() - local last_speed = mp.get_property_number("speed") - local new_speed = math.min(last_speed + options.fast_forward_increase, - options.fast_forward_cap) - if new_speed <= last_speed then return end - mp.set_property("speed", new_speed) -end - -function fade_audio(step) - local last_volume = mp.get_property_number("volume") - local new_volume = math.max(options.audio_fade_cap, - math.min(last_volume + step, volume_before)) - if new_volume == last_volume then - if step >= 0 then fade_dir = nil end - if fade_timer ~= nil then fade_timer:kill() end - fade_timer = nil - return - end - mp.set_property("volume", new_volume) -end - -function skip_ads(name, pos) - if pos == nil then return end - local sponsor_ahead = false - for uuid, t in pairs(ranges) do - if (options.fast_forward == uuid or not options.skip_once or - not t.skipped) and t.start_time <= pos and t.end_time > pos then - if options.fast_forward == uuid then return end - if options.fast_forward == false then - mp.osd_message("[sponsorblock] sponsor skipped") - mp.set_property("time-pos", t.end_time) - else - mp.osd_message("[sponsorblock] skipping sponsor") - end - t.skipped = true - last_skip = {uuid = uuid, dir = nil} - if options.report_views or options.auto_upvote then - local args = { - options.python_path, sponsorblock, "stats", database_file, - options.server_address, youtube_id, uuid, - options.report_views and "1" or "", uid_path, - options.user_id, options.auto_upvote and "1" or "" - } - if not legacy then - mp.command_native_async( - { - name = "subprocess", - playback_only = false, - args = args - }, function() end) - else - utils.subprocess_detached({args = args}) - end - end - if options.fast_forward ~= false then - options.fast_forward = uuid - speed_timer = mp.add_periodic_timer(1, fast_forward) - end - return - elseif (not options.skip_once or not t.skipped) and t.start_time <= pos + - 1 and t.end_time > pos + 1 then - sponsor_ahead = true - end - end - if options.audio_fade then - if sponsor_ahead then - if fade_dir ~= false then - if fade_dir == nil then - volume_before = mp.get_property_number("volume") - end - if fade_timer ~= nil then fade_timer:kill() end - fade_dir = false - fade_timer = mp.add_periodic_timer(.1, function() - fade_audio(-options.audio_fade_step) - end) - end - elseif fade_dir == false then - fade_dir = true - if fade_timer ~= nil then fade_timer:kill() end - fade_timer = mp.add_periodic_timer(.1, function() - fade_audio(options.audio_fade_step) - end) - end - end - if options.fast_forward and options.fast_forward ~= true then - options.fast_forward = true - speed_timer:kill() - mp.set_property("speed", 1) - end -end - -function vote(dir) - if last_skip.uuid == "" then - return mp.osd_message( - "[sponsorblock] no sponsors skipped, can't submit vote") - end - local updown = dir == "1" and "up" or "down" - if last_skip.dir == dir then - return mp.osd_message("[sponsorblock] " .. updown .. - "vote already submitted") - end - last_skip.dir = dir - local args = { - options.python_path, sponsorblock, "stats", database_file, - options.server_address, youtube_id, last_skip.uuid, "", uid_path, - options.user_id, dir - } - if not legacy then - mp.command_native_async({ - name = "subprocess", - playback_only = false, - args = args - }, function() end) - else - utils.subprocess({args = args}) - end - mp.osd_message("[sponsorblock] " .. updown .. "vote submitted") -end - -function update() - mp.command_native_async({ - name = "subprocess", - playback_only = false, - args = { - options.python_path, sponsorblock, "update", database_file, - options.server_address - } - }, getranges) -end - -function file_loaded() - local initialized = init - ranges = {} - segment = {a = 0, b = 0, progress = 0, first = true} - last_skip = {uuid = "", dir = nil} - local video_path = mp.get_property("path") - local youtube_id1 = string.match(video_path, - "https?://youtu%.be/([%a%d%-_]+).*") - local youtube_id2 = string.match(video_path, - "https?://w?w?w?%.?youtube%.com/v/([%a%d%-_]+).*") - local youtube_id3 = string.match(video_path, "/watch%?v=([%a%d%-_]+).*") - local youtube_id4 = string.match(video_path, "/embed/([%a%d%-_]+).*") - local local_pattern = nil - if options.local_pattern ~= "" then - local_pattern = string.match(video_path, options.local_pattern) - end - youtube_id = youtube_id1 or youtube_id2 or youtube_id3 or youtube_id4 or - local_pattern - if not youtube_id then return end - init = true - if not options.local_database then - getranges(true, true) - else - local exists = file_exists(database_file) - if exists and options.server_fallback then - getranges(true, true) - mp.add_timeout(0, function() - getranges(true, true, "", true) - end) - elseif exists then - getranges(true, true) - elseif options.server_fallback then - mp.add_timeout(0, function() getranges(true, true, "") end) - end - end - if initialized then return end - if options.skip then mp.observe_property("time-pos", "native", skip_ads) end - if options.display_name ~= "" then - local args = { - options.python_path, sponsorblock, "username", database_file, - options.server_address, youtube_id, "", "", uid_path, - options.user_id, options.display_name - } - if not legacy then - mp.command_native_async({ - name = "subprocess", - playback_only = false, - args = args - }, function() end) - else - utils.subprocess_detached({args = args}) - end - end - if not options.local_database or - (not options.auto_update and file_exists(database_file)) then return end - update() -end - -function set_segment() - if not youtube_id then return end - local pos = mp.get_property_number("time-pos") - if pos == nil then return end - if segment.progress > 1 then segment.progress = segment.progress - 2 end - if segment.progress == 1 then - segment.progress = 0 - segment.b = pos - mp.osd_message( - "[sponsorblock] segment boundary B set, press again for boundary A", - 3) - else - segment.progress = 1 - segment.a = pos - mp.osd_message( - "[sponsorblock] segment boundary A set, press again for boundary B", - 3) - end - if options.make_chapters and not segment.first then - local start_time = math.min(segment.a, segment.b) - local end_time = math.max(segment.a, segment.b) - if end_time - start_time ~= 0 and end_time ~= 0 then - clean_chapters() - create_chapter("Preview segment start", start_time) - create_chapter("Preview segment end", end_time) - end - end - segment.first = false -end - -function submit_segment() - if not youtube_id then return end - local start_time = math.min(segment.a, segment.b) - local end_time = math.max(segment.a, segment.b) - if end_time - start_time == 0 or end_time == 0 then - mp.osd_message("[sponsorblock] empty segment, not submitting") - elseif segment.progress <= 1 then - mp.osd_message(string.format( - "[sponsorblock] press Shift+G again to confirm: %.2d:%.2d:%.2d to %.2d:%.2d:%.2d", - math.floor(start_time / (60 * 60)), - math.floor(start_time / 60 % 60), - math.floor(start_time % 60), - math.floor(end_time / (60 * 60)), - math.floor(end_time / 60 % 60), - math.floor(end_time % 60)), 5) - segment.progress = segment.progress + 2 - else - mp.osd_message("[sponsorblock] submitting segment...", 30) - local submit - local args = { - options.python_path, sponsorblock, "submit", database_file, - options.server_address, youtube_id, tostring(start_time), - tostring(end_time), uid_path, options.user_id - } - if not legacy then - submit = mp.command_native({ - name = "subprocess", - capture_stdout = true, - playback_only = false, - args = args - }) - else - submit = utils.subprocess({args = args}) - end - if string.match(submit.stdout, "success") then - segment = {a = 0, b = 0, progress = 0, first = true} - mp.osd_message("[sponsorblock] segment submitted") - if options.make_chapters then - clean_chapters() - create_chapter("Submitted segment start", start_time) - create_chapter("Submitted segment end", end_time) - end - elseif string.match(submit.stdout, "error") then - mp.osd_message( - "[sponsorblock] segment submission failed, server may be down. try again", - 5) - elseif string.match(submit.stdout, "502") then - mp.osd_message( - "[sponsorblock] segment submission failed, server is down. try again", - 5) - elseif string.match(submit.stdout, "400") then - mp.osd_message( - "[sponsorblock] segment submission failed, impossible inputs", 5) - segment = {a = 0, b = 0, progress = 0, first = true} - elseif string.match(submit.stdout, "429") then - mp.osd_message( - "[sponsorblock] segment submission failed, rate limited. try again", - 5) - elseif string.match(submit.stdout, "409") then - mp.osd_message("[sponsorblock] segment already submitted", 3) - segment = {a = 0, b = 0, progress = 0, first = true} - else - mp.osd_message("[sponsorblock] segment submission failed", 5) - end - end -end - -mp.register_event("file-loaded", file_loaded) -mp.add_key_binding("e", "sponsorblock_set_segment", set_segment) -mp.add_key_binding("E", "sponsorblock_submit_segment", submit_segment) -mp.add_key_binding("w", "sponsorblock_upvote", function() return vote("1") end) -mp.add_key_binding("W", "sponsorblock_downvote", function() return vote("0") end) diff --git a/mpv/.config/mpv/scripts/sponsorblock/shared/sponsorblock.py b/mpv/.config/mpv/scripts/sponsorblock/shared/sponsorblock.py deleted file mode 100644 index c03705b..0000000 --- a/mpv/.config/mpv/scripts/sponsorblock/shared/sponsorblock.py +++ /dev/null @@ -1,110 +0,0 @@ -import urllib.request -import urllib.parse -import sqlite3 -import random -import string -import json -import sys -import os - -if sys.argv[1] in ["submit", "stats", "username"]: - if not sys.argv[8]: - if os.path.isfile(sys.argv[7]): - with open(sys.argv[7]) as f: - uid = f.read() - else: - uid = "".join(random.choices(string.ascii_letters + string.digits, k=36)) - with open(sys.argv[7], "w") as f: - f.write(uid) - else: - uid = sys.argv[8] - -opener = urllib.request.build_opener() -opener.addheaders = [("User-Agent", "mpv_sponsorblock/1.0 (https://github.com/po5/mpv_sponsorblock)")] -urllib.request.install_opener(opener) - -if sys.argv[1] == "ranges" and (not sys.argv[2] or not os.path.isfile(sys.argv[2])): - times = [] - try: - response = urllib.request.urlopen(sys.argv[3] + "/api/getVideoSponsorTimes?videoID=" + sys.argv[4]) - data = json.load(response) - for i, time in enumerate(data["sponsorTimes"]): - times.append(str(time[0]) + "," + str(time[1]) + "," + data["UUIDs"][i]) - print(":".join(times)) - except (TimeoutError, urllib.error.URLError) as e: - print("error") - except urllib.error.HTTPError as e: - if e.code == 404: - print("") - else: - print("error") -elif sys.argv[1] == "ranges": - conn = sqlite3.connect(sys.argv[2]) - conn.row_factory = sqlite3.Row - c = conn.cursor() - c.execute("SELECT startTime, endTime, votes, UUID FROM sponsorTimes WHERE videoID = ? AND shadowHidden = 0 AND votes > -1 AND category = 'sponsor'", (sys.argv[4],)) - times = [] - sponsors = c.fetchall() - best = list(sponsors) - dealtwith = [] - similar = [] - for sponsor_a in sponsors: - for sponsor_b in sponsors: - if sponsor_a is not sponsor_b and sponsor_a["startTime"] >= sponsor_b["startTime"] and sponsor_a["startTime"] <= sponsor_b["endTime"]: - similar.append([sponsor_a, sponsor_b]) - if sponsor_a in best: - best.remove(sponsor_a) - if sponsor_b in best: - best.remove(sponsor_b) - for sponsors_a in similar: - if sponsors_a in dealtwith: - continue - group = set(sponsors_a) - for sponsors_b in similar: - if sponsors_b[0] in group or sponsors_b[1] in group: - group.add(sponsors_b[0]) - group.add(sponsors_b[1]) - dealtwith.append(sponsors_b) - best.append(max(group, key=lambda x:x["votes"])) - for time in best: - times.append(str(time["startTime"]) + "," + str(time["endTime"]) + "," + time["UUID"]) - print(":".join(times)) -elif sys.argv[1] == "update": - try: - urllib.request.urlretrieve(sys.argv[3] + "/database.db", sys.argv[2] + ".tmp") - os.replace(sys.argv[2] + ".tmp", sys.argv[2]) - except PermissionError: - print("database update failed, file currently in use", file=sys.stderr) - exit(1) - except ConnectionResetError: - print("database update failed, connection reset", file=sys.stderr) - exit(1) - except TimeoutError: - print("database update failed, timed out", file=sys.stderr) - exit(1) - except urllib.error.URLError: - print("database update failed", file=sys.stderr) - exit(1) -elif sys.argv[1] == "submit": - try: - response = urllib.request.urlopen(sys.argv[3] + "/api/postVideoSponsorTimes?videoID=" + sys.argv[4] + "&startTime=" + sys.argv[5] + "&endTime=" + sys.argv[6] + "&userID=" + uid) - print("success") - except urllib.error.HTTPError as e: - print(e.code) - except: - print("error") -elif sys.argv[1] == "stats": - try: - if sys.argv[6]: - urllib.request.urlopen(sys.argv[3] + "/api/viewedVideoSponsorTime?UUID=" + sys.argv[5]) - if sys.argv[9]: - urllib.request.urlopen(sys.argv[3] + "/api/voteOnSponsorTime?UUID=" + sys.argv[5] + "&userID=" + uid + "&type=" + sys.argv[9]) - except: - pass -elif sys.argv[1] == "username": - try: - data = urllib.parse.urlencode({"userID": uid, "userName": sys.argv[9]}).encode() - req = urllib.request.Request(sys.argv[3] + "/api/setUsername", data=data) - urllib.request.urlopen(req) - except: - pass diff --git a/mpv/.config/mpv/scripts/sponsorblock_legacy.lua b/mpv/.config/mpv/scripts/sponsorblock_legacy.lua deleted file mode 100644 index 6a980e5..0000000 --- a/mpv/.config/mpv/scripts/sponsorblock_legacy.lua +++ /dev/null @@ -1,3 +0,0 @@ -if mp.get_script_directory == nil then - dofile(mp.find_config_file("scripts/sponsorblock/main.lua")) -end diff --git a/mpv/.config/mpv/scripts/sponsorblock_minimal.lua b/mpv/.config/mpv/scripts/sponsorblock_minimal.lua new file mode 100644 index 0000000..a681c93 --- /dev/null +++ b/mpv/.config/mpv/scripts/sponsorblock_minimal.lua @@ -0,0 +1,88 @@ +-- sponsorblock_minimal.lua +-- +-- This script skips sponsored segments of YouTube videos +-- using data from https://github.com/ajayyy/SponsorBlock +-- +-- original from https://codeberg.org/jouni/mpv_sponsorblock_minimal +-- adapted for local playback skipping and some refactoring by me + +local options = { + API = "https://sponsor.ajay.app/api/skipSegments", + + -- Categories to fetch and skip + categories = '"sponsor","intro","outro","interaction","selfpromo"' +} + +local function getranges() + local args = { + "curl", + "-s", + "-d", + "videoID="..youtube_id, + "-d", + "categories=["..options.categories.."]", + "-G", + options.API} + local sponsors = mp.command_native({name = "subprocess", capture_stdout = true, playback_only = false, args = args}) + + if string.match(sponsors.stdout,"%[(.-)%]") then + ranges = {} + for i in string.gmatch(string.sub(sponsors.stdout,2,-2),"%[(.-)%]") do + k,v = string.match(i,"(%d+.?%d*),(%d+.?%d*)") + ranges[k] = v + end + end + return + end + +local function skip_ads(name,pos) + if pos ~= nil then + for k,v in pairs(ranges) do + if tonumber(k) <= pos and tonumber(v) > pos then + --this message may sometimes be wrong + --it only seems to be a visual thing though + mp.osd_message("[sponsorblock] skipping forward "..math.floor(tonumber(v)-mp.get_property("time-pos")).."s") + --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",tonumber(v)+0.01) + return + end + end + end + return +end + +local function file_loaded() + local video_path = mp.get_property("path") + local youtube_id1 = string.match(video_path, "https?://youtu%.be/([%w-_]+).*") + local youtube_id2 = string.match(video_path, "https?://w?w?w?%.?youtube%.com/v/([%w-_]+).*") + local youtube_id3 = string.match(video_path, "/watch.*[?&]v=([%w-_]+).*") + local youtube_id4 = string.match(video_path, "/embed/([%w-_]+).*") + local localytfile = string.match(video_path, "-([%a%d%-_]+)%.[mw][kpe][v4b][m]?$") + youtube_id = youtube_id1 or youtube_id2 or youtube_id3 or youtube_id4 or localytfile + 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 + +local 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) diff --git a/mpv/README.md b/mpv/README.md index cfe7774..2c55b89 100644 --- a/mpv/README.md +++ b/mpv/README.md @@ -49,12 +49,8 @@ It degrades gracefully, and simply keeps running in higher quality if the file i ## sponsorblock -The [mpv-sponsorblock](https://github.com/po5/mpv_sponsorblock) script is included to enable automatically skipping many sponsorship segments integrated within youtube videos. +The [minimal mpv-sponsorblock](https://codeberg.org/jouni/mpv_sponsorblock_minimal) script is included to enable automatically skipping many sponsorship segments integrated within youtube videos. -This works mostly fully automated, it checks the database and marks affected segments in red on your timeline, which it automatically skips over. +This works mostly fully automated, it checks the database and finds affected segments, which it then automatically skips over. -If you are watching a video with sponsorship segments that have not yet been marked, you can add your own segment with `e` -(once at the beginning of the segment, once at the end) and when that is done send it off to the database with `E`. - -If you watch a video and it contains a well-functioning skip, simply hit `w` to upvote the previous segment. -If a segment did not work well, skipped over other content or similar issues, hit `W` to downvote it. +To toggle sponsorblock on or off just hit `b`, it will confirm the choice via osd.