parent
7e36541c07
commit
b14f412cda
@ -0,0 +1,259 @@
|
|||||||
|
import RPi.GPIO as GPIO
|
||||||
|
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)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
time.sleep(0.5) # Small delay to ensure the video is properly loaded
|
||||||
|
|
||||||
|
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 wait for button press and transition to next video
|
||||||
|
no_press_count = 0
|
||||||
|
|
||||||
|
# Function to handle the video chain
|
||||||
|
def wait_for_button_press(video_info):
|
||||||
|
service_name = "sorgin"
|
||||||
|
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.5) # Debounce delay (0.5 seconds)
|
||||||
|
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
|
||||||
|
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 = 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
|
||||||
|
print(f"Restarting service: {service_name}")
|
||||||
|
subprocess.run(["sudo", "systemctl", "restart", service_name], c>
|
||||||
|
restart_service(service_name)
|
||||||
|
print(f"Service {service_name} restarted successfully.")
|
||||||
|
exit()
|
||||||
|
return
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# 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 start looping Video 0000-Herensugea.mp4
|
||||||
|
def loop_video():
|
||||||
|
print("Starting Video 0000-Herensugea.mp4...")
|
||||||
|
|
||||||
|
# Initially turn off all LEDs
|
||||||
|
for led in leds:
|
||||||
|
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
|
||||||
|
|
||||||
|
# Wait for 3 seconds before enabling the button and LED
|
||||||
|
time.sleep(3)
|
||||||
|
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 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()
|
||||||
Loading…
Reference in new issue