Я пытаюсь отобразить поток rtsp через видеопроигрыватель kivy, это работает нормально, но в моем видео я получаю задержку в 2 или 3 секунды в потоке, которую в идеале я хотел бы устранить до 0,5-1 секунды.
Вот что у меня есть:
from kivy.app import App
from kivy.uix.video import Video
class TestApp(App):
def build(self):
video = Video(source='rtsp://my-stream-address', state='play')
video.size = (720, 320)
video.opacity = 0
video.state = 'play'
video.bind(texture=self._play_started)
return video
def _play_started(self, instance, value):
instance.opacity = 1
if __name__ == '__main__':
TestApp().run()
РЕДАКТИРОВАТЬ
У меня есть рабочее решение для потоковой передачи видео НО Я не знаю, как получить это в моем kivy gui.
Вот мое потоковое решение:
from threading import Thread
import cv2, time
class ThreadedCamera(object):
def __init__(self, src=0):
self.capture = cv2.VideoCapture(src)
self.capture.set(cv2.CAP_PROP_BUFFERSIZE, 2)
self.FPS = 1/30
self.FPS_MS = int(self.FPS * 1000)
# Start frame retrieval thread
self.thread = Thread(target=self.update, args=())
self.thread.daemon = True
self.thread.start()
def update(self):
while True:
if self.capture.isOpened():
(self.status, self.frame) = self.capture.read()
time.sleep(self.FPS)
def show_frame(self):
cv2.imshow('frame', self.frame)
cv2.waitKey(self.FPS_MS)
if __name__ == '__main__':
src = 'rtsp://my-stream-address'
threaded_camera = ThreadedCamera(src)
while True:
try:
threaded_camera.show_frame()
except AttributeError:
pass
РЕДАКТИРОВАТЬ 2
Я также обнаружил, что эта реализация виджета kivy video не использует встроенный виджет Video. Я до сих пор не уверен, как совместить мое рабочее решение с виджетом Kivy, но, возможно, это поможет кому-то помочь:
class KivyCamera(Image):
source = ObjectProperty()
fps = NumericProperty(30)
def __init__(self, **kwargs):
super(KivyCamera, self).__init__(**kwargs)
self._capture = None
if self.source is not None:
self._capture = cv2.VideoCapture(self.source)
Clock.schedule_interval(self.update, 1.0 / self.fps)
def on_source(self, *args):
if self._capture is not None:
self._capture.release()
self._capture = cv2.VideoCapture(self.source)
@property
def capture(self):
return self._capture
def update(self, dt):
ret, frame = self.capture.read()
if ret:
buf1 = cv2.flip(frame, 0)
buf = buf1.tostring()
image_texture = Texture.create(
size=(frame.shape[1], frame.shape[0]), colorfmt="bgr"
)
image_texture.blit_buffer(buf, colorfmt="bgr", bufferfmt="ubyte")
self.texture = image_texture
Мой первоначальный вопрос был о виджете Kivy Video player. Но теперь решение, которое я нахожу, заключается в использовании потоков с OpenCV, поэтому я изменил теги этого вопроса и приму любую реализацию этого решения в Kivy.