Add support for different playback speeds

This commit is contained in:
dmunozv04
2025-03-10 10:31:53 +01:00
parent 0d3ff8a54c
commit b4ccfb7e96
2 changed files with 23 additions and 13 deletions

View File

@@ -76,11 +76,11 @@ class DeviceListener:
# Method called on playback state change
async def __call__(self, state):
time_start = time.monotonic()
try:
self.task.cancel()
except BaseException:
pass
time_start = time.time()
self.task = asyncio.create_task(self.process_playstatus(state, time_start))
# Processes the playback state change
@@ -100,28 +100,29 @@ class DeviceListener:
start_next_segment = None
next_segment = None
for segment in segments:
if position < 2 and (segment["start"] <= position < segment["end"]):
segment_start = segment["start"]
is_within_start_range = position < 1 and segment_start <= position < segment["end"] and segment["end"] > 1
is_beyond_current_position = segment_start > position
if is_within_start_range or is_beyond_current_position:
next_segment = segment
start_next_segment = (
position # different variable so segment doesn't change
)
break
if segment["start"] > position:
next_segment = segment
start_next_segment = next_segment["start"]
start_next_segment = position if is_within_start_range else segment_start
break
if start_next_segment:
time_to_next = (
start_next_segment - position - (time.time() - time_start) - self.offset
)
(start_next_segment - position - (time.monotonic() - time_start))
/ self.lounge_controller.playback_speed
) - self.offset
await self.skip(time_to_next, next_segment["end"], next_segment["UUID"])
# Skips to the next segment (waits for the time to pass)
async def skip(self, time_to, position, uuids):
await asyncio.sleep(time_to)
self.logger.info("Skipping segment: seeking to %s", position)
await asyncio.create_task(self.api_helper.mark_viewed_segments(uuids))
await asyncio.create_task(self.lounge_controller.seek_to(position))
await asyncio.gather(
asyncio.create_task(self.lounge_controller.seek_to(position)),
asyncio.create_task(self.api_helper.mark_viewed_segments(uuids)),
)
async def cancel(self):
self.cancelled = True

View File

@@ -25,6 +25,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
self.auth.lounge_id_token = None
self.api_helper = api_helper
self.volume_state = {}
self.playback_speed = 1.0
self.subscribe_task = None
self.subscribe_task_watchdog = None
self.callback = None
@@ -154,6 +155,11 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
self.shorts_disconnected = True
elif event_type == "onAutoplayModeChanged":
create_task(self.set_auto_play_mode(self.auto_play))
elif event_type == "onPlaybackSpeedChanged":
data = args[0]
self.playback_speed = float(data.get("playbackSpeed", "1"))
create_task(self.get_now_playing())
super()._process_event(event_type, args)
@@ -185,6 +191,9 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
async def play_video(self, video_id: str) -> bool:
return await self._command("setPlaylist", {"videoId": video_id})
async def get_now_playing(self):
return await super()._command("getNowPlaying")
# Test to wrap the command function in a mutex to avoid race conditions with
# the _command_offset (TODO: move to upstream if it works)