This commit is contained in:
Ivan Habunek 2024-06-01 09:28:54 +02:00
parent 38636e2b21
commit adccb8ad0a
No known key found for this signature in database
GPG Key ID: F5F0623FF5EBCB3D
4 changed files with 38 additions and 11 deletions

1
.gitignore vendored
View File

@ -15,3 +15,4 @@ tmp/
/*.pyz
/pyrightconfig.json
/book
/*.mkv

View File

@ -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()

View File

@ -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(

View File

@ -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()