не работает cv2.VideoCapture на Android
Делаю программу под андроид, которая показывает демонстрацию экрана ПК на телефоне. На винде код работает исправно, но когда я собираю apk через бульдозер и пробую подключиться по айпи на сервер, откуда берется изображение, в консоли (через adb logcat) выдает ошибку. Код приложения:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.graphics.texture import Texture
import cv2
import numpy as np
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
KV = '''
#<KvLang>
MDScreen:
MDBoxLayout:
orientation: 'vertical'
padding: dp(20)
spacing: dp(10)
MDTextField:
id: ip_input
mode: "outlined"
size_hint_y: None
height: "50dp"
MDTextFieldHintText:
text: "Введите IP адрес сервера"
MDButton:
on_release: app.start_stream()
size_hint_y: None
height: "50dp"
MDButtonText:
text: "Подключиться"
BoxLayout:
id: image_container
size_hint: (1, 1)
pos_hint: {"center_x": 0.5, "center_y": 0.5}
MDLabel:
id: status_label
text: "Статус: Ожидание подключения"
halign: "center"
size_hint_y: None
height: "50dp"
#</KvLang>
'''
class KivyCamera(Image):
def __init__(self, url, fps=30, **kwargs):
super(KivyCamera, self).__init__(**kwargs)
self.url = url
self.fps = fps
self.capture = None
self.status_label = None
logger.debug(f"Инициализация KivyCamera с URL: {url}")
Clock.schedule_interval(self.update, 1.0 / fps)
def set_status(self, text):
try:
if self.status_label is None:
parent = self.parent
while parent is not None:
if hasattr(parent, 'ids') and 'status_label' in parent.ids:
self.status_label = parent.ids['status_label']
break
parent = parent.parent
if self.status_label:
self.status_label.text = text
except Exception:
pass
def update(self, dt):
try:
if self.capture is None:
self.capture = cv2.VideoCapture(self.url)
if not self.capture.isOpened():
self.set_status("Статус: Ошибка подключения")
return
self.set_status("Статус: Подключено")
ret, frame = self.capture.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
texture = Texture.create(size=(frame.shape[1], frame.shape[0]), colorfmt='rgb')
texture.blit_buffer(cv2.flip(frame, 0).tobytes(), colorfmt='rgb', bufferfmt='ubyte')
self.texture = texture
else:
self.capture.release()
self.capture = None
self.set_status("Статус: Переподключение...")
except Exception as e:
self.set_status(f"Статус: Ошибка - {str(e)}")
if self.capture:
self.capture.release()
self.capture = None
def __del__(self):
if self.capture:
self.capture.release()
class MainApp(MDApp):
def __init__(self, **kwargs):
super(MainApp, self).__init__(**kwargs)
self.camera_widget = None
def build(self):
return Builder.load_string(KV)
def start_stream(self):
screen = self.root
ip_address = screen.ids.ip_input.text
if not ip_address:
screen.ids.status_label.text = "Статус: Введите IP адрес"
return
if self.camera_widget is not None:
screen.ids.image_container.remove_widget(self.camera_widget)
try:
url = f'http://{ip_address}:5000/video_feed'
self.camera_widget = KivyCamera(url=url, fps=30)
screen.ids.image_container.add_widget(self.camera_widget)
screen.ids.status_label.text = "Статус: Подключение..."
except Exception as e:
screen.ids.status_label.text = f"Статус: Ошибка - {str(e)}"
if __name__ == '__main__':
MainApp().run()
часть файла buildozer.spec:
requirements = python3,kivy,https://github.com/kivymd/KivyMD/archive/master.zip,opencv_extras,materialyoucolor,numpy,asyncgui,asynckivy
android.permissions = android.permission.INTERNET, android.permission.CAMERA, (name=android.permission.WRITE_EXTERNAL_STORAGE;maxSdkVersion=18)
Ошибка, которую выдает adb logcat:
03-22 23:32:58.029 13883 15538 E cv::error(): OpenCV(4.5.1) Error: Bad argument (CAP_IMAGES: can't find starting number (in the name of file): http://192.168.0.11:5000/video_feed) in icvExtractPattern, file /home/mapium/python/PyRemoteControl/project_oop/android/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/other_builds/opencv/arm64-v8a__ndk_target_21/opencv/modules/videoio/src/cap_images.cpp, line 253
03-22 23:32:58.030 13883 15538 E OpenCV/4.5.1: [ERROR:0] global /home/mapium/python/PyRemoteControl/project_oop/android/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/other_builds/opencv/arm64-v8a__ndk_target_21/opencv/modules/videoio/src/cap.cpp (142) open VIDEOIO(CV_IMAGES): raised OpenCV exception:
03-22 23:32:58.030 13883 15538 E OpenCV/4.5.1:
03-22 23:32:58.030 13883 15538 E OpenCV/4.5.1: OpenCV(4.5.1) /home/mapium/python/PyRemoteControl/project_oop/android/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a/build/other_builds/opencv/arm64-v8a__ndk_target_21/opencv/modules/videoio/src/cap_images.cpp:253: error: (-5:Bad argument) CAP_IMAGES: can't find starting number (in the name of file): http://192.168.0.11:5000/video_feed in function 'icvExtractPattern'
03-22 23:32:58.030 13883 15538 E OpenCV/4.5.1:
03-22 23:32:58.030 13883 15538 E NativeCodec: failed to stat file: http://192.168.0.11:5000/video_feed (No such file or directory)
Если с телефона зайти на сам сайт откуда берется демонстрация экрана, то там все работает нормально