From 2df3ee5c6dfd69eb2376321d28a660437d3ad820 Mon Sep 17 00:00:00 2001 From: BennyThink Date: Sun, 13 Mar 2022 13:58:10 +0800 Subject: [PATCH] direct audio conversion --- ytdlbot/downloader.py | 9 +++++---- ytdlbot/limit.py | 5 +++-- ytdlbot/tasks.py | 23 ++++++----------------- ytdlbot/utils.py | 6 +++++- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/ytdlbot/downloader.py b/ytdlbot/downloader.py index e901ce4..e2e73c0 100644 --- a/ytdlbot/downloader.py +++ b/ytdlbot/downloader.py @@ -184,8 +184,9 @@ def can_convert_mp4(video_path, uid): return True -def ytdl_download(url, tempdir, bm) -> dict: +def ytdl_download(url, tempdir, bm, **kwargs) -> dict: chat_id = bm.chat.id + hijack = kwargs.get("hijack") response = {"status": True, "error": "", "filepath": []} output = pathlib.Path(tempdir, "%(title).70s.%(ext)s").as_posix() ydl_opts = { @@ -193,14 +194,14 @@ def ytdl_download(url, tempdir, bm) -> dict: 'outtmpl': output, 'restrictfilenames': False, 'quiet': True, - # "proxy": "socks5://127.0.0.1:1080" + "proxy": os.getenv("YTDL_PROXY") } formats = [ "bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio", "bestvideo[vcodec^=avc]+bestaudio[acodec^=mp4a]/best[vcodec^=avc]/best", None ] - adjust_formats(chat_id, url, formats) + adjust_formats(chat_id, url, formats, hijack) add_instagram_cookies(url, ydl_opts) address = ["::", "0.0.0.0"] if IPv6 else [None] @@ -249,7 +250,7 @@ def ytdl_download(url, tempdir, bm) -> dict: if settings[2] == "video" or isinstance(settings[2], MagicMock): # only convert if send type is video convert_to_mp4(response, bm) - if settings[2] == "audio": + if settings[2] == "audio" or hijack == "bestaudio[ext=m4a]": convert_audio_format(response, bm) # disable it for now # split_large_video(response) diff --git a/ytdlbot/limit.py b/ytdlbot/limit.py index dbf0095..87514d1 100644 --- a/ytdlbot/limit.py +++ b/ytdlbot/limit.py @@ -107,17 +107,18 @@ class VIP(Redis, MySQL): @staticmethod def extract_canonical_link(url): # canonic link works for many websites. It will strip out unnecessary stuff + proxy = {"https": os.getenv("YTDL_PROXY")} if os.getenv("YTDL_PROXY") else None props = ["canonical", "alternate", "shortlinkUrl"] headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"} # send head request first - r = requests.head(url, headers=headers) + r = requests.head(url, headers=headers, proxies=proxy) if r.status_code != http.HTTPStatus.METHOD_NOT_ALLOWED and "text/html" not in r.headers.get("content-type"): # get content-type, if it's not text/html, there's no need to issue a GET request logging.warning("%s Content-type is not text/html, no need to GET for extract_canonical_link", url) return url - html_doc = requests.get(url, headers=headers, timeout=5).text + html_doc = requests.get(url, headers=headers, timeout=5, proxies=proxy).text soup = BeautifulSoup(html_doc, "html.parser") for prop in props: element = soup.find("link", rel=prop) diff --git a/ytdlbot/tasks.py b/ytdlbot/tasks.py index 8373060..7d54064 100644 --- a/ytdlbot/tasks.py +++ b/ytdlbot/tasks.py @@ -211,28 +211,17 @@ def direct_normal_download(bot_msg, client, url): def normal_audio(bot_msg, client): chat_id = bot_msg.chat.id - fn = getattr(bot_msg.video, "file_name", None) or getattr(bot_msg.document, "file_name", None) + # fn = getattr(bot_msg.video, "file_name", None) or getattr(bot_msg.document, "file_name", None) status_msg = bot_msg.reply_text("Converting to audio...please wait patiently", quote=True) + orig_url: "str" = re.findall(r"http[s]://.*", bot_msg.caption)[0] with tempfile.TemporaryDirectory(prefix="ytdl-") as tmp: - logging.info("downloading to %s", tmp) - base_path = pathlib.Path(tmp) - video_path = base_path.joinpath(fn) - audio = base_path.joinpath(fn).with_suffix(f".{AUDIO_FORMAT}") - client.send_chat_action(chat_id, 'record_video_note') - status_msg.edit_text("Preparing your conversion....") - client.download_media(bot_msg, video_path) - logging.info("downloading complete %s", video_path) - # execute ffmpeg client.send_chat_action(chat_id, 'record_audio') - try: - run_ffmpeg(["ffmpeg", "-y", "-i", video_path, "-vn", "-acodec", "copy", audio], status_msg) - except subprocess.CalledProcessError: - # CPU consuming if re-encoding. - run_ffmpeg(["ffmpeg", "-y", "-i", video_path, audio], status_msg) - + # just try to download the audio using yt-dlp + resp = ytdl_download(orig_url, tmp, status_msg, hijack="bestaudio[ext=m4a]") status_msg.edit_text("Sending audio now...") client.send_chat_action(chat_id, 'upload_audio') - client.send_audio(chat_id, audio) + for f in resp["filepath"]: + client.send_audio(chat_id, f) status_msg.edit_text("✅ Conversion complete.") Redis().update_metrics("audio_success") diff --git a/ytdlbot/utils.py b/ytdlbot/utils.py index 90c2054..7a0677c 100644 --- a/ytdlbot/utils.py +++ b/ytdlbot/utils.py @@ -76,10 +76,14 @@ def is_youtube(url: "str"): return True -def adjust_formats(user_id: "str", url: "str", formats: "list"): +def adjust_formats(user_id: "str", url: "str", formats: "list", hijack=None): # high: best quality, 720P, 1080P, 2K, 4K, 8K # medium: 480P # low: 360P+240P + if hijack: + formats.insert(0, hijack) + return + mapping = {"high": [], "medium": [480], "low": [240, 360]} settings = get_user_settings(user_id) if settings and is_youtube(url):