added the opportunity to choose the activated audio sources and change theire priority

This commit is contained in:
Lars Noack
2022-11-16 13:21:30 +01:00
parent 5240f3eb34
commit 0cb5cd32e9
7 changed files with 156 additions and 13 deletions

View File

@@ -1,4 +1,3 @@
import logging
import time
import requests
@@ -7,6 +6,8 @@ import bs4
from ...utils.shared import *
from ...utils import phonetic_compares
from .source import AudioSource
TRIES = 5
TIMEOUT = 10
@@ -19,6 +20,38 @@ session.headers = {
session.proxies = proxies
class Musify(AudioSource):
@classmethod
def fetch_source(cls, row: dict):
super().fetch_source(row)
title = row['title']
artists = row['artists']
url = f"https://musify.club/search/suggestions?term={artists[0]} - {title}"
try:
r = session.get(url=url)
except requests.exceptions.ConnectionError:
return None
if r.status_code == 200:
autocomplete = r.json()
for row in autocomplete:
if any(a in row['label'] for a in artists) and "/track" in row['url']:
return get_download_link(row['url'])
return None
@classmethod
def fetch_audio(cls, row: dict):
super().fetch_audio(row)
url = row['url']
file_ = row['file']
return download_from_musify(file_, url)
def get_musify_url(row):
title = row['title']
artists = row['artists']

View File

@@ -1,5 +1,8 @@
from ...utils.shared import *
from typing import Tuple
logger = URL_DOWNLOAD_LOGGER
"""
The class "Source" is the superclass every class for specific audio
sources inherits from. This gives the advantage of a consistent
@@ -7,9 +10,11 @@ calling of the functions do search for a song and to download it.
"""
class Source:
def __init__(self):
pass
class AudioSource:
@classmethod
def fetch_source(cls, row: dict):
logger.info(f"try getting source {row['title']} from {cls.__name__}")
def get_source(self, row) -> Tuple[str, str]:
return "", ""
@classmethod
def fetch_audio(cls, row: dict):
logger.info(f"downloading audio from {row['url']} from {cls.__name__} to {row['file']}")

View File

@@ -1,10 +1,13 @@
from typing import List
import youtube_dl
import logging
import time
from ...utils.shared import *
from ...utils import phonetic_compares
from .source import AudioSource
logger = YOUTUBE_LOGGER
YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
YOUTUBE_URL_KEY = 'webpage_url'
@@ -13,6 +16,61 @@ WAIT_BETWEEN_BLOCK = 10
MAX_TRIES = 3
class Youtube(AudioSource):
@classmethod
def fetch_source(cls, row: dict):
super().fetch_source(row)
if row['isrc'] is None:
return None
real_title = row['title'].lower()
final_result = None
results = get_youtube_from_isrc(row['isrc'])
for result in results:
video_title = result['title'].lower()
match, distance = phonetic_compares.match_titles(video_title, real_title)
if match:
logger.warning(
f"dont downloading {result['url']} cuz the phonetic distance ({distance}) between {real_title} and {video_title} is to high.")
continue
final_result = result
if final_result is None:
return None
return final_result['url']
@classmethod
def fetch_audio(cls, row: dict, trie: int=0):
super().fetch_audio(row)
url = row['url']
file_ = row['file']
options = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'keepvideo': False,
'outtmpl': file_
}
try:
with youtube_dl.YoutubeDL(options) as ydl:
ydl.download([url])
except youtube_dl.utils.DownloadError:
logging.warning(f"youtube blocked downloading. ({trie}-{MAX_TRIES})")
if trie >= MAX_TRIES:
logging.warning("too many tries, returning")
logging.warning(f"retrying in {WAIT_BETWEEN_BLOCK} seconds again")
time.sleep(WAIT_BETWEEN_BLOCK)
return Youtube.fetch_audio(row, trie=trie + 1)
def get_youtube_from_isrc(isrc: str) -> List[dict]:
# https://stackoverflow.com/questions/63388364/searching-youtube-videos-using-youtube-dl
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl: