2024-03-31 19:39:54 +00:00
|
|
|
import click
|
2021-01-14 20:38:56 +00:00
|
|
|
import m3u8
|
|
|
|
|
|
|
|
from twitchdl import utils, twitch
|
2024-03-30 06:32:12 +00:00
|
|
|
from twitchdl.commands.download import get_video_placeholders
|
2021-01-14 20:38:56 +00:00
|
|
|
from twitchdl.exceptions import ConsoleError
|
2024-03-31 19:39:54 +00:00
|
|
|
from twitchdl.output import bold, print_table, print_video, print_clip, print_json, print_log
|
2024-04-02 07:44:20 +00:00
|
|
|
from twitchdl.twitch import Clip, Video
|
|
|
|
|
2021-01-14 20:38:56 +00:00
|
|
|
|
2024-03-23 09:50:42 +00:00
|
|
|
def info(id: str, *, json: bool = False):
|
|
|
|
video_id = utils.parse_video_identifier(id)
|
2021-01-14 20:38:56 +00:00
|
|
|
if video_id:
|
|
|
|
print_log("Fetching video...")
|
|
|
|
video = twitch.get_video(video_id)
|
|
|
|
|
2021-01-14 21:23:40 +00:00
|
|
|
if not video:
|
2024-03-28 11:06:50 +00:00
|
|
|
raise ConsoleError(f"Video {video_id} not found")
|
2021-01-14 21:23:40 +00:00
|
|
|
|
2021-01-14 20:38:56 +00:00
|
|
|
print_log("Fetching access token...")
|
|
|
|
access_token = twitch.get_access_token(video_id)
|
|
|
|
|
|
|
|
print_log("Fetching playlists...")
|
|
|
|
playlists = twitch.get_playlists(video_id, access_token)
|
|
|
|
|
2022-11-20 08:42:09 +00:00
|
|
|
print_log("Fetching chapters...")
|
|
|
|
chapters = twitch.get_video_chapters(video_id)
|
|
|
|
|
2024-03-23 09:50:42 +00:00
|
|
|
if json:
|
2022-11-20 08:42:09 +00:00
|
|
|
video_json(video, playlists, chapters)
|
|
|
|
else:
|
|
|
|
video_info(video, playlists, chapters)
|
|
|
|
return
|
2021-01-14 20:38:56 +00:00
|
|
|
|
2024-03-23 09:50:42 +00:00
|
|
|
clip_slug = utils.parse_clip_identifier(id)
|
2021-01-14 20:38:56 +00:00
|
|
|
if clip_slug:
|
|
|
|
print_log("Fetching clip...")
|
|
|
|
clip = twitch.get_clip(clip_slug)
|
2021-01-14 21:23:40 +00:00
|
|
|
if not clip:
|
2024-03-28 11:06:50 +00:00
|
|
|
raise ConsoleError(f"Clip {clip_slug} not found")
|
2021-01-14 21:23:40 +00:00
|
|
|
|
2024-03-23 09:50:42 +00:00
|
|
|
if json:
|
2021-01-14 21:23:40 +00:00
|
|
|
print_json(clip)
|
|
|
|
else:
|
|
|
|
clip_info(clip)
|
|
|
|
return
|
2021-01-14 20:38:56 +00:00
|
|
|
|
2024-03-28 11:06:50 +00:00
|
|
|
raise ConsoleError(f"Invalid input: {id}")
|
2021-01-14 20:38:56 +00:00
|
|
|
|
|
|
|
|
2024-04-02 07:37:53 +00:00
|
|
|
def video_info(video: Video, playlists, chapters):
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo()
|
2021-01-14 20:38:56 +00:00
|
|
|
print_video(video)
|
|
|
|
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo("Playlists:")
|
2021-01-14 20:38:56 +00:00
|
|
|
for p in m3u8.loads(playlists).playlists:
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo(f"{bold(p.stream_info.video)} {p.uri}")
|
2021-01-14 20:38:56 +00:00
|
|
|
|
2022-11-20 08:42:09 +00:00
|
|
|
if chapters:
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo()
|
|
|
|
click.echo("Chapters:")
|
2022-11-20 08:42:09 +00:00
|
|
|
for chapter in chapters:
|
|
|
|
start = utils.format_time(chapter["positionMilliseconds"] // 1000, force_hours=True)
|
|
|
|
duration = utils.format_time(chapter["durationMilliseconds"] // 1000)
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo(f'{start} {bold(chapter["description"])} ({duration})')
|
2022-11-20 08:42:09 +00:00
|
|
|
|
2024-03-30 06:32:12 +00:00
|
|
|
placeholders = get_video_placeholders(video, format = "mkv")
|
|
|
|
placeholders = [[f"{{{k}}}", v] for k, v in placeholders.items()]
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo("")
|
2024-03-30 06:32:12 +00:00
|
|
|
print_table(["Placeholder", "Value"], placeholders)
|
|
|
|
|
2021-01-14 20:38:56 +00:00
|
|
|
|
2022-11-20 08:42:09 +00:00
|
|
|
def video_json(video, playlists, chapters):
|
2021-01-14 20:38:56 +00:00
|
|
|
playlists = m3u8.loads(playlists).playlists
|
|
|
|
|
|
|
|
video["playlists"] = [
|
|
|
|
{
|
|
|
|
"bandwidth": p.stream_info.bandwidth,
|
|
|
|
"resolution": p.stream_info.resolution,
|
|
|
|
"codecs": p.stream_info.codecs,
|
|
|
|
"video": p.stream_info.video,
|
|
|
|
"uri": p.uri
|
|
|
|
} for p in playlists
|
|
|
|
]
|
|
|
|
|
2022-11-20 08:42:09 +00:00
|
|
|
video["chapters"] = chapters
|
|
|
|
|
2021-01-14 20:38:56 +00:00
|
|
|
print_json(video)
|
|
|
|
|
|
|
|
|
2024-04-02 07:44:20 +00:00
|
|
|
def clip_info(clip: Clip):
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo()
|
2021-01-14 20:38:56 +00:00
|
|
|
print_clip(clip)
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo()
|
|
|
|
click.echo("Download links:")
|
2021-01-14 20:38:56 +00:00
|
|
|
|
|
|
|
for q in clip["videoQualities"]:
|
2024-03-31 19:39:54 +00:00
|
|
|
click.echo(f"{bold(q['quality'])} [{q['frameRate']} fps] {q['sourceURL']}")
|