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_folder和on_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来进行视频剪辑。
相关文章:
 
python编写四画面同时播放swap视频
当代技术让我们能够创建各种有趣和实用的应用程序。在本篇博客中,我们将探索一个基于wxPython和OpenCV的四路视频播放器应用程序。这个应用程序可以同时播放四个视频文件,并将它们显示在一个GUI界面中。 C:\pythoncode\new\smetimeplaymp4.py 准备工作…...
 
用XSIBackup为VMware ESXi打造完美备份方案
文章目录 VMware ESXi 备份方案引言XSIBackup安装步骤1. XSIBackup软件安装2. SSH连接3. 定位到xsibackup目录4. 修改文件权限5. 安装cron查看crontab列表6. 配置备份任务结论VMware ESXi 备份方案 引言 数据就像是我们的生命线,一旦丢失,可能会带来无法挽回的损失。对于那…...
 
React 项目中引入msal验证以及部分报错处理
功能实现 如何在React 项目中引入msal身份验证, 微软在官网有提供文档支持,文档包含示例和具体使用的教程,地址如下: https://learn.microsoft.com/zh-cn/azure/active-directory/develop/tutorial-v2-nodejs-webapp-msal 照着文…...
Unity3D 2021 使用 SharpZipLib 遇到的安卓打包 I18N 相关问题
在 Unity3D 中,使用 ICSharpCode.SharpZipLib.dll 来做压缩和解压缩,但打包安卓后遇到问题,原因是字符编码程序集被裁减掉了导致。 根据网上搜索,将 UnityEditor 对应目录下的 I18N开头的,比如 I18N.CJK.dll 等系列文…...
 
软件工程(十五) 行为型设计模式(一)
1、责任链模式 简要说明 通过多个对象处理的请求,减少请求的发送者与接收者之间的耦合。将接受对象链接起来,在链中传递请求,直到有一个对象处理这个请求。 速记关键字 传递职责 类图如下 由类图可以比较容易的看出来,其实就是自己关联自己,形成了一个链,并且自己有…...
【校招VIP】前端算法考点之快慢指针题型
考点介绍: 链表是校招面试里手撕代码出现频度比较高的题型,三线和中小厂会考察简单的链表反转,大厂会进一步考察复杂度和双指针问题,比如中间元素、是否存在环等。 『前端算法考点之快慢指针题型』相关题目及解析内容可点击文章末…...
 
Docker基础入门:容器数据卷与Dockerfile构建镜像(发布)
Docker基础入门:容器数据卷与Dockerfile构建镜像(发布) 一、docker容器数据卷1.1、使用docker容器数据卷1.2、具名挂载、匿名挂载1.3、如何确定是具名挂载还是匿名挂载 二、使用dockerfile2.1 初识Dockerfile2.2 Dockerfile构建过程2.3 Docke…...
部署问题集合(二十一)从零开始搭建一台NAS服务器(Linux虚拟机)
前言 因工作需要,需要从零通过虚拟机搭建一台NAS服务器,以此记录下来 步骤 1、创建虚拟机 通过VMWare创建一台新虚拟机,虚拟机内存和磁盘自定义,不过建议尽量大一点 2、服务器端配置 查看是否安装有NFS服务:rpm …...
 
Git小白入门——了解分布式版本管理和安装
Git是什么? Git是目前世界上最先进的分布式版本控制系统(没有之一) 什么是版本控制系统? 程序员开发过程中,对于每次开发对各种文件的修改、增加、删除,达到预期阶段的一个快照就叫做一个版本。 如果有一…...
 
芯科科技宣布推出下一代暨第三代无线开发平台,打造更智能、更高效的物联网
第三代平台中的人工智能/机器学习引擎可将性能提升100倍以上 Simplicity Studio 6软件开发工具包通过新的开发环境将开发人员带向第三代平台 中国,北京 - 2023年8月22日 – 致力于以安全、智能无线连接技术,建立更互联世界的全球领导厂商Silicon Labs&…...
 
无涯教程-Android - Intents/Filters
Android Intent 是要执行的操作的抽象描述。它可以与 startActivity 一起启动Activity,将 broadcastIntent 发送给任何BroadcastReceiver组件,并与 startService(Intent)或 bindService(Intent,ServiceConnection,int)与后台服务进…...
 
NFTScan 正式上线 Base NFTScan 浏览器和 NFT API 数据服务
2023 年 8 月 24 号,NFTScan 团队正式对外发布了 Base NFTScan 基础设施,将为 Base 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商,Base 是继 Bitcoin、Ethereum、BNBChain、…...
 
【Git】测试持续集成——Git+Gitee+PyCharm
文章目录 概述一、使用Gitee1. 注册账号2. 绑定邮箱3. 新建仓库4. 查看项目地址 二、安装配置Git1. 下载安装包2. 校验是否安装成功。3. 配置Git4. Git命令5. Git实操 三、PyCharmGit1. 配置Git2. Clone项目3. 提交文件到服务器4. 从服务器拉取文件 概述 持续集成(…...
 
《HelloGitHub》第 89 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 …...
 
多维时序 | Matlab实现LSTM-Adaboost和LSTM多变量时间序列预测对比
多维时序 | Matlab实现LSTM-Adaboost和LSTM多变量时间序列预测对比 目录 多维时序 | Matlab实现LSTM-Adaboost和LSTM多变量时间序列预测对比预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实现LSTM-Adaboost和LSTM多变量时间序列预测对比 模型…...
 
c语言每日一练(12)
前言:每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,暑假时三天之内必有一更,到了开学之后,将看学业情…...
 
用AI + Milvus Cloud搭建着装搭配推荐系统
在上一篇文章中,我们学习了如何利用人工智能技术(例如开源 AI 向量数据库 Milvus Cloud 和 Hugging Face 模型)寻找与自己穿搭风格相似的明星。在这篇文章中,我们将进一步介绍如何通过对上篇文章中的项目代码稍作修改,获得更详细和准确的结果,文末附赠彩蛋。 注:试用此…...
 
41、springboot 整合 FreeMarker 模版技术
springboot 整合 FreeMarker 模版技术 ★ 整合FreeMarker的自动配置: FreeMarkerAutoConfiguration:负责整合Spring容器和获取FreeMarkerProperties加载的配置信息。FreeMarkerServletWebConfiguration/FreeMarkerReactiveWebConfiguration:…...
 
每天 26,315 美元罚款?交通安全局要求特斯拉提供 Autopilot数据
根据美国国家公路交通安全管理局(NHTSA)最近的特别命令,特斯拉公司被要求提供关于其自动驾驶功能Autopilot的相关信息。这一命令是继NHTSA于2021年8月启动初步评估后,在2022年6月升级为正式调查的一部分,NHTSA近期对特…...
 
3d激光slam建图与定位(2)_aloam代码阅读
1.常用的几种loam算法 aloam 纯激光 lego_loam 纯激光 去除了地面 lio_sam imu激光紧耦合 lvi_sam 激光视觉 2.代码思路 2.1.特征点提取scanRegistration.cpp,这个文件的目的是为了根据曲率提取4种特征点和对当前点云进行预处理 输入是雷达点云话题 输出是 4种特征点…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
 
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
 
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
 
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
 
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
