'FastAPI, stream multiple videos

How can I stream multiple videos in FastAPI ? With the following approach, I can only have one request open on browser, any other request I make is not working,

async def stream_video(url):
    """
    frames generator from video feed
    """
    global outputFrame

    while(True):
        cap = cv2.VideoCapture(url)
        ret, frame = cap.read()
        (flag, encodedImage) = cv2.imencode(".jpg", frame)
        
        if not flag:
            continue

        yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
               bytearray(encodedImage) + b'\r\n')


@router.get("/{camera_id}")
async def video_feed(camera_id):
    """
    return the response generated along with specific media type
    """
    if cam_list.get(camera_id) is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"Camera with id {camera_id} not found")

    url = cam_list[camera_id]

    return StreamingResponse(stream_video(url), media_type="multipart/x-mixed-replace;boundary=frame")

On browser, http://127.0.0.1:8000/endpoint1/camera1 works fine and I can see the camera feed, but if I open another tab and open http://127.0.0.1:8000/endpoint1/camera2, this one is not showing anything.



Solution 1:[1]

async does not magically make things parallel, so if you're never awaiting anything and just feeding stuff as fast as you can (or waiting in a blocking function like cv2.VideoCapture(url)), you're going to only have a single function executing.

If you don't have the option to do things properly async, just drop the async definition on the function and FastAPI will run your code in a threadpool instead.

Another option is to use tell uvicorn to use multiple workers with the --workers parameter, but you should still aim to use proper async/await compatible calls in that case - but I'm not sure that opencv have a proper async API available.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MatsLindh