mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-23 19:47:08 -04:00
Add support for Youtube urls
This commit is contained in:
parent
10ceecb55c
commit
7347330a42
6 changed files with 63 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,3 +17,4 @@ StreamripDownloads
|
||||||
*.mkv
|
*.mkv
|
||||||
*.aac
|
*.aac
|
||||||
*.pyc
|
*.pyc
|
||||||
|
*test.py
|
||||||
|
|
|
@ -765,7 +765,7 @@ class Tracklist(list):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for item in self:
|
for item in self:
|
||||||
if self.client.source != 'soundcloud':
|
if self.client.source != "soundcloud":
|
||||||
# soundcloud only gets metadata after `target` is called
|
# soundcloud only gets metadata after `target` is called
|
||||||
# message will be printed in `target`
|
# message will be printed in `target`
|
||||||
click.secho(f'\nDownloading "{item!s}"', fg="blue")
|
click.secho(f'\nDownloading "{item!s}"', fg="blue")
|
||||||
|
@ -951,3 +951,39 @@ class Tracklist(list):
|
||||||
|
|
||||||
if isinstance(key, int):
|
if isinstance(key, int):
|
||||||
super().__setitem__(key, val)
|
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
|
||||||
|
|
|
@ -69,6 +69,9 @@ class Config:
|
||||||
"soundcloud": {
|
"soundcloud": {
|
||||||
"quality": 0,
|
"quality": 0,
|
||||||
},
|
},
|
||||||
|
"youtube": {
|
||||||
|
"quality": 0,
|
||||||
|
},
|
||||||
"database": {"enabled": True, "path": None},
|
"database": {"enabled": True, "path": None},
|
||||||
"conversion": {
|
"conversion": {
|
||||||
"enabled": False,
|
"enabled": False,
|
||||||
|
|
|
@ -145,7 +145,7 @@ LASTFM_URL_REGEX = r"https://www.last.fm/user/\w+/playlists/\w+"
|
||||||
QOBUZ_INTERPRETER_URL_REGEX = (
|
QOBUZ_INTERPRETER_URL_REGEX = (
|
||||||
r"https?://www\.qobuz\.com/\w\w-\w\w/interpreter/[-\w]+/[-\w]+"
|
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
|
TIDAL_MAX_Q = 7
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,14 @@ import click
|
||||||
import requests
|
import requests
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from .bases import Track, Video
|
from .bases import Track, Video, YoutubeVideo
|
||||||
from .clients import DeezerClient, QobuzClient, SoundCloudClient, TidalClient
|
from .clients import DeezerClient, QobuzClient, SoundCloudClient, TidalClient
|
||||||
from .config import Config
|
from .config import Config
|
||||||
from .constants import (
|
from .constants import (
|
||||||
CONFIG_PATH,
|
CONFIG_PATH,
|
||||||
DB_PATH,
|
DB_PATH,
|
||||||
LASTFM_URL_REGEX,
|
LASTFM_URL_REGEX,
|
||||||
|
YOUTUBE_URL_REGEX,
|
||||||
MEDIA_TYPES,
|
MEDIA_TYPES,
|
||||||
QOBUZ_INTERPRETER_URL_REGEX,
|
QOBUZ_INTERPRETER_URL_REGEX,
|
||||||
SOUNDCLOUD_URL_REGEX,
|
SOUNDCLOUD_URL_REGEX,
|
||||||
|
@ -58,6 +59,7 @@ class MusicDL(list):
|
||||||
self.soundcloud_url_parse = re.compile(SOUNDCLOUD_URL_REGEX)
|
self.soundcloud_url_parse = re.compile(SOUNDCLOUD_URL_REGEX)
|
||||||
self.lastfm_url_parse = re.compile(LASTFM_URL_REGEX)
|
self.lastfm_url_parse = re.compile(LASTFM_URL_REGEX)
|
||||||
self.interpreter_url_parse = re.compile(QOBUZ_INTERPRETER_URL_REGEX)
|
self.interpreter_url_parse = re.compile(QOBUZ_INTERPRETER_URL_REGEX)
|
||||||
|
self.youtube_url_parse = re.compile(YOUTUBE_URL_REGEX)
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
if self.config is None:
|
if self.config is None:
|
||||||
|
@ -89,7 +91,17 @@ class MusicDL(list):
|
||||||
:raises ParsingError
|
: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:
|
if item_id in self.db:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"ID {item_id} already downloaded, use --no-db to override."
|
f"ID {item_id} already downloaded, use --no-db to override."
|
||||||
|
@ -170,6 +182,10 @@ class MusicDL(list):
|
||||||
item.client.source
|
item.client.source
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if item is YoutubeVideo:
|
||||||
|
item.download(**arguments)
|
||||||
|
continue
|
||||||
|
|
||||||
arguments["quality"] = self.config.session[item.client.source]["quality"]
|
arguments["quality"] = self.config.session[item.client.source]["quality"]
|
||||||
if isinstance(item, Artist):
|
if isinstance(item, Artist):
|
||||||
filters_ = tuple(
|
filters_ = tuple(
|
||||||
|
@ -266,10 +282,7 @@ class MusicDL(list):
|
||||||
|
|
||||||
logger.debug(f"Parsed urls: {parsed}")
|
logger.debug(f"Parsed urls: {parsed}")
|
||||||
|
|
||||||
if parsed != []:
|
return parsed
|
||||||
return parsed
|
|
||||||
|
|
||||||
raise ParsingError(f"Error parsing URL: `{url}`")
|
|
||||||
|
|
||||||
def handle_lastfm_urls(self, urls):
|
def handle_lastfm_urls(self, urls):
|
||||||
# https://www.last.fm/user/nathan3895/playlists/12058911
|
# https://www.last.fm/user/nathan3895/playlists/12058911
|
||||||
|
|
|
@ -415,10 +415,10 @@ class Playlist(Tracklist):
|
||||||
self.download_message()
|
self.download_message()
|
||||||
|
|
||||||
def _download_item(self, item: Track, **kwargs):
|
def _download_item(self, item: Track, **kwargs):
|
||||||
kwargs['parent_folder'] = self.folder
|
kwargs["parent_folder"] = self.folder
|
||||||
if self.client.source == "soundcloud":
|
if self.client.source == "soundcloud":
|
||||||
item.load_meta()
|
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):
|
if kwargs.get("set_playlist_to_album", False):
|
||||||
item["album"] = self.name
|
item["album"] = self.name
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue