diff --git a/p24.py b/p24.py index 64e7623..d3dab2f 100644 --- a/p24.py +++ b/p24.py @@ -3,6 +3,7 @@ import os import time import mpv import random # Import random module to handle random video selection +import subprocess # Set up GPIO pins for Buttons and LEDs GPIO.setmode(GPIO.BCM) @@ -84,7 +85,8 @@ video_paths = { 46: {"video": "0499-END.mp4", "leds": [], "buttons": [], "next_videos": [], "duration": 150}, } -# Initialize mpv player with fullscreen mode + +# Initialize mpv player player = mpv.MPV(ytdl=True, keep_open=True, fullscreen=True) # Function to play a video using mpv @@ -93,151 +95,174 @@ def play_video(video_name, loop=False): if os.path.exists(video_path): print(f"Now playing {video_name}") player.play(video_path) + player.loop = loop - # Loop the video indefinitely if required - if loop: - player.loop = True # Set loop to True for looping video - else: - player.loop = False # Disable looping for non-looping videos + time.sleep(0.5) # Small delay to ensure the video is properly loaded - # Wait until the video finishes playing while not player.idle: - time.sleep(0.1) # Wait until the video finishes playing + time.sleep(0.1) else: print(f"Video {video_name} not found.") # Function to activate buttons and LEDs for the next video def activate_next_buttons_and_leds(buttons_to_enable, leds_to_enable): - # Reset all buttons and LEDs before enabling new ones for button in buttons: - GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # Disable buttons (pull-down to avoid false presses) + GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) for led in leds: - GPIO.output(led, GPIO.LOW) # Turn off all LEDs + GPIO.output(led, GPIO.LOW) - # Enable the next buttons and LEDs for button in buttons_to_enable: - GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Enable next choices (pull-up to detect presses) + GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP) for led in leds_to_enable: - GPIO.output(led, GPIO.HIGH) # Turn on LEDs + GPIO.output(led, GPIO.HIGH) -# Function to handle the chain of videos -def handle_video_chain(video_id): - # Get the current video details from the dictionary - video_info = video_paths.get(video_id) - - if not video_info: - print(f"Error: Video with ID {video_id} not found.") +# Function to activate buttons and LEDs before the video ends +def activate_before_video_ends(video_info): + video_duration = video_info["duration"] + if video_info["video"] == "0000-Herensugea.mp4": return - print(f"Playing video: {video_info['video']}") - if video_id == 1: # Special case for video 0000-Herensugea.mp4 to loop - play_video(video_info["video"], loop=True) # Loop video 0000-Herensugea.mp4 - else: - play_video(video_info["video"], loop=False) # Play without looping for other videos - activate_before_video_ends(video_info) - wait_for_button_press(video_info) + time_to_activate = video_duration - 120 + print(f"Activating buttons/LEDs at {time_to_activate} seconds.") + time.sleep(time_to_activate) + activate_next_buttons_and_leds(video_info["buttons"], video_info["leds"]) + + +# Function to wait for button press and transition to next video +no_press_count = 0 -# Function to wait for a button press and transition to the next video +# Function to handle the video chain def wait_for_button_press(video_info): + service_name = "sorgin" + global no_press_count last_button_press = None - no_press_count = 0 # This will track how many consecutive times we've had no button press - - # Timeout period (2 minutes before the video ends) - timeout = 120 # 120 seconds for 2 minutes before the video ends + timeout = video_info["duration"] - 30 start_time = time.time() print(f"Waiting for button press from {video_info['buttons']}...") - while True: + # Check for button presses + pressed_button = None for button in video_info["buttons"]: - # Check if the button is pressed (GPIO input LOW means the button is pressed) - if GPIO.input(button) == GPIO.LOW: # Button pressed (low state due to pull-up) - if last_button_press != button: # Ensure the button press is not repeated continuously + if GPIO.input(button) == GPIO.LOW: # Button pressed + if last_button_press != button: last_button_press = button + pressed_button = button print(f"Button {button} pressed.") - time.sleep(0.3) # Debounce delay to ensure one press is detected - break - else: - # If no button pressed yet, check the timeout logic - if time.time() - start_time >= timeout: - no_press_count += 1 - print(f"No button pressed. Timeout count: {no_press_count}") - - # If we've had two consecutive timeouts, restart from Video 1 - if no_press_count >= 2: - print("Two consecutive timeouts detected. Restarting from Video 1.") - handle_video_chain(1) # Restart from Video 1 - return # Exit after restarting the system - - # Reset the timer for the next loop if there's only one timeout - start_time = time.time() - - if last_button_press: - break # Exit the loop once a button has been pressed - - time.sleep(0.1) # Check for button press every 0.1 seconds - - # If button was pressed successfully, reset no_press_count and proceed - no_press_count = 0 - - # Proceed with the next video from the selected button - if video_info["buttons"]: # Ensure there are buttons to reference - button_index = video_info["buttons"].index(last_button_press) - next_video_id = video_info["next_videos"][button_index] if button_index < len(video_info["next_videos"]) else None - if next_video_id: - handle_video_chain(next_video_id) - else: - print("End of video chain reached. Restarting from Video 1.") - handle_video_chain(1) # Restart from Video 1 if no next video - else: - print("No buttons associated with this video. Restarting from Video 1.") - handle_video_chain(1) # Restart from Video 1 - -# Function to activate buttons and LEDs 2 minutes before the video ends -def activate_before_video_ends(video_info): - video_duration = video_info["duration"] # Get the duration from the video_info dictionary - - # If it's the first video (0000-Herensugea.mp4), don't activate buttons until it's about to end - if video_info["video"] == "0000-Herensugea.mp4": - return # Don't activate buttons/LEDs for the first video - - # Wait for the 2 minutes before the video ends - time_to_activate = video_duration - 120 # Time to activate next buttons and LEDs (2 minutes before end) - print(f"Video duration: {video_duration} seconds. Activating next buttons and LEDs at {time_to_activate} seconds.") + no_press_count = 0 + time.sleep(0.5) # Debounce delay (0.5 seconds) + break # Exit loop after a button is pressed + + if pressed_button: + # Find the index of the pressed button in the video_info['buttons'] + button_index = video_info["buttons"].index(pressed_button) + + # Now select the next video based on this index + if button_index < len(video_info["next_videos"]): + next_video_id = video_info["next_videos"][button_index] # Use the index of the button press + handle_video_chain(next_video_id) # Play the correct next video + return + + # If no button was pressed, handle timeout + elapsed_time = time.time() - start_time + if elapsed_time >= timeout: + print(f"Timeout reached after {elapsed_time:.2f} seconds.") + no_press_count += 1 + if no_press_count >= 2: + print("Two consecutive timeouts. Restarting from Video 1.") + no_press_count = 0 + print(f"Restarting service: {service_name}") + subprocess.run(["sudo", "systemctl", "restart", service_name], check=True) + restart_service(service_name) + print(f"Service {service_name} restarted successfully.") + exit() + else: + # Handle transition to the next video after timeout + if video_info["next_videos"]: + next_video_id = random.choice(video_info["next_videos"]) # Randomly choose from next_videos + handle_video_chain(next_video_id) + else: + print("No next video available. Restarting from Video 1.") + print(f"Restarting service: {service_name}") + subprocess.run(["sudo", "systemctl", "restart", service_name], check=True) + restart_service(service_name) + print(f"Service {service_name} restarted successfully.") + exit() + + time.sleep(0.1) # Small delay to reduce CPU usage + +# Function to handle the video chain +def handle_video_chain(video_id): + video_info = video_paths.get(video_id) + if not video_info: + print(f"Error: Video with ID {video_id} not found.") + return - time.sleep(time_to_activate) # Wait until we're within 2 minutes of the video ending + print(f"Playing video: {video_info['video']}") + if video_id == 1: + play_video(video_info["video"], loop=True) + else: + play_video(video_info["video"], loop=False) + activate_before_video_ends(video_info) + wait_for_button_press(video_info) - # Once we're within 2 minutes of the video ending, activate buttons and LEDs - activate_next_buttons_and_leds(video_info["buttons"], video_info["leds"]) # Function to start looping Video 0000-Herensugea.mp4 def loop_video(): print("Starting Video 0000-Herensugea.mp4...") - GPIO.output(LED_PIN_1, GPIO.HIGH) # Turn on LED 1 - # Ensure all other LEDs are off - for led in [LED_PIN_2, LED_PIN_3, LED_PIN_4, LED_PIN_5]: + + # Initially turn off all LEDs + for led in leds: GPIO.output(led, GPIO.LOW) - # Set loop behavior and start playing video 0000-Herensugea.mp4 - play_video("0000-Herensugea.mp4", loop=True) # Loop the first video - handle_video_chain(1) # Start handling button presses after video 0000-Herensugea.mp4 + video_name = "0000-Herensugea.mp4" + video_path = os.path.join(video_folder, video_name) + + if not os.path.exists(video_path): + print(f"Error: {video_name} not found.") + return + + print(f"Looping video {video_name} until Button 1 is pressed.") + player.play(video_path) + player.loop = True # Enable infinite looping + + GPIO.output(LED_PIN_1, GPIO.HIGH) # Activate LED 1 + GPIO.setup(BUTTON_PIN_1, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Enable Button 1 + + print("Button 1 and LED 1 activated.") + + try: + while True: + # Monitor BUTTON_PIN_1 + if GPIO.input(BUTTON_PIN_1) == GPIO.LOW: # Button pressed + print("Button 1 pressed. Exiting loop...") + player.stop() # Stop the player + handle_video_chain(2) # Transition to the next video + return + time.sleep(0.1) # Small delay to reduce CPU usage + except Exception as e: + print(f"Error during looping: {e}") + finally: + player.stop() # Ensure the player stops when exiting + + +# Function to reset GPIO pins and states +def reset_gpio_pins(): + for button in buttons: + GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Reset buttons to input mode with pull-up + for led in leds: + GPIO.output(led, GPIO.LOW) # Turn off all LEDs # Main function to run the system def start_system(): try: - loop_video() # Start by looping Video 0000-Herensugea.mp4 + loop_video() # Start with the looping video except KeyboardInterrupt: print("Program interrupted, cleaning up GPIO.") GPIO.cleanup() - -# Start the video chain with the first video -#def start_system(): -# try: -# print("Starting video system...") -# handle_video_chain(1) # Start with the first video -# except KeyboardInterrupt: -# print("Program interrupted, cleaning up GPIO.") -# GPIO.cleanup() + except Exception as e: + print(f"Unexpected error: {e}") + GPIO.cleanup() if __name__ == "__main__": start_system()