Add support for Youtube urls

This commit is contained in:
nathom 2021-04-22 17:22:33 -07:00
parent 10ceecb55c
commit 7347330a42
6 changed files with 63 additions and 10 deletions

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ StreamripDownloads
*.mkv
*.aac
*.pyc
*test.py

View File

@ -765,7 +765,7 @@ class Tracklist(list):
else:
for item in self:
if self.client.source != 'soundcloud':
if self.client.source != "soundcloud":
# soundcloud only gets metadata after `target` is called
# message will be printed in `target`
click.secho(f'\nDownloading "{item!s}"', fg="blue")
@ -951,3 +951,39 @@ class Tracklist(list):
if isinstance(key, int):
super().__setitem__(key, val)
class YoutubeVideo:
"""Dummy class implemented for consistency with the Media API."""
class DummyClient:
source = 'youtube'
def __init__(self, url: str):
self.url = url
self.client = self.DummyClient()
def download(self, parent_folder='StreamripDownloads', **kwargs):
filename_formatter = "%(track_number)s.%(track)s.%(container)s"
filename = os.path.join(parent_folder, filename_formatter)
p = subprocess.Popen(
[
"youtube-dl",
"-x",
"--add-metadata",
"--audio-format",
"mp3",
"--embed-thumbnail",
"-o",
filename,
self.url,
]
)
p.wait()
def load_meta(self, *args, **kwargs):
pass
def tag(self, *args, **kwargs):
pass

View File

@ -69,6 +69,9 @@ class Config:
"soundcloud": {
"quality": 0,
},
"youtube": {
"quality": 0,
},
"database": {"enabled": True, "path": None},
"conversion": {
"enabled": False,

View File

@ -145,7 +145,7 @@ LASTFM_URL_REGEX = r"https://www.last.fm/user/\w+/playlists/\w+"
QOBUZ_INTERPRETER_URL_REGEX = (
r"https?://www\.qobuz\.com/\w\w-\w\w/interpreter/[-\w]+/[-\w]+"
)
YOUTUBE_URL_REGEX = r"https://www\.youtube\.com/watch\?v=\w+"
TIDAL_MAX_Q = 7

View File

@ -12,13 +12,14 @@ import click
import requests
from tqdm import tqdm
from .bases import Track, Video
from .bases import Track, Video, YoutubeVideo
from .clients import DeezerClient, QobuzClient, SoundCloudClient, TidalClient
from .config import Config
from .constants import (
CONFIG_PATH,
DB_PATH,
LASTFM_URL_REGEX,
YOUTUBE_URL_REGEX,
MEDIA_TYPES,
QOBUZ_INTERPRETER_URL_REGEX,
SOUNDCLOUD_URL_REGEX,
@ -58,6 +59,7 @@ class MusicDL(list):
self.soundcloud_url_parse = re.compile(SOUNDCLOUD_URL_REGEX)
self.lastfm_url_parse = re.compile(LASTFM_URL_REGEX)
self.interpreter_url_parse = re.compile(QOBUZ_INTERPRETER_URL_REGEX)
self.youtube_url_parse = re.compile(YOUTUBE_URL_REGEX)
self.config = config
if self.config is None:
@ -89,7 +91,17 @@ class MusicDL(list):
:raises ParsingError
"""
for source, url_type, item_id in self.parse_urls(url):
# youtube is handled by youtube-dl, so much of the
# processing is not necessary
youtube_urls = self.youtube_url_parse.findall(url)
if youtube_urls != []:
self.extend(YoutubeVideo(u) for u in youtube_urls)
parsed = self.parse_urls(url)
if not parsed and len(self) == 0:
raise ParsingError(url)
for source, url_type, item_id in parsed:
if item_id in self.db:
logger.info(
f"ID {item_id} already downloaded, use --no-db to override."
@ -170,6 +182,10 @@ class MusicDL(list):
item.client.source
)
if item is YoutubeVideo:
item.download(**arguments)
continue
arguments["quality"] = self.config.session[item.client.source]["quality"]
if isinstance(item, Artist):
filters_ = tuple(
@ -266,10 +282,7 @@ class MusicDL(list):
logger.debug(f"Parsed urls: {parsed}")
if parsed != []:
return parsed
raise ParsingError(f"Error parsing URL: `{url}`")
return parsed
def handle_lastfm_urls(self, urls):
# https://www.last.fm/user/nathan3895/playlists/12058911

View File

@ -415,10 +415,10 @@ class Playlist(Tracklist):
self.download_message()
def _download_item(self, item: Track, **kwargs):
kwargs['parent_folder'] = self.folder
kwargs["parent_folder"] = self.folder
if self.client.source == "soundcloud":
item.load_meta()
click.secho(f"Downloading {item!s}", fg='blue')
click.secho(f"Downloading {item!s}", fg="blue")
if kwargs.get("set_playlist_to_album", False):
item["album"] = self.name