Flask Streaming mp4 video works perfectly on windows but not mobile phone

30 views Asked by At

I am trying to create small flask app, that streams mp4 from my surveillance camera. I use this mp4 link (https://www.w3schools.com/html/movie.mp4) for my testing, as it works perfectly and play in every platform. for some reason, when I restream it in my app, It works perfectly in Window (Chrome), but not in iPhone (Chrome and Safari) not Android (Chrome)

This is my Flask backend:

# Dictionary containing camera names and corresponding MP4 stream URLs
camera_mp4_streams = {
    "Camera 1": "https://www.w3schools.com/html/movie.mp4",
}
@app.route('/video_feed/<camera>')
@login_required
def video_feed(camera):
    mp4_stream_url = camera_mp4_streams.get(camera)
    if mp4_stream_url:
        headers = {
            'Accept-Ranges': 'bytes'  # Enable byte-range requests
        }
        response = requests.get(mp4_stream_url, headers=headers, stream=True)
        return Response(
            response.iter_content(chunk_size=4096),
            mimetype='video/mp4',
            headers={
                'Content-Type': 'video/mp4',  # Specify video MIME type
                'Accept-Ranges': 'bytes'  # Confirm byte-range requests
            }
        )
    else:
        return "Camera not found", 404

this is my HTML relevant code:

<div class="container">
    <!-- Flask loop for cameras -->
    {% for camera, mp4_stream_url in cameras.items() %}
    <div class="camera-card">
        <div class="camera-title">{{ camera }}</div>
        <video class="camera-stream" autoplay muted controls>
            <source src="{{ url_for('video_feed', camera=camera) }}" type="video/mp4">
            Your browser does not support the video tag.
        </video>
    </div>
    </div>
    {% endfor %}
</div>

I'm pretty sure it something with my flask backend, but I can't figure out what's the problem

This is how it shows in Windows and iPhone

1

There are 1 answers

0
Detlef On

It seems to me that certain browsers require the specification of a Content-Length header.

@app.route('/video_feed/<camera>')
def video_feed(camera):
    mp4_stream_url = camera_mp4_streams.get(camera)
    if mp4_stream_url:
        headers = {
            'Accept-Ranges': 'bytes'  # Enable byte-range requests
        }
        response = requests.get(mp4_stream_url, headers=headers, stream=True)
        return Response(
            response.iter_content(chunk_size=4096), 
            mimetype='video/mp4',
            headers={
                'Content-Type': 'video/mp4',  # Specify video MIME type
                'Content-Length': response.headers['Content-length'], # <- !!!
                'Accept-Ranges': 'bytes'  # Confirm byte-range requests
            }
        )
    abort(404, 'Camera not found')