当Flask文件中的流式响应无法播放时

时间:2015-12-18 06:29:24

标签: python flask ffmpeg subprocess

我目前有一个在来自youtube的flv流上运行ffmpeg enconder的函数。

def console(cmd, add_newlines=False):
    p = Popen(cmd, shell=True, stdout=PIPE)
    while True:
        data = p.stdout.readline()
        if add_newlines:
            data += str('\n')
        yield data

        p.poll()
        if isinstance(p.returncode, int):
            if p.returncode > 0:
                # return code was non zero, an error?
                print 'error:', p.returncode
            break

当我运行ffmpeg命令并将其输出到文件时,这可以正常工作。该文件可以播放。

mp3 = console('ffmpeg -i "%s" -acodec libmp3lame -ar 44100 -f mp3 test.mp3' % video_url, add_newlines=True)

但是当我通过-而不是test.mp3将ffmpeg输出到stdout时,会传输该响应。文件流正常,是正确的大小。但是没有正确播放。听起来很奇怪,当我检查文件的属性时,它不像test.mp3那样显示它的数据

@app.route('/test.mp3')
def generate_large_mp3(path):
    mp3 = console('ffmpeg -i "%s" -acodec libmp3lame -ar 44100 -f mp3 -' % video_url, add_newlines=True)
    return Response(stream_with_context(mp3), mimetype="audio/mpeg3",
                   headers={"Content-Disposition":
                                "attachment;filename=test.mp3"})

我有什么遗失的吗?

1 个答案:

答案 0 :(得分:2)

使用flask来传输子进程生成的mp3内容:

#!/usr/bin/env python
import os
from functools import partial
from subprocess import Popen, PIPE

from flask import Flask, Response  # $ pip install flask

mp3file = 'test.mp3'
app = Flask(__name__)


@app.route('/')
def index():
    return """<!doctype html>
<title>Play {mp3file}</title>
<audio controls autoplay >
    <source src="{mp3file}" type="audio/mp3" >
    Your browser does not support this audio format.
</audio>""".format(mp3file=mp3file)


@app.route('/' + mp3file)
def stream():
    process = Popen(['cat', mp3file], stdout=PIPE, bufsize=-1)
    read_chunk = partial(os.read, process.stdout.fileno(), 1024)
    return Response(iter(read_chunk, b''), mimetype='audio/mp3')

if __name__ == "__main__":
    app.run()

['cat', mp3file]替换为将mp3内容写入其标准输出的ffmpeg命令。