PyQt5 视频播放--在QVideoWidget上显示视频
1、功能概述
(1)QMediaPlayer不仅可以播放音频文件,还可以播放wmv、avi等视频文件。
2、主要函数
(1)setMedia(QMediaContent):指定一个媒体资源;
(2)setPlaylist():指定一个播放列表;
(3)setVideoOutput(QVideoWidget):指定一个界面组件用于视频显示;
重构参数:
setVideoOutput(self, QVideoWidget)
setVideoOutput(self, QGraphicsVideoItem)
setVideoOutput(self, QAbstractVideoSurface)
(4)setNotifyInterval(1000):设置信息更新周期,1000ms。
(5)setFullScreen(True):设置全屏。
3、主要类
(1)QVideoWidget是从QWidget和QMediaBindableInterface双重继承的类,是一个类似于QWidget的类,但是可以显示视频画面。
(2)QGraphicsVideoItem是从QGraphicsObject和QMediaBindableInterface双重继承的类,是Graphics View架构里的一种图形项,用于在Graphics View架构里显示视频画面。
(3)QAbstractVideoSurface是从QObject直接继承的用于视频显示的抽象类,它提供了用于视频画面显示的标准接口,用户需要从这个类继承一个类,实现解码视频帧内容的自定义显示。
4、详细代码
示例使用QMediaPlayer播放视频文件,然后在QVideoWidget组件上显示视频画面。本示例的UI界面如图所示。UI界面的设计过程不作过多介绍。
使用QVideoWidget显示画面的视频播放器
MainWindow.ui设计时的效果和布局层次
注意:组件面板里并没有QVideoWidget类,需要用提升法将一个QWidget组件提升为QVideoWidget类。右键点击该组件,将其从QWidget提升为QVideoWidget。
组件类型提升对话框
组件提升法可以将一个组件提升为一个Qt已有的类,也可以提升为一个自定义的类,但是提升后的类必须是基类的子类或更下级的类。
具体代码如下:
import sysfrom PyQt5.QtWidgets import QApplication, QMainWindow,QFileDialogfrom PyQt5.QtCore import pyqtSlot,QUrl,QDir, QFileInfo,Qt,QEventfrom PyQt5.QtGui import QIcon,QKeyEvent,QMouseEventfrom PyQt5.QtMultimedia import QMediaContent,QMediaPlayerfrom ui_MainWindow import Ui_MainWindowclass QmyMainWindow(QMainWindow):def __init__(self, parent=None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui=Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.player = QMediaPlayer(self) #创建视频播放器 self.player.setNotifyInterval(1000) #信息更新周期, ms self.player.setVideoOutput(self.ui.videoWidget) #视频显示组件 self.ui.videoWidget,installEventFilter(self) #事件过滤器 self.__duration = "" self.__curPos = "" self.player.stateChanged.connect(self.do_stateChanged) self.player.positionChanged.connect(self.do_positionChanged) self.player.durationChanged.connect(self.do_durationChanged)## ==============自定义功能函数========================## ==============event处理函数========================== def closeEvent(self,event): #窗体关闭时 # 窗口关闭时不能自动停止播放,需手动停止 if (self.player.state() == QMediaPlayer.PlayingState): self.player.stop() def eventFilter(self, watched, event): ##事件过滤器 if (watched != self.ui.videoWidget): return super().eventFilter(watched, event) #鼠标左键按下时,暂停或继续播放 if event.type() == QEvent.MouseButtonPress: if event.button() == Qt.LeftButton: if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() #全屏状态时,按ESC键退出全屏 if event.type() == QEvent.KeyPress: if event.key() == Qt.Key_Escape: if self.ui.videoWidget.isFullScreen(): self.ui.videoWidget.setFullScreen(False) return super().eventFilter(watched,event)## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot() ##打开文件 def on_btnOpen_clicked(self): curPath = QDir.currentPath() #获取系统当前目录 title = "选择视频文件" filt = "视频文件(*.wmv *.avi);;所有文件(*.*)" fileName, flt = QFileDialog.getOpenFileName(self, title, curPath, filt) if (fileName == ""): return fileInfo = QFileInfo(fileName) baseName = fileInfo.fileName() self.ui.LabCurMedia.setText(baseName) curPath = fileInfo.absolutePath() QDir.setCurrent(curPath) #重设当前目录 media = QMediaContent(QUrl.fromLocalFile(fileName)) self.player.setMedia(media) #设置播放文件 self.player.play() @pyqtSlot() ##播放 def on_btnPlay_clicked(self): self.player.play() @pyqtSlot() ##暂停 def on_btnPause_clicked(self): self.player.pause() @pyqtSlot() ##停止 def on_btnStop_clicked(self): self.player.stop() @pyqtSlot() ##全屏 def on_btnFullScreen_clicked(self): self.ui.videoWidget.setFullScreen(True) @pyqtSlot() ##静音按钮 def on_btnSound_clicked(self): mute=self.player.isMuted() self.player.setMuted(not mute) if mute: self.ui.btnSound.setIcon(QIcon(":/icons/images/volumn.bmp")) else: self.ui.btnSound.setIcon(QIcon(":/icons/images/mute.bmp")) @pyqtSlot(int) ##音量调节 def on_sliderVolumn_valueChanged(self,value): self.player.setVolume(value) @pyqtSlot(int) ##播放进度调节 def on_sliderPosition_valueChanged(self,value): self.player.setPosition(value)## =============自定义槽函数=============================== def do_stateChanged(self, state): ##状态变化 isPlaying = (state == QMediaPlayer.PlayingState) self.ui.btnPlay.setEnabled(not isPlaying) self.ui.btnPause.setEnabled(isPlaying) self.ui.btnStop.setEnabled(isPlaying) def do_durationChanged(self,duration): ##文件长度变化 self.ui.sliderPosition.setMaximum(duration) #先把ms化为s,再转换为min secs = duration / 1000 #秒 mins = secs / 60 #分钟 secs = secs % 60 #余数秒 self.__duration = "%d:%d"%(mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration) def do_positionChanged(self, position): ##当前播放位置变化 if (self.ui.sliderPosition.isSliderDown()): return #如果正在拖动滑条,退出 self.ui.sliderPosition.setSliderPosition(position) secs = position/1000 #秒 mins = secs/60 #分钟 secs = secs % 60 #余数秒 self.__curPos = "%d:%d"%(mins, secs) self.ui.LabRatio.setText(self.__curPos + "/" + self.__duration)
使用事件过滤器EventFilter为视频显示组件videoWidget提供了鼠标和按键操作功能,使得在画面上点击鼠标左键时可以暂停或继续播放,在全屏状态下按Esc键可以退出全屏状态。
来源地址:https://blog.csdn.net/qq_35412059/article/details/129451553
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341