From adccb8ad0a9265ed6c5cb8eb26b672270fb77d58 Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Sat, 1 Jun 2024 09:28:54 +0200 Subject: [PATCH] wip --- .gitignore | 1 + twitchdl/commands/download.py | 26 ++++++++++++++++++++++---- twitchdl/playlists.py | 18 +++++++++++++----- twitchdl/progress.py | 4 ++-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 4c96bec..821767c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ tmp/ /*.pyz /pyrightconfig.json /book +/*.mkv diff --git a/twitchdl/commands/download.py b/twitchdl/commands/download.py index 75d5182..ffa843e 100644 --- a/twitchdl/commands/download.py +++ b/twitchdl/commands/download.py @@ -50,7 +50,14 @@ def download_one(video: str, args: DownloadOptions): raise ConsoleError(f"Invalid input: {video}") -def _join_vods(playlist_path: str, target: str, overwrite: bool, video: Video): +def _join_vods( + playlist_path: str, + target: str, + overwrite: bool, + video: Video, + start_offset: int, + duration: int, +): description = video["description"] or "" description = description.strip() @@ -60,6 +67,10 @@ def _join_vods(playlist_path: str, target: str, overwrite: bool, video: Video): playlist_path, "-c", "copy", + "-ss", + str(start_offset), + "-to", + str(duration), "-metadata", f"artist={video['creator']['displayName']}", "-metadata", @@ -73,11 +84,11 @@ def _join_vods(playlist_path: str, target: str, overwrite: bool, video: Video): "warning", f"file:{target}", ] - if overwrite: command.append("-y") click.secho(f"{' '.join(command)}", dim=True) + result = subprocess.run(command) if result.returncode != 0: raise ConsoleError("Joining files failed") @@ -275,7 +286,14 @@ def _download_video(video_id: str, args: DownloadOptions) -> None: print_log("Fetching playlist...") vods_text = http_get(playlist.url) vods_m3u8 = load_m3u8(vods_text) - vods = enumerate_vods(vods_m3u8, start, end) + vods, start_offset, end_offset = enumerate_vods(vods_m3u8, start, end) + vods_duration = sum(v.duration for v in vods) + duration = vods_duration - start_offset - end_offset + + print(f"{vods_duration=}") + print(f"{start_offset=}") + print(f"{end_offset=}") + print(f"{duration=}") if args.dry_run: click.echo("Dry run, video not downloaded.") @@ -311,7 +329,7 @@ def _download_video(video_id: str, args: DownloadOptions) -> None: _concat_vods(targets, target) else: print_log("Joining files...") - _join_vods(join_playlist_path, target, args.overwrite, video) + _join_vods(join_playlist_path, target, args.overwrite, video, start_offset, duration) click.echo() diff --git a/twitchdl/playlists.py b/twitchdl/playlists.py index 3a27058..72fdbc6 100644 --- a/twitchdl/playlists.py +++ b/twitchdl/playlists.py @@ -3,7 +3,7 @@ Parse and manipulate m3u8 playlists. """ from dataclasses import dataclass -from typing import Generator, List, Optional, OrderedDict +from typing import Generator, List, Optional, OrderedDict, Tuple import click import m3u8 @@ -57,25 +57,33 @@ def enumerate_vods( document: m3u8.M3U8, start: Optional[int] = None, end: Optional[int] = None, -) -> List[Vod]: +) -> Tuple[List[Vod], int, int]: """Extract VODs for download from document.""" vods = [] vod_start = 0 + # How much time needs to be taken off by ffmpeg when joining + start_offset = 0 + end_offset = 0 + for index, segment in enumerate(document.segments): vod_end = vod_start + segment.duration - # `vod_end > start` is used here becuase it's better to download a bit - # more than a bit less, similar for the end condition start_condition = not start or vod_end > start end_condition = not end or vod_start < end if start_condition and end_condition: vods.append(Vod(index, segment.uri, segment.duration)) + if start and start > vod_start and start < vod_end: + start_offset = start - vod_start + + if end and end > vod_start and end < vod_end: + end_offset = vod_end - end + vod_start = vod_end - return vods + return vods, int(start_offset), int(end_offset) def make_join_playlist( diff --git a/twitchdl/progress.py b/twitchdl/progress.py index 4c4765a..0f1b349 100644 --- a/twitchdl/progress.py +++ b/twitchdl/progress.py @@ -121,8 +121,8 @@ class Progress: def print(self): now = time.time() - # Don't print more often than 10 times per second - if self.last_printed and now - self.last_printed < 0.1: + # Don't print more often than 5 times per second + if self.last_printed and now - self.last_printed < 0.2: return self._recalculate()