烧瓶send_file不发送文件

时间:2018-12-12 16:23:05

标签: python flask ffmpeg youtube-dl

我正在将Flask与send_file()配合使用,以使人们从服务器上下载文件。

我当前的代码如下:

@app.route('/', methods=["GET", "POST"])
def index():
    if request.method == "POST":
        link = request.form.get('Link')
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            info_dict = ydl.extract_info(link, download=False)
            video_url = info_dict.get("url", None)
            video_id = info_dict.get("id", None)
            video_title = info_dict.get('title', None)
            ydl.download([link])
        print("sending file...")
        send_file("dl/"+video_title+".f137.mp4", as_attachment=True)
        print("file sent, deleting...")
        os.remove("dl/"+video_title+".f137.mp4")
        print("done.")
        return render_template("index.html", message="Success!")
    else:
        return render_template("index.html", message=message)

我添加.f137.mp4的唯一原因是因为我使用AWS C9作为我的在线IDE,并且无法安装FFMPEG在Amazon Linux上将音频和视频结合在一起。但是,这不是问题。问题是它没有发送下载请求。

这是控制台输出:

127.0.0.1 - - [12/Dec/2018 16:17:41] "POST / HTTP/1.1" 200 -
[youtube] 2AYgi2wsdkE: Downloading webpage
[youtube] 2AYgi2wsdkE: Downloading video info webpage
[youtube] 2AYgi2wsdkE: Downloading webpage
[youtube] 2AYgi2wsdkE: Downloading video info webpage
WARNING: You have requested multiple formats but ffmpeg or avconv are not installed. The formats won't be merged.
[download] Destination: dl/Meme Awards v244.f137.mp4
[download] 100% of 73.82MiB in 00:02
[download] Destination: dl/Meme Awards v244.f140.m4a
[download] 100% of 11.63MiB in 00:00
sending file...
file sent, deleting...
done.
127.0.0.1 - - [12/Dec/2018 16:18:03] "POST / HTTP/1.1" 200 -

任何帮助都将受到赞赏。谢谢!

3 个答案:

答案 0 :(得分:2)

您需要return的{​​{1}}结果:

send_file

不幸的是,这将使您在发送文件后更加难以“清理”,因此您可能希望将其作为计划维护的一部分(例如,运行cron作业以删除旧的下载文件)。有关该问题的更多信息,请参见here

答案 1 :(得分:1)

扩展@Rob Bricheno的回答,如果你需要在请求后清理,你可以创建一个延迟方法,在请求完成后执行:

@app.route('/', methods=["GET", "POST"])
def index():
    if request.method == "POST":
        link = request.form.get('Link')
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            info_dict = ydl.extract_info(link, download=False)
            video_url = info_dict.get("url", None)
            video_id = info_dict.get("id", None)
            video_title = info_dict.get('title', None)
            ydl.download([link])
        print("sending file...")
        response = send_file("dl/"+video_title+".f137.mp4", as_attachment=True)
        # Create handle for processing display results (non-blocking, excecutes after response is returned)
        @flask.after_this_request
        def add_close_action(response):
            @response.call_on_close
            def process_after_request():
                try:
                    print("file sent, deleting...")
                    os.remove("dl/"+video_title+".f137.mp4")
                    print("done.")
                except Exception as e:
                    logger.exception(str(e))
        return response
    else:
        return render_template("index.html", message=message)

答案 2 :(得分:0)

如罗布·布里奇诺(Rob Bricheno)所说,

  

您需要返回send_file的结果

因此,您可以保存“ flask.send_file”的结果,然后进行清理,然后返回结果。

print("sending file...")
result = send_file("dl/"+video_title+".f137.mp4", as_attachment=True)
print("file sent, deleting...")
os.remove("dl/"+video_title+".f137.mp4")
return result