Search code examples
pythonpython-asynciovideo-captureopencv

Adding a coroutine with a webcam feed to a running asyncio loop stops tasks from running


If I run 1+n async greeting loops everything works fine. Whenever I add the runCamera method, it stops the greeting loops from running. Why is this happening? Or is this rather a case for threading? I want the greeting loops to run and the webcam image showing at the same time.

    def main():
        loop = asyncio.get_event_loop()
        asyncio.ensure_future(greet_every_two_seconds())
        asyncio.ensure_future(runCamera())
        loop.run_forever()

    async def greet_every_two_seconds():
        while True:
          print('Hello World')
          await asyncio.sleep(1)

    async def runCamera():
        vid = cv.VideoCapture(0)

        while (True):
           ret, frame = vid.read()
          cv.imshow('frame', frame)
           if cv.waitKey(1) & 0xFF == ord('q'):
               break

        vid.release()
        cv.destroyAllWindows()

Solution

  • It is a matter of threading and my guess is that that is due to: Threading provides thread-based concurrency, suitable for blocking I/O tasks - Asyncio doesnt.

    Solution based on the two methods shown above (greet_every_two_seconds and runCamera) looks like this:

    def main():
        server = threading.Thread(target=start_cam, daemon=True)
        server.start()
        client = threading.Thread(target=client_call)
        client.start()
        client.join()
    
    
    def start_greeting():
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        asyncio.ensure_future(greet_every_two_seconds())
        loop.run_forever()
    
    def start_cam():
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        asyncio.ensure_future(runCamera())
        loop.run_forever()