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 sys
from PyQt5.QtWidgets import QApplication, QMainWindow,QFileDialog
from PyQt5.QtCore import pyqtSlot,QUrl,QDir, QFileInfo,Qt,QEvent
from PyQt5.QtGui import QIcon,QKeyEvent,QMouseEvent
from PyQt5.QtMultimedia import QMediaContent,QMediaPlayer
from ui_MainWindow import Ui_MainWindow
classQmyMainWindow(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处理函数==========================defcloseEvent(self,event):#窗体关闭时# 窗口关闭时不能自动停止播放,需手动停止if(self.player.state()== QMediaPlayer.PlayingState):
self.player.stop()defeventFilter(self, watched, event):##事件过滤器if(watched != self.ui.videoWidget):returnsuper().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)returnsuper().eventFilter(watched,event)## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot()##打开文件defon_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()##播放defon_btnPlay_clicked(self):
self.player.play()@pyqtSlot()##暂停defon_btnPause_clicked(self):
self.player.pause()@pyqtSlot()##停止defon_btnStop_clicked(self):
self.player.stop()@pyqtSlot()##全屏defon_btnFullScreen_clicked(self):
self.ui.videoWidget.setFullScreen(True)@pyqtSlot()##静音按钮defon_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)##音量调节defon_sliderVolumn_valueChanged(self,value):
self.player.setVolume(value)@pyqtSlot(int)##播放进度调节defon_sliderPosition_valueChanged(self,value):
self.player.setPosition(value)## =============自定义槽函数=============================== defdo_stateChanged(self, state):##状态变化
isPlaying =(state == QMediaPlayer.PlayingState)
self.ui.btnPlay.setEnabled(not isPlaying)
self.ui.btnPause.setEnabled(isPlaying)
self.ui.btnStop.setEnabled(isPlaying)defdo_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)defdo_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键可以退出全屏状态。
版权归原作者 Coder_Zeus 所有, 如有侵权,请联系我们删除。