direct audio conversion

This commit is contained in:
BennyThink 2022-03-13 13:58:10 +08:00
parent 97dbacad04
commit 2df3ee5c6d
No known key found for this signature in database
GPG Key ID: 6CD0DBDA5235D481
4 changed files with 19 additions and 24 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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")

View File

@ -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):