Reputation: 974
I'm using python embedded youtube_dl
and I'd like to download video content directly into a temporary file. I attempted to create a NamedTemporaryFile
and have youtube_dl
write into it, but I always get a prompt that the file was already downloaded (the temporary file has that name and it thinks the download already happened).
I also attempted to have youtube_dl
stream downloaded data to stdout
and redirect stdout
to the temporary file but I can't get the python embedded version to do that. It doesn't output to stdout
it simply creates a file named -.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"])
To summarize, the code above won't override -.mp4
files if they already exist and it won't stream the download into stdout
so I can redirect it into a temp file.
The temp file is needed because it's an intermediary step for further processing. At this point it feels like I'll need to copy the file to temp file and delete the original or I'll need to use youtube_dl
with a subprocess which feels silly.
Upvotes: 5
Views: 5452
Reputation: 96
I have run into a similar issue before. A good work around I found was to use tempfile.TemporaryDirectory() to temporarily store the file and then open() to retrieve the file.
Looking at the youtube_dl code base, it looks like you want to use extract_info instead of the download
method directly.
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.
Note that you should use snake_case for the arguments (the keys in ydl_opts
) since you are not using the cli. I also think recode-video
is not a supported option, but check here to be sure.
Also note that I'm assuming that you want to download one video. The code above doesn't account for retrieving playlist from the temp directory, and I intentionally added the noplaylist
option to ydl_opts
.
Upvotes: 6