Skip to main content

Python module for playing and recording videos with sound inside tkinter Label widget using Pillow, imageio, and PyAudio, including media playback control, slider, and fps aware buffering.

Project description

tkVideoUtils - Python module for playing videos and camera feeds in a Tkinter label, with recording functionality

Contributors Forks Stargazers Issues MIT License

About The Project

tkVideoUtils is a Python module for playing and recording videos in GUIs created with tkinter. Using imageio-ffmpeg, webcams can be indexed and streamed in a tkinter Label. They can also be recorded (in their original resolution) by calling the start_recording() function! This project was heavily inspired by huskeee's tkvideo library, check their project out!

Built With

Installation

End-users:

  • Clone the repo and run setup.py
git clone https://github.com/wsarce/tkVideoUtils.git
python ./tkvideo/setup.py

or

  • Install the package from PyPI
pip install tkVideoUtils

Developers and contributors

  • Clone the repo and install the module in developer mode
git clone https://github.com/wsarce/tkVideoUtils.git
python ./tkvideo/setup.py develop

or

  • Install the package from PyPI in editable mode
pip install -e tkvideoplayer

This will create a shim between your code and the module binaries that gets updated every time you change your code.

Usage

Playing a Video in a Label

from tkinter import *

from ttkwidgets import TickScale

from tkvideoutils import VideoPlayer
from tkinter import filedialog, messagebox


def on_closing():
    player.loading = False
    root.quit()
    root.destroy()


if __name__ == '__main__':
    # create instance of window
    root = Tk()
    # set window title
    root.title('Video Player')
    # load images
    pause_image = PhotoImage(file='pause.png')
    play_image = PhotoImage(file='play.png')
    skip_backward = PhotoImage(file='skip_backward.png')
    skip_forward = PhotoImage(file='skip_forward.png')
    # create user interface
    button = Button(root, image=play_image)
    forward_button = Button(root, image=skip_forward)
    backward_button = Button(root, image=skip_backward)
    video_label = Label(root)
    video_path = 'recorded_video.mp4'
    audio_path = 'recorded_video.wav'
    slider_var = IntVar(root)
    slider = TickScale(root, orient="horizontal", variable=slider_var)
    # place elements
    video_label.pack()
    button.pack()
    forward_button.pack()
    backward_button.pack()
    slider.pack()

    if video_path:
        # read video to display on label
        player = VideoPlayer(root, video_path, audio_path, video_label, size=(700, 500),
                             play_button=button, play_image=play_image, pause_image=pause_image,
                             slider=slider, slider_var=slider_var, keep_ratio=True, cleanup_audio=True)
    else:
        messagebox.showwarning("Select Video File", "Please retry and select a video file.")
        sys.exit(1)
    player.set_clip(50, 70)
    forward_button.config(command=player.skip_video_forward)
    backward_button.config(command=player.skip_video_backward)
    root.protocol("WM_DELETE_WINDOW", on_closing)
    root.mainloop()

Playing and Recording a Webcam in a Label

from tkinter import *
from tkvideoutils import VideoRecorder
from tkinter import messagebox


def merge_sources():
    if player.merge_sources(merged_path, ffmpeg_exe):
        print("Sources merged!")
    else:
        print("Something went wrong")


def stop_recording():
    player.stop_recording()
    player.stop_playback()
    button['command'] = merge_sources


def start_recording():
    player.start_recording()
    button['command'] = stop_recording


if __name__ == '__main__':
    # create instance of window
    root = Tk()
    # set window title
    root.title('Video Player')
    # load images
    pause_image = PhotoImage(file='pause.png')
    play_image = PhotoImage(file='play.png')
    # create user interface
    button = Button(root, image=play_image)
    video_label = Label(root)
    video_path = 'raw_video.mp4'
    audio_path = 'recorded_video.wav'
    merged_path = 'recorded_video.mp4'
    # place elements
    video_label.pack()
    button.pack()
    # Get existing video sources
    video_sources = VideoRecorder.get_video_sources()
    audio_sources = VideoRecorder.get_audio_sources()
    print(video_sources, audio_sources)
    # TODO: Fill out FFMPEG path
    ffmpeg_exe = r''

    if video_sources:
        if video_path:
            # read video to display on label
            player = VideoRecorder(video_source=video_sources[0], audio_source=audio_sources[1],
                                   video_path=video_path, audio_path=audio_path, fps=8, label=video_label,
                                   size=(700, 500))
            player.start_playback()
        else:
            messagebox.showwarning("Select Video File", "Please retry and select a video file.")
            sys.exit(1)
        button.config(command=start_recording)
        root.mainloop()
    else:
        print("No video sources found!")

Issues / Suggestions

Have a problem that needs to be solved or a suggestion to make? See the issues page.

Notes on Freezing

If you want to freeze your Python scripts that reference tkVideoUtils, there are some general notes to keep in mind:

  • Due to the use of ImageIO, the lazy import error causes frozen Python scripts to fail to start or fail to execute the imageio codepaths. This can make it look like imageio-ffmpeg is failing with a backend issue. To circumvent this, follow this answer. This answer says to overwrite your imageio folder in your exe output directory with the imageio folder from your virtual environment (venv\Lib\site-packages\imageio). I can verify that this works.
  • I prefer copying the ffmpeg exe version that is packaged with imageio-ffmpeg into your exe directory in a known folder and updating os.environ['IMAGEIO_FFMPEG_EXE'] with that directory. This ensures a known path.

License

Distributed under the MIT License. See LICENSE for more information.

Contact

Walker Arce - wsarcera@gmail.com Project Link: https://github.com/wsarce/tkVideoUtils

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tkVideoUtils-1.2.8.tar.gz (21.4 kB view details)

Uploaded Source

Built Distributions

tkVideoUtils-1.2.8-py3.8.egg (25.3 kB view details)

Uploaded Source

tkVideoUtils-1.2.8-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file tkVideoUtils-1.2.8.tar.gz.

File metadata

  • Download URL: tkVideoUtils-1.2.8.tar.gz
  • Upload date:
  • Size: 21.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.10

File hashes

Hashes for tkVideoUtils-1.2.8.tar.gz
Algorithm Hash digest
SHA256 9da4a9bc0285c5618fef5f59594352c7a2eb98aaad9c529c3c8d0d7ae9991396
MD5 c07f33339da0e6e28f5b71f62495e417
BLAKE2b-256 85b9b9b3fc34d317829ca80b85bb8f3744605d17abebb4ed5d98b1d3515103f0

See more details on using hashes here.

File details

Details for the file tkVideoUtils-1.2.8-py3.8.egg.

File metadata

  • Download URL: tkVideoUtils-1.2.8-py3.8.egg
  • Upload date:
  • Size: 25.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.10

File hashes

Hashes for tkVideoUtils-1.2.8-py3.8.egg
Algorithm Hash digest
SHA256 b1c4582516e48a831688052e9b34cc9a4d9cc6312a3d5608466d7885e48e7c7f
MD5 0c2cbfec28a46522c6233943125e3a6d
BLAKE2b-256 42b7b8705781d9674266b72a0353cbcf04e3ea8eac4613f98c6e03d7e3ec5caf

See more details on using hashes here.

File details

Details for the file tkVideoUtils-1.2.8-py3-none-any.whl.

File metadata

  • Download URL: tkVideoUtils-1.2.8-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.62.3 importlib-metadata/4.11.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.10

File hashes

Hashes for tkVideoUtils-1.2.8-py3-none-any.whl
Algorithm Hash digest
SHA256 33bc9b59cf2faa7171d6152b72f7ae9e0adc021e6432b794f94321e5fe27b996
MD5 ce8ba62458bdf40e708afff8caadeba7
BLAKE2b-256 7d69f3626451254406e947e213264fcfb30d662e3b124decab66c2b9635b684c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page