dkrivoruchko / ScreenStream

ScreenStream Android App
https://screenstream.io
MIT License
1.56k stars 319 forks source link

Unable to capture stream using cv2.VideoCapture #231

Closed SMDIndomitable closed 5 months ago

SMDIndomitable commented 6 months ago

Hi, is there a reason why cv2.VideoCapture is unable to read the stream? Love the application, and would appreciate that cv2.VideoCapture is able to read the stream

dkrivoruchko commented 6 months ago

Hi. What type of stream you what to capture - MJPEG ot WebRTC?

SMDIndomitable commented 6 months ago

Hi. What type of stream you what to capture - MJPEG ot WebRTC?

I am using MJPEG

dkrivoruchko commented 6 months ago

Make sure that you point to the actual stream address, which is http:///stream.mjpeg Like http://192.168.231.69:8080/stream.mjpeg

SMDIndomitable commented 6 months ago

Hi, yep, that's what I did, it made several connections as shown on the application, however all of them disconnected very quickly. Resulted in a "CAP_IMAGES: can't find starting number " error on cv2.VideoCapture

dkrivoruchko commented 6 months ago

What do you meat by "disconnected very quickly" - app stop sending data or what? When you try to open steam via OpenCV-does app show another client connected?

SMDIndomitable commented 6 months ago

I apologize for the confusion. Yes, when I open the stream via OpenCV, the app shows a client connected, however it does the follow within the span of 5 seconds. Connected -> Disconnected -> Connected -> Disconnected -> Connected -> Disconnected, so it attempts to connect, but connection breaks immediately, and it retries for 3-4 times on the application.

SMDIndomitable commented 6 months ago

However, if I use the following code:

import requests
import numpy as np
import cv2

stream_url = "http://10.10.8.175:8080/stream.mjpeg"  

response = requests.get(stream_url, stream=True)

response.raw.decode_content = True
response.headers['Content-Type'] = 'image/jpeg'

buffer = bytes()

for chunk in response.iter_content(chunk_size=4096):
    buffer += chunk
    a = buffer.find(b'\xff\xd8')  # Start of JPEG frame
    b = buffer.find(b'\xff\xd9')  # End of JPEG frame

    while a != -1 and b != -1:
        frame_data = buffer[a:b+2]
        buffer = buffer[b+2:]

        frame = cv2.imdecode(np.frombuffer(frame_data, dtype=np.uint8), cv2.IMREAD_COLOR)

        cv2.imshow("Frame", frame)
        cv2.waitKey(1)

        a = buffer.find(b'\xff\xd8')
        b = buffer.find(b'\xff\xd9')

cv2.destroyAllWindows()

It works properlly

dkrivoruchko commented 6 months ago

Here https://answers.opencv.org/question/220468/video-from-ip-camera-cant-find-starting-number-cvicvextractpattern/ it says that: I had this issue as well and it was a result of not having compiled with ffmpeg "-DWITH_FFMPEG=ON".

SMDIndomitable commented 6 months ago

Hi, my OpenCV is complied with FFMPEG. It works on other IP cameras application (http), but it just doesnt work on this, I have no idea why.

dkrivoruchko commented 6 months ago

That's strange. Can you please put here full code that works with other streams but not the stream from the app.

SMDIndomitable commented 6 months ago

Here is the code:

import cv2

def display_rtsp_stream(rtsp_url):
    cap = cv2.VideoCapture(rtsp_url)
    if not cap.isOpened():
        print("Failed to open RTSP stream.")
        return

    while True:
        ret, frame = cap.read()
        if ret:
            cv2.imshow('RTSP Stream', frame)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

    cap.release()
    cv2.destroyAllWindows()

rtsp_url = "http://IP_ADDRESS:8080/stream.mjpeg"
display_rtsp_stream(rtsp_url)
dkrivoruchko commented 6 months ago

Ok. There is a bug of how MJPEG stream is being sent. It's ok for browsers, but not for OpenCV. A fix will be in next release.

dkrivoruchko commented 6 months ago

This is a Python that I used for tests:

import cv2

def display_rtsp_stream():
    stream = cv2.VideoCapture("http://192.168.231.70:8080/stream.mjpeg")
    if not stream.isOpened():
        print("Failed to open MJPEG stream.")
        return

    while True:
        ret, frame = stream.read()
        if ret:
            cv2.imshow('MJPEG Stream', frame)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

    stream.release()
    cv2.destroyAllWindows()

display_rtsp_stream()
SMDIndomitable commented 6 months ago

Alright, thank you very much :D, appreciate it

dkrivoruchko commented 5 months ago

Should be fixed in 4.0.30 version. Please verify.

SMDIndomitable commented 5 months ago

Yep, it is fixed. tested, and verified. Thank you so much!

dkrivoruchko commented 5 months ago

Thanks