Closed Peyof closed 1 year ago
Hi,
without knowing what your current approach is, there are two things i might help you with:
omxplayer would definitly need to be called via Popen, as the current way to run it will block your script from doing anything else. you need a pipe to send terminate or kill to the process. (import subprocess, signal)
the keyboard has its own library, maybe it needs to be installed via pip first
i might have time next week to check it out. could you tell me more about the context in which this would be used? i have thought of the sync mode of something that is started before the output is „public“, as it will take a minute or so for the sync to work properly- that is why the current implementation only works for one file at a time.
best, Julius
Hello Julius,
Thank you for your reply.
Here's what I've already tried to do using your script:
`# mp4museum v6 unified - july 2023
import time, vlc, os, glob import keyboard import RPi.GPIO as GPIO from subprocess import * import socket import signal import sys import errno
audiodevice = "0"
if os.path.isfile('/boot/alsa.txt'): f = open('/boot/alsa.txt', 'r') audiodevice = f.read(1)
GPIO.setmode(GPIO.BOARD) GPIO.setup(11, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
def buttonPause(channel): inputfilter = 0 for x in range(0,200): if GPIO.input(11): inputfilter = inputfilter + 1 time.sleep(.001) if (inputfilter > 50): player.pause()
def buttonNext(channel): inputfilter = 0 for x in range(0,200): if GPIO.input(13): inputfilter = inputfilter + 1 time.sleep(.001) if (inputfilter > 50): player.stop()
def vlc_play(source): if("loop." in source): vlc_instance = vlc.Instance('--input-repeat=999999999 -q -A alsa --alsa-audio-device hw:' + audiodevice) else: vlc_instance = vlc.Instance('-q -A alsa --alsa-audio-device hw:'+ audiodevice) global player player = vlc_instance.media_player_new() media = vlc_instance.media_new(source) player.set_media(media) player.play() time.sleep(1) current_state = player.get_state() while current_state == 3 or current_state == 4: time.sleep(.01) current_state = player.get_state() media.release() player.release()
def search_file(file_name):
file_path_media = f'/media/*/{file_name}'
file_path_boot = f'/boot/{file_name}'
matching_files = glob.glob(file_path_media) + glob.glob(file_path_boot)
if matching_files:
# Return the first found file name
return matching_files[0]
# Return False if the file is not found
return False
vlc_play("/home/pi/mp4museum-boot.mp4") vlc_play("/home/pi/mp4museum-boot.mp4")
vlc_play("/home/pi/mp4museum.mp4")
GPIO.add_event_detect(11, GPIO.RISING, callback = buttonPause, bouncetime = 234) GPIO.add_event_detect(13, GPIO.RISING, callback = buttonNext, bouncetime = 1234)
enableSync = search_file("sync-leader.txt") syncFile = search_file("sync.mp4") if syncFile and enableSync: print("Sync Mode LEADER:" + syncFile) p = Popen(["omxplayer-sync", "-u", "-m", syncFile])
enableSync = search_file("sync-player.txt") syncFile = search_file("sync.mp4") if syncFile and enableSync: print("Sync Mode PLAYER:" + syncFile) p = Popen(["omxplayer-sync", "-u", "-l", syncFile])
while True:
if keyboard.read_key() == "a":
p.terminate()
if keyboard.read_key() == "s":
p = Popen(["omxplayer-sync", "-u", "-m", syncFile])
p = Popen(["omxplayer-sync", "-u", "-l", syncFile])
while(1): for file in sorted(glob.glob(r'/media//.*')): vlc_play(file)`
For the purposes of an exhibition in Paris, I need to synchronize 4 raspberry pi players so that the videos are played and broadcast, each on their screen, one after the other. So far, no problem. The 4 videos will be of the same length, with video blacks to manage their proper sequencing.
But, using a fifth raspberry pi equipped with 5 buttons, I need to be able to interrupt the synchronized video playback to immediately start playing a video on the corresponding screen. The fifth button will restart synchronized playback. The whole system will be networked.
My idea was therefore to modify the script so as to be able to interrupt the omxplayer-sync subprocess and launch playback (via vlc) of the corresponding video (without the video blacks). I think I can manage communication between the fifth raspberry and the others (I've done this kind of thing before), but for the moment I can't manage to interrupt the omxplayer-sync subprocess, for lack of knowledge on the subject.
Thanks for your help Best, Pierre
hey,
i substituted the start of omxplayer with this:
process = subprocess.Popen(["omxplayer-sync", "-u", "-l", syncFile])
it worked, i have yet to stop it again ;)
best, Julius.
Thank you very much Julius, One more thing, how do you stop the subprocess? Because I think I made the same substitution as yours without succeeding in stopping the process. Best and many thanks
I'm sorry, I didn't quite understand what you said: "i have yet to stop it again ;)"
Hello Julius, Here's where I'm at:
# mp4museum v6 unified - july 2023
# (c) julius schmiedel - http://mp4museum.org
import time, vlc, os, glob
import RPi.GPIO as GPIO
import subprocess
from multiprocessing import active_children
import signal
import keyboard
import sys
# read audio device config
audiodevice = "0"
if os.path.isfile('/boot/alsa.txt'):
f = open('/boot/alsa.txt', 'r')
audiodevice = f.read(1)
# setup GPIO pin
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
# functions to be called by event listener
# with code to filter interference / static discharges
def buttonPause(channel):
inputfilter = 0
for x in range(0,200):
if GPIO.input(11):
inputfilter = inputfilter + 1
time.sleep(.001)
if (inputfilter > 50):
player.pause()
def buttonNext(channel):
inputfilter = 0
for x in range(0,200):
if GPIO.input(13):
inputfilter = inputfilter + 1
time.sleep(.001)
if (inputfilter > 50):
player.stop()
# play media with vlc
def vlc_play(source):
if("loop." in source):
vlc_instance = vlc.Instance('--input-repeat=999999999 -q -A alsa --alsa-audio-device hw:' + audiodevice)
else:
vlc_instance = vlc.Instance('-q -A alsa --alsa-audio-device hw:'+ audiodevice)
global player
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(source)
player.set_media(media)
player.play()
time.sleep(1)
current_state = player.get_state()
while current_state == 3 or current_state == 4:
time.sleep(.01)
current_state = player.get_state()
media.release()
player.release()
# find a file, and if found, return its path (for sync)
def search_file(file_name):
# Use glob to find files matching the pattern in both directories
file_path_media = f'/media/*/{file_name}'
file_path_boot = f'/boot/{file_name}'
matching_files = glob.glob(file_path_media) + glob.glob(file_path_boot)
if matching_files:
# Return the first found file name
return matching_files[0]
# Return False if the file is not found
return False
# *** run player ****
# start player twice to make sure it is working
# seems weird but works
vlc_play("/home/pi/mp4museum-boot.mp4")
vlc_play("/home/pi/mp4museum-boot.mp4")
# please do not remove my logo screen
vlc_play("/home/pi/mp4museum.mp4")
# add event listener which reacts to GPIO signal
GPIO.add_event_detect(11, GPIO.RISING, callback = buttonPause, bouncetime = 234)
GPIO.add_event_detect(13, GPIO.RISING, callback = buttonNext, bouncetime = 1234)
# check for sync mode instructions
enableSync = search_file("sync-leader.txt")
syncFile = search_file("sync.mp4")
if syncFile and enableSync:
print("Sync Mode LEADER:" + syncFile)
p = subprocess.Popen(["omxplayer-sync", "-u", "-m", syncFile])
pid = p.pid
active = active_children()
time.sleep(20)
os.kill(pid, signal.SIGKILL)
# os.killpg(os.getpgid(os.getpid()), signal.SIGTERM)
# for child in active:
# child.kill()
# while True:
# if keyboard.read_key() == "a":
# print("You Pressed Key a!")
# pid = p.pid
# os.kill(pid, signal.SIGKILL)
# time.sleep(5)
enableSync = search_file("sync-player.txt")
syncFile = search_file("sync.mp4")
if syncFile and enableSync:
print("Sync Mode PLAYER:" + syncFile)
subprocess.run(["omxplayer-sync", "-u", "-l", syncFile])
# the loop
while(1):
for file in sorted(glob.glob(r'/media/*/*.*')):
vlc_play(file)
I can get out of the "omxplayer-sync" subprocess (with os.kill()), and thus start the video playback by vlc, but the omxplayer playback remains active (you can hear the sound of the video played by omxplayer).
I can also interrupt omxplayer via ssh with :
sudo pkill -9 -f omxplayer-sync
sudo pkill -9 -f omxplayer
sudo pkill -9 -f omxplayer.bin
But I don't know how to integrate this into the python code.
Do you have an idea?
Best,
Hi Julius,
I finally found a solution that works to interrupt the omxplayer-sync and omxplayer processes:
os.kill(pid, signal.SIGKILL)
os.system("sudo pkill -9 -f omxplayer-sync")
os.system("sudo pkill -9 -f omxplayer")
os.system("sudo pkill -9 -f omxplayer.bin")
Here's my test code:
import time, vlc, os, glob
import RPi.GPIO as GPIO
import subprocess
import signal
import keyboard
import sys
enableSync = search_file("sync-leader.txt")
syncFile = search_file("sync.mp4")
while True:
if syncFile and enableSync:
print("Sync Mode LEADER:" + syncFile)
p = subprocess.Popen(["omxplayer-sync", "-u", "-m", syncFile])
pid = p.pid
time.sleep(5)
if keyboard.read_key() == "a":
print("You Pressed Key a!")
os.kill(pid, signal.SIGKILL)
os.system("sudo pkill -9 -f omxplayer-sync")
os.system("sudo pkill -9 -f omxplayer")
os.system("sudo pkill -9 -f omxplayer.bin")
pvlc = subprocess.Popen(["vlc", "/media/internal/2020_02-WIFI-Priere-Final.mp4"])
pidvlc = pvlc.pid
time.sleep(5)
if keyboard.read_key() == "s":
print("You Pressed Key s!")
os.kill(pidvlc, signal.SIGKILL)
p = subprocess.Popen(["omxplayer-sync", "-u", "-m", syncFile])
time.sleep(5)
Best and many thanks
thanks for your reply, i‘ll keep this for future reference
Hello,
For the purposes of a project, I would need to interrupt (via keyboard input for example) the omxplayer-sync subprocess. I tried different methods to stop the subprocess, but it doesn't work: https://www.pythonpool.com/python-subprocess-terminate/#FAQs
Could you put me on the right track?
THANKS,