我目前有一个在来自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"})
我有什么遗失的吗?
答案 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
命令。