added frame rate functionality

This commit is contained in:
tobiglaser 2021-11-20 18:30:28 +01:00
parent 05fdce5b3c
commit 5559276bfd

View file

@ -10,6 +10,7 @@ try:
except ImportError: except ImportError:
import tkinter as tk # for Python3 import tkinter as tk # for Python3
import threading import threading
from time import perf_counter, sleep
import imageio import imageio
from PIL import Image, ImageTk from PIL import Image, ImageTk
@ -28,15 +29,19 @@ class tkvideo():
:param size: :param size:
Changes the video's dimensions (2-tuple, Changes the video's dimensions (2-tuple,
default is 640x360) default is 640x360)
:param hz:
Sets the video's frame rate (float,
default 0 is unchecked)
""" """
def __init__(self, path, label, loop = 0, size = (640,360)): def __init__(self, path, label, loop = 0, size = (640,360), hz = 0):
self.path = path self.path = path
self.label = label self.label = label
self.loop = loop self.loop = loop
self.size = size self.size = size
self.hz = hz
def load(self, path, label, loop): def load(self, path, label, loop, hz):
""" """
Loads the video's frames recursively onto the selected label widget's image parameter. Loads the video's frames recursively onto the selected label widget's image parameter.
Loop parameter controls whether the function will run in an infinite loop Loop parameter controls whether the function will run in an infinite loop
@ -44,23 +49,44 @@ class tkvideo():
""" """
frame_data = imageio.get_reader(path) frame_data = imageio.get_reader(path)
if hz > 0:
frame_duration = float(1 / hz)
else:
frame_duration = float(0)
if loop == 1: if loop == 1:
while True: while True:
before = perf_counter()
for image in frame_data.iter_data(): for image in frame_data.iter_data():
frame_image = ImageTk.PhotoImage(Image.fromarray(image).resize(self.size)) frame_image = ImageTk.PhotoImage(Image.fromarray(image).resize(self.size))
label.config(image=frame_image) label.config(image=frame_image)
label.image = frame_image label.image = frame_image
diff = frame_duration + before
after = perf_counter()
diff = diff - after
if diff > 0:
sleep(diff)
before = perf_counter()
else: else:
before = perf_counter()
for image in frame_data.iter_data(): for image in frame_data.iter_data():
frame_image = ImageTk.PhotoImage(Image.fromarray(image).resize(self.size)) frame_image = ImageTk.PhotoImage(Image.fromarray(image).resize(self.size))
label.config(image=frame_image) label.config(image=frame_image)
label.image = frame_image label.image = frame_image
diff = frame_duration + before
after = perf_counter()
diff = diff - after
if diff > 0:
sleep(diff)
before = perf_counter()
def play(self): def play(self):
""" """
Creates and starts a thread as a daemon that plays the video by rapidly going through Creates and starts a thread as a daemon that plays the video by rapidly going through
the video's frames. the video's frames.
""" """
thread = threading.Thread(target=self.load, args=(self.path, self.label, self.loop)) thread = threading.Thread(target=self.load, args=(self.path, self.label, self.loop, self.hz))
thread.daemon = 1 thread.daemon = 1
thread.start() thread.start()