This commit is contained in:
Marc Beninca 2025-03-16 15:52:43 +01:00
parent 02cf8f83e7
commit 0b5d96116c
Signed by: marc.beninca
GPG key ID: 9C7613450C80C24F
3 changed files with 291 additions and 79 deletions

View file

@ -1,4 +1,4 @@
import yt_dlp
"""YouTube DownLoad."""
# playlists
# …
@ -14,7 +14,6 @@ import yt_dlp
# playlist / entries
# …
# videos
# id
# channel
@ -36,8 +35,80 @@ import yt_dlp
# 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"
# video
# id
# title
# formats
@ -50,93 +121,57 @@ import yt_dlp
# 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}"
def extract_playlist(playlist_id):
options = {
"quiet": False,
"extract_flat": True,
"force_generic_extractor": False,
"ignoreerrors": False,
}
url = f"https://youtube.com/playlist?list={playlist_id}"
print(f"""\
{options}
class Videos(Tab):
{url}
def __init__(self, channel_id: str) -> None:
self.channel_id = channel_id
""")
with yt_dlp.YoutubeDL(options) as y:
return y.extract_info(url, download=False)
def get_url(self) -> str:
return f"{Tab.URL_ROOT}/channel/{self.channel_id}/videos"
def extract_playlists(channel_id):
options = {
"quiet": False,
"extract_flat": True,
"force_generic_extractor": False,
"ignoreerrors": False,
"skip_download": True,
}
url = f"https://youtube.com/channel/{channel_id}/playlists"
print(f"""\
{options}
{url}
""")
with yt_dlp.YoutubeDL(options) as y:
return y.extract_info(url, download=False)
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):
options = {
"format": "bestvideo[ext=mp4]+bestaudio[ext=mp4]",
"outtmpl": "%(id)s.%(ext)s",
"writesubtitles": True,
"writethumbnail": True,
"ignoreerrors": False,
}
url = f"https://youtu.be/{video_id}"
print(f"""\
{options}
{url}
""")
with yt_dlp.YoutubeDL(options) as y:
return y.download([url])
def download_video(video_id: str):
return command(Action.DOWNLOAD_VIDEO, video_id)
def extract_video(video_id):
options = {
"quiet": False,
"ignoreerrors": False,
}
url = f"https://youtu.be/{video_id}"
print(f"""\
{options}
{url}
""")
with yt_dlp.YoutubeDL(options) as y:
return y.extract_info(url, download=False)
def extract_playlist(playlist_id: str):
return command(Action.EXTRACT_PLAYLIST, playlist_id)
def extract_videos(channel_id):
options = {
"quiet": False,
"extract_flat": True,
"force_generic_extractor": False,
"ignoreerrors": False,
}
url = f"https://youtube.com/channel/{channel_id}/videos"
print(f"""\
{options}
def extract_playlists(channel_id: str):
return command(Action.EXTRACT_PLAYLISTS, channel_id)
{url}
""")
with yt_dlp.YoutubeDL(options) as y:
return y.extract_info(url, download=False)
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)

177
rwx/sw/yt_dlp/__init__.py Normal file
View file

@ -0,0 +1,177 @@
"""YouTube."""
# 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)

0
rwx/sw/yt_dlp/video.py Normal file
View file