#python-3.6 #youtube-dl
#python-3.6 #youtube-dl
Вопрос:
Я использую python embedded youtube_dl
и хотел бы загружать видеоконтент непосредственно во временный файл. Я попытался создать NamedTemporaryFile
и youtube_dl
записать в него, но я всегда получаю сообщение о том, что файл уже загружен (временный файл имеет это имя, и он считает, что загрузка уже произошла).
Я также попытался youtube_dl
передать загруженные данные stdout
во временный файл и перенаправить stdout
их во временный файл, но я не могу заставить встроенную версию python сделать это. Он не выводит данные stdout
, а просто создает файл с именем -.mp4
.
import youtube_dl
ydl_opts = {
"format": "bestvideo[ext=mp4] bestaudio[ext=m4a]/best[ext=mp4]/best",
"merge-output-format": "mp4",
"recode-video": "mp4",
"outtmpl": "-",
"verbose": True,
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(["https://www.youtube.com/watch?v=h3h035Eyz5Aamp;ab_channel=Loku"])
Подводя итог, приведенный выше код не будет переопределять -.mp4
файлы, если они уже существуют, и не будет передавать потоковую загрузку, stdout
чтобы я мог перенаправить ее во временный файл.
Временный файл необходим, потому что это промежуточный шаг для дальнейшей обработки. На данный момент мне кажется, что мне нужно скопировать файл во временный файл и удалить оригинал, или мне нужно будет использовать youtube_dl
с подпроцессом, который кажется глупым.
Ответ №1:
Я уже сталкивался с подобной проблемой раньше. Хорошим решением, которое я нашел, было использование tempfile.TemporaryDirectory() для временного хранения файла, а затем open() для извлечения файла.
Глядя на базу кода youtube_dl, похоже, что вы хотите использовать extract_info вместо download
прямого метода.
import tempfile
from youtube_dl import YoutubeDL
from youtube_dl.utils import DownloadError
with tempfile.TemporaryDirectory() as tempdirname:
ydl_opts = {
"format": "bestvideo[ext=mp4] bestaudio[ext=m4a]/best[ext=mp4]/best",
"merge_output_format": "mp4",
"outtmpl": f"{tempdirname}/%(id)s.%(ext)s",
"noplaylist": True,
"verbose": True,
}
ydl = YoutubeDL(ydl_opts)
try:
meta = ydl.extract_info(
"https://www.youtube.com/watch?v=h3h035Eyz5Aamp;ab_channel=Loku",
download=True,
)
except DownloadError as e:
raise e
else:
video_id = meta["id"]
video_ext = meta["ext"]
file = open(f"{tempdirname}/{video_id}.{video_ext}", "rb")
# whatever else you gotta do bruh...
# when the with statement finishes execution, the temp directory
# will be cleaned up.
Обратите внимание, что вы должны использовать snake_case для аргументов (ключей в ydl_opts
), поскольку вы не используете cli. Я также думаю recode-video
, что это не поддерживаемый вариант, но проверьте здесь, чтобы убедиться.
Также обратите внимание, что я предполагаю, что вы хотите загрузить одно видео. Приведенный выше код не учитывает получение списка воспроизведения из каталога temp, и я намеренно добавил эту noplaylist
опцию ydl_opts
.
Комментарии:
1. В итоге я скопировал во временный файл и удалил оригинал, потому что он лучше подходит для моего варианта использования. Я также надеялся подтолкнуть
youtube_dl
разработчиков к рассмотрению этой проблемы (опубликовал проблему некоторое время назад), но они еще не ответили. В любом случае я принимаю ваш ответ, добро пожаловать в stackoverflow.2. Круто, рад, что вы нашли решение. Спасибо за приветствие.