python - PyQt QMediaPlayer setPosition 对位置值进行四舍五入
问题描述
我有一个旨在帮助同步实验视频和数据信号的应用程序。该应用程序有一个视频小部件和一个可以设置视频时间位置的滑块。但是,QMediaPlayer 只会将位置设置为 500 毫秒/1000 毫秒的间隔(在我的应用程序中为 500 毫秒/在人为的应用程序中为 1000 毫秒),而视频以 50fps 的速度拍摄,这意味着 20 毫秒的间隔。这使得同步变得毫无用处。我在位置更改之前和之后添加了位置的输出。
任何帮助,将不胜感激。
这是更改滑块时的输出:
New slider position 326
Media player updated position 0
New slider position 816
Media player updated position 0
New slider position 1306
Media player updated position 0
New slider position 1632
Media player updated position 1000
New slider position 1959
Media player updated position 1000
New slider position 2449
Media player updated position 2000
New slider position 2938
Media player updated position 2000
New slider position 3428
Media player updated position 2000
New slider position 3755
Media player updated position 3000
New slider position 4081
Media player updated position 3000
New slider position 4571
Media player updated position 4000
New slider position 4897
Media player updated position 4000
New slider position 5224
Media player updated position 4000
New slider position 5550
Media player updated position 5000
New slider position 5714
Media player updated position 5000
New slider position 6040
Media player updated position 5000
New slider position 6203
Media player updated position 6000
New slider position 6530
我还尝试设置从 mediaPlayer.position () 检索到的特定位置,但无济于事。
这是人为的应用程序:
import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import QSize, Qt, QUrl
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QLabel, QWidget, QSlider
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout
#
# Reference https://pythonprogramminglanguage.com/pyqt5-video-widget/
#
class MainWindow (QMainWindow):
def __init__ (self, parent=None):
super (QMainWindow, self).__init__ (parent)
#
# Set the filename here
#
filename = '/Users/yuval/src/lab/S4560001.MP4'
self.setMinimumSize (QSize (640, 480))
self.setWindowTitle ('Video & Data Viewer and Annotator')
self.mediaPlayer = QMediaPlayer (None, QMediaPlayer.VideoSurface)
videoWidget = QVideoWidget ()
videoWidget.setMinimumSize (640,200)
#
# Position Slider
#
self.positionSlider = QSlider (Qt.Horizontal)
self.positionSlider.setRange (0, 0)
self.positionSlider.sliderMoved.connect (self.setPosition)
#
# Position Label
#
self.positionLabel = QLabel ('00:00:000')
centralWidget = QWidget (self)
self.setCentralWidget (centralWidget)
#
# Layout the Control Widgets
#
ctlLayout = QHBoxLayout ()
ctlLayout.setContentsMargins (0, 0, 0, 0)
ctlLayout.addWidget (self.positionSlider)
ctlLayout.addWidget (self.positionLabel)
#
# Layout the Window
#
layout = QVBoxLayout ()
layout.addWidget (videoWidget)
layout.addLayout (ctlLayout)
centralWidget.setLayout (layout)
self.mediaPlayer.setVideoOutput (videoWidget)
self.mediaPlayer.positionChanged.connect (self.positionChanged)
self.mediaPlayer.durationChanged.connect (self.durationChanged)
self.mediaPlayer.error.connect (self.handleError)
self.mediaPlayer.setNotifyInterval (100)
self.mediaPlayer.setMuted (True)
print (filename)
if filename != '':
self.mediaPlayer.setMedia (
QMediaContent (QUrl.fromLocalFile (filename)))
def positionChanged (self, position):
self.positionSlider.setValue (position)
def durationChanged (self, duration):
self.positionSlider.setRange (0, duration)
def setPosition (self, position):
print (f'New slider position {position}')
self.mediaPlayer.setPosition (position)
print (f'Media player updated position {self.mediaPlayer.position ()}')
def handleError (self):
print ('Error: ' + self.mediaPlayer.errorString ())
if __name__ == '__main__':
app = QtWidgets.QApplication (sys.argv)
mainWin = MainWindow ()
mainWin.show ()
sys.exit (app.exec_ ())
我在 MacOS 10.14.16 (Mojave) 上运行。
Python 3.7.4
Python 包:PyQt5==5.13.0 PyQt5-sip==4.19.18
端口包:py37-pyqt5 @5.12.2_0(活动) qt5 @5.12.4_0(活动)
解决方案
找到了答案。问题出在 Qt5 中,他们“声称”这不是错误,似乎也没有任何修复它的计划。它特定于 MacOS,在 Windows 上运行良好(我怀疑是 Linux)。问题是 Qt5 使用了具有时间容忍度的 MacOS API。默认情况下,它只会使用“关键帧”,但可以限制其容差。Qt5 没有指定容差,因此它会调整关键帧的时间。
如果有人在 MacOS Qt5 开发团队中,如果你能解决这个问题,那就太好了。是的,如果我有一个开发环境,我会自己修复它(但无论如何我可能会被否决)。
MacOS / AVFoundation API 是https://developer.apple.com/documentation/avfoundation/avplayeritem/1387418-seek
推荐阅读
- java - 以下程序将如何工作?
- php - 上传到 AWS S3 存储桶时出错 - AWS4-HMAC-SHA256
- python - 在调用 dev 时打破 for 循环
- scala - Scala:如何将数组/列表列表分配给两个变量?
- mysql - 在管理面板中编辑产品时出现错误 Magento 2
- reactjs - ReactJS 中的 Twilio 视频 - 初始设置后如何访问房间对象?
- r - 在循环中动态命名变量以创建 30 个 ggplots
- node.js - Firebase startAfter 不适用于 doc ref
- vb.net - 如何检查第一个 Datagridview 是否也存在于第二个 Datagridview 中
- jsdoc - 如何使用 JSDoc 记录 ES6 类属性