如何在 tkinter 中显示视频预览 window

How to display video preview in tkinter window

我遇到了如何在 tkinter window 中显示视频预览 window 的问题。下面的代码将播放视频,但我想在 tkinter window..

中显示该视频

Python代码:

from moviepy.editor import *
from moviepy.video.fx.resize import resize  
import pygame   

pygame.display.set_caption('Kumawat!')   
clip=VideoFileClip('mk.mp4')    
w=1300    
h=700    
display=(w,h)       
clip.resize(display).preview()    
pygame.quit()    

经过一些研究,您似乎无法轻松地将剪辑嵌入到 tkinter 框架中。我想到的解决方案是:

  • 使用imageio下载视频
  • 使用迭代器将每个视频帧提取到图像中
  • 将图像转换为 ImageTk
  • 将此图像添加到 tkinter 标签

在下面的示例中,我添加了两个控制按钮来启动和停止视频以及一个等待循环 运行 假设每秒 24 帧的实时视频。我没有研究如何包含声音。

import time
import tkinter as tk
import imageio
from PIL import Image, ImageTk

global pause_video

# download video at: http://www.html5videoplayer.net/videos/toystory.mp4
video_name = "toystory.mp4"
video = imageio.get_reader(video_name)


def video_frame_generator():
    def current_time():
        return time.time()

    start_time = current_time()
    _time = 0
    for frame, image in enumerate(video.iter_data()):

        # turn video array into an image and reduce the size
        image = Image.fromarray(image)
        image.thumbnail((750, 750), Image.ANTIALIAS)

        # make image in a tk Image and put in the label
        image = ImageTk.PhotoImage(image)

        # introduce a wait loop so movie is real time -- asuming frame rate is 24 fps
        # if there is no wait check if time needs to be reset in the event the video was paused
        _time += 1 / 24
        run_time = current_time() - start_time
        while run_time < _time:
            run_time = current_time() - start_time
        else:
            if run_time - _time > 0.1:
                start_time = current_time()
                _time = 0

        yield frame, image


def _stop():
    global pause_video
    pause_video = True


def _start():
    global pause_video
    pause_video = False


if __name__ == "__main__":

    root = tk.Tk()
    root.title('Video in tkinter')

    my_label = tk.Label(root)
    my_label.pack()
    tk.Button(root, text='start', command=_start).pack(side=tk.LEFT)
    tk.Button(root, text='stop', command=_stop).pack(side=tk.LEFT)

    pause_video = False
    movie_frame = video_frame_generator()

    while True:
        if not pause_video:
            frame_number, frame = next(movie_frame)
            my_label.config(image=frame)

        root.update()

    root.mainloop()