title: Python opencv wait for camera to be free
body: <p>My idea is using a Raspberry Pi for streaming video, for which Django will do the heavy lifting. In <strong>another process</strong>, I will also run some Celery workers, which capture a picture from the same camera every 5th seconds and send the picture to the public server. </p>
  
  <p>The Django server will be started with <code>python manage.py runserver</code></p>
  
  <p>The Celery workers will be started with <code>celery -A videoclient worker -l info -B --scheduler django_celery_beat.schedulers:DatabaseScheduler</code></p>
  
  <p>Following is the code to access the camera. Since there is only one camera and two independent processes want to access it, how can I make the line <code>self.video = cv2.VideoCapture(0)</code> wait for the camera to be free instead of throwing an exception? For my requirement a high latency is acceptable.</p>
  
  <p>Camera code</p>
  
  <pre><code>import cv2
  
  
  class VideoCamera(object):
      def get_frame(self):
          try:
              self.video = cv2.VideoCapture(0)
              success, image = self.video.read()
              self.video.release()
              ret, jpeg = cv2.imencode('.jpg', image)
              return jpeg.tobytes()
          finally:
              self.video.release()
  
  
  video_camera = VideoCamera()
  
  
  def gen(camera):
      while True:
          frame = camera.get_frame()
          yield (b'--frame\r\n'
                 b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
  </code></pre>
  
  <p>Streaming on local browser:</p>
  
  <pre><code>from django.contrib import admin
  from django.http import StreamingHttpResponse
  from django.urls import path
  
  from videoclient.camera import video_camera, gen
  
  urlpatterns = [
      path('monitor/', lambda r: StreamingHttpResponse(gen(video_camera),
                                                       content_type='multipart/x-mixed-replace; boundary=frame')),
      path('admin/', admin.site.urls),
  </code></pre>
  
  <p>]</p>
  
  <p>Celery:</p>
  
  <pre><code>from __future__ import absolute_import, unicode_literals
  import os
  from celery import Celery, shared_task
  from django.conf import settings
  from videoclient.camera import video_camera
  
  os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'videoclient.settings')
  
  app = Celery('videoclient')
  
  app.config_from_object('django.conf:settings')
  
  app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
  
  
  @app.task(bind=True)
  def debug_task(self):
      print('Request: {0!r}'.format(self.request))
  
  @shared_task
  def uploadimage():
      image = video_camera.get_frame()
      # Upload the image to server
  </code></pre>