Compare commits
No commits in common. "03458db82937a260406d503977a0a4ffd57e33bf" and "60497cf29d98f478da85148f2bc7ee4024a20aa1" have entirely different histories.
03458db829
...
60497cf29d
4 changed files with 7 additions and 87 deletions
|
@ -22,9 +22,6 @@ class Config:
|
||||||
# Proxy URL for yt_proxied downloader (can be used for geo-restricted content)
|
# Proxy URL for yt_proxied downloader (can be used for geo-restricted content)
|
||||||
self.yt_proxy = os.getenv('YT_PROXY') or 'http://127.0.0.1:1080'
|
self.yt_proxy = os.getenv('YT_PROXY') or 'http://127.0.0.1:1080'
|
||||||
|
|
||||||
self.save_lyrics = _parse_bool(os.getenv('SAVE_LYRICS'), True)
|
|
||||||
self.save_cover = _parse_bool(os.getenv('SAVE_COVER'), True)
|
|
||||||
|
|
||||||
|
|
||||||
_config: Config | None = None
|
_config: Config | None = None
|
||||||
|
|
||||||
|
@ -34,11 +31,3 @@ def get() -> Config:
|
||||||
if _config is None:
|
if _config is None:
|
||||||
_config = Config()
|
_config = Config()
|
||||||
return _config
|
return _config
|
||||||
|
|
||||||
|
|
||||||
def _parse_bool(val: str | None, default: bool) -> bool:
|
|
||||||
if val is None:
|
|
||||||
return default
|
|
||||||
if val in {'false', 'off', 'no', '0'}:
|
|
||||||
return False
|
|
||||||
return bool(val)
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
import mimetypes
|
|
||||||
import subprocess
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import http_pool
|
|
||||||
|
|
||||||
|
|
||||||
def download_from_yt(url: str, album_path: Path) -> None:
|
|
||||||
'''YouTube-specific cover art downloader.
|
|
||||||
See https://git.dc09.ru/DarkCat09/musicdlp/issues/1#issuecomment-202'''
|
|
||||||
|
|
||||||
path = album_path / 'cover.webp'
|
|
||||||
if path.exists():
|
|
||||||
return
|
|
||||||
|
|
||||||
ret = subprocess.call(
|
|
||||||
[
|
|
||||||
'ffmpeg',
|
|
||||||
'-nostdin',
|
|
||||||
'-i', url,
|
|
||||||
'-vf', 'crop=ih:ih',
|
|
||||||
str(album_path / 'cover.webp'),
|
|
||||||
],
|
|
||||||
stdout=subprocess.DEVNULL,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
)
|
|
||||||
|
|
||||||
if ret != 0:
|
|
||||||
raise RuntimeError(f'FFmpeg returned {ret} exit code')
|
|
||||||
|
|
||||||
|
|
||||||
def download(url: str, album_path: Path) -> None:
|
|
||||||
'''General cover art downloader'''
|
|
||||||
|
|
||||||
resp = http_pool.get().request('GET', url)
|
|
||||||
ct = resp.headers['content-type']
|
|
||||||
if not ct.startswith('image'):
|
|
||||||
raise ValueError('thumbnail is not an image')
|
|
||||||
ext = mimetypes.guess_extension(ct) or '.jpg'
|
|
||||||
|
|
||||||
path = album_path / ('cover' + ext)
|
|
||||||
if path.exists():
|
|
||||||
return
|
|
||||||
|
|
||||||
with path.open('wb') as f:
|
|
||||||
f.write(resp.data)
|
|
|
@ -1,9 +1,6 @@
|
||||||
from pathlib import Path
|
|
||||||
from mutagen import mp3, id3
|
from mutagen import mp3, id3
|
||||||
from yt_dlp.postprocessor import PostProcessor
|
from yt_dlp.postprocessor import PostProcessor
|
||||||
|
|
||||||
import config
|
|
||||||
import cover
|
|
||||||
import genius
|
import genius
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,10 +44,6 @@ class ID3TagsPP(PostProcessor):
|
||||||
'''Inserts ID3 tags after all PPs (for YT: InfoYouTubePP and FFmpegExtractAudioPP),
|
'''Inserts ID3 tags after all PPs (for YT: InfoYouTubePP and FFmpegExtractAudioPP),
|
||||||
triggers searching and parsing lyrics from Genius'''
|
triggers searching and parsing lyrics from Genius'''
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.cfg = config.get()
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def run(self, information):
|
def run(self, information):
|
||||||
|
|
||||||
file = mp3.MP3(information['filepath'])
|
file = mp3.MP3(information['filepath'])
|
||||||
|
@ -69,24 +62,13 @@ class ID3TagsPP(PostProcessor):
|
||||||
if 'genre' in information:
|
if 'genre' in information:
|
||||||
file['TCON'] = id3.TCON(encoding=ENC_UTF8, text=information['genre'])
|
file['TCON'] = id3.TCON(encoding=ENC_UTF8, text=information['genre'])
|
||||||
|
|
||||||
if self.cfg.save_lyrics:
|
try:
|
||||||
try:
|
lyr_title, lyr_url = genius.search(title, artists[0])
|
||||||
lyr_title, lyr_url = genius.search(title, artists[0])
|
genius.raise_on_irrelevant_result(lyr_title, title, artists[0])
|
||||||
genius.raise_on_irrelevant_result(lyr_title, title, artists[0])
|
file['USLT'] = id3.USLT(encoding=ENC_UTF8, text=genius.parse(lyr_url))
|
||||||
file['USLT'] = id3.USLT(encoding=ENC_UTF8, text=genius.parse(lyr_url))
|
except:
|
||||||
except:
|
pass
|
||||||
pass
|
|
||||||
|
|
||||||
file.save()
|
file.save()
|
||||||
|
|
||||||
if self.cfg.save_cover:
|
|
||||||
try:
|
|
||||||
album_path = Path(information['filepath']).parent
|
|
||||||
if 'youtube' in information['extractor']:
|
|
||||||
cover.download_from_yt(information['thumbnail'], album_path)
|
|
||||||
else:
|
|
||||||
cover.download(information['thumbnail'], album_path)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return [], information
|
return [], information
|
||||||
|
|
|
@ -5,9 +5,8 @@ import subprocess
|
||||||
|
|
||||||
from mutagen import mp3
|
from mutagen import mp3
|
||||||
|
|
||||||
import config
|
|
||||||
import http_pool
|
|
||||||
import id3pp
|
import id3pp
|
||||||
|
import http_pool
|
||||||
|
|
||||||
|
|
||||||
TEST_MP3 = 'music/test.mp3'
|
TEST_MP3 = 'music/test.mp3'
|
||||||
|
@ -36,10 +35,6 @@ class TestPostProcessorsOnFakeData(TestCase):
|
||||||
|
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
|
|
||||||
cfg = config.get()
|
|
||||||
cfg.save_lyrics = False
|
|
||||||
cfg.save_cover = False
|
|
||||||
|
|
||||||
http_pool.get()
|
http_pool.get()
|
||||||
|
|
||||||
def test_infoytpp(self) -> None:
|
def test_infoytpp(self) -> None:
|
||||||
|
|
Loading…
Add table
Reference in a new issue