python编写四画面同时播放swap视频

当代技术让我们能够创建各种有趣和实用的应用程序。在本篇博客中,我们将探索一个基于wxPython和OpenCV的四路视频播放器应用程序。这个应用程序可以同时播放四个视频文件,并将它们显示在一个GUI界面中。
C:\pythoncode\new\smetimeplaymp4.py
在这里插入图片描述

准备工作

在开始之前,我们需要安装一些必要的库。确保你已经安装了Python和以下库:

  • wxPython:用于创建图形用户界面。
  • OpenCV:用于视频处理和播放。
  • moviepy:用于视频剪辑。

你可以使用pip来安装这些库。在命令行中运行以下命令:

pip install wxPython opencv-python moviepy

安装完成后,我们就可以开始编写代码了。

导入库

首先,让我们导入所需的库:

import os
import wx
import cv2
from moviepy.editor import VideoFileClip
  • os库用于文件和文件夹操作。
  • wx库用于创建GUI界面。
  • cv2库用于视频处理。
  • moviepy库用于视频剪辑。

创建文件列表窗口

我们将创建一个名为FileListFrame的wx.Frame子类,用于显示文件列表和选择文件夹。

class FileListFrame(wx.Frame):def __init__(self):super().__init__(None, title="选择MP4文件", size=(400, 300))self.folder_path = ""  # 添加实例变量来存储文件夹路径panel = wx.Panel(self)# 创建选择文件夹的按钮select_button = wx.Button(panel, label="选择文件夹")select_button.Bind(wx.EVT_BUTTON, self.on_select_folder)# 创建列表框,用于显示文件列表self.list_box = wx.ListBox(panel, style=wx.LB_MULTIPLE | wx.LB_HSCROLL)# 创建播放按钮play_button = wx.Button(panel, label="播放")play_button.Bind(wx.EVT_BUTTON, self.on_play)# 设置布局管理器sizer = wx.BoxSizer(wx.VERTICAL)sizer.Add(select_button, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)sizer.Add(self.list_box, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)sizer.Add(play_button, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)panel.SetSizer(sizer)

__init__方法中,我们设置了窗口的标题和大小,并初始化了一个实例变量folder_path来存储文件夹路径。

接下来,我们创建一个wx.Panel,并在其中添加了一个选择文件夹的按钮、一个文件列表框和一个播放按钮。按钮的点击事件分别绑定到了on_select_folderon_play方法。

最后,我们使用布局管理器(wx.BoxSizer)来设置控件的布局。

处理选择文件夹事件

我们需要实现on_select_folder方法,以处理选择文件夹的事件。

def on_select_folder(self, event):dialog = wx.DirDialog(self, message="选择文件夹")if dialog.ShowModal() == wx.ID_OK:self.folder_path = dialog.GetPath()  # 存储选择的文件夹路径self.update_file_list(self.folder_path)dialog.Destroy()

在该方法中,我们创建了一个文件夹选择对话框(wx.DirDialog)。当对话框显示并用户选择了文件夹后,我们将选定的文件夹路径存储在folder_path实例变量中,并调用update_file_list方法更新文件列表框中显示的文件列表。

最后,我们销毁对话框。

更新文件列表

接下来,我们需要实现update_file_list方法,用于更新文件列表框中显示的文件列表。

def update_file_list(self, folder_path):self.list_box.Clear()if folder_path:video_files = [f for f in os.listdir(folder_path) if f.endswith(".mp4")]for file in video_files:self.list_box.Append(file)

在该方法中,我们首先清空文件列表框中的内容,然后检查folder_path是否为空。如果不为空,我们使用os.listdir函数获取文件夹中所有的文件,并筛选出以".mp4"为扩展名的视频文件。然后,我们将这些视频文件添加到文件列表框中显示出来。

处理播放按钮事件

现在,让我们实现on_play方法,以处理播放按钮的点击事件。

def on_play(self, event):selected_files = self.list_box.GetSelections()  # 获取选择的文件索引if selected_files:video_paths = [os.path.join(self.folder_path, self.list_box.GetString(file_index)) for file_index in selected_files]if len(video_paths) == 4:player_frame = VideoPlayerFrame(video_paths)player_frame.Show()else:wx.MessageBox("请选择四个视频文件!", "错误", wx.OK | wx.ICON_ERROR)else:wx.MessageBox("请选择视频文件!", "错误", wx.OK | wx.ICON_ERROR)

在该方法中,我们首先获取文件列表框中选中的文件索引。然后,我们使用这些索引来获取选中的视频文件的路径。

接下来,我们检查选中的视频文件数量是否为4。如果是4个视频文件,我们创建一个VideoPlayerFrame实例,并将视频文件路径作为参数传递给它。最后,我们显示VideoPlayerFrame窗口。

如果选中的视频文件数量不是4,或者没有选择任何视频文件,我们将显示一个错误消息框,提示用户选择正确的视频文件。

创建视频播放器窗口

我们将创建一个名为VideoPlayerFrame的wx.Frame子类,用于显示四路视频播放器的窗口。

class VideoPlayerFrame(wx.Frame):def __init__(self, video_paths):super().__init__(None, title="四路视频播放器", size=(800, 600))self.video_players = []panel = wx.Panel(self)grid = wx.GridSizer(rows=2, cols=2, hgap=10, vgap=10)for path in video_paths:video_player = VideoPlayer(panel, path)grid.Add(video_player, proportion=1, flag=wx.EXPAND)self.video_players.append(video_player)panel.SetSizer(grid)self.Bind(wx.EVT_CLOSE, self.on_close)

__init__方法中,我们设置了窗口的标题和大小,并初始化了一个实例变量video_players,用于存储四个视频播放器的实例。

接下来,我们创建一个wx.Panel,并使用网格布局(wx.GridSizer)将四个视频播放器放置在窗口中。对于每个视频文件路径,我们创建一个VideoPlayer实例,并将其添加到网格布局中和video_players列表中。

最后,我们将网格布局设置为面板的布局管理器,并绑定窗口关闭事件到on_close方法。

创建视频播放器

现在,我们将创建一个名为VideoPlayer的wx.Panel子类,用于显示单个视频播放器。

class VideoPlayer(wx.Panel):def __init__(self, parent, video_path):super().__init__(parent)self.video_path = video_pathself.video_capture = cv2.VideoCapture(video_path)self.timer = wx.Timer(self)self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)self.static_bitmap = wx.StaticBitmap(self)self.update_frame()self.timer.Start(30)  # 每30毫秒更新一帧def update_frame(self):ret, frame = self.video_capture.read()if ret:frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)bitmap = wx.Bitmap.FromBuffer(frame.shape[1], frame.shape[0], frame)self.static_bitmap.SetBitmap(bitmap)def on_timer(self, event):self.update_frame()

__init__方法中,我们初始化了一些实例变量,包括视频文件路径、OpenCV的视频捕获对象(cv2.VideoCapture)、定时器(wx.Timer)和一个静态位图控件(wx.StaticBitmap)。

我们在update_frame方法中读取视频的下一帧,并将其转换为RGB格式。然后,我们将帧数据转换为wx.Bitmap对象,并将其设置为静态位图控件的位图。这样可以实现视频的实时播放。

on_timer方法中,我们在定时器事件触发时调用update_frame方法,以更新视频帧。

运行应用程序

现在我们已经完成了所有必要的类和方法,让我们在main函数中实例化FileListFrame窗口,并运行应用程序的主事件循环。

def main():app = wx.App()frame = FileListFrame()frame.Show()app.MainLoop()if __name__ == "__main__":main()

main函数中,我们创建了一个wx.App实例,并实例化了FileListFrame窗口。然后,我们显示窗口并启动应用程序的主事件循环。
##完整代码

import os
import wx
import cv2
from moviepy.editor import VideoFileClipclass FileListFrame(wx.Frame):def __init__(self):super().__init__(None, title="选择MP4文件", size=(400, 300))self.folder_path = ""  # 添加实例变量来存储文件夹路径panel = wx.Panel(self)# 创建选择文件夹的按钮select_button = wx.Button(panel, label="选择文件夹")select_button.Bind(wx.EVT_BUTTON, self.on_select_folder)# 创建列表框,用于显示文件列表self.list_box = wx.ListBox(panel, style=wx.LB_MULTIPLE | wx.LB_HSCROLL)# 创建播放按钮play_button = wx.Button(panel, label="播放")play_button.Bind(wx.EVT_BUTTON, self.on_play)# 设置布局管理器sizer = wx.BoxSizer(wx.VERTICAL)sizer.Add(select_button, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)sizer.Add(self.list_box, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)sizer.Add(play_button, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)panel.SetSizer(sizer)def on_select_folder(self, event):dialog = wx.DirDialog(self, message="选择文件夹")if dialog.ShowModal() == wx.ID_OK:self.folder_path = dialog.GetPath()  # 存储选择的文件夹路径self.update_file_list(self.folder_path)dialog.Destroy()def update_file_list(self, folder_path):self.list_box.Clear()if folder_path:video_files = [f for f in os.listdir(folder_path) if f.endswith(".mp4")]for file in video_files:self.list_box.Append(file)def on_play(self, event):selected_indices = self.list_box.GetSelections()if len(selected_indices) != 4:wx.MessageBox("请选择四个MP4文件!", "提示", wx.OK | wx.ICON_INFORMATION)returnselected_files = [self.list_box.GetString(index) for index in selected_indices]video_paths = [os.path.join(self.folder_path, file) for file in selected_files]  # 使用实例变量video_player_frame = VideoPlayerFrame(video_paths)video_player_frame.Show()class VideoPlayerFrame(wx.Frame):def __init__(self, video_paths):super().__init__(None, title="四路视频播放器", size=(800, 600))panel = wx.Panel(self)grid = wx.GridSizer(rows=2, cols=2, hgap=5, vgap=5)self.video_players = []for path in video_paths:video_player = VideoPlayer(panel, path)self.video_players.append(video_player)grid.Add(video_player, 0, wx.EXPAND)panel.SetSizer(grid)self.Bind(wx.EVT_CLOSE, self.on_close)def on_close(self, event):for video_player in self.video_players:video_player.release()event.Skip()class VideoPlayer(wx.Panel):def __init__(self, parent, video_path):super().__init__(parent)self.video_path = video_pathself.cap = cv2.VideoCapture(self.video_path)self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))self.video_window = wx.StaticBitmap(self, size=(self.width, self.height))self.timer = wx.Timer(self)self.Bind(wx.EVT_TIMER, self.update_frame, self.timer)self.timer.Start(30)sizer = wx.BoxSizer(wx.VERTICAL)sizer.Add(self.video_window, 0, wx.ALL, 5)self.SetSizer(sizer)def update_frame(self, event):ret, frame = self.cap.read()if ret:img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)bitmap = wx.Bitmap.FromBuffer(self.width, self.height, img)self.video_window.SetBitmap(bitmap)def release(self):self.cap.release()if __name__ == '__main__':app = wx.App()frame = FileListFrame()frame.Show()app.MainLoop()

总结

通过使用wxPython和OpenCV,我们成功创建了一个四路视频播放器应用程序。该应用程序允许用户选择一个包含四个MP4视频文件的文件夹,并在一个GUI界面中同时播放这四个视频文件。我们使用了wxPython来创建图形用户界面,OpenCV来处理和播放视频,以及moviepy来进行视频剪辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/56495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rabbitmq卸载重新安装3.8版本

卸载之前的版本的rabbitmq 卸载rabbitmq 卸载前先停止rabbitmq服务 /usr/lib/rabbitmq/bin/rabbitmqctl stop查看rabbitmq安装的相关列表 yum list | grep rabbitmq卸载rabbitmq相关内容 yum -y remove rabbitmq-server.noarch 卸载erlang 查看erlang安装的相关列表 …

Android启动优化

Android启动优化 启动分类 冷启动热启动 启动监控 生命周期监控首屏渲染监控用户可交互监控 启动报表 50分位,90分位图分段图,1s到2s,2s到3s不同Android版本,不同设备,不同app版本启动时间 启动优化 懒加载线程…

STM32 F103C8T6学习笔记13:IIC通信—AHT10温湿度传感器模块

今日学习一下这款AHT10 温湿度传感器模块,给我的OLED手环添加上测温湿度的功能。 文章提供源码、测试工程下载、测试效果图。 目录 AHT10温湿度传感器: 特性: 连接方式: 适用场所范围: 程序设计: 设…

js 类、原型及class

js 一直允许定义类。ES6新增了相关语法(包括class关键字)让创建类更容易。新语法创建的类和老式的类原理相同。js 的类和基于原型的继承机制与Java等语言中的类和继承机制有着本质区别。 1 类和原型 类意味着一组对象从同一个原型对象继承属性。因此,原型对象是…

跨专业申请成功|金融公司经理赴美国密苏里大学访学交流

J经理所学专业与从事工作不符,尽管如此,我们还是为其成功申请到美国密苏里大学经济学专业的访问学者职位,全家顺利过签出国。 J经理背景: 申请类型: 自费访问学者 工作背景: 某金融公司经理 教育背景&am…

(视频教程)单细胞转录组多组差异基因分析及可视化函数

很久以前,我们发布过一个单细胞多组差异基因可视化的方法。跟着Cell学单细胞转录组分析(八):单细胞转录组差异基因分析及多组结果可视化。主要复现参考的是这篇发表在《Cell》上的文章。可以将多个组的差异结果展示出来。 (reference:A Spati…

XPath:学习使用XPath语法提取HTML/XML文档中的数据使用语法

以下是一些XPath语法示例,用于提取HTML/XML文档中的数据: 选择元素: 选择所有p元素: //p 选择根元素: / 属性匹配: 选择class属性为"example"的div元素: //div[classexample] 文本内容…

在VScode中执行npm、yarn命令报错解

在VScode中执行npm、yarn命令报错解 我使用的是vnm安装好npm,在WindowsR 界面是可以运行查看出版本的;但是在VScode中报错。 查了很多资料,我这种情况的原因是在VScode中默认使用的终端是Powershell,然后我切换到系统的cmd则可以…

原生微信小程序使用 wxs;微信小程序使用 vant-weapp组件

1.原生微信小程序使用 wxs 1.内嵌 WXS 脚本 2. 定义外链 wxs 3. 使用外连wxs 在这里插入图片描述 2. 微信小程序使用 vant weapp 1.安装步骤 2. 安装包管理(package.json)文件的方法 操作顺序 :文档地址 如果使用 typescript 需要操作步骤3,否则不…

python语言学习

序言 此系列用于总结python语言的相关知识点,用于帮助自己和有缘人查阅 1、python基本数据类型 python基本数据类型 – 字符串

使用 wxPython 和 pymupdf进行 PDF 加密

PDF 文件是一种常见的文档格式,但有时候我们希望对敏感信息进行保护,以防止未经授权的访问。在本文中,我们将使用 Python 和 wxPython 库创建一个简单的图形用户界面(GUI)应用程序,用于对 PDF 文件进行加密…

自动化运维:Ansible基础与命令行模块操作

目录 一、理论 1. Ansible 2.部署Ansible自动化运维工具 3.Ansible常用模块 4.hostsinverntory主机清单 二、实验 1.部署Ansible自动化运维工具 2.ansible 命令行模块 3.hostsinverntory主机清单 三、问题 1. ansible远程shell失败 2.组变量查看webservers内主机ip报…

基于Java+SpringBoot+Vue前后端分离美食推荐商城设计和实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

显著性检验(Significance Test)

参考链接&#xff1a;Click Here 显著性检验&#xff08;Significance Test&#xff09;主要分为两个类别&#xff1a; Statistical Significance Test (统计显著性检验) 计量方式&#xff1a;p-value < 0.05 目的&#xff1a;检验原始分布与目标分布之间是否具有显著差异性…

如何在树莓派上使用Nginx搭建本地站点并通过内网穿透实现远程访问

文章目录 1. Nginx安装2. 安装cpolar3.配置域名访问Nginx4. 固定域名访问5. 配置静态站点 安装 Nginx&#xff08;发音为“engine-x”&#xff09;可以将您的树莓派变成一个强大的 Web 服务器&#xff0c;可以用于托管网站或 Web 应用程序。相比其他 Web 服务器&#xff0c;Ngi…

时间和日期--Python

1. 时间&#xff1a;time模块 总结&#xff1a;2. datetime模块 相比与time模块&#xff0c;datetime模块的接口更直观、更容易调用 2.1 datetime模块定义的类 &#xff08;1&#xff09;datetime.date:表示日期的类。常用的属性有&#xff1a;year、month、day; &#xff…

九大ES5特性,巩固你的JavaScript基础

文章目录 1. 变量声明和作用域&#xff1a;使用 var 关键字声明变量函数作用域和全局作用域变量提升 2. 数据类型&#xff1a;基本数据类型&#xff1a;Number、String、Boolean、null、undefined引用数据类型&#xff1a;Object、Array、Function、Date 3. 函数&#xff1a;函…

vue中form、table和input标签过长

form标签过长 效果&#xff1a; 代码&#xff1a; <el-form-item v-for"(item,index) in ticketEditTable1" :label"item.fieldNameCn" :propitem.fieldName :key"item.fieldNameCn" overflow"":rules"form[item.fieldName…

Linux 中的 sysctl 命令及示例

介绍 Linux管理员使用该命令在运行时sysctl读取或修改内核参数。无需重新启动即可实时控制和修改网络、 I/O 操作和内存管理设置的选项对于高可用性系统至关重要。 了解如何使用该sysctl命令及其选项来动态调整系统性能。

Android中使用JT808协议进行车载终端通信的实现和优化

JT808是一种在中国广泛应用的车载终端通信协议&#xff0c;用于车辆与监控中心之间的数据通信。下面是关于Android平台上使用JT808协议进行通信的一般步骤和注意事项&#xff1a; 协议了解&#xff1a;首先&#xff0c;您需要详细了解JT808协议的规范和定义。该协议包含了通信消…