Stack Overflow на русском Asked by Luchunpen on December 14, 2021
Я хочу сделать покадровый переход по видеофайлу, но проблема в том, что после проигрывания, достаточно пары секунд, реальная позиция видео не соответствует значению из QMediaPlayer.position(), а именно отставание на 1-2 кадра. Это легко наблюдается если проиграть видео с каким нибудь счетчиком или быстрыми действиями. При этом если продолжить проигрывать видео сняв его с паузы без перехода, плеер ожидаемо продолжает с места остановки.
Для теста выкладываю рабочий скрипт, который по нажатии кнопки "Seek to current position" позволяет перейти на текущую позицию полученную из QMediaPlay.position().
Буду благодарен любым ответам и возможности решения этой проблемы.
import sys
from PyQt5.QtCore import QUrl, QSize
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QVBoxLayout, QWidget
class VideoWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumSize(QSize(500, 500))
self.setGeometry(0, 0, 500, 500)
self.mainLayout = QVBoxLayout()
self.centralWidget = QWidget()
self.centralWidget.setLayout(self.mainLayout)
self.setCentralWidget(self.centralWidget)
video_widget = QVideoWidget()
button = QPushButton('Play', self)
button.clicked.connect(self.playMedia)
button2 = QPushButton("Seek to current position", self)
button2.clicked.connect(self.seekToCurrentPosition)
self.mainLayout.addWidget(video_widget)
self.mainLayout.addWidget(button)
self.mainLayout.addWidget(button2)
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.mediaPlayer.setVideoOutput(video_widget)
self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile("1.mp4")))
def playMedia(self):
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
self.mediaPlayer.pause()
print("current_position: ", self.mediaPlayer.position())
else:
self.mediaPlayer.play()
def seekToCurrentPosition(self):
if self.mediaPlayer.state() != QMediaPlayer.PausedState:
return
current_pos = self.mediaPlayer.position()
self.mediaPlayer.setPosition(current_pos)
if __name__ == '__main__':
app = QApplication(sys.argv)
player = VideoWindow()
player.show()
exitCode = app.exec_()
sys.exit(exitCode)
С трудом понял о чем вы говорите и то после кучи принтов и установления сигнала
self.mediaPlayer.positionChanged.connect(self.positionChanged)
да self.mediaPlayer.position()
отличается от self._position
.
используйте то что вам надо.
import sys
from PyQt5.QtCore import QUrl, QSize
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QVBoxLayout, QWidget
class VideoWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setMinimumSize(QSize(500, 500))
self.resize(500, 500)
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.button = QPushButton('Play', self)
self.button.clicked.connect(self.playMedia)
button2 = QPushButton("Искать в текущей позиции", self)
button2.clicked.connect(self.seekToCurrentPosition)
video_widget = QVideoWidget(self) # self
self.mediaPlayer = QMediaPlayer(self, QMediaPlayer.VideoSurface) # self
self.mediaPlayer.setVideoOutput(video_widget)
self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile("Samonastrojka.avi")))
self._position = 0 # +++ !!!
self.mediaPlayer.positionChanged.connect(self.positionChanged) # +++ !!!
self.mainLayout = QVBoxLayout(self.centralWidget)
self.mainLayout.addWidget(video_widget)
self.mainLayout.addWidget(self.button)
self.mainLayout.addWidget(button2)
def playMedia(self):
print(f'nplayMedia state 1: {self.mediaPlayer.state()} - '
f'{self.mediaPlayer.position()} <--> {self._position}')
if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
self.mediaPlayer.pause()
self.button.setText('Play')
print(f"current_position: {self.mediaPlayer.position()} <--> {self._position}")
else:
self.mediaPlayer.play()
self.button.setText('Pause')
print(f'playMedia state 2: {self.mediaPlayer.state()} - {self.mediaPlayer.position()}'
f' <--> {self._position}')
def seekToCurrentPosition(self):
print(f'nseekToCurrentPosition state: {self.mediaPlayer.state()}- '
f'{self.mediaPlayer.position()}<--> {self._position}')
if self.mediaPlayer.state() != QMediaPlayer.PausedState:
return
current_pos = self.mediaPlayer.position()
print(f'seekToCurrentPosition current_pos 1: {current_pos}<--> {self._position}')
self.mediaPlayer.setPosition(current_pos)
print(f'seekToCurrentPosition current_pos 2: {self.mediaPlayer.position()}<--> {self._position}')
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def positionChanged(self, position):
self._position = position # <<<-------<
# print(self._position)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == '__main__':
app = QApplication(sys.argv)
player = VideoWindow()
player.show()
exitCode = app.exec_()
sys.exit(exitCode)
Answered by S. Nick on December 14, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP