I am currently working on a project where I need to stream video from an RTSP source, convert it to FLV format using FFmpeg, and then send the FLV stream to clients upon request. The code I have written to achieve this is as follows:
import subprocess
from flask import Flask, Response, stream_with_context
app = Flask(__name__)
flv_header = b''
def update_stream(ffmpeg_path="ffmpeg", rtsp_url='rtsp://192.168.1.168/0', rtsp_id="rtsp01"):
global flv_header
command = [
ffmpeg_path,
'-i', rtsp_url,
'-c:v', 'libx264',
'-c:a', 'aac',
'-b:v', '1M',
'-g', '30',
'-preset', 'ultrafast',
'-bsf:v', 'dump_extra',
'-f', 'flv',
'-'
]
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
flv_header = process.stdout.read(1024)
while True:
data = process.stdout.read(1024)
if not data:
break
producer.notify(rtsp_id, data)
@app.route('/flv/<user_id>/<rtsp_id>')
def flv_stream(user_id, rtsp_id):
try:
consumer_queue = producer.register(user_id, rtsp_id)
@stream_with_context
def generate():
yield flv_header
while True:
yield consumer_queue.get()
response = Response(generate(), mimetype='video/x-flv')
response.headers.add('Access-Control-Allow-Origin', '*') # Allow all origins
response.headers.add('Access-Control-Allow-Methods', '*') # Allow all HTTP methods
response.headers.add('Access-Control-Allow-Headers', 'Content-Type') # Allow specific headers
return response
except Exception as e:
print(f'{e}')
In order to handle initial playback issues in FFplay and VLC, I save the first 1024 bytes of the FLV stream and send this header before streaming the actual data. This workaround allows playback in FFplay and VLC, but it does not work with flv.js.
When attempting to play the stream using flv.js, the stream keeps loading indefinitely, and the console outputs warnings like:
flv.min.js:9 [FLVDemuxer] > Invalid PrevTagSize 3491417133
[FLVDemuxer] > Unsupported tag type 204, skipped
I have tried several modifications to the FFmpeg command, including adding parameters such as -bsf:v dump_extra
, but none of these changes have resolved the issue. My expectation is that the FLV stream would play smoothly in flv.js just as it does in FFplay and VLC.