Random

This is a replacement for the standard script, that will index all JPG files and then play them back in random order. After all files have been played back, the indexing is done again, and a new random playback round begins. Find the code on GitHub/JuliusCode/mp4museum

Overview

This script is designed to run on a Raspberry Pi and utilizes the VLC media player to display images (JPEG files) from a specific directory. It also listens for button presses on GPIO pins to control playback (pause and next). The script includes functionality for synchronization with other players if specific files are present.

Imports

import time, vlc, os, glob
import RPi.GPIO as GPIO
import subprocess
import random
  • time: Used for sleep functions and timing.
  • vlc: The VLC Python bindings to control media playback.
  • os: Provides functions to interact with the operating system (like file paths).
  • glob: Used for file pattern matching.
  • RPi.GPIO: A library to control GPIO pins on the Raspberry Pi.
  • subprocess: Allows running shell commands from Python.
  • random: Used to shuffle the list of image files.

Audio Device Configuration

audiodevice = "0"

if os.path.isfile('/boot/alsa.txt'):
    f = open('/boot/alsa.txt', 'r')
    audiodevice = f.read(1)
  • This section checks for a configuration file (/boot/alsa.txt) to determine which audio device to use. If the file exists, it reads the first character to set the audiodevice.

GPIO Setup

GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
  • Sets up the GPIO pins using the BOARD numbering scheme.
  • Pins 11 and 13 are configured as input pins with pull-down resistors, meaning they will read low (0) when not pressed.

Button Event Handlers

def buttonPause(channel):
    inputfilter = 0
    for x in range(0,200):
        if GPIO.input(11):
            inputfilter += 1
        time.sleep(.001)
    if (inputfilter > 50):
        player.pause()

def buttonNext(channel):
    inputfilter = 0
    for x in range(0,200):
        if GPIO.input(13):
            inputfilter += 1
        time.sleep(.001)
    if (inputfilter > 50):
        player.stop()
  • These functions are called when the respective GPIO pins detect a rising edge (button press).
  • They implement a simple debounce mechanism to filter out noise or static discharges by counting the number of times the button is pressed within a short time frame.

VLC Playback Function

def vlc_play(source):
    if("loop." in source):
        vlc_instance = vlc.Instance('--input-repeat=999999999 -q -A alsa --alsa-audio-device hw:' + audiodevice)
    else:
        vlc_instance = vlc.Instance('-q -A alsa --alsa-audio-device hw:'+ audiodevice)

    global player
    player = vlc_instance.media_player_new()
    media = vlc_instance.media_new(source)
    player.set_media(media)
    player.play()
    time.sleep(1)
    current_state = player.get_state()
    while current_state == 3 or current_state == 4:
        time.sleep(.01)
        current_state = player.get_state()
    media.release()
    player.release()
  • This function initializes a VLC media player instance and plays the specified media file.
  • If the media file name contains “loop.”, it sets the player to repeat the media indefinitely.
  • It waits for the media to start playing and releases resources afterward.

File Search Function

def search_file(file_name):
    file_path_media = f'/media/*/{file_name}'
    file_path_boot = f'/boot/{file_name}'
    matching_files = glob.glob(file_path_media) + glob.glob(file_path_boot)

    if matching_files:
        return matching_files[0]

    return False
  • Searches for a file in specified directories (/media/*/ and /boot/) and returns the first match found.

Player Initialization

vlc_play("/home/pi/mp4museum-boot.mp4")
vlc_play("/home/pi/mp4museum-boot.mp4")
vlc_play("/home/pi/mp4museum.mp4")
  • Plays a boot video twice to ensure the player is working, followed by a logo screen.

GPIO Event Detection

GPIO.add_event_detect(11, GPIO.RISING, callback=buttonPause, bouncetime=234)
GPIO.add_event_detect(13, GPIO.RISING, callback=buttonNext, bouncetime=1234)
  • This code sets up event detection on GPIO pins 11 and 13.
  • When a rising edge (button press) is detected on pin 11, the buttonPause function is called, and for pin 13, the buttonNext function is called.
  • The bouncetime parameter is used to prevent multiple detections from a single button press due to mechanical bouncing, ensuring that the button press is registered only once within the specified time.

Sync Mode Check

enableSync = search_file("sync-leader.txt")
syncFile = search_file("sync.mp4")
if syncFile and enableSync:
    print("Sync Mode LEADER:" + syncFile)
    subprocess.run(["omxplayer-sync", "-u", "-m", syncFile]) 

enableSync = search_file("sync-player.txt")
syncFile = search_file("sync.mp4")
if syncFile and enableSync:
    print("Sync Mode PLAYER:" + syncFile)
    subprocess.run(["omxplayer-sync", "-u", "-l", syncFile]) 
  • This section checks for the presence of specific files (sync-leader.txt and sync-player.txt) to determine if the player should enter sync mode.
  • If the sync-leader.txt file is found, it runs the omxplayer-sync command with the -m option, indicating it is the leader in a synchronized playback setup.
  • If sync-player.txt is found, it runs omxplayer-sync with the -l option, indicating it is a player in sync mode.
  • The subprocess.run function is used to execute these commands in the shell, allowing for synchronization with other media players.

Main Loop

while(1):
    jpg_files = glob.glob('/media/internal/*.jpg')
    random.shuffle(jpg_files)
    for file in jpg_files:
        vlc_play(file)
  • This is the main loop of the program, which runs indefinitely (while(1)).
  • It uses glob.glob to find all JPEG files in the specified directory (/media/internal/).
  • The list of JPEG files is shuffled randomly using random.shuffle(jpg_files), ensuring that the images are displayed in a different order each time the loop runs.
  • It then iterates through the shuffled list of image files and plays each file using the vlc_play function.

Summary

  • The code is designed to create a media player that can display images (JPEG files) from a specific directory on a Raspberry Pi.
  • It uses GPIO buttons to control playback (pause and next).
  • The main loop continuously checks for JPEG files in the specified directory and displays them in a random order.