当前位置: 首页 > wzjs >正文

一个简单的游戏网站建设网站要多钱

一个简单的游戏网站建设,网站要多钱,青海省建设工程监理协会网站,网站建设工作策划方案Python实现视频播放器 Python实现视频播放器,在如下博文中介绍过 Python实现本地视频/音频播放器https://blog.csdn.net/cnds123/article/details/137874107 Python简单GUI程序示例 中 “四、视频播放器” https://blog.csdn.net/cnds123/article/details/122903…

Python实现视频播放器

Python实现视频播放器,在如下博文中介绍过

Python实现本地视频/音频播放器https://blog.csdn.net/cnds123/article/details/137874107

Python简单GUI程序示例 中 “四、视频播放器” https://blog.csdn.net/cnds123/article/details/122903311

现在再补充介绍一个。读者可以学习比较之。

预备知识

tkinter 是 Python 的标准库之一,用于创建图形用户界面(GUI)。它不需要单独安装,因为它是 Python 安装时自带的模块。

ttk 是 tkinter 的扩展模块,提供了更现代的 GUI 控件(如样式化的按钮、下拉菜单等)。

Style 是 ttk 模块的一部分,用于自定义 GUI 控件的样式。

time 是 Python 的标准库,用于处理时间相关的操作。

threading 是 Python 的标准库,用于实现多线程编程。

需要安装第三方库:opencv-python、pillow、ffpyplayer

cv2 是 OpenCV(Open Source Computer Vision Library)的 Python 接口,用于计算机视觉任务,如图像处理、视频处理等。

pip install opencv-python

Pillow 是 Python Imaging Library(PIL)的一个分支,用于处理图像。

pip install pillow

ffpyplayer 是一个基于 FFmpeg 的 Python 库,用于播放音频和视频。

pip install ffpyplayer

本文介绍了Python实现视频播放器及其改进版本

先看第一个效果图:

源码如下:

import cv2
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk, ImageSequence
from tkinter import ttk
from ffpyplayer.player import MediaPlayer
import time
import threading
from tkinter.ttk import Styleclass VideoPlayTk:def __init__(self):self.__win = tk.Tk()self.__canvas = None     # 画布变量self.__videoWH = [1920, 1080]  # 窗口大小self.__num1 = 0.6# 窗口缩小系数,默认为0.6,最大最好1self.__data = list()self.__uploadImgSize = [150, 150]  # 一个加载视频的gif图片尺寸self.__canvasWH = []     # 画布的宽度 和 高度self.__canvasImg = None  # 画布图片self.__canvasXY = []     # 图片插入到canvas的具体左上角坐标x,yself.__progressBar = None  # 进度条self.__Llabel = None   # 左边显示时间的标签self.__Rlabel = None   # 右边显示时间的标签self.__player = None   # 音频播放 变量self.__scale = None   # 调节音量的控件self.__stopBtn = None   # 暂停按钮self.__stopState = ''  # 一个控制相关线程的变量self.__running = True  # 控制线程运行的标志def sectionOne(self):width = int(self.__videoWH[0] * self.__num1)height = int(self.__videoWH[1] * self.__num1)self.__canvasWH = [width, height]self.__win.title('视频播放器')self.__win.geometry(f'{width}x{height + 90}')self.__win.resizable(height=0, width=0)# 窗口不可放大# 菜单self.__win.iconbitmap('./example.ico')mainMenu = tk.Menu(self.__win)fileMenu = tk.Menu(mainMenu, tearoff=False)# 不添加分割线fileMenu.add_command(label='打开', command=self.__openDir)fileMenu.add_separator()# 设置分割线fileMenu.add_command(label='退出', command=self.__on_close)mainMenu.add_cascade(label='文件', menu=fileMenu)# 在主目录菜单上新增“文件”选项,并通过menu参数与下拉菜单绑定self.__win.config(menu=mainMenu)# 将主菜单设置在窗口上# 画布self.__canvas = tk.Canvas(self.__win, bg='black', width=width, height=height)self.__canvas.grid(row=0, column=0, columnspan=3)self.__Llabel = tk.Label(self.__win, text='00:00:00', font=('华文宋体', 12))self.__Llabel.grid(row=1, column=0)# 进度条style = Style()style.theme_use('clam')style.configure("my0.Horizontal.TProgressbar", troughcolor='white', background='red')# 设置进度条的颜色progressBar = ttk.Progressbar(self.__win, orient=tk.HORIZONTAL,style='my0.Horizontal.TProgressbar')progressBar.grid(row=1, column=1)progressBar['length'] = width - 200progressBar['value'] = 0self.__progressBar = progressBarself.__Rlabel = tk.Label(self.__win, text='00:00:00', font=('华文宋体', 12))self.__Rlabel.grid(row=1, column=2)self.__stopBtn = tk.Button(self.__win,text='暂停',font=('华文宋体', 12),command=self.__fun5)self.__stopBtn.grid(row=2,column=0,sticky=tk.E)# 音量self.__scale = tk.Scale(self.__win, from_=0, to=100, resolution=1, length=120, orient=tk.HORIZONTAL,font=('华文宋体', 12),command=self.__fun2)self.__scale.grid(row=2, column=1, sticky=tk.E)self.__scale.set(100)self.__win.protocol("WM_DELETE_WINDOW", self.__on_close)self.__win.mainloop()def __on_close(self):self.__running = False  # 停止线程if self.__player is not None:self.__player.close_player()self.__win.quit()self.__win.destroy()  # 确保窗口被销毁# 暂停播放的方法def __fun5(self):if self.__player is not None:self.__player.set_pause(True)# 点击暂停按钮,视频播放暂停self.__stopState = 'stop'# 设置暂停播放状态# 调节音量的方法def __fun2(self, value):if self.__player is not None:self.__player.set_volume(int(value) / 100)# value 值的范围为0~100,set_volume方法参数取值为0.0 ~ 1.0# 将总的时间(单位秒)进行相关格式化  如 119 为 00:01:59def __getTime(self,totleTime):hour = 0minute = totleTime//60if minute > 60:hour = minute // 60second = int(totleTime%60)return '{:02d}:{:02d}:{:02d}'.format(hour,minute,second)def __openDir(self):fileName = filedialog.askopenfilename()# 视频文件的绝对路径if fileName != '':cap = cv2.VideoCapture(filename=fileName)self.__data = list()w = cap.get(propId=cv2.CAP_PROP_FRAME_WIDTH)h = cap.get(propId=cv2.CAP_PROP_FRAME_HEIGHT)fps = cap.get(propId=cv2.CAP_PROP_FPS)count = cap.get(propId=cv2.CAP_PROP_FRAME_COUNT)print('时长:',int(count*(1/fps)))self.__data = [int(w), int(h), int(fps), int(count),int(count*(1/fps))]print(self.__data)# 使用cv2获取视频的尺寸,比如1920*1080,帧率(1秒以内变换图片的张数),图片的总数,总时长canvas_x = 0canvas_y = 0if w / self.__canvasWH[0] == h / self.__canvasWH[1]:print('图片大小1920*1080')bi = w / self.__canvasWH[0]else:if w / self.__canvasWH[0] > h / self.__canvasWH[1]:bi = w / self.__canvasWH[0]canvas_y = int((self.__canvasWH[1] - h / bi) // 2)else:bi = h / self.__canvasWH[1]canvas_x = int((self.__canvasWH[0] - w / bi) // 2)self.__canvasXY = [canvas_x, canvas_y]# 根据视频的尺度用于确定画布 图片左上角坐标# 下面这一段代码可以注释,只是实现播放视频时实现视频加载图标w = self.__canvasWH[0]h = self.__canvasWH[1]x = (w - self.__uploadImgSize[0]) // 2y = (h - self.__uploadImgSize[1]) // 2self.__canvas.delete(tk.ALL)img_i = 0while img_i < 5:uploadImg = Image.open('upload.gif')iter = ImageSequence.Iterator(uploadImg)for frame in iter:pic = ImageTk.PhotoImage(frame)self.__canvas.create_image(x, y, image=pic, anchor=tk.W)time.sleep(0.01)self.__canvas.update()img_i += 1size = (int(self.__data[0] / bi), int(self.__data[1] / bi))self.__player = MediaPlayer(filename=fileName)thread1 = threading.Thread(target=self.__fun3)# 时间加载的线程thread2 = threading.Thread(target=self.__fun4)# 时间进度条的线程thread1.start()thread2.start()print('执行主程序!')self.__fun1(size)self.__player.close_player()cap.release()# 时间进度条def __fun4(self):progressBar = self.__progressBarprogressBar['maximum'] = self.__data[4]progressBar['value'] = 0for i in range(self.__data[4]+1):if not self.__running:breakif self.__stopState == 'stop':breakprogressBar['value'] += 1time.sleep(1)# 时间展示def __fun3(self):print(self.__getTime(self.__data[4]))self.__Rlabel['text'] = self.__getTime(self.__data[4])second1 = 0minute1 = 0hour1 = 0for i in range(self.__data[4]+1):if not self.__running:breakif second1 != 0 and second1 == 60:minute1 += 1second1 = 0if minute1 == 59 and second1 == 60:hour1 += 1minute1 = 0second1 = 0if self.__stopState == 'stop':breakself.__Llabel['text'] = '{:02d}:{:02d}:{:02d}'.format(hour1,minute1,second1)time.sleep(1)second1 += 1# 播放图片def __fun1(self, size):i = 0self.__canvas.delete(tk.ALL)self.__stopState = ''while i < self.__data[3]:if not self.__running:breakframe, val = self.__player.get_frame()if self.__stopState == 'stop':breakif val == 'eof':self.__player.set_pause(True) # 需要!不信你试试breakelif frame is None:if i != 0:self.__player.set_pause(True)# self.__player.close_player()breakelse:time.sleep(0.01)else:image, pts = framebytes_1 = bytes(image.to_bytearray()[0])img2 = Image.frombytes("RGB", image.get_size(), bytes_1)img2 = img2.resize(size=size,resample=Image.ANTIALIAS)self.__canvasImg = ImageTk.PhotoImage(image=img2)self.__canvas.create_image(self.__canvasXY[0], self.__canvasXY[1], image=self.__canvasImg, anchor=tk.NW)self.__canvas.update()time.sleep(1/self.__data[2])i += 1if __name__ == '__main__':a = VideoPlayTk()a.sectionOne()

改进,添加“继续”播放按钮

先看效果图:

源码如下:

import cv2
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk, ImageSequence
from tkinter import ttk
from ffpyplayer.player import MediaPlayer
import time
import threading
from tkinter.ttk import Styleclass VideoPlayTk:def __init__(self):self.__win = tk.Tk()self.__canvas = None     # 画布变量self.__videoWH = [1920, 1080]  # 窗口大小self.__num1 = 0.6# 窗口缩小系数,默认为0.6,最大最好1self.__data = list()self.__uploadImgSize = [150, 150]  # 一个加载视频的gif图片尺寸self.__canvasWH = []     # 画布的宽度 和 高度self.__canvasImg = None  # 画布图片self.__canvasXY = []     # 图片插入到canvas的具体左上角坐标x,yself.__progressBar = None  # 进度条self.__Llabel = None   # 左边显示时间的标签self.__Rlabel = None   # 右边显示时间的标签self.__player = None   # 音频播放 变量self.__scale = None   # 调节音量的控件self.__stopBtn = None   # 暂停按钮self.__resumeBtn = None  # 继续按钮self.__stopState = ''  # 一个控制相关线程的变量self.__running = True  # 控制线程运行的标志self.__current_frame = 0  # 当前播放的帧数self.__video_thread = None  # 视频播放线程self.__progress_thread = None  # 进度条更新线程self.__progress_value = 0  # 保存进度条的当前值self.__time_value = 0  # 保存时间标签的当前值self.__video_finished = False  # 视频播放结束标志def sectionOne(self):width = int(self.__videoWH[0] * self.__num1)height = int(self.__videoWH[1] * self.__num1)self.__canvasWH = [width, height]self.__win.title('视频播放器')self.__win.geometry(f'{width}x{height + 120}')  # 增加高度以容纳更多按钮self.__win.resizable(height=0, width=0)# 窗口不可放大# 菜单self.__win.iconbitmap('./example.ico')mainMenu = tk.Menu(self.__win)fileMenu = tk.Menu(mainMenu, tearoff=False)# 不添加分割线fileMenu.add_command(label='打开', command=self.__openDir)fileMenu.add_separator()# 设置分割线fileMenu.add_command(label='退出', command=self.__on_close)mainMenu.add_cascade(label='文件', menu=fileMenu)# 在主目录菜单上新增“文件”选项,并通过menu参数与下拉菜单绑定self.__win.config(menu=mainMenu)  # 将主菜单设置在窗口上# 画布self.__canvas = tk.Canvas(self.__win, bg='black', width=width, height=height)self.__canvas.grid(row=0, column=0, columnspan=3)self.__Llabel = tk.Label(self.__win, text='00:00:00', font=('华文宋体', 12))self.__Llabel.grid(row=1, column=0)# 进度条style = Style()style.theme_use('clam')style.configure("my0.Horizontal.TProgressbar", troughcolor='white', background='red')# 设置进度条的颜色progressBar = ttk.Progressbar(self.__win, orient=tk.HORIZONTAL, style='my0.Horizontal.TProgressbar')progressBar.grid(row=1, column=1)progressBar['length'] = width - 200progressBar['value'] = 0self.__progressBar = progressBarself.__Rlabel = tk.Label(self.__win, text='00:00:00', font=('华文宋体', 12))self.__Rlabel.grid(row=1, column=2)# 暂停按钮self.__stopBtn = tk.Button(self.__win, text='暂停', font=('华文宋体', 12), command=self.__pause_video)self.__stopBtn.grid(row=2, column=0, sticky=tk.E)# 继续按钮self.__resumeBtn = tk.Button(self.__win, text='继续', font=('华文宋体', 12), command=self.__resume_video)self.__resumeBtn.grid(row=2, column=1)  # , sticky=tk.E# 音量self.__scale = tk.Scale(self.__win, from_=0, to=100, resolution=1, length=120, orient=tk.HORIZONTAL,font=('华文宋体', 12), command=self.__adjust_volume)self.__scale.grid(row=2, column=2) # , sticky=tk.Eself.__scale.set(100)self.__win.protocol("WM_DELETE_WINDOW", self.__on_close)self.__win.mainloop()def __on_close(self):self.__running = False  # 停止线程if self.__player is not None:self.__player.close_player()self.__win.quit()self.__win.destroy()  # 确保窗口被销毁# 暂停视频def __pause_video(self):if self.__player is not None:self.__player.set_pause(True)self.__stopState = 'stop'  # 设置暂停状态self.__progress_value = self.__progressBar['value']  # 保存进度条的当前值self.__time_value = self.__get_seconds_from_time(self.__Llabel['text'])  # 保存时间标签的当前值# 继续视频def __resume_video(self):if self.__player is not None:self.__player.set_pause(False)self.__stopState = ''  # 清除暂停状态# 如果视频播放线程已经结束,重新启动它if self.__video_thread is None or not self.__video_thread.is_alive():size = (int(self.__data[0] / (self.__data[0] / self.__canvasWH[0])), int(self.__data[1] / (self.__data[1] / self.__canvasWH[1])))self.__video_thread = threading.Thread(target=self.__play_video, args=(size,))self.__video_thread.start()# 如果进度条线程已经结束,重新启动它if self.__progress_thread is None or not self.__progress_thread.is_alive():self.__progress_thread = threading.Thread(target=self.__update_progress)self.__progress_thread.start()# 如果时间标签线程已经结束,重新启动它if not hasattr(self, '__time_thread') or not self.__time_thread.is_alive():self.__time_thread = threading.Thread(target=self.__update_time)self.__time_thread.start()# 调节音量的方法def __adjust_volume(self, value):if self.__player is not None:self.__player.set_volume(int(value) / 100)# value 值的范围为0~100,set_volume方法参数取值为0.0 ~ 1.0# 将总的时间(单位秒)进行相关格式化  如 119 为 00:01:59def __getTime(self, totleTime):hour = 0minute = totleTime // 60if minute > 60:hour = minute // 60second = int(totleTime % 60)return '{:02d}:{:02d}:{:02d}'.format(hour, minute, second)# 将时间字符串转换为秒数def __get_seconds_from_time(self, time_str):h, m, s = map(int, time_str.split(':'))return h * 3600 + m * 60 + sdef __openDir(self):fileName = filedialog.askopenfilename()# 视频文件的绝对路径if fileName != '':# 停止当前视频播放self.__running = Falseif self.__player is not None:self.__player.close_player()if self.__video_thread is not None and self.__video_thread.is_alive():self.__video_thread.join()if self.__progress_thread is not None and self.__progress_thread.is_alive():self.__progress_thread.join()if hasattr(self, '__time_thread') and self.__time_thread.is_alive():self.__time_thread.join()# 重置状态变量self.__running = Trueself.__stopState = ''self.__progress_value = 0self.__time_value = 0self.__video_finished = False# 重置时间轴和进度条self.__Llabel['text'] = '00:00:00'self.__Rlabel['text'] = '00:00:00'self.__progressBar['value'] = 0cap = cv2.VideoCapture(filename=fileName)self.__data = list()w = cap.get(propId=cv2.CAP_PROP_FRAME_WIDTH)h = cap.get(propId=cv2.CAP_PROP_FRAME_HEIGHT)fps = cap.get(propId=cv2.CAP_PROP_FPS)count = cap.get(propId=cv2.CAP_PROP_FRAME_COUNT)print('时长:', int(count * (1 / fps)))self.__data = [int(w), int(h), int(fps), int(count), int(count * (1 / fps))]print(self.__data)# 使用cv2获取视频的尺寸,比如1920*1080,帧率(1秒以内变换图片的张数),图片的总数,总时长canvas_x = 0canvas_y = 0if w / self.__canvasWH[0] == h / self.__canvasWH[1]:print('图片大小1920*1080')bi = w / self.__canvasWH[0]else:if w / self.__canvasWH[0] > h / self.__canvasWH[1]:bi = w / self.__canvasWH[0]canvas_y = int((self.__canvasWH[1] - h / bi) // 2)else:bi = h / self.__canvasWH[1]canvas_x = int((self.__canvasWH[0] - w / bi) // 2)self.__canvasXY = [canvas_x, canvas_y]# 根据视频的尺度用于确定画布 图片左上角坐标# 下面这一段代码可以注释,只是实现播放视频时实现视频加载图标w = self.__canvasWH[0]h = self.__canvasWH[1]x = (w - self.__uploadImgSize[0]) // 2y = (h - self.__uploadImgSize[1]) // 2self.__canvas.delete(tk.ALL)img_i = 0while img_i < 5:uploadImg = Image.open('upload.gif')iter = ImageSequence.Iterator(uploadImg)for frame in iter:pic = ImageTk.PhotoImage(frame)self.__canvas.create_image(x, y, image=pic, anchor=tk.W)time.sleep(0.01)self.__canvas.update()img_i += 1size = (int(self.__data[0] / bi), int(self.__data[1] / bi))self.__player = MediaPlayer(filename=fileName)self.__video_thread = threading.Thread(target=self.__play_video, args=(size,))self.__video_thread.start()self.__progress_thread = threading.Thread(target=self.__update_progress)self.__progress_thread.start()self.__time_thread = threading.Thread(target=self.__update_time)self.__time_thread.start()print('执行主程序!')cap.release()# 时间进度条def __update_progress(self):progressBar = self.__progressBarprogressBar['maximum'] = self.__data[4]progressBar['value'] = self.__progress_value  # 从保存的位置恢复进度条for i in range(self.__progress_value, self.__data[4] + 1):if not self.__running or self.__video_finished:breakif self.__stopState == 'stop':breakprogressBar['value'] = itime.sleep(1)# 时间展示def __update_time(self):self.__Rlabel['text'] = self.__getTime(self.__data[4])second1 = self.__time_value % 60minute1 = (self.__time_value // 60) % 60hour1 = self.__time_value // 3600for i in range(self.__time_value, self.__data[4] + 1):if not self.__running or self.__video_finished:breakif second1 != 0 and second1 == 60:minute1 += 1second1 = 0if minute1 == 59 and second1 == 60:hour1 += 1minute1 = 0second1 = 0if self.__stopState == 'stop':breakself.__Llabel['text'] = '{:02d}:{:02d}:{:02d}'.format(hour1, minute1, second1)time.sleep(1)second1 += 1self.__time_value += 1# 播放视频def __play_video(self, size):i = 0self.__canvas.delete(tk.ALL)self.__stopState = ''while i < self.__data[3]:if not self.__running:breakframe, val = self.__player.get_frame()if self.__stopState == 'stop':breakif val == 'eof':self.__video_finished = True  # 设置视频播放结束标志self.__player.set_pause(True) # 需要!不信你试试breakelif frame is None:if i != 0:self.__player.set_pause(True)breakelse:time.sleep(0.01)else:image, pts = framebytes_1 = bytes(image.to_bytearray()[0])img2 = Image.frombytes("RGB", image.get_size(), bytes_1)img2 = img2.resize(size=size, resample=Image.ANTIALIAS)self.__canvasImg = ImageTk.PhotoImage(image=img2)self.__canvas.create_image(self.__canvasXY[0], self.__canvasXY[1], image=self.__canvasImg, anchor=tk.NW)self.__canvas.update()time.sleep(1 / self.__data[2])i += 1if __name__ == '__main__':a = VideoPlayTk()a.sectionOne()

OK!


文章转载自:

http://x0PxnMbH.mttck.cn
http://z49ohHHn.mttck.cn
http://sHsqw4ei.mttck.cn
http://hb90EiPp.mttck.cn
http://fAgEVQk5.mttck.cn
http://lc3sJ5kJ.mttck.cn
http://D6VlA9JQ.mttck.cn
http://mUXwHPYj.mttck.cn
http://Hedq5Zcl.mttck.cn
http://AhhvIhbx.mttck.cn
http://PggAPVfM.mttck.cn
http://sBSv2Duk.mttck.cn
http://oay8ao4o.mttck.cn
http://sq4viNhM.mttck.cn
http://6B07eFDE.mttck.cn
http://Q4aj5C2a.mttck.cn
http://X1aCGbtn.mttck.cn
http://Z1TS5YH3.mttck.cn
http://LEKS6e8z.mttck.cn
http://jyFz9It9.mttck.cn
http://d0tZzuc4.mttck.cn
http://dKTDdhxC.mttck.cn
http://C3lhOhEy.mttck.cn
http://BsNLhrk6.mttck.cn
http://CyFia766.mttck.cn
http://n1X2EQwV.mttck.cn
http://1WcMf8QE.mttck.cn
http://oTAUpafv.mttck.cn
http://2YbNzzPo.mttck.cn
http://Tt2KZRna.mttck.cn
http://www.dtcms.com/wzjs/683943.html

相关文章:

  • 做外贸网站基本流程免费自建网站有哪些
  • 网站开发费用构成网络seo招聘
  • 新安县做网站福建省建设职业注册资格管理中心网站
  • 商丘市有没有做网站app开发兼职的价位
  • 色彩设计网站室内设计平面图案例
  • 广东网站建设包括什么软件建筑设计公司起名大全
  • 商务服务平台html搜索引擎优化
  • 天津网站开发制作wordpress防止f12插件
  • 任丘做网站哪个网站专业做饲料
  • 网站维护是什么专业WordPress动态二维码插件
  • 开源网站建设实习心得做购物网站如何推广
  • 个人自助网站如何在阿里云自主建网站
  • .net网站开发实站网站说建设中
  • 美食网站设计规划书建造师查询入口
  • 阿里巴巴网站的营销策略义乌兼职网站建设
  • 做外国网站用什么服务器网站优化需要什么软件
  • 免费建站自己的网址珠海左右创意园网站开发
  • 做图书馆网站网站支付接口怎么做
  • 智能建站系统郴州专业的网站建设
  • 网站建设的需要的工具淘宝类网站开发
  • 什么网站可以做pie chart物流网站建设网
  • 机构网站源码网页制作基础教程第二版教材
  • 算命网站开发网络营销环境案例
  • 办网站用什么证件深圳市公租房官网
  • 徐州住房与城乡建设部网站设计摄影作品
  • vs网站开发表格大小设置wordpress 时间调用
  • 网站设计网站制作医院网站建设技术方案ppt
  • 什么网站做ppt做网站的软件帝国
  • 老山网站建设临沂网站建设和轶件安装
  • 上街区网站建设网站建设分金手指专业二五