how to stream multiple camera feeds to single socket in python

I am working on a module where i have to detect some predefined objects in the video stream. For object detection i am using YOLO. I need to process multiple camera feeds in parallel. I tried with multithreaded socket in python as discussed in this answer. but it failed to handle multiple clients at same time. Without sockets, i just tried with threads in python.

from concurrent.futures import ThreadPoolExecutor
import threading
import random
import cv2
from detection_image import get_detected_object
import numpy as np
import time

def task(video_file):
    time.sleep(5)
    cap = cv2.VideoCapture(video_file)
    while True:    
        cap.set(1, frame_num)
        ret, frame = cap.read()
        ## Method to detect object in current frame.
        result = get_detected_object(frame)

def main():
    executor = ThreadPoolExecutor(max_workers=2)
    task1 = executor.submit(task("1.mp4"))
    task2 = executor.submit(task("2.mp4"))

if __name__ == '__main__':
    main() 

But this also doesnt seem to work. I am thinking to create separate sockets for every camera and process the stream separately. Is this a correct way to do ? or if multithreaded approach is correct, how can I achieve that ?

Can anybody suggest ?


Solution 1:

Creating multiple sockets for multiple cameras is not a very good appraoch unless it is the actual requirement. If just threading is applicable for your project, then You can do just like this.

from concurrent.futures import ThreadPoolExecutor
import threading
import random
import cv2
from detection_image import get_detected_object
import numpy as np

def task():
   executor = ThreadPoolExecutor(max_workers=2)  

   cap1 = cv2.VideoCapture("1.mp4")
   cap2 = cv2.VideoCapture("2.mp4")

   while True:
       _, frame1 = cap1.read()
       _, frame2 = cap2.read()
       task1 = executor.submit(get_detected_object(frame1, COLORS, classes, net))
       task2 = executor.submit(get_detected_object(frame2, COLORS, classes, net))


if __name__ == '__main__':
   task()

VideoCapture of opencv is synchronus, so we can not do threading on VideoCapture level. So, instead of creating threads for every video file, you can create thread at the level of "read()" function, which works fine.

Hope this is helpfull :)