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
# …
@ -39,8 +39,7 @@ from abc import ABC, abstractmethod
from enum import Enum
from rwx import Object
from rwx.log import stream as log
import yt_dlp
from yt_dlp import YoutubeDL
class Action(Enum):
@ -66,6 +65,7 @@ class Tab(Object, ABC):
log.info(self.object_id)
self.url = self.get_url()
log.info(self.url)
self.info = Tab.yt_dl(self.get_options()).extract_info(self.url, download=False)
def get_options(self) -> dict:
"""Return options for the action.
@ -85,14 +85,13 @@ class Tab(Object, ABC):
"""
@staticmethod
def dl(opt: dict) -> yt_dlp.YoutubeDL:
def yt_dl(opt: dict) -> YoutubeDL:
options = {**opt, "ignoreerrors": False, "quiet": False}
log.info(options)
return yt_dlp.YoutubeDL(options)
return YoutubeDL(options)
class Playlist(Tab):
def __init__(self, playlist_id: str) -> None:
self.playlist_id = playlist_id
@ -101,7 +100,6 @@ class Playlist(Tab):
class Playlists(Tab):
def __init__(self, channel_id: str) -> None:
self.channel_id = channel_id
@ -122,16 +120,24 @@ class Playlists(Tab):
# tags
# fulltitle
class Video(Tab):
def __init__(self, video_id: str) -> None:
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:
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
@ -140,38 +146,8 @@ class Videos(Tab):
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)