Я пытаюсь написать простой скрипт, который поможет мне запустить и остановить воспроизведение видео на нескольких Raspberry Pi с помощью mqtt.
Это первый раз, когда я пытаюсь запустить и остановить подпроцесс из сценарий python и у меня возникают проблемы с пониманием правильного порядка операций
есть мой код
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()
Я могу успешно запустить видео, но не могу его остановить. Я почти уверен, что это связано с тем, что объект p
уничтожается в конце обратного вызова on_message
, но я не вижу, где я могу создать свой процесс в другом месте.
Edit
это наивный подход с использованием глобального ключевого слова
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()
, но я могу воспроизвести видео только один раз, и вызов terminate
не останавливает воспроизведение
Редактировать 2
Теперь я объявляю p
глобальным, как это было предложено, но я не могу понять, как начать воспроизведение имени файла, которое я получаю из подписки MQTT
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()