PyQt提供了视频播放的库,可以很方便的播放视频,主要是看其中库函数的用法。这里简单的实现了一个视频播放器,可以实现自动循环播放视频,打开视频,进度条,暂停和开始,以及下一个视频的功能。
这里要注意这个库不是很好安装,可以试试通过apt-get install python3-pyqt5.qtmultimedia 直接安装的,源码安装可能会报错。
代码如下:这里我设置的是全屏模式,可以通过ctrl+q退出。
#!/usr/bin/python3
#-*- coding:utf-8 -*-
import sys
import cv2
from time import sleep
from threading import Thread
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import QtGui
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import QVideoWidget
class PlayVideo(QWidget):
bClose = False
fn_list = ["/home/pi/Documents/垃圾分类图片和视频/movie/movie1.mp4","/home/pi/Documents/垃圾分类图片和视频/movie/movie2.mp4","/home/pi/Documents/垃圾分类图片和视频/movie/movie3.mp4"]
play_index = 0
def __init__(self, parent=None):
super(PlayVideo, self).__init__(parent)
self.setWindowTitle('垃圾分类')
self.setWindowIcon(QIcon("/home/pi/Documents/垃圾分类图片和视频/pic/ico1.png"))
self.screen = QDesktopWidget().screenGeometry()
self.resize(self.screen.width(), self.screen.height())
#设置菜单栏
bar = QMenuBar(self)
bar.setFixedSize(self.screen.width(),30)
#设置选项二
play_menu = bar.addMenu("播放选项")
#设置按钮一
play_video = QAction("打开视频文件",self)
play_video.setShortcut("Ctrl+1")
play_video.setIcon(QIcon('/home/pi/Documents/垃圾分类图片和视频/图标/播放视频'))
play_video.triggered.connect(self.manual_choose)
play_menu.addAction(play_video)
#设置按钮二
play_pictures = QAction("自动播放视频",self)
play_pictures.setShortcut("Ctrl+2")
play_pictures.setIcon(QIcon('/home/pi/Documents/垃圾分类图片和视频/图标/播放图片'))
play_pictures.triggered.connect(self.auto_choose)
play_menu.addAction(play_pictures)
#设置停止按钮
play_stop = QAction("停止",self)
play_stop.setShortcut("Ctrl+3")
#play_stop.triggered.connect(self.video_stop)
play_menu.addAction(play_stop)
#设置退出按钮
exit_menu = bar.addMenu("其他")
exit_option = QAction("退出",self)
exit_option.setShortcut("Ctrl+Q")
exit_option.setIcon(QIcon('/home/pi/Documents/垃圾分类图片和视频/图标/退出'))
exit_option.triggered.connect(self.exit_stop)
exit_menu.addAction(exit_option)
#设置菜单栏的位置
bar.move(0,0)
#用来显示视频画面的Label组建,自带双缓冲,不闪烁
layout = QGridLayout()
self.lbVideo=QVideoWidget() # 定义视频显示的widget
self.lbVideo.setFixedSize(1000,620)
self.player = QMediaPlayer()
self.player.setVideoOutput(self.lbVideo)# 视频播放输出的widget,就是上面定义的
self.player.durationChanged.connect(self.showDuration)
self.player.positionChanged.connect(self.setCurrent_)
layout.addWidget(self.lbVideo,0,0,3,3)
#设置滑动条
self.s1 = QSlider(Qt.Horizontal)
self.s1.setToolTip("滑动条")
self.s1.setMinimum(0)#设置最大值
self.s1.setMaximum(50)#设置最小值
self.s1.setSingleStep(1)#设置间隔
self.s1.setValue(0)#设置当前值
self.s1.sliderReleased.connect(self.drag_action)
self.stop_flag = 0#如果当前为播放值为0,如果当前为暂停值为1
layout.addWidget(self.s1,3,1,1,1)
#设置两个标签分别是当前时间和结束时间
self.label_start = QLabel("00:00")
layout.addWidget(self.label_start,3,0,1,1)
self.label_end = QLabel("00:00")
layout.addWidget(self.label_end,3,2,1,1)
#设置暂停播放和下一个按钮
self.stop_button = QPushButton()
self.stop_button.setIcon(QIcon('/home/pi/Documents/垃圾分类图片和视频/图标/暂停.png'))
self.stop_button.setIconSize(QSize(40,40))
self.stop_button.clicked.connect(self.stop_action)
layout.addWidget(self.stop_button,4,0,1,1)
self.next_button = QPushButton()
self.next_button.setIcon(QIcon('/home/pi/Documents/垃圾分类图片和视频/图标/下一个.png'))
self.next_button.setIconSize(QSize(40,40))
self.next_button.clicked.connect(self.next_action)
layout.addWidget(self.next_button,4,2,1,1)
self.setLayout(layout)
#播放列表
self.playlist = QMediaPlaylist()
self.playlist.setMediaObject(self.player)
for i in self.fn_list:
#加入播放列表
self.playlist.addMedia(QMediaContent(QUrl("file://"+i)))
#设置播放模式为循环播放
self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
self.player.setPlaylist(self.playlist)
def playVideoFile(self):#播放影片
self.player.play()
def next_action(self):
self.playlist.next()
#获取当前播放进度包括时间和进度条显示
def setCurrent_(self):
self.current_num = self.player.position()
self.label_start.setText(self.int2time(self.current_num))
self.s1.setValue(self.current_num)#设置当前值
#读取当前播放视频的总时长
def showDuration(self):
self.maxvalue = self.player.duration()
self.s1.setMaximum(self.maxvalue)
self.label_end.setText(self.int2time(self.maxvalue))
#拖动条部分,释放拖动条是改变进度
def drag_action(self):
if self.s1.value()!=self.current_num:
self.player.setPosition(self.s1.value())
#将读取到的毫秒转为秒
def int2time(self,num):
#以毫秒为单位
num /= 1000
hour = int(num/3600)
minute = int((num - hour*3600)/60)
second = int(num - hour*3600 - minute*60)
if hour < 10:
str_hour = '0'+str(hour)
else:
str_hour = str(hour)
if minute < 10:
str_minute = '0'+str(minute)
else:
str_minute = str(minute)
if second < 10:
str_second = '0'+str(second)
else:
str_second = str(second)
return str_hour+':'+str_minute+":"+str_second
#按下暂停和播放部分
def stop_action(self):
if self.stop_flag == 0:
self.stop_flag = 1
self.player.pause()
self.stop_button.setIcon(QIcon('/home/pi/Documents/垃圾分类图片和视频/图标/播放.png'))
else:
self.stop_flag = 0
self.player.play()
self.stop_button.setIcon(QIcon('/home/pi/Documents/垃圾分类图片和视频/图标/暂停.png'))
#手动选择要播放的文件
def manual_choose(self):#手动选择视频播放
fn,_ = QFileDialog.getOpenFileName(self,'Open file','/home/pi/Documents/垃圾分类图片和视频/movie',"Video files (*.mp4 *.avi)")
self.playlist.addMedia(QMediaContent(QUrl("file://"+fn)))
self.playlist.setCurrentIndex(self.playlist.mediaCount()-1)
#自动播放视频
def auto_choose(self):#自动选择视频播放,如何自动视频播放?
self.player.play()
pass
#退出
def exit_stop(self):
self.stop_flag = 0
self.player.stop()
self.close()
if __name__=="__main__":
app = QApplication(sys.argv)
form = PlayVideo()
form.showFullScreen()
sys.exit(app.exec_())
可以看出主要是几个函数的应用:
1.QVideoWidget()视频在这个组件中播放。
2.QMediaPlayer()类是主要的播放器。
play()函数播放;
stop()函数停止播放;
pause()函数暂停;
setVideoOuput()设置输出的播放组件;
duration()函数获取当前视频的总时长,这里和durationChanged()函数关联,表示总时长发生改变是修改总时长,和进度条的最大长度。
position()函数表示当前进度,这里和positionChanged()函数关联,表示进度改变时修改当前已经播放时长和进度条进度。
进度的单位是毫秒所以在自己写的int2time()函数中进行了转化。
如果不使用列表播放可以直接通过setMedia()指定当前播放的视频,只是要注意参数的格式为QMediaContent(QUrl(“file://”+文件路径)),比如setMedia(QMediaContent(QUrl(“file://”+“home/pi/hello.mp4”)))
3.QMediaPlaylist()可以很方便的实现播放列表功能。
同样要指定播放器,setMeidaObject()
添加要播放的视频,addMedia()
设置播放模式,setPlaybackMode()
播放下一个视频,next()
获取当前索引,currentIndex()
当前播放列表中视频的总长度,mediaCount()
设置当前播放视频,setCurrentIndex()
缺陷:这里还没有写好,因为没有对加入的视频进行检查,应该采用类似哈希表的形式,不然可以重复添加同一个视频。