Reputation: 13
I'm trying to code a simple script that will help me to start and stop video playback on multiple Raspberry Pi using mqtt.
This is the first time I'm trying to start and stop subprocess from a python script and I'm having trouble understanding the correct order of operation
there is my code
import paho.mqtt.client as mqtt
import multiprocessing, time, signal
import os
def player(video):
print("Playing " + video)
os.system("omxplayer-sync " + video)
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe("player/#")
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
if msg.topic == "player/PLAY":
p = multiprocessing.Process(target=player, args=[str(msg.payload.decode())])
p.start()
if msg.topic == "player/STOP":
print("Stopping video")
print(p, p.is_alive())
print("Terminating video")
p.terminate()
print(p, p.is_alive())
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("localhost", 1883, 60)
client.loop_forever()
I can successfully start the video but I can't stop it.
I'm pretty sure this is due to the fact that the p
object is destroyed at the end of the on_message
callback but I don't see where I can create my Process elsewhere.
Edit
this is a naive approach using the global keyword
import paho.mqtt.client as mqtt
import multiprocessing, time, signal
import os
videoFile = ""
class GracefulExit:
kill_now = False
def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)
def exit_gracefully(self,signum, frame):
self.kill_now = True
def player():
global videoFile
print("Playing " + videoFile)
os.system("omxplayer-sync " + videoFile)
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe("player/#")
def on_message(client, userdata, msg):
global videoFile
print(msg.topic+" "+str(msg.payload))
if msg.topic == "player/PLAY":
videoFile = str(msg.payload.decode())
p.start()
if msg.topic == "player/STOP":
print("Stopping video")
print(p, p.is_alive())
print("Terminating video")
p.terminate()
print(p, p.is_alive())
def main():
app_killer = GracefulExit()
while not app_killer.kill_now:
try:
time.sleep(0.5)
except BaseException:
print("Encountered an exeption.")
break
print ("End of the program.")
if __name__ == '__main__':
print("Starting the program")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("localhost", 1883, 60)
client.loop_start()
p = multiprocessing.Process(target=player)
main()
but I can play the video just once and calling terminate
doesn't stop the playback
Edit 2
Now I'm declaring p
as a global as suggested, but I can't figure how to start playing a filename that I'm receiving from MQTT subscription
import paho.mqtt.client as mqtt
import multiprocessing, time, signal
import os
def player():
print("Playing " + "synctest.mp4")
os.system("omxplayer-sync " + "synctest.mp4")
p = multiprocessing.Process(target=player)
class GracefulExit:
kill_now = False
def __init__(self):
signal.signal(signal.SIGINT, self.exit_gracefully)
signal.signal(signal.SIGTERM, self.exit_gracefully)
def exit_gracefully(self,signum, frame):
self.kill_now = True
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
client.subscribe("player/#")
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
if msg.topic == "player/PLAY":
print("p.args= " + p.name)
videoFile = str(msg.payload.decode())
#how to put the videoFile into the args given to p ?
p.start()
if msg.topic == "player/STOP":
print("Stopping video")
print(p, p.is_alive())
print("Terminating video")
p.terminate()
print(p, p.is_alive())
def main():
app_killer = GracefulExit()
while not app_killer.kill_now:
try:
time.sleep(0.5)
except BaseException:
print("Encountered an exeption.")
break
print ("End of the program.")
if __name__ == '__main__':
print("Starting the program")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("localhost", 1883, 60)
client.loop_start()
main()
Upvotes: 0
Views: 575