Django PIPE youtube-dl для просмотра для загрузки
TL;DR: Я хочу передавать вывод youtube-dl в браузер пользователя по нажатию кнопки, без необходимости сохранять видео на диске моего сервера.
Итак, я пытаюсь иметь кнопку "скачать" на странице (django backend), где пользователь может скачать видео, которое он смотрит. Я использую последнюю версию youtube-dl. В моем представлении загрузки у меня есть этот кусок кода:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
file = ydl.download([f"https://clips.twitch.tv/{pk}"])
И это работает, в некоторой степени. Он загружает файл на мою машину, но я не уверен, как позволить пользователям загружать файл.
Я придумал несколько способов достижения этой цели, но единственным, который действительно работает для меня, был бы способ передачи загрузки пользователю (клиенту) без необходимости хранить видео на моем диске. Я нашел этот вопрос по тому же вопросу, но я не уверен, как заставить его работать. Я успешно передал загрузку в stdout
с помощью ydl_opts = {'outtmpl': '-'}
, но я не уверен, как передать это в ответ моего представления. В одном из ответов сопровождающего упоминается subprocess.Popen
, я посмотрел, но не смог понять, как это должно быть реализовано в моем случае.
Я сделал обходной путь. Я загружаю файл с определенным именем, возвращаю представление с помощью HttpResponse с контент-типом force-download, а затем удаляю файл с помощью python. Это не то, что я изначально имел в виду, но это второе наиболее близкое решение, которое я смог придумать. Я буду выбирать этот ответ как принятый вопрос, пока мастер Python не даст решение исходного вопроса. Код, который у меня есть сейчас:
def download_clip(request, pk):
ydl_opts = {
'outtmpl': f"{pk}.mp4"
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([f"https://clips.twitch.tv/{pk}"])
path = f"{pk}.mp4"
file_path = os.path.join(path)
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/force-download")
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
os.remove(file_path)
return response
raise Http404