Устранение проблем с покадровой буферизацией и задержками при работе с кадрами FFpyplayer и QPixmap с потоком UDP в формPython

Программы на Python
Ответить
Anonymous
 Устранение проблем с покадровой буферизацией и задержками при работе с кадрами FFpyplayer и QPixmap с потоком UDP в форм

Сообщение Anonymous »

Я пытаюсь построить код, найденный в этом посте, для моего варианта использования. Однако у меня возникли проблемы с Python FFpyPlayer; с традиционным ffplay у меня нет подобных проблем. При запуске моего приложения я замечаю эффект буферизации замедленной съемки, при котором воспроизведение видео значительно ускоряется, а затем возвращается к нормальной скорости. На некоторых видео я заметил некоторое заикание или задержку. Я использую ffpyplayer для обработки воспроизведения видео из потока udp в фоновом потоке с кадрами. Не знаю, где и как, но я считаю, что проблема возникает при получении и отображении кадров с использованием QPixmap PyQt. Ниже приведена команда, используемая для отправки потока udp с помощью ffmpeg с этим стоковым видео:

Код: Выделить всё

ffmpeg -re -stream_loop -1 -i .\2099536-hd_1920_1080_30fps.mp4 -f mpegts udp://127.0.0.1:51234?localaddr=127.0.0.1
А вот команда ffplay, которая работает без проблем:

Код: Выделить всё

ffplay udp://127.0.0.1:51234
Вот пример кода, который использует ffpyplay для отображения упомянутых проблем:

Код: Выделить всё

from PyQt6 import QtGui, QtWidgets, QtCore
from ffpyplayer.player import MediaPlayer
import time
from threading import Thread

class VideoDisplayWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.player = None
self.layout = QtWidgets.QVBoxLayout(self)
self.video_frame_widget = QtWidgets.QLabel()
self.layout.addWidget(self.video_frame_widget)
self.frame_rate = 30

self.latest_frame = QtGui.QPixmap()

self.timer = QtCore.QTimer()
self.timer.setTimerType(QtCore.Qt.TimerType.PreciseTimer)
self.timer.timeout.connect(self.nextFrameSlot)
self.timer.start(int(1000.0/self.frame_rate))

self.play()
self.setLayout(self.layout)

def play(self):
play_thread = Thread(target=self._play, daemon=True)
play_thread.start()

def _play(self):
player = MediaPlayer("udp://127.0.0.1:51234")
val = ''
while val != 'eof':
frame, val = player.get_frame()
if val != 'eof' and frame is not None:
img, t = frame
# display img
w = img.get_size()[0]
h = img.get_size()[1]
data = img.to_bytearray()[0]

qimage = QtGui.QImage(data, w, h, QtGui.QImage.Format.Format_RGB888)
self.latest_frame = QtGui.QPixmap.fromImage(qimage)
time.sleep(0.001)

def nextFrameSlot(self):
self.video_frame_widget.setPixmap(self.latest_frame)

if __name__ == "__main__":
current_port = 51234
app = QtWidgets.QApplication([])
player = VideoDisplayWidget()
player.show()

exit(app.exec())
Вот блок кода, адаптированный из этого поста, который без проблем работает с ffpyplay с использованием opencv:

Код: Выделить всё

from ffpyplayer.player import MediaPlayer
import time
from pathlib import Path
import numpy as np
import cv2

player = MediaPlayer("udp://127.0.0.1:51234")
val = ''
while val != 'eof':
frame, val = player.get_frame()
if val != 'eof' and frame is not None:
img, t = frame
# display img
w = img.get_size()[0]
h = img.get_size()[1]
arr = np.uint8(np.array(img.to_bytearray()[0]).reshape(h,w,3)) # h - height of frame, w - width of frame, 3 - number of channels in frame
arr = cv2.cvtColor(arr, cv2.COLOR_BGR2RGB)

cv2.imshow('test', arr)
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
Есть ли конкретная настройка или параметр, который мне следует настроить с помощью ffpyplay и/или pyqt, чтобы предотвратить эффект догоняющей покадровой буферизации?


Подробнее здесь: https://stackoverflow.com/questions/787 ... ayer-frame
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»