使用 python youtube_dl 将数据直接下载到临时文件中
Downloading data directly into a temporary file with python youtube_dl
我正在使用 python 嵌入式 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=h3h035Eyz5A&ab_channel=Loku"])
总而言之,上面的代码不会覆盖 -.mp4
文件(如果它们已经存在)并且它不会将下载流式传输到 stdout
因此我可以将其重定向到临时文件。
需要临时文件,因为它是进一步处理的中间步骤。在这一点上,我觉得我需要将文件复制到临时文件并删除原始文件,或者我需要使用 youtube_dl
和一个感觉很傻的子进程。
我之前 运行 遇到过类似的问题。我发现一个很好的解决方法是使用 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=h3h035Eyz5A&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
不是受支持的选项,但请检查 here 以确保。
另请注意,我假设您要下载一个视频。上面的代码没有考虑从临时目录中检索播放列表,我特意将 noplaylist
选项添加到 ydl_opts
.
我正在使用 python 嵌入式 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=h3h035Eyz5A&ab_channel=Loku"])
总而言之,上面的代码不会覆盖 -.mp4
文件(如果它们已经存在)并且它不会将下载流式传输到 stdout
因此我可以将其重定向到临时文件。
需要临时文件,因为它是进一步处理的中间步骤。在这一点上,我觉得我需要将文件复制到临时文件并删除原始文件,或者我需要使用 youtube_dl
和一个感觉很傻的子进程。
我之前 运行 遇到过类似的问题。我发现一个很好的解决方法是使用 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=h3h035Eyz5A&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
不是受支持的选项,但请检查 here 以确保。
另请注意,我假设您要下载一个视频。上面的代码没有考虑从临时目录中检索播放列表,我特意将 noplaylist
选项添加到 ydl_opts
.