更新日志:
202211251640:第一版,基本功能:视频导入,播放、暂停、播放时间显示、音量控制

视频播放器

概述:本文是利用PyQt5加上ffmpeg来编写一个具备基本功能的视频播放器(播放、暂停、进度调整、音量调整、视频播放列表、文件夹导入视频等)

实现步骤设想:PyQt制作UI界面,利用Qvideowidget来显示播放的视频,利用Qmediaplayer来播放视频,利用ffmpeg来获取视频信息。利用Qfiledialog来进行文件的导入,利用ctypes、comtypes、pycaw来实现对系统音量的读取和设置。

界面构想预览:

程序代码

1 、Qvideowidget:

1实例化:

self.vm=QVideoWidget(self)

2 调用:

self.player.setVideoOutput(self.vm)

2 、Qmediaplayer:

1 实例化:

self.player=QMediaPlayer()

2 播放/暂停:

self.player.setMedia(QMediaContent(QUrl(self.videoname)))
self.player.setVideoOutput(self.vm)
self.player.play()
self.player.pause()

3 播放状态监控:

播放状态的监测,利用qmediaplayer的statechanged槽函数来进行,方便对于视频播放过程中进行控制。

self.player.stateChanged.connect(self.do_mediaplayer_statechanged)
def do_mediaplayer_statechanged(self,state):if state == QMediaPlayer.PlayingState:#self.is_playing=Trueself.gb1.setTitle('正在播放')passif state == QMediaPlayer.PausedState:#self.is_playing=Falseself.gb1.setTitle('暂停中')passif state == QMediaPlayer.StoppedState:#self.is_playing=Falseself.gb1.setTitle('无歌曲')self.player.setVideoOutput(None)self.is_pause=True#self.vm.close()print(state)

3 完整代码:

#-*-encoding:utf-8-*
"""名称:视频播放器版本:V0.1作者:菌尘注:使用Qt多媒体播放,需要下载解码器,如:K-lite:http://www.codecguide.com/download_k-lite_codec_pack_full.htm或者:LAV Filters:https://github.com/Nevcairiel/LAVFilters/releases
"""
import os
import string
import sys
import time
import random
import configparser
#import chardet
#pip install ffmpeg-python,不要直接pip install ffmpeg
import ffmpeg
from ctypes import cast,POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities,IAudioEndpointVolume
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
from qss_read import QssReadclass video_player_win(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.qssfile1='music_play_pro2022\qss_video_main_win_style.qss'self.qss1=QssRead.readQSS(self.qssfile1)self.vm=QVideoWidget(self)self.vm.setGeometry(20,20,600,480)#self.vm.setStyleSheet("background-color:lime")self.h1_layout=QHBoxLayout()self.player=QMediaPlayer()self.player.setVolume(3)self.player.stateChanged.connect(self.do_mediaplayer_statechanged)self.is_playing=Falseself.is_pause=Trueself.gb1=QGroupBox('',self)self.gb1.setGeometry(10,520,640,40)self.lbl_videostarttime=QLabel(self)self.lbl_videostarttime.setGeometry(10,545,100,20)self.lbl_videostarttime.setText('00:00:00')self.lbl_videowholetime=QLabel(self)self.lbl_videowholetime.setGeometry(600,545,100,20)self.lbl_videowholetime.setText('00:00:00')#播放进度条self.play_slider=QSlider(Qt.Horizontal,self)self.play_slider.setStyle(QStyleFactory.create('Fusion'))self.play_slider.setMinimum(0)self.play_slider.setMaximum(1000)self.play_slider.setStyleSheet("background-color:#80C8F1")#音量进度条self.volume_slider=QSlider(Qt.Horizontal,self)self.volume_slider.setStyle(QStyleFactory.create('Fusion'))self.volume_slider.setGeometry(480,580,100,20)self.volume_slider.setMinimum(0)self.volume_slider.setMaximum(100)self.volume_slider.setStyleSheet("background-color:#7CF3DF")self.volume_slider.valueChanged.connect(self.video_volume_change_func)self.lbl_videovolume=QLabel(self)self.lbl_videovolume.setGeometry(440,580,20,20)self.lbl_videovolume.setStyleSheet("background-color:lime")self.lbl_videovolume.setText(str(self.volume_slider.value()))self.btn_sourcevideopath=QPushButton('导入视频',self)self.btn_sourcevideopath.setGeometry(660,100,80,40)self.btn_sourcevideopath.setStyle(QStyleFactory.create('Fusion'))self.btn_sourcevideopath.clicked.connect(self.get_sourcevideopath_func)self.btn_sourcevideofolder=QPushButton('导入文件夹',self)self.btn_sourcevideofolder.setGeometry(660,160,80,40)self.btn_sourcevideofolder.setStyle(QStyleFactory.create('Fusion'))self.list_videoplaylist=QListWidget(self)self.list_videoplaylist.setGeometry(760,10,230,500)self.list_videoplaylist.doubleClicked.connect(self.video_index_func)self.video_list=[]self.btn_last=QPushButton('上一个',self)self.btn_last.setGeometry(250,490,60,40)  self.btn_last.setStyle(QStyleFactory.create('Fusion'))      self.btn_playvideo=QPushButton('',self)self.btn_playvideo.setGeometry(320,490,60,40)self.btn_playvideo.setStyle(QStyleFactory.create('Fusion'))self.btn_playvideo.setIcon(QIcon('music_play_pro2022\stopicon.jpeg'))self.btn_playvideo.clicked.connect(self.vedio_play_func)self.btn_next=QPushButton('下一个',self)self.btn_next.setGeometry(390,490,60,40)self.btn_next.setStyle(QStyleFactory.create('Fusion'))self.h1_layout.addWidget(self.play_slider)self.gb1.setLayout(self.h1_layout)self.timer1=QTimer(self)self.timer1.start(50)self.timer1.timeout.connect(self.video_time_func)self.get_systemvolume_init_func()self.setWindowTitle('视频播放器V001')self.setGeometry(100,40,1000,600)self.setFixedSize(QSize(1000,680))self.setStyleSheet(self.qss1)self.show()def paintEvent(self, e) -> None:""""""#建立Qpainter对象qp=QPainter()      qp.begin(self)                      #绘图开始                                   qp.drawRect(10,10,640,500)          #绘图代码区域qp.end()                            #绘图结束def get_systemvolume_init_func(self):"""初始化系统音量值比对关系"""# 音量对应关系# 0% --- -65.25# 55% --- -8.92# 100% --- 0.0self.volume_match={0: -65.25, 1: -56.99, 2: -51.67, 3: -47.74, 4: -44.62, 5: -42.03, 6: -39.81, 7: -37.89, 8: -36.17, 9: -34.63, 10: -33.24,11: -31.96, 12: -30.78, 13: -29.68, 14: -28.66, 15: -27.7, 16: -26.8, 17: -25.95, 18: -25.15, 19: -24.38, 20: -23.65,21: -22.96, 22: -22.3, 23: -21.66, 24: -21.05, 25: -20.46, 26: -19.9, 27: -19.35, 28: -18.82, 29: -18.32, 30: -17.82,31: -17.35, 32: -16.88, 33: -16.44, 34: -16.0, 35: -15.58, 36: -15.16, 37: -14.76, 38: -14.37, 39: -13.99, 40: -13.62,41: -13.26, 42: -12.9, 43: -12.56, 44: -12.22, 45: -11.89, 46: -11.56, 47: -11.24, 48: -10.93, 49: -10.63, 50: -10.33,51: -10.04, 52: -9.75, 53: -9.47, 54: -9.19, 55: -8.92, 56: -8.65, 57: -8.39, 58: -8.13, 59: -7.88, 60: -7.63,61: -7.38, 62: -7.14, 63: -6.9, 64: -6.67, 65: -6.44, 66: -6.21, 67: -5.99, 68: -5.76, 69: -5.55, 70: -5.33,71: -5.12, 72: -4.91, 73: -4.71, 74: -4.5, 75: -4.3, 76: -4.11, 77: -3.91, 78: -3.72, 79: -3.53, 80: -3.34,81: -3.15, 82: -2.97, 83: -2.79, 84: -2.61, 85: -2.43, 86: -2.26, 87: -2.09, 88: -1.91, 89: -1.75, 90: -1.58,91: -1.41, 92: -1.25, 93: -1.09, 94: -0.93, 95: -0.77, 96: -0.61, 97: -0.46, 98: -0.3, 99: -0.15, 100: 0.0}#音量值反对应self.volume_match_2={-65.25:0, -56.99:1, -51.67:2, -47.74:3, -44.62:4, -42.03:5, -39.81:6,-37.89:7, -36.17:8, -34.63:9, -33.24:10,-31.96:11, -30.78:12, -29.68:13, -28.66:14, -27.7:15, -26.8:16, -25.95:17, -25.15:18,  -24.38:19, -23.65:20,-22.96:21, -22.3:22, -21.66:23, -21.05:24, -20.46:25, -19.9:26, -19.35:27,  -18.82:28,  -18.32:29,  -17.82:30,-17.35:31, -16.88:32, -16.44:33, -16.0:34, -15.58:35,-15.16:36, -14.76:37, -14.37:38,  -13.99:39, -13.62:40,-13.26:41, -12.9:42, -12.56:43, -12.22:44,-11.89:45, -11.56:46, -11.24:47, -10.93:48,  -10.63:49, -10.33:50,-10.04:51, -9.75:52, -9.47:53, -9.19:54, -8.92:55, -8.65:56, -8.39:57, -8.13:58,  -7.88:59,  -7.63:60,-7.38:61, -7.14:62, -6.9:63, -6.67:64, -6.44:65, -6.21:66, -5.99:67,  -5.76:68,  -5.55:69, -5.33:70,-5.12:71,-4.91:72, -4.71:73, -4.5:74, -4.3:75, -4.11:76,  -3.91:77, -3.72:78,  -3.53:79,  -3.34:80,-3.15:81, -2.97:82, -2.79:83, -2.61:84, -2.43:85, -2.26:86, -2.09:87,  -1.91:88, -1.75:89, -1.58:90,-1.41:91, -1.25:92, -1.09:93, -0.93:94, -0.77:95, -0.61:96, -0.46:97, -0.3:98,  -0.15:99,  0.0:100}self.devices11=AudioUtilities.GetSpeakers()self.interface=self.devices11.Activate(IAudioEndpointVolume._iid_,CLSCTX_ALL,None)self.volum11=cast(self.interface,POINTER(IAudioEndpointVolume))self.mute=self.volum11.GetMute()def get_systemvolume_func(self):"""获取系统音量"""#if self.mute == 1:#print('系统静音')#else:#print('系统未静音')vm=self.volum11.GetMasterVolumeLevel()#print(vm)vm2=round(vm,2)#print(vm2)vm3=self.volume_match_2[vm2]#print(vm3)#v1=self.volum11.GetVolumeRange()#print(v1)return vm3def set_sys_volume_func(self,v1:int):"""设置系统音量"""self.sys_volume_value=self.volume_match[v1]#print(self.sys_volume_value)self.volum11.SetMasterVolumeLevel(self.sys_volume_value,None)def video_index_func(self):""""""   self.volume_slider.setValue(self.get_systemvolume_func())self.is_playing=Falseself.indexpath=self.list_videoplaylist.currentRow()self.videoname=self.video_list[self.indexpath]self.player.setMedia(QMediaContent(QUrl(self.videoname)))self.player.setVideoOutput(self.vm)self.player.play()self.is_playing=Trueself.is_pause=Falsedef get_sourcevideopath_func(self):""""""self.path1,_=QFileDialog.getOpenFileName(self,'','C:/',"video(*.mp4)")if os.path.exists(self.path1):self.list_videoplaylist.addItem(self.path1)self.video_list.append(self.path1)def video_volume_change_func(self):""""""self.videovolume=self.volume_slider.value()if self.is_playing:self.player.setVolume(self.videovolume)self.lbl_videovolume.setText(str(self.videovolume))self.set_sys_volume_func(self.videovolume)if self.get_systemvolume_func() == 0:print('静音')def do_mediaplayer_statechanged(self,state):if state == QMediaPlayer.PlayingState:#self.is_playing=Trueself.gb1.setTitle('正在播放')passif state == QMediaPlayer.PausedState:#self.is_playing=Falseself.gb1.setTitle('暂停中')passif state == QMediaPlayer.StoppedState:#self.is_playing=Falseself.gb1.setTitle('无歌曲')self.player.setVideoOutput(None)self.is_pause=True#self.vm.close()print(state)def video_time_func(self):""""""     if self.is_playing:self.play_slider.setMinimum(0)self.play_slider.setMaximum(int(self.player.duration()/1000))self.lbl_videostarttime.setText(time.strftime('%H:%M:%S', time.localtime(self.player.position() / 1000)))self.lbl_videowholetime.setText(time.strftime('%H:%M:%S', time.localtime(self.player.duration() / 1000)))self.video_current_position=int(self.player.position()/1000)self.play_slider.setValue(self.video_current_position)self.state1=self.player.state()if self.state1 == 0:self.play_slider.setValue(0)self.is_playing=Falseself.lbl_videostarttime.setText('00:00:00')self.lbl_videowholetime.setText('00:00:00')def vedio_play_func(self):""""""if self.is_pause == True:if self.is_playing == False:self.player.setVideoOutput(self.vm)         self.player.play()self.is_pause=Falseself.is_playing=Trueself.btn_playvideo.setIcon(QIcon('music_play_pro2022\stopicon.jpeg'))elif self.is_pause == False:self.player.pause()self.is_pause=Trueself.btn_playvideo.setIcon(QIcon('music_play_pro2022\playicon.jpeg'))if __name__ == '__main__':app=QApplication(sys.argv)vpw1=video_player_win()sys.exit(app.exec_())

注:
1、qssread:

class QssRead:@staticmethoddef readQSS(style):with open(style, "r",encoding="utf-8") as f:return f.read()

2、qss样式文件:

/*
*
{
color:red;
}
窗体背景色为渐变色
*/
QMainWindow
{background-color:qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #81F5D8,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #8EF068);/*background-color:qradialgradient(cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 red, stop:1 blue)*//*background-color:qconicalgradient(cx:0.5, cy:0.5, angle:0, stop:0 blue, stop:0.2 yellow,stop:1 #4CF562)*/
}
QMenuBar
{background-color:qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #81F5D8,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #8EF068);
}
QMenu
{background-color:qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #81F5D8,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #8EF068);
}
QListWidget
{background-color:qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #f3dcb4,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #dfc2f5);
}
QPushButton
{text-align:center;color:#100f0f;background-color:qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #81F5D8,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #8EF068);setStyle:QStyleFactory.create('fusion');
}
QLabel
{text-align: center;font:lighter;font-size:13px;background-color:#BBD9F1;color:black;}
QGroupBox
{background-color:qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #202222,stop:0.2 #9fb8c6,stop:0.5 #6ba8d6 stop:1 #365cd9); }
QComboBox
{background-color:#84EEAD;setStyle:QStyleFactory.create('fusion');
}
QCheckBox
{text-align: center;
}QLineEdit
{background-color: rgb(250, 250, 250);
}
QTextEdit
{background-color:antiquewhite;
}
QMessageBox
{   background-color: aquamarine;
}

注:至于UI显示所需的图片,可以自己替换。

4 视频演示:

待添加。

<Python>PyQt5+ffmpeg,简单视频播放器的编写(解码器:K-lite)相关推荐

  1. 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  2. QT软件开发-基于FFMPEG设计视频播放器-软解图像(一)

    QT软件开发-基于FFMPEG设计视频播放器-CPU软解视频(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT软件开发-基于 ...

  3. FFmpeg+SDL视频播放器

    本博客是摘自雷霄骅大神的课程<基于 FFmpeg + SDL 的视频播放器的制作>课程 里的内容,非常适合音视频小白入门,在这里感谢雷神的指导! 目录 FFmpeg和SDL的整合实现视频播 ...

  4. 用Pyqt5写一个视频播放器

    用Pyqt5写一个视频播放器 编写方式: Qt Designer设计,pyuic5转化为.py文件. 播放器效果: 代码链接:https://github.com/GRF-Sunomikp31/Qt_ ...

  5. 基于FFmpeg开发视频播放器, 基本流程(一)

    刚开始学习FFmpeg,用几篇文章记录下,使用ffmpeg开发一个简单的视频播放器,大概的过程.这里只讨论核心代码,如解封装,音频的解码播放,视频的解码播放,音视频同步,不涉及UI布局. 基于FFmp ...

  6. android 实现视频播放功能,android开发之简单视频播放器(VideoView)

    简单视频播放器的使用 一.简单使用videoView和MediaController实现播放控制 1.添加需要的权限 2.设置布局 android:id="@+id/main_video&q ...

  7. Opencv 简单视频播放器

    最近看了一下[1]_2011_OpenCV 2 Computer Vision Application Programming Cookbook.pdf,写了一个利用Opencv库实现的简单视频播放器 ...

  8. QT软件开发-基于FFMPEG设计视频播放器-解码音频(三)

    QT软件开发-基于FFMPEG设计视频播放器-CPU软解视频(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT软件开发-基于 ...

  9. QT软件开发-基于FFMPEG设计视频播放器-GPU硬解、OpenGL渲染、解码音频完整例子(六)

    QT软件开发-基于FFMPEG设计视频播放器-CPU软解视频(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT软件开发-基于 ...

最新文章

  1. java软件工程师成长过程的学习
  2. MongoRepository
  3. Mysql 查询一天中每半小时记录的数量
  4. NLP(二十二)使用LSTM进行语言建模以预测最优词
  5. P2572 [SCOI2010]序列操作
  6. C#互操作性平台调用基础知识
  7. 【分享】Android JNI实例​
  8. 霸榜 | 微软CV模型收获近 2k star
  9. nnt第三代接任务软件
  10. 联想H61主板升级BIOS,支持nvme硬盘
  11. 扫描远程服务器开放端口
  12. ebay免费模板html,ebay免费模板
  13. 【视频编码】ffmpeg压缩视频文件
  14. 面向小白,无脑安装OrCAD
  15. 【RIPro6.4子主题UI美化包】日主题专业版RIPRO细节美化
  16. 安装最新eclipse luna和中文语言包
  17. 计算机q启动时有logo,怎么取消电脑开机显示logo
  18. 你领证了吗?各地2022上半年软考证书发放中...
  19. linux u盘fat32转ntfs,u盘fat32怎么转换为ntfs_u盘fat32转ntfs的方法 - 河东手机站
  20. Xcode非ARC项目转ARC,ARC项目中支持非ARC也就是共存

热门文章

  1. 桌面linux 排行榜,观点|自由之选:七大顶尖 Linux 桌面环境比拼
  2. git与github初入门:git与git命令的基本使用
  3. 辽宁省自考本科算法与数据结构考试大纲
  4. seata的xid是如何传播的?
  5. Python实现自动小One易统计打卡
  6. 基于STM32的0.96寸OLED显示屏显示汉字+数字
  7. 直播APP源码,直播系统源码开发公司:搭建直播平台的具体方案
  8. 一文看懂Mesh组网
  9. python-----删除同一文件夹下相似的图片
  10. 《JavaScript高级程序设计 (第3版)》学习笔记13:chapter_5 - 4 RegExp类型