AttributeError: 'NoneType' object has no attribute 'get'

I am trying to start a video stream using my webcam as input working on Colab.

I get the following error when calling JS function from my Python code. Here is the code:

# start streaming video from webcam
video_stream()// JS function
# label for video
label_html = 'Capturing...'

scenes_1 = []
scenes_2 = []

scene_manager1 = SceneManager()
scene_manager1.add_detector(ContentDetector(threshold=30.0))

scene_manager2 = SceneManager()
scene_manager2.add_detector(ContentDetector(threshold=30.0))

def callback_1(image, frame_num):
      global scenes_1
      print("callback_1: Found a scene on video 1.")
      scenes_1 += [(image, frame_num)]

def callback_2(image, frame_num):
      global scenes_2
      print("callback_2: Found a scene on video 2.")
      scenes_2 += [(image, frame_num)]

cap = video_stream()
scene_manager1.detect_scenes(cap, callback = callback_1)

cap2 =cv2.VideoCapture('Our Story.mp4', 0)
scene_manager2.detect_scenes(cap2, callback = callback_2)

And here is the error I get:

---------------------------------------------------------------------------

AttributeError Traceback (most recent call last)

[<ipython-input-11-163de13ff729>] in <module>()
 34
 35 cap = video_stream()
 ---> 36 scene_manager1.detect_scenes(cap, callback = callback_1)
 37
 38 cap2 =cv2.VideoCapture('Our Story.mp4', 0)

/usr/local/lib/python3.7/dist-packages/scenedetect/scene_manager.py in detect_scenes(self, frame_source, end_time, frame_skip, show_progress, callback)
 624 end_frame = None
 625 self._base_timecode = FrameTimecode(
 --> 626 timecode=0, fps=frame_source.get(cv2.CAP_PROP_FPS))
 627
 628 total_frames = math.trunc(frame_source.get(cv2.CAP_PROP_FRAME_COUNT))

AttributeError: 'NoneType' object has no attribute 'get'

What is the problem and how can I overcome this issue, please.

can you give us links to the SceneManager class ?

and the video_stream() function ?

Here is the SceneManager documentation and the following is the video_stream() function:

# JavaScript to properly create our live video stream using our webcam as input
def video_stream():
  js = Javascript('''
    var video;
    var div = null;
    var stream;
    var captureCanvas;
    var imgElement;
    var labelElement;
    
    var pendingResolve = null;
    var shutdown = false;
    
    function removeDom() {
       stream.getVideoTracks()[0].stop();
       video.remove();
       div.remove();
       video = null;
       div = null;
       stream = null;
       imgElement = null;
       captureCanvas = null;
       labelElement = null;
    }
    
    function onAnimationFrame() {
      if (!shutdown) {
        window.requestAnimationFrame(onAnimationFrame);
      }
      if (pendingResolve) {
        var result = "";
        if (!shutdown) {
          captureCanvas.getContext('2d').drawImage(video, 0, 0, 640, 480);
          result = captureCanvas.toDataURL('image/jpeg', 0.8)
        }
        var lp = pendingResolve;
        pendingResolve = null;
        lp(result);
      }
    }
    
    async function createDom() {
      if (div !== null) {
        return stream;
      }

      div = document.createElement('div');
      div.style.border = '2px solid black';
      div.style.padding = '3px';
      div.style.width = '100%';
      div.style.maxWidth = '600px';
      document.body.appendChild(div);
      
      const modelOut = document.createElement('div');
      modelOut.innerHTML = "<span>Status:</span>";
      labelElement = document.createElement('span');
      labelElement.innerText = 'No data';
      labelElement.style.fontWeight = 'bold';
      modelOut.appendChild(labelElement);
      div.appendChild(modelOut);
           
      video = document.createElement('video');
      video.style.display = 'block';
      video.width = div.clientWidth - 6;
      video.setAttribute('playsinline', '');
      video.onclick = () => { shutdown = true; };
      stream = await navigator.mediaDevices.getUserMedia(
          {video: { facingMode: "environment"}});
      div.appendChild(video);

      imgElement = document.createElement('img');
      imgElement.style.position = 'absolute';
      imgElement.style.zIndex = 1;
      imgElement.onclick = () => { shutdown = true; };
      div.appendChild(imgElement);
      
      const instruction = document.createElement('div');
      instruction.innerHTML = 
          '<span style="color: red; font-weight: bold;">' +
          'When finished, click here or on the video to stop this demo</span>';
      div.appendChild(instruction);
      instruction.onclick = () => { shutdown = true; };
      
      video.srcObject = stream;
      await video.play();

      captureCanvas = document.createElement('canvas');
      captureCanvas.width = 640; //video.videoWidth;
      captureCanvas.height = 480; //video.videoHeight;
      window.requestAnimationFrame(onAnimationFrame);
      
      return stream;
    }
    async function stream_frame(label, imgData) {
      if (shutdown) {
        removeDom();
        shutdown = false;
        return '';
      }

      var preCreate = Date.now();
      stream = await createDom();
      
      var preShow = Date.now();
      if (label != "") {
        labelElement.innerHTML = label;
      }
            
      if (imgData != "") {
        var videoRect = video.getClientRects()[0];
        imgElement.style.top = videoRect.top + "px";
        imgElement.style.left = videoRect.left + "px";
        imgElement.style.width = videoRect.width + "px";
        imgElement.style.height = videoRect.height + "px";
        imgElement.src = imgData;
      }
      
      var preCapture = Date.now();
      var result = await new Promise(function(resolve, reject) {
        pendingResolve = resolve;
      });
      shutdown = false;
      
      return {'create': preShow - preCreate, 
              'show': preCapture - preShow, 
              'capture': Date.now() - preCapture,
              'img': result};
    }
    ''')

  display(js)
  
def video_frame(label, bbox):
  data = eval_js('stream_frame("{}", "{}")'.format(label, bbox))
  return data

your problem is a generic python programming problem and there’s no evidence that OpenCV was part of the problem. this is the wrong forum for that. yes I’m also in a bad mood because you messaged me privately out of the blue with your problem.

well, i can only guess, - what your video_stream() function returns
(some dictionary) is not a valid FrameSource object

1 Like

video_stream() only runs JavaScript to display stream but it doesn’t return any stream which you could use in Python. It always returns None.

It would need some JavaScript code with loop which gets frames from web browser Canvas and use AJAX to send it to server/Python.


EDIT:

I found my answer on Stackoverflow: OpenCV not working in Google Colaboratory

and code on Colab

2 Likes

@furas , glad to hear you found your answer.

Your initial problem was you weren’t able to open webcam from colab. And that’s reasonable, because colab runs on a server without any local webcam.

OpenCV doesn’t provide any mean to do it (it’s not a CV related problem), but there are some ways to capture local webcam and send images to colab, as you pointed out in the links.

I think it’s mostly because frame_source is empty, i.e video is not getting read properly, hence the video object frame_source must be None.

Try to use cv2.imshow and display the frames of the video, this will give you an idea if it’s reading it properly or not.

1 Like