Why are my GPIO button inputs being doubled?

Project Advice

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

1115
Loading comments…