IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 基于tkinter更新机制构建的视频播放GUI -> 正文阅读

[Python知识库]基于tkinter更新机制构建的视频播放GUI

声明,初始代码来自谷歌同行,本人在原先的代码添加了播放暂停的功能。

先上源码,再解析部分本人认为比较重要的点

import time
import tkinter
import cv2 as cv
import PIL.Image, PIL.ImageTk


class App:
    # 将类作为参数传入
    # app = App(tkinter.Tk(), "tkinter player", 'test.mp4')
    def __init__(self, window, window_title, video_source=''):
        self.photo = None
        self.window = window    # window = tkinter.Tk()
        self.window.title = window_title # tkinter.Tk().title() = window_title
        self.video_source = 0 if not video_source else video_source # 这里用if else not是为了避免,python传参的警告
        self.vid = myvideocapture(self.video_source)
        # Canvas in window, 1080*1080——> window_size >= canvas
        self.canvas = tkinter.Canvas(window, width=self.vid.width, height=self.vid.height, )    # 设置画布,窗口大小>=画布大小
        self.canvas.pack()  # pack()方法布局,还有place等方法替代

        # add  buttons
        self.btn_pause = tkinter.Button(window, text='pause', width=50, command=self.pause) # command对应button绑定的事件
        self.btn_pause.pack(anchor=tkinter.CENTER, fill=tkinter.Y, side=tkinter.RIGHT, expand=True)
        # self.btn_pause.pack(anchor=tkinter.CENTER, fill=tkinter.Y, expand=True)
        self.btn_play = tkinter.Button(window, text='play', width=50, command=self.play)
        self.btn_play.pack(anchor=tkinter.CENTER, fill=tkinter.Y, side=tkinter.LEFT, expand=True)
        # self.btn_play.pack(anchor=tkinter.CENTER, fill=tkinter.Y, expand=True)
        # flag control video player
        self.flag = 1
        self.delay = 15
        self.update()
        self.window.mainloop()

    def update(self):
        """

        :return:
        """
        ret, frame = self.vid.get_frame()
        if ret:
            self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame))
            self.canvas.create_image(0, 0, image=self.photo, anchor=tkinter.NW)
        # 设置暂停播放flag
        if self.flag:
            self.window.after(self.delay, self.update)

    def pause(self):
        """

        :return:
        """
        self.flag = 0

    def play(self):
        """

        :return:
        """
        self.flag = 1
        self.window.after(self.delay, self.update)


class myvideocapture:
    def __init__(self, vid_source=''):
        # 避免之前的,传参的问题
        self.vid = cv.VideoCapture(0) if not vid_source else cv.VideoCapture(vid_source)
        if not self.vid.isOpened():
            raise ValueError('unable to open video source!', vid_source)
        self.width = self.vid.get(cv.CAP_PROP_FRAME_WIDTH)
        self.height = self.vid.get(cv.CAP_PROP_FRAME_HEIGHT)

    def __del__(self):
        if self.vid.isOpened():
            self.vid.release()

    def get_frame(self):
        if self.vid.isOpened():
            ret, frame = self.vid.read()
            if ret:
                # opencv——BGR(blue-green-red)
                # PIL, matplotlib——(RGB)
                return (ret, cv.cvtColor(frame, cv.COLOR_BGR2RGB))
            else:
                return (ret, None)
        else:
            return None


if __name__ == '__main__':
    app = App(tkinter.Tk(), "tkinter player", 'test.mp4')

效果如下

在这里插入图片描述

重点内容解析

  1. 在app类的内置属性中,将tkinter.Tk()作为一个类传入参数,这是新手不太熟练的东西,但在python上做的比较久的同学会比较常用,重点在于一个万物皆对象的思想。
  2. 0 if not video_source else video_source,这里的三目运算,我们在利用pycharm开发时,因为python的自由度很高,可能会出现这样的情况,如图:在这里插入图片描述你看,即使初始默认参数为整形,传入了字符串,但是不会报错,依然可以运行,但是我本人认为这样是不合理的,而且这样确实会有警告,所以我将默认字符串设置为一个空字符串,利用一个三目运算来确保这里逻辑正确。在这里插入图片描述
  3. 在opencv读取视频时,色彩空间是BGR,但是PIL与matplotlib对改类数据的读取却采用的是RGB,色彩空间不同,如果直接转化,会出现很神奇的色彩差,大家可以自己试一试,当然很有意思,但是却违背了我们的需求。所以一定要经过色彩空间转换。
  4. 播放的核心在于tkinter的更新机制,在学习opencv后,我相信绝大多数同学播放视频都采用的是如下方法:在这里插入图片描述
    我想说的是,因为tkinter本身就是一个while true的循环机制,用opencv再调用一个无限循环,这种做法不合理。而且产生高延迟,完全可以利用tkinter的after更新机制,该方法可以理解为一个sleep,(对一个进程暂停若干时间到下一个进程),我们的方法就是,在获取一帧后暂停若干毫秒再获取下一帧。这样我们可以得到帧数为(1000/time)基本视频保持在27+帧就可以比较顺畅。
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:38:17  更:2022-04-26 11:41:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 15:17:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码