如何创建具有 2 windows 相同视频的视频播放器?
How to create a video player with 2 windows with the same video?
我需要用 PyQt 做一个视频播放器。这个视频播放器的特别之处在于我需要 2 windows 具有相同的视频,一个在我的界面中,另一个在另一台显示器中,两者都应该从界面控制。我曾经用视频(鸟所在的地方)做一个单独的寡妇,但我无法处理那个白色小部件中的另一个。
这是代码:
self.player = QMediaPlayer()
self.player.play()
# Setup the playlist.
self.playlist = QMediaPlaylist()
self.player.setPlaylist(self.playlist)
# # Add viewer for video playback, separate floating window.
self.viewer = ViewerWindow(self)
self.viewer.setWindowFlags(self.viewer.windowFlags() | Qt.WindowStaysOnTopHint)
self.viewer.setMinimumSize(QSize(480, 360))
self.viewer.setWindowTitle("VR Therapy")
self.videoWidget = QVideoWidget(self)
self.viewer.setCentralWidget(self.videoWidget)
self.player.setVideoOutput(self.videoWidget)
# Connect control buttons/slides for media player.
self.playButton_2.pressed.connect(self.player.play)
self.pauseButton_2.pressed.connect(self.player.pause)
self.stopButton_2.clicked.connect(self.player.stop)
self.volumeSlider_2.valueChanged.connect(self.player.setVolume)
self.viewButton_2.toggled.connect(self.toggle_viewer)
self.viewer.state.connect(self.viewButton_2.setChecked)
self.previousButton_2.pressed.connect(self.playlist.previous)
self.nextButton_2.pressed.connect(self.playlist.next)
self.model = PlaylistModel(self.playlist)
self.playlistView_2.setModel(self.model)
self.playlist.currentIndexChanged.connect(self.playlist_position_changed)
selection_model = self.playlistView_2.selectionModel()
selection_model.selectionChanged.connect(self.playlist_selection_changed)
self.player.durationChanged.connect(self.update_duration)
self.player.positionChanged.connect(self.update_position)
self.timeSlider_2.valueChanged.connect(self.player.setPosition)
视频播放器
QMediaPlayer 是媒体源的控制器,也就是说,它控制播放、暂停等时间,而 QVideoWidget 是 QMediaPlayer 提供的内部显示的帧的众多查看器之一QAbstractVideoSurface。因此,如果 QMediaPlayer 将帧提供给 N 个输出,应该没有问题,为此您必须使用 setVideoOutput()
方法:
void QMediaPlayer::setVideoOutput(const QVector<QAbstractVideoSurface
*> &surfaces)
Sets multiple video surfaces as the video output of a media player. This allows the media player to render video frames on
different surfaces.
All video surfaces must support at least one shared
QVideoFrame::PixelFormat.
If a video output has already been set on the media player the new
surfaces will replace it.
This function was introduced in Qt 5.15.
from functools import cached_property
import sys
from PyQt5 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setCentralWidget(self.video_widget)
self.viewer.show()
self.player.setVideoOutput(
[self.video_widget.videoSurface(), self.viewer.videoSurface()]
)
self.player.setPlaylist(self.playlist)
self.playlist.addMedia(
QtMultimedia.QMediaContent(
QtCore.QUrl("http://techslides.com/demos/sample-videos/small.mp4")
)
)
self.player.play()
@cached_property
def player(self):
return QtMultimedia.QMediaPlayer()
@cached_property
def video_widget(self):
return QtMultimediaWidgets.QVideoWidget()
@cached_property
def viewer(self):
view = QtMultimediaWidgets.QVideoWidget()
view.setWindowFlags(view.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
view.setMinimumSize(480, 360)
view.setWindowTitle("VR Therapy")
return view
@cached_property
def playlist(self):
return QtMultimedia.QMediaPlaylist()
def main():
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
我需要用 PyQt 做一个视频播放器。这个视频播放器的特别之处在于我需要 2 windows 具有相同的视频,一个在我的界面中,另一个在另一台显示器中,两者都应该从界面控制。我曾经用视频(鸟所在的地方)做一个单独的寡妇,但我无法处理那个白色小部件中的另一个。 这是代码:
self.player = QMediaPlayer()
self.player.play()
# Setup the playlist.
self.playlist = QMediaPlaylist()
self.player.setPlaylist(self.playlist)
# # Add viewer for video playback, separate floating window.
self.viewer = ViewerWindow(self)
self.viewer.setWindowFlags(self.viewer.windowFlags() | Qt.WindowStaysOnTopHint)
self.viewer.setMinimumSize(QSize(480, 360))
self.viewer.setWindowTitle("VR Therapy")
self.videoWidget = QVideoWidget(self)
self.viewer.setCentralWidget(self.videoWidget)
self.player.setVideoOutput(self.videoWidget)
# Connect control buttons/slides for media player.
self.playButton_2.pressed.connect(self.player.play)
self.pauseButton_2.pressed.connect(self.player.pause)
self.stopButton_2.clicked.connect(self.player.stop)
self.volumeSlider_2.valueChanged.connect(self.player.setVolume)
self.viewButton_2.toggled.connect(self.toggle_viewer)
self.viewer.state.connect(self.viewButton_2.setChecked)
self.previousButton_2.pressed.connect(self.playlist.previous)
self.nextButton_2.pressed.connect(self.playlist.next)
self.model = PlaylistModel(self.playlist)
self.playlistView_2.setModel(self.model)
self.playlist.currentIndexChanged.connect(self.playlist_position_changed)
selection_model = self.playlistView_2.selectionModel()
selection_model.selectionChanged.connect(self.playlist_selection_changed)
self.player.durationChanged.connect(self.update_duration)
self.player.positionChanged.connect(self.update_position)
self.timeSlider_2.valueChanged.connect(self.player.setPosition)
视频播放器
QMediaPlayer 是媒体源的控制器,也就是说,它控制播放、暂停等时间,而 QVideoWidget 是 QMediaPlayer 提供的内部显示的帧的众多查看器之一QAbstractVideoSurface。因此,如果 QMediaPlayer 将帧提供给 N 个输出,应该没有问题,为此您必须使用 setVideoOutput()
方法:
void QMediaPlayer::setVideoOutput(const QVector<QAbstractVideoSurface *> &surfaces)
Sets multiple video surfaces as the video output of a media player. This allows the media player to render video frames on different surfaces.All video surfaces must support at least one shared QVideoFrame::PixelFormat.
If a video output has already been set on the media player the new surfaces will replace it.
This function was introduced in Qt 5.15.
from functools import cached_property
import sys
from PyQt5 import QtCore, QtWidgets, QtMultimedia, QtMultimediaWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setCentralWidget(self.video_widget)
self.viewer.show()
self.player.setVideoOutput(
[self.video_widget.videoSurface(), self.viewer.videoSurface()]
)
self.player.setPlaylist(self.playlist)
self.playlist.addMedia(
QtMultimedia.QMediaContent(
QtCore.QUrl("http://techslides.com/demos/sample-videos/small.mp4")
)
)
self.player.play()
@cached_property
def player(self):
return QtMultimedia.QMediaPlayer()
@cached_property
def video_widget(self):
return QtMultimediaWidgets.QVideoWidget()
@cached_property
def viewer(self):
view = QtMultimediaWidgets.QVideoWidget()
view.setWindowFlags(view.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
view.setMinimumSize(480, 360)
view.setWindowTitle("VR Therapy")
return view
@cached_property
def playlist(self):
return QtMultimedia.QMediaPlaylist()
def main():
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()