This little snippet was generated using ChatGPT with more than a little bit of prompting from yours truly. Its purpose was to play a video on full-screen & looping modes. Ubuntu  was chosen because it was a free open source operating system, along with Python and associated libraries.

A practical usage of this is to automate wall-screen reception desk displays or kiosks, saving the user(s) from having to click on the play button or checking if there are errors in the video playing process. It’s a ‘set and forget it’ type of deal.

The setup:

1. Install Ubuntu Desktop

2. Run the commands in Bash Shell
sudo apt install python3-pip python3-tk python3-dev vdpau-driver-all python3-pyaudio xdotool libx11-dev libxkbcommon-x11-0 gnome-screenshot
pip install psutil pyautogui pyaudio python-xlib opencv-python mss
export DISPLAY=:0

3. Place the script on the user’s desktop

4. Create a SystemD service (you can do this without instructions. I believe in you)

5. Create a desktop shortcut
nano ~/Desktop/stop-playvideo.desktop
# add this content
[Desktop Entry]
Version=1.0
Name=Stop PlayVideo Service
Comment=Stop the playvideo.service using systemctl
Exec=gnome-terminal — bash -c “sudo systemctl stop playvideo.service; exec bash”
Icon=system-shutdown
Terminal=true
Type=Application

6. Allow scripts launching [on Ubuntu systems]
chmod a+x ~/Desktop/stop-playvideo.desktop
gio set ~/Desktop/stop-playvideo.desktop metadata::trusted true

# Note: there were many iteration of this script with other methods
# of determining whether video stream was playing and without errors (e.g. paused, frozen, out-of-memory, minimized). I've found that the only reliable method of detection is ImageGrab. Other methods (from PIL, autopygui.locateOnScreen, numpy, mss, etc) have deemed unreliable at the time of script generation. Although short, this script has taken much more efforts with prompting that meets the eyes.

import psutil
import subprocess
import time
import signal
import sys
import pyautogui  # Import PyAutoGUI for simulating mouse clicks
from PIL import ImageGrab, ImageChops

# Configure these variables
videoPath = "/home/kimconnect/Desktop/TESTVIDEO.mp4"
check_interval = 1  # Check VLC status every minute
play_interval = 1  # Click play button every minute(s) (adjust as needed)

# Global variable to hold the VLC process
vlc_process = None

def kill_all_vlc():
    """Kill all running instances of VLC."""
    for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
        if proc.info['name'] == 'vlc':
            proc.kill()
            print(f"Killed VLC process with PID {proc.pid}")

def start_vlc_fullscreen():
    """Start VLC in fullscreen mode."""
    global vlc_process
    try:
        vlc_process = subprocess.Popen(["vlc", "--fullscreen", "--x11-display", ":0", "--loop","--repeat", videoPath], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        print("Started VLC in fullscreen mode with looping.")
    except Exception as e:
        print(f"Error starting VLC: {e}")

def is_vlc_running():
    """Check if VLC process is running."""
    for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
        if proc.info['name'] == 'vlc':
            return True
    return False

def is_vlc_playing():
    def take_screenshot():
        # Capture screenshot of the entire screen (screen 0)
        screenshot = ImageGrab.grab()
        return screenshot

    def images_are_different(img1, img2):
        # Compare two images pixel by pixel
        diff = ImageChops.difference(img1, img2)
        # Check if there are any differences
        return diff.getbbox() is not None

    try:
        max_attempts=20
        for i in range(max_attempts):
            # Take initial screenshot
            baseline_screenshot = take_screenshot()
            print("Took baseline screenshot.")

            # Wait for 5 seconds
            time.sleep(2)

            # Take second screenshot
            after_screenshot = take_screenshot()
            print("Took differential screenshot number"+ str(i+1))

            # Compare images
            if images_are_different(baseline_screenshot, after_screenshot):
                print("Screenshots are different. Good.")
                return True
            elif i<max_attempts:
                print("Screenshots are identical on attempt number "+str(i+1))
            else:
                return False
            del baseline_screenshot
            del after_screenshot

    except KeyboardInterrupt:
        print("\nProcess interrupted.")
        return False

def restart_vlc():
    """Restart VLC and resume playing the video."""
    kill_all_vlc()
    start_vlc_fullscreen()

def click_fullscreen_button():
    try:
        pyautogui.press('f')
        print("Pressed the spacebar to play/pause VLC.")
    except Exception as e:
        print(f"Error pressing the spacebar: {e}")

def cleanup():
    """Cleanup function to terminate VLC if script is terminated."""
    global vlc_process
    if vlc_process:
        vlc_process.terminate()
        vlc_process.wait()
        print("Terminated VLC.")
    sys.exit(0)

# Register signal handlers
signal.signal(signal.SIGINT, lambda signum, frame: cleanup())
signal.signal(signal.SIGTERM, lambda signum, frame: cleanup())

if __name__ == "__main__":
    try:
        # Kill all running instances of VLC before starting
        kill_all_vlc()

        # Start VLC in fullscreen mode initially with looping
        start_vlc_fullscreen()

        #button_timer = time.time()

        while True:
            time.sleep(check_interval)
            if not is_vlc_running():
                print("VLC is not running. Restarting...")
                start_vlc_fullscreen()
            elif not is_vlc_playing():
                print("VLC is not playing. Restarting...")
                restart_vlc()

    except KeyboardInterrupt:
        print ("keyboard interruption detected")
        if not is_vlc_running():
            cleanup()