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