This commit is contained in:
Marc Beninca 2025-03-16 16:17:02 +01:00
parent 0b5d96116c
commit 61ea62a272
Signed by: marc.beninca
GPG key ID: 9C7613450C80C24F
2 changed files with 15 additions and 216 deletions

View file

@ -1,177 +0,0 @@
"""YouTube DownLoad."""
# playlists
# …
# entries
# playlists / entries
# title
# id
# playlist
# entries
# playlist / entries
# …
# videos
# id
# channel
# channel_id
# title
# channel_follower_count
# description
# tags
# thumbnails
# uploader_id
# uploader
# entries
# videos / entries
# id
# title
# description truncated
# duration
# thumbnails
# view_count
from abc import ABC, abstractmethod
from enum import Enum
from rwx import Object
from rwx.log import stream as log
import yt_dlp
class Action(Enum):
DOWNLOAD_VIDEO = 0
EXTRACT_PLAYLIST = 1
EXTRACT_PLAYLISTS = 2
EXTRACT_VIDEO = 3
EXTRACT_VIDEOS = 4
class Tab(Object, ABC):
"""YouTube Tab."""
URL_ROOT = "https://youtube.com"
def __init__(self, object_id: str) -> None:
"""Set object id.
:param object_id: object identifier
:type object_id: str
"""
self.object_id = object_id
log.info(self.object_id)
self.url = self.get_url()
log.info(self.url)
def get_options(self) -> dict:
"""Return options for the action.
:rtype: dict
"""
return {
"extract_flat": True,
"skip_download": True,
}
@abstractmethod
def get_url(self) -> str:
"""Return URL to access for object.
:rtype: str
"""
@staticmethod
def dl(opt: dict) -> yt_dlp.YoutubeDL:
options = {**opt, "ignoreerrors": False, "quiet": False}
log.info(options)
return yt_dlp.YoutubeDL(options)
class Playlist(Tab):
def __init__(self, playlist_id: str) -> None:
self.playlist_id = playlist_id
def get_url(self) -> str:
return f"{Tab.URL_ROOT}/playlist?list={self.playlist_id}"
class Playlists(Tab):
def __init__(self, channel_id: str) -> None:
self.channel_id = channel_id
def get_url(self) -> str:
return f"{Tab.URL_ROOT}/channel/{self.channel_id}/playlists"
# id
# title
# formats
# thumbnails
# thumbnail
# description
#
# duration
# view_count
# categories
# tags
# fulltitle
class Video(Tab):
def __init__(self, video_id: str) -> None:
self.video_id = video_id
def get_url(self) -> str:
return f"{Tab.URL_ROOT}/watch?v={self.video_id}"
class Videos(Tab):
def __init__(self, channel_id: str) -> None:
self.channel_id = channel_id
def get_url(self) -> str:
return f"{Tab.URL_ROOT}/channel/{self.channel_id}/videos"
def command(action: Action):
match action:
case Action.DOWNLOAD_VIDEO:
options = {
"format": "bestvideo[ext=mp4]+bestaudio[ext=mp4]",
"outtmpl": "%(id)s.%(ext)s",
"writesubtitles": True,
"writethumbnail": True,
}
log.info(options)
with dl(options) as youtube:
match action:
case Action.DOWNLOAD_VIDEO:
youtube.download([url])
case _:
youtube.extract_info(url, download=False)
def download_video(video_id: str):
return command(Action.DOWNLOAD_VIDEO, video_id)
def extract_playlist(playlist_id: str):
return command(Action.EXTRACT_PLAYLIST, playlist_id)
def extract_playlists(channel_id: str):
return command(Action.EXTRACT_PLAYLISTS, channel_id)
def extract_video(video_id: str):
return command(Action.EXTRACT_VIDEO, video_id)
def extract_videos(channel_id: str):
return command(Action.EXTRACT_VIDEOS, channel_id)

View file

@ -1,4 +1,4 @@
"""YouTube.""" """YouTube DownLoad."""
# playlists # playlists
# … # …
@ -39,8 +39,7 @@ from abc import ABC, abstractmethod
from enum import Enum from enum import Enum
from rwx import Object from rwx import Object
from rwx.log import stream as log from rwx.log import stream as log
from yt_dlp import YoutubeDL
import yt_dlp
class Action(Enum): class Action(Enum):
@ -66,6 +65,7 @@ class Tab(Object, ABC):
log.info(self.object_id) log.info(self.object_id)
self.url = self.get_url() self.url = self.get_url()
log.info(self.url) log.info(self.url)
self.info = Tab.yt_dl(self.get_options()).extract_info(self.url, download=False)
def get_options(self) -> dict: def get_options(self) -> dict:
"""Return options for the action. """Return options for the action.
@ -85,14 +85,13 @@ class Tab(Object, ABC):
""" """
@staticmethod @staticmethod
def dl(opt: dict) -> yt_dlp.YoutubeDL: def yt_dl(opt: dict) -> YoutubeDL:
options = {**opt, "ignoreerrors": False, "quiet": False} options = {**opt, "ignoreerrors": False, "quiet": False}
log.info(options) log.info(options)
return yt_dlp.YoutubeDL(options) return YoutubeDL(options)
class Playlist(Tab): class Playlist(Tab):
def __init__(self, playlist_id: str) -> None: def __init__(self, playlist_id: str) -> None:
self.playlist_id = playlist_id self.playlist_id = playlist_id
@ -101,7 +100,6 @@ class Playlist(Tab):
class Playlists(Tab): class Playlists(Tab):
def __init__(self, channel_id: str) -> None: def __init__(self, channel_id: str) -> None:
self.channel_id = channel_id self.channel_id = channel_id
@ -122,16 +120,24 @@ class Playlists(Tab):
# tags # tags
# fulltitle # fulltitle
class Video(Tab): class Video(Tab):
def __init__(self, video_id: str) -> None: def __init__(self, video_id: str) -> None:
self.video_id = video_id self.video_id = video_id
def download(self) -> None:
Tab.yt_dl(
{
"format": "bestvideo[ext=mp4]+bestaudio[ext=mp4]",
"outtmpl": "%(id)s.%(ext)s",
"writesubtitles": True,
"writethumbnail": True,
}
).download([self.url])
def get_url(self) -> str: def get_url(self) -> str:
return f"{Tab.URL_ROOT}/watch?v={self.video_id}" return f"{Tab.URL_ROOT}/watch?v={self.video_id}"
class Videos(Tab): class Videos(Tab):
def __init__(self, channel_id: str) -> None: def __init__(self, channel_id: str) -> None:
self.channel_id = channel_id self.channel_id = channel_id
@ -140,38 +146,8 @@ class Videos(Tab):
def command(action: Action): def command(action: Action):
match action:
case Action.DOWNLOAD_VIDEO:
options = {
"format": "bestvideo[ext=mp4]+bestaudio[ext=mp4]",
"outtmpl": "%(id)s.%(ext)s",
"writesubtitles": True,
"writethumbnail": True,
}
log.info(options) log.info(options)
with dl(options) as youtube: with dl(options) as youtube:
match action: match action:
case Action.DOWNLOAD_VIDEO:
youtube.download([url])
case _: case _:
youtube.extract_info(url, download=False) youtube.extract_info(url, download=False)
def download_video(video_id: str):
return command(Action.DOWNLOAD_VIDEO, video_id)
def extract_playlist(playlist_id: str):
return command(Action.EXTRACT_PLAYLIST, playlist_id)
def extract_playlists(channel_id: str):
return command(Action.EXTRACT_PLAYLISTS, channel_id)
def extract_video(video_id: str):
return command(Action.EXTRACT_VIDEO, video_id)
def extract_videos(channel_id: str):
return command(Action.EXTRACT_VIDEOS, channel_id)