diff --git a/p31b_from30.py b/p31b_from30.py new file mode 100644 index 0000000..a8aa002 --- /dev/null +++ b/p31b_from30.py @@ -0,0 +1,239 @@ +import RPi.GPIO as GPIO +import os +import time +import mpv +import random # Import random module to handle random video selection + +# Set up GPIO pins for Buttons and LEDs +GPIO.setmode(GPIO.BCM) + +BUTTON_PIN_1 = 14 +BUTTON_PIN_2 = 15 +BUTTON_PIN_3 = 18 +BUTTON_PIN_4 = 23 +BUTTON_PIN_5 = 24 +BUTTON_PIN_6 = 25 +BUTTON_PIN_7 = 8 + +LED_PIN_1 = 2 +LED_PIN_2 = 3 +LED_PIN_3 = 4 +LED_PIN_4 = 17 +LED_PIN_5 = 27 +LED_PIN_6 = 22 +LED_PIN_7 = 10 + +buttons = [BUTTON_PIN_1, BUTTON_PIN_2, BUTTON_PIN_3, BUTTON_PIN_4, BUTTON_PIN_5, BUTTON_PIN_6, BUTTON_PIN_7] +leds = [LED_PIN_1, LED_PIN_2, LED_PIN_3, LED_PIN_4, LED_PIN_5, LED_PIN_6, LED_PIN_7] + +# Set up buttons and LEDs +for button in buttons: + GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Buttons connect to GND when pressed + +for led in leds: + GPIO.setup(led, GPIO.OUT) + +# Define the video and button actions (using custom video names here) +video_folder = "/home/ezn/sorgin" +video_paths = { + 1: {"video": "0000-Herensugea.mp4", "leds": [LED_PIN_1], "buttons": [BUTTON_PIN_1], "next_videos": [2], "duration": 92}, + 2: {"video": "0001-Herensugea.mp4", "leds": [LED_PIN_1], "buttons": [BUTTON_PIN_1], "next_videos": [3], "duration": 150}, + 3: {"video": "0003-Herensugea.mp4", "leds": [LED_PIN_2, LED_PIN_3, LED_PIN_4, LED_PIN_5], "buttons": [BUTTON_PIN_2, BUTTON_PIN_3, BUTTON_PIN_4, BUTTON_PIN_5], "next_videos": [4, 15, 27, 39], "duration": 150}, + 4: {"video": "0101-Tartalo.mp4", "leds": [LED_PIN_6, LED_PIN_4], "buttons": [BUTTON_PIN_6, BUTTON_PIN_4], "next_videos": [6, 26], "duration": 352}, + 5: {"video": "0102B-Xarma.mp4", "leds": [LED_PIN_5, LED_PIN_2], "buttons": [BUTTON_PIN_5, BUTTON_PIN_2], "next_videos": [41, 7], "duration": 150}, + 6: {"video": "0102-Xarma.mp4", "leds": [LED_PIN_2], "buttons": [BUTTON_PIN_2], "next_videos": [7], "duration": 150}, + 7: {"video": "0103-Xarma-Tartalo.mp4", "leds": [LED_PIN_5, LED_PIN_3], "buttons": [BUTTON_PIN_5, BUTTON_PIN_3], "next_videos": [8, 32], "duration": 150}, + 8: {"video": "0104-IpariSuri-Maider.mp4", "leds": [LED_PIN_3, LED_PIN_2], "buttons": [BUTTON_PIN_3, BUTTON_PIN_2], "next_videos": [44, 10], "duration": 150}, + 9: {"video": "0105E-EYES-IpariSuri.mp4", "leds": [LED_PIN_4, LED_PIN_7, LED_PIN_1], "buttons": [BUTTON_PIN_4, BUTTON_PIN_7, BUTTON_PIN_1], "next_videos": [19, 11, 10], "duration": 150}, + 10: {"video": "0105-IpariSuri-Maider-Xarma-Tartalo.mp4", "leds": [LED_PIN_1, LED_PIN_4, LED_PIN_7], "buttons": [BUTTON_PIN_1, BUTTON_PIN_4, BUTTON_PIN_7], "next_videos": [9, 19, 11], "duration": 150}, + 11: {"video": "0106-Mairu.mp4", "leds": [LED_PIN_4, LED_PIN_7], "buttons": [BUTTON_PIN_4, BUTTON_PIN_7], "next_videos": [12, 22], "duration": 150}, + 12: {"video": "0107-Mairu-Oxik.mp4", "leds": [LED_PIN_1], "buttons": [BUTTON_PIN_1], "next_videos": [13], "duration": 150}, + 13: {"video": "0199-END.mp4", "leds": [], "buttons": [], "next_videos": [], "duration": 150}, + 14: {"video": "0201B-Maider.mp4", "leds": [LED_PIN_5], "buttons": [BUTTON_PIN_5], "next_videos": [16], "duration": 150}, + 15: {"video": "0201-Maider.mp4", "leds": [LED_PIN_5], "buttons": [BUTTON_PIN_5], "next_videos": [16], "duration": 150}, + 16: {"video": "0202-MaiderIpariSuri.mp4", "leds": [LED_PIN_2, LED_PIN_7], "buttons": [BUTTON_PIN_2, BUTTON_PIN_7], "next_videos": [17, 28], "duration": 150}, + 17: {"video": "0203-Tartalo.mp4", "leds": [LED_PIN_5], "buttons": [BUTTON_PIN_5], "next_videos": [18], "duration": 150}, + 18: {"video": "0204-Tartalo-IpariSuri-Maider.mp4", "leds": [LED_PIN_6, LED_PIN_4], "buttons": [BUTTON_PIN_6, BUTTON_PIN_4], "next_videos": [10, 19], "duration": 150}, + 19: {"video": "0205-Oxik.mp4", "leds": [LED_PIN_2, LED_PIN_7], "buttons": [BUTTON_PIN_2, BUTTON_PIN_7], "next_videos": [20, 43], "duration": 150}, + 20: {"video": "0206-Oxik-Tartalo.mp4", "leds": [LED_PIN_7, LED_PIN_3], "buttons": [BUTTON_PIN_7, BUTTON_PIN_3], "next_videos": [21, 35], "duration": 150}, + 21: {"video": "0207-XarmaMairu.mp4", "leds": [LED_PIN_2], "buttons": [BUTTON_PIN_2], "next_videos": [22], "duration": 150}, + 22: {"video": "0208-ALL.mp4", "leds": [LED_PIN_2, LED_PIN_1], "buttons": [BUTTON_PIN_2, BUTTON_PIN_1], "next_videos": [25, 23], "duration": 150}, + 23: {"video": "0208E-EYES-Mairu.mp4", "leds": [LED_PIN_1], "buttons": [BUTTON_PIN_1], "next_videos": [24], "duration": 150}, + 24: {"video": "0208E-EYES-Xarma.mp4", "leds": [LED_PIN_2], "buttons": [BUTTON_PIN_2], "next_videos": [25], "duration": 150}, + 25: {"video": "0299-END.mp4", "leds": [], "buttons": [], "next_videos": [], "duration": 150}, + 26: {"video": "0301B-Oxik.mp4", "leds": [LED_PIN_6, LED_PIN_7], "buttons": [BUTTON_PIN_6, BUTTON_PIN_7], "next_videos": [5, 29], "duration": 150}, + 27: {"video": "0301-Oxik.mp4", "leds": [LED_PIN_7, LED_PIN_6], "buttons": [BUTTON_PIN_7, BUTTON_PIN_6], "next_videos": [30, 40], "duration": 150}, + 28: {"video": "0302B-Mairu.mp4", "leds": [LED_PIN_4], "buttons": [BUTTON_PIN_4], "next_videos": [31], "duration": 150}, + 29: {"video": "0302C-Mairu.mp4", "leds": [LED_PIN_2, LED_PIN_4], "buttons": [BUTTON_PIN_2, BUTTON_PIN_4], "next_videos": [43, 31], "duration": 150}, + 30: {"video": "0302-Mairu.mp4", "leds": [LED_PIN_4], "buttons": [BUTTON_PIN_4], "next_videos": [31], "duration": 150}, + 31: {"video": "0303-Oxik-Mairu.mp4", "leds": [LED_PIN_6, LED_PIN_2], "buttons": [BUTTON_PIN_6, BUTTON_PIN_2], "next_videos": [32, 43], "duration": 150}, + 32: {"video": "0304-Xarma-Tartalo-Maider.mp4", "leds": [LED_PIN_7, LED_PIN_3], "buttons": [BUTTON_PIN_7, BUTTON_PIN_3], "next_videos": [34, 44], "duration": 150}, + 33: {"video": "0305E-EYES-Tartalo.mp4", "leds": [LED_PIN_6, LED_PIN_5, LED_PIN_1], "buttons": [BUTTON_PIN_6, BUTTON_PIN_5, BUTTON_PIN_1], "next_videos": [21, 35, 33], "duration": 150}, + 34: {"video": "0305-Xarma-Tartalo-Maider-Mairu-Oxik.mp4", "leds": [LED_PIN_6, LED_PIN_5, LED_PIN_1], "buttons": [BUTTON_PIN_6, BUTTON_PIN_5, BUTTON_PIN_1], "next_videos": [21, 35, 33], "duration": 150}, + 35: {"video": "0306-IpariSuri.mp4", "leds": [LED_PIN_5, LED_PIN_3], "buttons": [BUTTON_PIN_5, BUTTON_PIN_3], "next_videos": [45, 36], "duration": 150}, + 36: {"video": "0307-ALL.mp4", "leds": [LED_PIN_3, LED_PIN_1], "buttons": [BUTTON_PIN_3, BUTTON_PIN_1], "next_videos": [38, 37], "duration": 150}, + 37: {"video": "0307E-EYES-Maider.mp4", "leds": [LED_PIN_3, LED_PIN_1], "buttons": [BUTTON_PIN_3, BUTTON_PIN_1], "next_videos": [38, 36], "duration": 150}, + 38: {"video": "0399-END.mp4", "leds": [], "buttons": [], "next_videos": [], "duration": 150}, + 39: {"video": "0401-IpariSuri.mp4", "leds": [LED_PIN_2, LED_PIN_6], "buttons": [BUTTON_PIN_2, BUTTON_PIN_6], "next_videos": [17, 40], "duration": 150}, + 40: {"video": "0402-Xarma.mp4", "leds": [LED_PIN_2, LED_PIN_5], "buttons": [BUTTON_PIN_2, BUTTON_PIN_5], "next_videos": [5, 41], "duration": 150}, + 41: {"video": "0403-Xarma-IpariSuri.mp4", "leds": [LED_PIN_7], "buttons": [BUTTON_PIN_7], "next_videos": [43], "duration": 150}, + 42: {"video": "0404E-EYES-Oxik.mp4", "leds": [LED_PIN_1, LED_PIN_2, LED_PIN_3, LED_PIN_4], "buttons": [BUTTON_PIN_1, BUTTON_PIN_2, BUTTON_PIN_3, BUTTON_PIN_4], "next_videos": [43, 11, 44, 20], "duration": 150}, + 43: {"video": "0404-Oxik-Tartalo-Mairu.mp4", "leds": [LED_PIN_1, LED_PIN_2, LED_PIN_3, LED_PIN_4], "buttons": [BUTTON_PIN_1, BUTTON_PIN_2, BUTTON_PIN_3, BUTTON_PIN_4], "next_videos": [42, 11, 44, 20], "duration": 150}, + 44: {"video": "0405-Maider.mp4", "leds": [LED_PIN_5, LED_PIN_3], "buttons": [BUTTON_PIN_5, BUTTON_PIN_3], "next_videos": [36, 45], "duration": 150}, + 45: {"video": "0406-MaiderIpariSuri.mp4", "leds": [LED_PIN_4], "buttons": [BUTTON_PIN_4], "next_videos": [46], "duration": 150}, + 46: {"video": "0499-END.mp4", "leds": [], "buttons": [], "next_videos": [], "duration": 150}, +} + + +# Initialize mpv player +player = mpv.MPV(ytdl=True, keep_open=True, fullscreen=True) + +# Function to play a video using mpv +def play_video(video_name, loop=False): + video_path = os.path.join(video_folder, video_name) + if os.path.exists(video_path): + print(f"Now playing {video_name}") + player.play(video_path) + player.loop = loop + + while not player.idle: + 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): + for button in buttons: + GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) + for led in leds: + GPIO.output(led, GPIO.LOW) + + for button in buttons_to_enable: + GPIO.setup(button, GPIO.IN, pull_up_down=GPIO.PUD_UP) + for led in leds_to_enable: + GPIO.output(led, GPIO.HIGH) + +# 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 + + 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 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 + + 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) + +# Function to wait for button press and transition to next video +no_press_count = 0 + +# Function to wait for button press and transition to next video +def wait_for_button_press(video_info): + global no_press_count + last_button_press = None + timeout = video_info["duration"] - 30 + start_time = time.time() + + print(f"Waiting for button press from {video_info['buttons']}...") + while True: + for button in video_info["buttons"]: + if GPIO.input(button) == GPIO.LOW: + if last_button_press != button: + last_button_press = button + print(f"Button {button} pressed.") + no_press_count = 0 + time.sleep(0.3) # Small delay to debounce the button press + break + else: + 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 + loop_video() # Restart from Video 1 + return # Exit the function after restarting the video + else: + # Handle transition to the next video after timeout + if video_info["next_videos"]: + next_video_id = video_info["next_videos"][0] + handle_video_chain(next_video_id) + else: + print("No next video available. Restarting from Video 1.") + loop_video() # Restart from Video 1 + return + + # Check for button press, if detected, exit the loop and handle transition + if last_button_press: + 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.") + loop_video() + break + + time.sleep(0.1) + +# Function to start looping Video 0000-Herensugea.mp4 +def loop_video(): + print("Starting Video 0000-Herensugea.mp4...") + GPIO.output(LED_PIN_1, GPIO.HIGH) + for led in [LED_PIN_2, LED_PIN_3, LED_PIN_4, LED_PIN_5]: + GPIO.output(led, GPIO.LOW) + + 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 + + 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 + +# Main function to run the system +def start_system(): + try: + loop_video() # Start with the looping 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()