diff --git a/commands/voice/playback.py b/commands/voice/playback.py index 6bd34bc..55b1a79 100644 --- a/commands/voice/playback.py +++ b/commands/voice/playback.py @@ -2,6 +2,7 @@ import disnake_paginator import arguments import commands +import sponsorblock import utils from constants import EMBED_COLOR from state import players @@ -89,11 +90,19 @@ async def pause(message): async def fast_forward(message): tokens = commands.tokenize(message.content) parser = arguments.ArgumentParser(tokens[0], "fast forward audio playback") - parser.add_argument( - "seconds", + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument( + "-s", + "--seconds", type=lambda v: arguments.range_type(v, min=0, max=300), help="the amount of seconds to fast forward", ) + group.add_argument( + "-S", + "--sponsorblock", + action="store_true", + help="go to the end of the current sponsorblock segment", + ) if not (args := await parser.parse_args(message, tokens)): return @@ -104,8 +113,26 @@ async def fast_forward(message): await utils.reply(message, "nothing is playing!") return + seconds = args.seconds + if args.sponsorblock: + video = sponsorblock.get_segments(players[message.guild.id].current.player.id) + if not video: + await utils.reply( + message, "no sponsorblock segments were found for this video!" + ) + return + + progress = message.guild.voice_client.source.original.progress + for segment in video["segments"]: + begin, end = map(float, segment["segment"]) + if progress >= begin and progress < end: + seconds = end - message.guild.voice_client.source.original.progress + if not seconds: + await utils.reply(message, "no sponsorblock segment is currently playing!") + return + message.guild.voice_client.pause() - message.guild.voice_client.source.original.fast_forward(args.seconds) + message.guild.voice_client.source.original.fast_forward(seconds) message.guild.voice_client.resume() await utils.add_check_reaction(message) diff --git a/constants.py b/constants.py index 5a1e3eb..45df0de 100644 --- a/constants.py +++ b/constants.py @@ -36,6 +36,7 @@ RELOADABLE_MODULES = [ "events", "extra", "fun", + "sponsorblock", "tasks", "utils", "voice", diff --git a/sponsorblock.py b/sponsorblock.py new file mode 100644 index 0000000..91c97b4 --- /dev/null +++ b/sponsorblock.py @@ -0,0 +1,21 @@ +import hashlib + +import requests + +from state import sponsorblock_cache + + +def get_segments(videoId: str): + if videoId in sponsorblock_cache: + return sponsorblock_cache[videoId] + + hashPrefix = hashlib.sha256(videoId.encode()).hexdigest()[:4] + response = requests.get( + f'https://sponsor.ajay.app/api/skipSegments/{hashPrefix}?categories=["music_offtopic"]' + ) + print(response.text) + if response.status_code == 200 and ( + results := list(filter(lambda v: videoId == v["videoID"], response.json())) + ): + sponsorblock_cache[videoId] = results[0] + return results[0] diff --git a/state.py b/state.py index 52dd17c..d232fdb 100644 --- a/state.py +++ b/state.py @@ -15,4 +15,5 @@ idle_tracker = {"is_idle": False, "last_used": time.time()} kill = {"transcript": False} message_responses = LimitedSizeDict() players = {} +sponsorblock_cache = LimitedSizeDict(size_limit=100) start_time = time.time()