Created
May 28, 2018 11:46
-
-
Save anthonyeden/f3b3bdf6f62badd8f87bb574283f488a to your computer and use it in GitHub Desktop.
Sending FFmpeg output to HTTP, via Python's Flash
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Streaming FFmpeg to HTTP, via Python's Flask. | |
This is an incredibly simple example, which will yield issues due to inconsistant input and output rates. | |
If you're going to use this, VLC works okay as a client. | |
You really need to move FFmpeg into a separate thread, which should help stream audio more consistantly to the HTTP client. | |
Example by Anthony Eden (https://mediarealm.com.au) | |
""" | |
from flask import Flask | |
from flask import stream_with_context, request, Response | |
import subprocess | |
import time | |
app = Flask(__name__) | |
@app.route("/") | |
def hello(): | |
def generate(): | |
startTime = time.time() | |
buffer = [] | |
sentBurst = False | |
ffmpeg_command = ["ffmpeg", "-f", "avfoundation", "-i", ":2", "-acodec", "libmp3lame", "-ab", "32k", "-ac", "1", "-f", "mpeg", "pipe:stdout"] | |
process = subprocess.Popen(ffmpeg_command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, bufsize = -1) | |
while True: | |
# Get some data from ffmpeg | |
line = process.stdout.read(1024) | |
# We buffer everything before outputting it | |
buffer.append(line) | |
# Minimum buffer time, 3 seconds | |
if sentBurst is False and time.time() > startTime + 3 and len(buffer) > 0: | |
sentBurst = True | |
for i in range(0, len(buffer) - 2): | |
print "Send initial burst #", i | |
yield buffer.pop(0) | |
elif time.time() > startTime + 3 and len(buffer) > 0: | |
yield buffer.pop(0) | |
process.poll() | |
if isinstance(process.returncode, int): | |
if process.returncode > 0: | |
print 'FFmpeg Error', p.returncode | |
break | |
return Response(stream_with_context(generate()), mimetype = "audio/mpeg") | |
if __name__ == "__main__": | |
app.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another option to kill the process is to use the
call_on_close
decorator:But you need to start the ffmpeg process outside of the
generate
closure e.g.