如何在Tkinter中播放视频。实例将通过使用 Frame 和 Label 小部件来实现视频渲染。
第一步,安装需要依赖库:
pip install imageio pillow tkvideo
第二步,导入依赖库
from tkinter import *
import imageio
from PIL import Image, ImageTk
第三步,解析视频流
下面将使用 Imageio 库来存储视频并获取其元数据及其帧。 然后使用 PIL 库将捕获为图像的帧添加到在 Frame() 小部件中定义的 Label() 小部件中。
def stream():
try:
image = video.get_next_data()
frame_image = Image.fromarray(image)
frame_image=ImageTk.PhotoImage(frame_image)
l1.config(image=frame_image)
l1.image = frame_image
l1.after(delay, lambda: stream())
except:
video.close()
return
上述函数将视频中的每一帧作为图像提取出来,然后将其存储在变量中,并将图像参数设置为标签。 stream() 函数被递归调用。 这是使用 .after()注册回调来完成的。在前面的文章中,对after函数和PhotoImage作了介绍,请参考:
Python编程实例-Tkinter GUI编程-异步编程-after()函数
Python编程实例-Tkinter GUI编程-PhotoImage
第四步,定义GUI
root = Tk()
root.title('Video in a Frame')
f1 = Frame()
l1 = Label(f1)
l1.pack()
f1.pack()
video_name = "test_video2.mp4" # 视频路径
video = imageio.get_reader(video_name)
delay = int(1000 / video.get_meta_data()['fps'])
stream()
root.mainloop()
代码工作流程如下:
将 Tk 窗口定义为根变量。
接下来,我们创建一个 Frame 和一个 Label ,以 frame 为父级,后面将使用后者将视频的每一帧显示为图像。
然后我们定义一个变量来存储视频的路径,并以前面的变量作为参数调用 imageio 库的 .get_reader() 方法来读取该视频。
接下来,我们通过 .get_meta_data()['fps'] 方法计算视频的 FPS,并对结果进行一些计算以确保准确性。
在下一步中,我们调用 stream() 函数来流式传输视频。
以 root.mainloop() 结束程序,以在窗口运行时保持进程递归运行。
第五步,完整代码
from tkinter import *
import imageio
from PIL import Image, ImageTk
def stream():
try:
image = video.get_next_data()
frame_image = Image.fromarray(image)
frame_image = ImageTk.PhotoImage(frame_image)
l1.config(image=frame_image)
l1.image = frame_image
l1.after(delay, lambda: stream())
except:
video.close()
return
root = Tk()
root.title('Video in a Frame')
f1 = Frame()
l1 = Label(f1)
l1.pack()
f1.pack()
video_name = "D:/Develop/machine-vision-workbench/resources/videos/test_video2.mp4" # Image-path
video = imageio.get_reader(video_name)
delay = int(1000 / video.get_meta_data()['fps'])
stream()
root.mainloop()