1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- import hashlib
- import config
- from .utils import system
- from .type import Album, Track
- from genius.type import Album as gAlbum
- import asyncio
- from pathlib import Path
- import genius
- from .mp3 import set_track
- from .slice import slice_audio
- class Downloader:
- @staticmethod
- async def download_audio(url: str):
- if "youtu.be" in url:
- filename = url.split("/")[-1] + ".mp3"
- else:
- filename = url.split("?")[-1] + ".mp3"
- path = config.tmp_folder / filename
- if path.exists():
- return path
- command = f'youtube-dl -o "tmp/%(id)s.%(ext)s" -x --audio-format mp3 {url}'
- await system(command)
- return path
- @staticmethod
- async def download_album(album: Album):
- tasks = []
- if "watch" in album.audio_url or "youtu.be" in album.audio_url:
- _, genius_album = await asyncio.gather(
- asyncio.Task(Downloader.download_audio(album.audio_url)),
- genius.get_album(album.meta_url)
- )
- for track in album.tracks:
- tasks.append(
- asyncio.Task(Downloader.download_track(track, genius_album))
- )
- return genius_album, await asyncio.gather(*tasks)
- @staticmethod
- async def download_track(track: Track, album: gAlbum = None):
- hash = hashlib.md5(track.meta_url.split("/")[-1].encode()).hexdigest()
- async def get_audio():
- src = await Downloader.download_audio(track.audio_url)
- return await slice_audio(src, config.tmp_folder / f"{hash}.mp3", track.timecode)
- dst, meta = await asyncio.gather(
- asyncio.Task(get_audio()),
- asyncio.Task(genius.get_track(track.meta_url))
- )
- meta.album = album
- meta.number = album.track_urls[meta.url]
- await set_track(dst, meta)
- return dst, meta
- @staticmethod
- async def download(object):
- res: dict[Path, Track] = {}
- album = None
- if object.type == "album":
- album, tracks = await Downloader.download_album(object)
- for key, value in tracks:
- res[key] = value
- else:
- key, value = await Downloader.download_track(object)
- res[key] = value
- return album, res
|