Merge pull request #8 from tobiglaser/master

Added frame rate functionality
This commit is contained in:
Xenofon Konitsas 2021-12-06 12:55:51 +02:00 committed by GitHub
commit 7ea6525d2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

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()