编辑UI

编辑UI如下图所示:

新建视频播放类Display

定义如下初始化函数

def __init__(self, ui, mainWnd):
self.ui = ui
self.mainWnd = mainWnd # 默认视频源为相机
self.ui.radioButtonCam.setChecked(True)
self.isCamera = True # 信号槽设置
ui.Open.clicked.connect(self.Open)
ui.Close.clicked.connect(self.Close)
ui.radioButtonCam.clicked.connect(self.radioButtonCam)
ui.radioButtonFile.clicked.connect(self.radioButtonFile) # 创建一个关闭事件并设为未触发
self.stopEvent = threading.Event()
self.stopEvent.clear()

打开相机

防止UI卡死,需要单独用一个线程去显示视频,可以选中打开相机还是打开本机mp4文件。

    def Open(self):
if not self.isCamera:
self.fileName, self.fileType = QFileDialog.getOpenFileName(self.mainWnd, 'Choose file', '', '*.mp4')
self.cap = cv2.VideoCapture(self.fileName)
self.frameRate = self.cap.get(cv2.CAP_PROP_FPS)
else:
# 下面两种rtsp格式都是支持的
# cap = cv2.VideoCapture("rtsp://admin:Supcon1304@172.20.1.126/main/Channels/1")
self.cap = cv2.VideoCapture("rtsp://admin:Supcon1304@172.20.1.126:554/h264/ch1/main/av_stream") # 创建视频显示线程
th = threading.Thread(target=self.Display)
th.start()

关闭相机

启动线程可以直接调用start(),但是结束线程并没有现成的接口可以调用。

添加一个事件用来判断是否需要关闭相机

def Close():
# 关闭事件设为触发,关闭视频播放
stopEvent.set()

显示视频画面

注意:

  1. OpenCV获得的图像帧数据是RGB格式,QImage是BGR格式,所以需要进行格式转换;
  2. 每次显示完成后都去判断是否点击了关闭按钮。
    def Display(self):
self.ui.Open.setEnabled(False)
self.ui.Close.setEnabled(True) while self.cap.isOpened():
success, frame = self.cap.read()
# RGB转BGR
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
self.ui.DispalyLabel.setPixmap(QPixmap.fromImage(img)) if self.isCamera:
cv2.waitKey(1)
else:
cv2.waitKey(int(1000 / self.frameRate)) # 判断关闭事件是否已触发
if True == self.stopEvent.is_set():
# 关闭事件置为未触发,清空显示label
self.stopEvent.clear()
self.ui.DispalyLabel.clear()
self.ui.Close.setEnabled(False)
self.ui.Open.setEnabled(True)
break

完整源代码

文件VideoDisplay.py


import cv2
import threading
from PyQt5.QtCore import QFile
from PyQt5.QtWidgets import QFileDialog, QMessageBox
from PyQt5.QtGui import QImage, QPixmap class Display:
def __init__(self, ui, mainWnd):
self.ui = ui
self.mainWnd = mainWnd # 默认视频源为相机
self.ui.radioButtonCam.setChecked(True)
self.isCamera = True # 信号槽设置
ui.Open.clicked.connect(self.Open)
ui.Close.clicked.connect(self.Close)
ui.radioButtonCam.clicked.connect(self.radioButtonCam)
ui.radioButtonFile.clicked.connect(self.radioButtonFile) # 创建一个关闭事件并设为未触发
self.stopEvent = threading.Event()
self.stopEvent.clear() def radioButtonCam(self):
self.isCamera = True def radioButtonFile(self):
self.isCamera = False def Open(self):
if not self.isCamera:
self.fileName, self.fileType = QFileDialog.getOpenFileName(self.mainWnd, 'Choose file', '', '*.mp4')
self.cap = cv2.VideoCapture(self.fileName)
self.frameRate = self.cap.get(cv2.CAP_PROP_FPS)
else:
# 下面两种rtsp格式都是支持的
# cap = cv2.VideoCapture("rtsp://admin:Supcon1304@172.20.1.126/main/Channels/1")
self.cap = cv2.VideoCapture("rtsp://admin:Supcon1304@172.20.1.126:554/h264/ch1/main/av_stream") # 创建视频显示线程
th = threading.Thread(target=self.Display)
th.start() def Close(self):
# 关闭事件设为触发,关闭视频播放
self.stopEvent.set() def Display(self):
self.ui.Open.setEnabled(False)
self.ui.Close.setEnabled(True) while self.cap.isOpened():
success, frame = self.cap.read()
# RGB转BGR
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
img = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
self.ui.DispalyLabel.setPixmap(QPixmap.fromImage(img)) if self.isCamera:
cv2.waitKey(1)
else:
cv2.waitKey(int(1000 / self.frameRate)) # 判断关闭事件是否已触发
if True == self.stopEvent.is_set():
# 关闭事件置为未触发,清空显示label
self.stopEvent.clear()
self.ui.DispalyLabel.clear()
self.ui.Close.setEnabled(False)
self.ui.Open.setEnabled(True)
break

文件main.py


import sys
import DisplayUI
from PyQt5.QtWidgets import QApplication, QMainWindow
from VideoDisplay import Display if __name__ == '__main__':
app = QApplication(sys.argv)
mainWnd = QMainWindow()
ui = DisplayUI.Ui_MainWindow() # 可以理解成将创建的 ui 绑定到新建的 mainWnd 上
ui.setupUi(mainWnd) display = Display(ui, mainWnd) mainWnd.show() sys.exit(app.exec_())

效果图

PyQt5播放实时视频流或本地视频文件的更多相关文章

  1. iOS开发- 获取本地视频文件

    下面具体介绍下实现过程.先看效果图.图1. 未实现功能前, iTunes截图 图2. 实现功能后, iTunes截图 图3. 实现功能后, 运行截图 好了, 通过图片, 我们可以看到实现的效果.功能包 ...

  2. iOS 本地视频和网络视频流播放

    需求:最近公司需要做一个楼宇对讲的功能:门口机(连接WIFI)拨号对室内机(对应的WIFI)的设备进行呼叫,室内机收到呼叫之后将对收到的数据进行UDP广播的转发,手机(连接对应的WIFI)收到视频流之 ...

  3. Supermap/Cesium 开发心得----本地视频接入播放

    在三维中,为了增加现实感.给人一种带入感,我们会采取接入视频的方式来实现,那么如何接入视频呢? 由于没有截至写文章为止,我没有视频流数据,所以只能采取本地视频文件的方式来做. 本文介绍结束视频的其中一 ...

  4. android 播放assets文件里视频文件的问题

    今天做了一个功能,就是播放项目工程里面的视频文件,不是播放SD卡视频文件. 因为之前写webview加载assets文件夹时,是这样写的: webView = new WebView(this); w ...

  5. 视频文件自动转rtsp流

    最近碰到一个项目需要用到 rtsp 视频流做测试, 由于真实环境的 摄像头 并不能满足需求,故尝试了一下用本地视频文件转换成rtsp视频流做测试,记录一下~ 采用方案: Docker + EasyDa ...

  6. 【opencv】VideoCapture打不开本地视频文件或者网络IP摄像头

    1.前提:成功打开本地USB摄像头 // 创建VideoCapture对象 VideoCapture vc = new VideoCapture(); // 可以成功打开本地USB摄像头 // 参数可 ...

  7. Android必知必会-获取视频文件的截图、缩略图

    背景 公司最近要求给我负责的APP加上视频录制和发布的功能,我简单的完成了基本的录制和视频压缩功能,后来发现发布接口需要上传视频的截图,网上搜索了一下资料,在这里整理一下. 代码实现 /** * 获取 ...

  8. “本地视频使用flashFXP上传虚拟服务器“的方法

    一.视频转换格式 首先,想要在网页中直接嵌入视频,就得用video标签,而<video>支持的仅有的几种格式中,MP4是兼容性,通用性各方面相对友好的,所以,建议上传之前先转换格式并压缩. ...

  9. .net利用本地播放器播放视频文件代码

    前台点击按钮,执行js事件,跳转到后台代码: function funShowVideo(index) {            var iTop = (window.screen.availHeig ...

随机推荐

  1. OpenCV开发笔记(七十):红胖子带你傻瓜式编译VS2017x64版本的openCV4

    前言   红胖子来也!!!  opencv_contrib是opencv提供额外的工具,提供一些基础算法,之前编译了不带opencv_contrib的版本,不带opencv_contrib的cuda硬 ...

  2. linux(centos8):用cut显示文本内容的指定列

    一,cut命令的用途 从一个文本文件或者文本流中提取文本列 分别用: 字节.字符.字段 作为单位进行提取 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.co ...

  3. CentOS7下RabbitMQ服务安装配置 (亲测有效)

    erlang 21.3 rabbitmq-server 3.7.14 下载地址 链接: https://pan.baidu.com/s/1g_T1Q_6zpyO3AepS0ZPgYQ 提取码: abq ...

  4. QJsonObject 遍历

    遍历QjsonObject方式 方式一 QJsonObject::const_iterator it = l_obj.constBegin(); QJsonObject::const_iterator ...

  5. 第10天 | 12天搞定Python,文件操作(超详细)

    在开发系统的过程中,经常会用到XML存储和传输数据,XML是一种用于标记电子文件使其具有结构性的标记语言,在博客中经常会见到. JSON是一种轻量级的数据交换格式,常被用在后端和前端的数据交互上,如你 ...

  6. CentOS8安装本地mail工具-mailx-12.5-29.el8.x86_64

    概述 服务器需要发告警邮件 查找是否已安装 [root@C8-1 ~]# type mail -bash: type: mail: not found [root@C8-1 ~]# which mai ...

  7. JVM内存管理和垃圾回收

    无论对于Java程序员还是大数据研发人员,JVM是必须掌握的技能之一.既是面试中经常问的问题,也是在实际业务中对程序进行调优.排查类似于内存溢出.栈溢出.内存泄漏等问题的关键.笔者将按下图分多篇文章详 ...

  8. Docker启动Mysql镜像

    date: 2020-03-14 17:00:00 updated: 2020-03-14 18:00:00 Docker启动Mysql镜像 管理员权限!!! docker run -p 3306:3 ...

  9. Nexus3常用功能备忘

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. Java技术平台介绍

    Java的名字的来源:Java是印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名.Java语言中的许多库类名称,多与咖啡有关, 如JavaBeans(咖啡豆).NetBeans(网络豆)以及ObjectB ...