Kivy Video Player задержка / отставание - PullRequest
2 голосов
/ 24 февраля 2020

Я пытаюсь отобразить поток 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.

...