最近在学习pytq5的QMediaPlayer模块,其实刚开始是学习的pyside6的,因为pyside6的官方文档相对较详细一些,pyqt5的官方文档大片的文档解释都是TODO,我不太明白这种句式,但是做到添加播放列表QMediaPlaylist的时候,pyside6无法识别这个模块,我很疑惑,查了才发现现在Qt6的QtMultimedia相对与Qt5有较大重写,现在还有很多模块没有补齐,Qt6改动。后面有稍稍改了一下代码,改用pyqt5.
我遇到的一些pyqt6变化
图里面的需要的功能都完成,打开文件分两种的一种是添加单个或者多个文件,另一个是添加文件夹下面的所有文件(不过还没加检索,如果含有其他.txt .py文件也会一股脑添加到播放列表),此外没给控件设置样式,所以有点粗犷简陋。
如果要自己通过designer设计,需要记得添加一个Qwidget控件提升为QVideoWidget。
提升的类叫QVideoWidget,头文件:PyQt5.QtMultimediaWidgets
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(623, 446)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName("verticalLayout")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setHorizontalSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.nowtime = QtWidgets.QLabel(self.centralwidget)
self.nowtime.setText("")
self.nowtime.setObjectName("nowtime")
self.gridLayout.addWidget(self.nowtime, 2, 4, 1, 1)
self.playlistBox = QtWidgets.QComboBox(self.centralwidget)
self.playlistBox.setObjectName("playlistBox")
self.playlistBox.addItem("")
self.playlistBox.addItem("")
self.playlistBox.addItem("")
self.gridLayout.addWidget(self.playlistBox, 1, 4, 1, 1)
self.play_button = QtWidgets.QPushButton(self.centralwidget)
self.play_button.setObjectName("play_button")
self.gridLayout.addWidget(self.play_button, 3, 0, 1, 1)
self.videoout = QVideoWidget(self.centralwidget)
self.videoout.setEnabled(True)
self.videoout.setObjectName("videoout")
self.gridLayout.addWidget(self.videoout, 0, 0, 2, 4)
self.mid_button = QtWidgets.QPushButton(self.centralwidget)
self.mid_button.setObjectName("mid_button")
self.gridLayout.addWidget(self.mid_button, 3, 2, 1, 1)
self.timeSlider = QtWidgets.QSlider(self.centralwidget)
self.timeSlider.setEnabled(True)
self.timeSlider.setMaximum(99)
self.timeSlider.setOrientation(QtCore.Qt.Horizontal)
self.timeSlider.setObjectName("timeSlider")
self.gridLayout.addWidget(self.timeSlider, 2, 0, 1, 4)
self.volumeSlider = QtWidgets.QSlider(self.centralwidget)
self.volumeSlider.setEnabled(True)
self.volumeSlider.setOrientation(QtCore.Qt.Vertical)
self.volumeSlider.setObjectName("volumeSlider")
self.gridLayout.addWidget(self.volumeSlider, 1, 5, 2, 2)
self.volume = QtWidgets.QLabel(self.centralwidget)
self.volume.setObjectName("volume")
self.gridLayout.addWidget(self.volume, 3, 5, 1, 2)
self.listvidename = QtWidgets.QListWidget(self.centralwidget)
self.listvidename.setObjectName("listvidename")
self.gridLayout.addWidget(self.listvidename, 0, 4, 1, 3)
self.left_button = QtWidgets.QPushButton(self.centralwidget)
self.left_button.setEnabled(True)
self.left_button.setObjectName("left_button")
self.gridLayout.addWidget(self.left_button, 3, 1, 1, 1)
self.right_button = QtWidgets.QPushButton(self.centralwidget)
self.right_button.setObjectName("right_button")
self.gridLayout.addWidget(self.right_button, 3, 3, 1, 1)
self.gridLayout.setColumnStretch(0, 5)
self.gridLayout.setColumnStretch(1, 5)
self.gridLayout.setColumnStretch(2, 5)
self.gridLayout.setColumnStretch(3, 5)
self.gridLayout.setColumnStretch(4, 1)
self.gridLayout.setColumnStretch(5, 1)
self.gridLayout.setRowStretch(0, 10)
self.gridLayout.setRowStretch(1, 5)
self.gridLayout.setRowStretch(2, 1)
self.gridLayout.setRowStretch(3, 1)
self.verticalLayout.addLayout(self.gridLayout)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 623, 22))
self.menubar.setObjectName("menubar")
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionfiles = QtWidgets.QAction(MainWindow)
self.actionfiles.setObjectName("actionfiles")
self.actiondirs = QtWidgets.QAction(MainWindow)
self.actiondirs.setObjectName("actiondirs")
self.actionnext = QtWidgets.QAction(MainWindow)
self.actionnext.setEnabled(True)
self.actionnext.setObjectName("actionnext")
self.actionprevious = QtWidgets.QAction(MainWindow)
self.actionprevious.setObjectName("actionprevious")
self.actionpause = QtWidgets.QAction(MainWindow)
self.actionpause.setObjectName("actionpause")
self.actionstop = QtWidgets.QAction(MainWindow)
self.actionstop.setObjectName("actionstop")
self.menu.addAction(self.actionfiles)
self.menu.addAction(self.actiondirs)
self.menubar.addAction(self.menu.menuAction())
self.toolBar.addAction(self.actionprevious)
self.toolBar.addAction(self.actionpause)
self.toolBar.addAction(self.actionnext)
self.toolBar.addAction(self.actionstop)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.playlistBox.setItemText(0, _translate("MainWindow", "顺序播放"))
self.playlistBox.setItemText(1, _translate("MainWindow", "随机播放"))
self.playlistBox.setItemText(2, _translate("MainWindow", "洗脑循环"))
self.play_button.setText(_translate("MainWindow", "播放"))
self.mid_button.setText(_translate("MainWindow", "暂停"))
self.volume.setText(_translate("MainWindow", "音量"))
self.left_button.setText(_translate("MainWindow", "快退"))
self.right_button.setText(_translate("MainWindow", "快进"))
self.menu.setTitle(_translate("MainWindow", "打开文件"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionfiles.setText(_translate("MainWindow", "文件"))
self.actiondirs.setText(_translate("MainWindow", "文件夹"))
self.actionnext.setText(_translate("MainWindow", "下一部"))
self.actionnext.setToolTip(_translate("MainWindow", "下首歌"))
self.actionprevious.setText(_translate("MainWindow", "上一部"))
self.actionprevious.setToolTip(_translate("MainWindow", "上"))
self.actionpause.setText(_translate("MainWindow", "暂停"))
self.actionpause.setToolyiTip(_translate("MainWindow", "暂停"))
self.actionstop.setText(_translate("MainWindow", "停止"))
from PyQt5.QtMultimediaWidgets import QVideoWidget
我挑一些我做时候比较困难的,最后发完整代码
# 打开文件
self.actionfiles.triggered.connect(self.open_file)
# 打开文件夹
self.actiondirs.triggered.connect(self.open_dir)
# 选取文件
def open_file(self):
urls = QFileDialog.getOpenFileUrls()[0]
for url in urls:
yu = url.toString()
drv, left = os.path.split(yu)
self.listvidename.addItem(left)
content = QMediaContent(url)
self.playlist.addMedia(content)
num = self.playlist.mediaCount() - len(urls)
self.playlist.setCurrentIndex(num)
self.listvidename.setCurrentRow(num)
self.player.play()
# 选取文件夹
def open_dir(self):
dir = QFileDialog.getExistingDirectory()
files = os.listdir(dir)
for file in files:
self.listvidename.addItem(file)
url = os.path.join(dir, file)
Qurl = QUrl.fromLocalFile(url)
content = QMediaContent(Qurl)
self.playlist.addMedia(content)
self.playlist.setCurrentIndex(0)
self.listvidename.setCurrentRow(0)
self.player.play()
# 当前播放音量
self.volumeSlider.setValue(50) #默认音量是50
self.volumeSlider.setTickInterval(10)
self.volumeSlider.setTickPosition(QSlider.TicksBelow) # 刻度位置
self.volumeSlider.valueChanged.connect(self.change_volume) # 修改音量
# 调节音量
def change_volume(self, num):
self.volume.setText(str(num))
self.player.setVolume(num)
这里需要注意一点,self.timeSlider的最大值放在槽函数里面,原因,
这段代码只显示分和秒,不显示小时,all是总时间,单位是毫秒,换算成小时,分,秒即可,num是已经播放的时间,修改和前面一样
# 当前播放的进度,显示调整视频进度条
self.timeSlider.setValue(0)
self.timeSlider.setMinimum(0)
self.player.positionChanged.connect(self.get_time)
# 获取获得进度条进度
def get_time(self, num):
self.timeSlider.setMaximum(self.player.duration())
self.timeSlider.setValue(num)
d = QDateTime.fromMSecsSinceEpoch(num).toString("mm:ss")
all = self.player.duration()
all_d = QDateTime.fromMSecsSinceEpoch(all).toString("mm:ss")
self.nowtime.setText(d + '/ ' + all_d)
self.timeSlider.sliderPressed.connect(self.player.pause)
self.timeSlider.sliderMoved.connect(self.change_time)
self.timeSlider.sliderReleased.connect(self.player.play)
# 调节播放进度
def change_time(self, num):
self.player.setPosition(num)
这里是结合combobox控件来选择模式,它列表元素的被选中后会反射index,根据box里面的每行对应的内容匹配对应模式
# 默认设置顺序循环播放
self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
# 改变播放顺序
self.playlistBox.activated.connect(self.change_PlayBackMode)
# 切换播放模式
def change_PlayBackMode(self, num):
self.actionnext.setEnabled(True)
if num == 0:
self.playlist.setPlaybackMode(QMediaPlaylist.Loop) # 顺序循环播放
if num == 1:
self.playlist.setPlaybackMode(QMediaPlaylist.Random) # 随机播放
if num == 2:
self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) # 当前视频循环播放
self.actionnext.setDisabled(True)
# 基于pyqt5
import os
import sys
from PyQt5.QtCore import QDateTime, QUrl
from PyQt5.QtMultimedia import QAudioOutput, QMediaPlayer, QMediaContent, QMediaPlaylist
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import QMainWindow, QFileDialog, QApplication, QSlider
from mediawin_qt5 import Ui_MainWindow
class Video_win(QMainWindow, Ui_MainWindow):
def __init__(self):
super(Video_win, self).__init__()
self.setupUi(self)
# self.audio = QAudioOutput() #pyside6中要单独实例音频
self.player = QMediaPlayer()
# self.player.setAudioOutput(self.audio) # 读取输出音频设备
self.player.setVideoOutput(self.videoout)
# 播放列表
self.playlist = QMediaPlaylist()
self.player.setPlaylist(self.playlist)
# 当前播放的进度,显示调整视频进度条
self.timeSlider.setValue(0)
self.timeSlider.setMinimum(0)
self.player.positionChanged.connect(self.get_time)
self.timeSlider.sliderPressed.connect(self.player.pause)
self.timeSlider.sliderMoved.connect(self.change_time)
self.timeSlider.sliderReleased.connect(self.player.play)
# 当前播放音量
self.volumeSlider.setValue(50)
self.volumeSlider.setTickInterval(10)
self.volumeSlider.setTickPosition(QSlider.TicksBelow) # 刻度位置
self.volumeSlider.valueChanged.connect(self.change_volume) # 修改音量
# 打开文件
self.actionfiles.triggered.connect(self.open_file)
# 打开文件夹
self.actiondirs.triggered.connect(self.open_dir)
# 通过列表切换视频
self.listvidename.itemClicked.connect(self.change_by_list)
# 快进
self.right_button.clicked.connect(self.up_time)
# play
self.play_button.clicked.connect(self.player.play)
# pause
self.mid_button.clicked.connect(self.player.pause)
# 快退
self.left_button.clicked.connect(self.down_time)
# 下一部
self.actionnext.triggered.connect(self.next_video)
# 上一部
self.actionprevious.triggered.connect(self.previous_video)
# 默认设置顺序循环播放
self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
# 改变播放顺序
self.playlistBox.activated.connect(self.change_PlayBackMode)
# 切换播放模式
def change_PlayBackMode(self, num):
self.actionnext.setEnabled(True)
if num == 0:
self.playlist.setPlaybackMode(QMediaPlaylist.Loop) # 顺序循环播放
if num == 1:
self.playlist.setPlaybackMode(QMediaPlaylist.Random) # 随机播放
if num == 2:
self.playlist.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop) # 当前视频循环播放
self.actionnext.setDisabled(True)
# 下一部
def next_video(self):
self.playlist.next()
num = self.playlist.currentIndex()
self.listvidename.setCurrentRow(num)
# self.player.play()
# 上一部
def previous_video(self):
self.playlist.previous()
num = self.playlist.currentIndex()
self.listvidename.setCurrentRow(num)
self.player.play()
# 选取文件
def open_file(self):
urls = QFileDialog.getOpenFileUrls()[0]
for url in urls:
yu = url.toString()
drv, left = os.path.split(yu)
self.listvidename.addItem(left)
content = QMediaContent(url)
self.playlist.addMedia(content)
num = self.playlist.mediaCount() - len(urls)
self.playlist.setCurrentIndex(num)
self.listvidename.setCurrentRow(num)
self.player.play()
# 选取文件夹
def open_dir(self):
dir = QFileDialog.getExistingDirectory()
files = os.listdir(dir)
for file in files:
self.listvidename.addItem(file)
url = os.path.join(dir, file)
Qurl = QUrl.fromLocalFile(url)
content = QMediaContent(Qurl)
self.playlist.addMedia(content)
self.playlist.setCurrentIndex(0)
self.listvidename.setCurrentRow(0)
self.player.play()
# 调节音量
def change_volume(self, num):
self.volume.setText(str(num))
self.player.setVolume(num)
# 调节播放进度
def change_time(self, num):
self.player.setPosition(num)
# 快进
def up_time(self):
num = self.player.position() + int(self.player.duration() / 20)
self.player.setPosition(num)
def down_time(self):
num = self.player.position() - int(self.player.duration() / 20)
self.player.setPosition(num)
# 获取获得进度条进度
def get_time(self, num):
self.timeSlider.setMaximum(self.player.duration())
self.timeSlider.setValue(num)
d = QDateTime.fromMSecsSinceEpoch(num).toString("mm:ss")
all = self.player.duration()
all_d = QDateTime.fromMSecsSinceEpoch(all).toString("mm:ss")
self.nowtime.setText(d + '/ ' + all_d)
# 通过点击播放列表切换视频
def change_by_list(self, current):
index = self.listvidename.currentRow()
self.playlist.setCurrentIndex(index)
self.player.play()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Video_win()
win.show()
sys.exit(app.exec())
学习这个QMediaPlayer模块的过程中走了好多弯路,网上关于Qt的资料倒是挺多,但写的很详细的大部分都是C++,我本身C++可能入门都谈不上,看官方文档也很吃力,遇到问题一般都是结合这两者,虽然磕磕盼盼,到最后勉强还是能解决问题。当然这个模块还有很多地方没用到,也不够熟练。
最后,这篇代码写得不够精细,存在错误的地方请指点一下,谢谢