Skip to content

Instantly share code, notes, and snippets.

@thewh1teagle
Last active February 16, 2024 23:02
Show Gist options
  • Save thewh1teagle/7daa52d9cb29fc341a7ee533198986d9 to your computer and use it in GitHub Desktop.
Save thewh1teagle/7daa52d9cb29fc341a7ee533198986d9 to your computer and use it in GitHub Desktop.
Stream any ffmpeg input to web (Posix only). make sure the input works first by trying the command
video.mp4

Write stream with mplayer to fifo file (ram)

mkfifo in
mplayer -dumpstream video.mp4 -dumpfile in
from flask import Flask, Response
import subprocess
import io
import select
app = Flask(__name__)
stream_sync = False
@app.route('/')
def index():
return """
<video src="/stream" controls autoplay muted width="200" height="200"></video>
"""
@app.route('/stream')
def stream_video():
# Set the command to loop the video using ffmpeg
command = 'ffmpeg -i in -movflags frag_keyframe+empty_moov -f mp4 -'.split()
# Start ffmpeg process
ffmpeg_process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=10**8)
pull = select.poll()
pull.register(ffmpeg_process.stdout, select.POLLIN)
def generate():
global stream_sync
while True:
# Read video chunk
chunk = ffmpeg_process.stdout.read(1024)
if not stream_sync:
while pull.poll(1):
ffmpeg_process.stdout.read(1024)
stream_sync = True
if not chunk:
break
yield chunk
# Set response headers for streaming
headers = {
'Content-Type': 'video/mp4',
'Accept-Ranges': 'bytes'
}
# Return the response with the generator function
return Response(generate(), headers=headers)
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment