Why are my GPIO button inputs being doubled?
Hi all,
i'm using a raspberry pi zero to make an ambient media player. I have the videos preloaded, and using omxplayer (with omxwrapper to pick up gpio inputs when the video is playing) I have it set up to play videos with 2 gpio button inputs for next and previous video.
Things worth noting:
-due to the shape of the project (small TV) i can't use the aux input easily, so I'm using a 3.5mm AUX DAC adapter, connected to a USB hub. Im using a pam8302 for the amp
But for some reason, when I press either of the buttons, the input is being registered twice and it's skipping videos. it starts with episode 1, but 1 button input will send it straight to episode 3. I'm fairly new to electronics and coding, so I'm not 100% sure how to diagnose the problem and move forward from here. any help would be appreciated. Code is as follows:
import os
import glob
import time
import threading
import RPi.GPIO as GPIO
from omxplayer.player import OMXPlayer
from signal import pause
# --- SETTINGS ---
VIDEO_PATH = "/home/pi/mediaplayer_py"
BUTTON_NEXT = 17
BUTTON_PREV = 27
# Force audio to USB DAC explicitly
OMX_ARGS = ["--adev", "alsa:plughw:1,0"]
# --- SETUP ---
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_NEXT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUTTON_PREV, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Load playlist
playlist = sorted(glob.glob(os.path.join(VIDEO_PATH, "*.mp4")))
if not playlist:
raise FileNotFoundError("No videos found in " + VIDEO_PATH)
current_index = 0
player = None
manual_skip = False
def play_video(index):
global player, current_index, manual_skip
if player:
try:
manual_skip = True
player.quit()
except Exception as e:
print("Error quitting player:", e)
current_index = index % len(playlist)
print(f"Playing: {playlist[current_index]}")
time.sleep(0.5) # Let DAC init
player = OMXPlayer(
playlist[current_index],
args=OMX_ARGS,
dbus_name="org.mpris.MediaPlayer2.omxplayer1"
)
def on_exit(*args, **kwargs):
global manual_skip
if manual_skip:
manual_skip = False
else:
threading.Timer(0.1, lambda: next_video()).start()
player.exitEvent += on_exit
def next_video(*args, **kwargs):
play_video(current_index + 1)
def prev_video(*args, **kwargs):
play_video(current_index - 1)
# GPIO buttons
GPIO.add_event_detect(BUTTON_NEXT, GPIO.FALLING, callback=next_video, bouncetime=400)
GPIO.add_event_detect(BUTTON_PREV, GPIO.FALLING, callback=prev_video, bouncetime=400)
# Start playback
play_video(0)
try:
pause()
except KeyboardInterrupt:
if player:
player.quit()
GPIO.cleanup()
Posted Sep 2, 2025, 3:30 PM UTC