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.rhkb.cn/news/108919.html

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

相关文章

sql数据库怎么备份,sql 实时备份

在当今互联网时代,数据已经成为企业的核心资产。然而,数据的安全性和完整性面临硬件问题、软件故障、人工操作错误等各种威胁。为了保证数据的安全,实时备份已经成为公司必须采取的重要措施之一。下面我们就重点介绍SQL实时备份的重要实施方法…

百亿补贴通用H5导航栏方案 | 京东云技术团队

背景 在移动端页面中,由于屏幕空间有限,导航条扮演着非常重要的角色,提供了快速导航到不同页面或功能的方式。用户也通常会在导航条中寻找他们感兴趣的内容,因此导航条的曝光率较高。在这样的背景下,提供一个动态灵活…

你不知道的宝藏合金:高熵合金

高熵合金(High-entropy alloys)简称HEA,是由五种或五种以上等量或大约等量金属形成的合金。由于高熵合金可能具有许多理想的性质,因此在材料科学及工程上相当受到重视。 传统合金是以1~2种金属为主,并通过添加特定的少…

基于PyTorch深度学习遥感影像地物分类与目标检测、分割及遥感影像问题深度学习优化

我国高分辨率对地观测系统重大专项已全面启动,高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB,遥感大数据时…

兄弟,王者荣耀的段位排行榜是通过Redis实现的?

目录 一、排行榜设计方案1、数据库直接排序2、王者荣耀好友排行 二、Redis实现计数器1、什么是计数器功能?2、Redis实现计数器的原理(1)使用INCR命令实现计数器(2)使用INCRBY命令实现计数器 三、通过Redis实现“王者荣…

Java注解与反射

💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! Java注解与反射 Java注解和反射是Java语言中两个强大的特性,它们可以一起使用以实现动态的、灵活的编程和元数据处理 注解 Java注解(Annotatio…

c语言六子棋(Alpha-Beta剪枝算法)

c语言Alpha-Beta剪枝算法六子棋介绍 Alpha-Beta剪枝算法是一种用于优化博弈树搜索的算法,可以在搜索过程中减少不必要的计算,从而提高搜索效率。该算法常用于博弈游戏,如六子棋。 六子棋是一种类似于五子棋的棋类游戏,在一个六边形…

ubuntu20.04 编译安装运行emqx

文章目录 安装依赖编译运行登录dashboard压力测试 安装依赖 Erlang/OTP OTP 24 或 25 版本 apt-get install libncurses5-dev sudo apt-get install erlang如果安装的erlang版本小于24的话,可以使用如下方法自行编译erlang 1.源码获取 wget https://github.com/erla…

【大模型AIGC系列课程 3-2】国产开源大模型:ChatGLM

1. GLM https://arxiv.org/pdf/2103.10360.pdf GLM是General Language Model的缩写,是一种通用的语言模型预训练框架。它的主要目标是通过自回归的空白填充来进行预训练,以解决现有预训练框架在自然语言理解(NLU)、无条件生成和有条件生成等任务中表现不佳的问题。 具体来…

WPF网格拖动自动布局效果

WPF网格拖动自动布局效果 使用Canvas和鼠标相关事件实现如下的效果: XAML代码: <Window x:Class="CanvasTest.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:

java练习8.100m小球落地

题目: 如一个小球从100米高度自由落下&#xff0c;每次落地后就反跳回原高度的一半。 那么求它在第10次落地时&#xff0c;共经过多少米&#xff1f;第10次反弹多高&#xff1f; public static void main(String[] args) {/*假如一个小球从100米高度自由落下&#xff0c;每次落…

按软件开发阶段的角度划分:单元测试、集成测试、系统测试、验收测试

1.单元测试&#xff08;Unit Testing&#xff09; 单元测试&#xff0c;又称模块测试。对软件的组成单位进行测试&#xff0c;其目的是检验软件基本组成单位的正确性。测试的对象是软件里测试的最小单位&#xff1a;模块。 测试阶段&#xff1a;编码后或者编码前&#xff08;…

天润融通「微藤大语言模型平台2.0」以知识驱动企业高速增长

8月23日&#xff0c;天润融通&#xff08;又称“天润云”,2167.HK&#xff09;&#xff0c;正式发布「微藤大语言模型平台2.0」。 “大模型企业知识企业知识工程”。 “不能有效记录和管理知识的企业是不能持续进步的。在企业的生产流程中&#xff0c;相比于其他场景&#xff0…

com.mysql.jdbc.PacketTooBigException: Packet for query is too large(windows)

使用mysql查询数据的时候报错&#xff1a; Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1078 > 1024). You can change this value on the server by setting the max_allowed_packet variable. 这是因为mysql的server默认接受数据…

ISIS路由协议

骨干区域与非骨干区域 凡是由级别2组建起来的邻居形成骨干区域&#xff1b;级别1就在非骨干区域&#xff0c;骨干区域有且只有一个&#xff0c;并且需要连续&#xff0c;ISIS在IP环境下目前不支持虚链路。 路由器级别 L1路由器只能建立L1的邻居&#xff1b;L2路由器只能建立L…

IDEA启动两个Tomcat服务的方式 使用nginx进行反向代理 JMeter测试分布式情况下synchronized锁失效

目录 引出IDEA启动Tomcat两个端口的方式1.编辑配置2.添加新的端口-Dserver.port80833.service里面管理4.启动后进行测试 使用nginx进行反向代理反向代理多个端口运行日志查看启动关闭重启 分布式情况下synchronized失效synchronized锁代码启动tomcat两个端口nginx反向代理JMete…

VR智慧校园资中控管理平台综合提升了课堂教学质量

随着越来越多高校在课堂中引进VR虚拟仿真实训系统&#xff0c;为了方便老师对全班同学进行高效率地管理&#xff0c;VR中控平台应运而生。下面为您详细介绍VR中控平台在课堂教学中的应用优势。 VR中控系统安装在教师总控端&#xff0c;融合了课件、视频、3D动画等丰富的教学资源…

python+mysql+前后端分离国内职位数据分析(源码+文档+指导)

系统阐述的是使用国内python职位数据分析系统的设计与实现&#xff0c;对于Python、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计&#xff0c;描述&#xff0c;实现和分析与测试方面来表明开发的过程。开发中使用了 Flask框架和MySql数据库技术搭建系统的整体…

二、数学建模之整数规划篇

1.定义 2.例题 3.使用软件及解题 一、定义 1.整数规划&#xff08;Integer Programming&#xff0c;简称IP&#xff09;&#xff1a;是一种数学优化问题&#xff0c;它是线性规划&#xff08;Linear Programming&#xff0c;简称LP&#xff09;的一个扩展形式。在线性规划中&…

ZeroMQ入门

官网: ZeroMQ 简介 ZeroMQ是一个库&#xff0c;不是消息队列也不是消息中间件&#xff0c;介于应用层和传输层之间&#xff08;按照TCP/IP划分&#xff09;。 传统的Socket通信模式需要创建连接&#xff0c;销毁连接&#xff0c;选择协议等一些列操作。而ZeroMQ是在Socket封…