首页 > 解决方案 > Kivy 视频播放器延迟/滞后

问题描述

我正在尝试通过 kivy 视频播放器显示 rtsp 流,这运行良好,但在我的视频中,我在流中得到 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 视频小部件的实现。我仍然不确定如何将我的工作解决方案与 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 视频播放器小部件。但是现在我找到的解决方案是使用 OpenCV 的线程,所以我已经更改了这个问题的标签,并将接受这个解决方案的任何 Kivy 实现。

标签: pythonopencvkivyrtspkivy-language

解决方案


推荐阅读