Why is it that when I create a livestream in Python using ffmpeg, and then I open the browser and visit the page, the page keeps loading continuously, and in PyCharm logs, I see binary data? There are no errors displayed, and the code seems correct to me. I even tried saving to a file for testing purposes, and when I play the video, everything works fine. Does anyone know what might be wrong here?
Code:
def generate_frames():
cap = cv2.VideoCapture(os.path.normpath(app_root_dir().joinpath("data/temp", "video-979257305707693982.mp4")))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
yield frame
@app.route('/video_feed')
def video_feed():
ffmpeg_command = [
'ffmpeg', '-f', 'rawvideo', '-pix_fmt', 'bgr24',
'-s:v', '1920x1080', '-r', '60',
'-i', '-', '-vf', 'setpts=2.5*PTS', # Video Speed
'-c:v', 'libvpx-vp9', '-g', '60', '-keyint_min', '60',
'-b:v', '6M', '-minrate', '4M', '-maxrate', '12M', '-bufsize', '8M',
'-crf', '0', '-deadline', 'realtime', '-tune', 'psnr', '-quality', 'good',
'-tile-columns', '6', '-threads', '8', '-lag-in-frames', '16',
'-f', 'webm', '-'
]
ffmpeg_process = subprocess.Popen(ffmpeg_command, stdin=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1)
frames_generator = generate_frames()
for frame in frames_generator:
ffmpeg_process.stdin.write(frame)
ffmpeg_process.stdin.flush()
ffmpeg_process.stdin.close()
ffmpeg_process.wait()
def generate_video_stream(process):
startTime = time.time()
buffer = []
sentBurst = False
chunk = process.stderr.read(4096)
buffer.append(chunk)
# 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', process.returncode)
return Response(stream_with_context(generate_video_stream(ffmpeg_process)), mimetype='video/webm', content_type="video/webm; codecs=vp9", headers=Headers([("Connection", "close")]))