Python,根据接收到的消息暂停子进程
我刚来这里,对Python编程还很陌生,编程知识也不多。
我正在设计一个代码,它可以接收GTalk上的即时消息(IM),然后根据收到的消息来运行一个子进程(在OMXPlayer上播放mp4或mp3文件)。现在我可以运行这个子进程,但我不知道怎么暂停或停止这些mp3/mp4文件(子进程)。有什么建议吗?
def message_handler(connect_object, message_node):
R = (message_node.getBody())
if R == "video" :
movie_path = '/home/pi/Desktop/media/video.mp4'
p = subprocess.Popen(['omxplayer',movie_path])
elif R == "music" :
movie_path = '/home/pi/Desktop/media/music.mp3'
p = subprocess.Popen(['omxplayer',movie_path])
elif R == "pause":
p.kill() # it gives me erroe "p is not defined"
os.kill(p.pid, signal.SIGSTOP) # doesn't do nothing
else:
pass
2 个回答
0
当你在一个函数里声明一个变量,比如 p
,这个变量只在这个函数的 命名空间 内存在。简单来说,命名空间就是在某个时刻可以访问的变量和函数的列表。你用 popen
创建了一个子进程对象,并把它绑定到函数 message_handler
里的 p
。所以,p
只在这个函数的命名空间里存在。一旦 message_handler
执行完毕,它的命名空间也就消失了,p
的绑定也随之消失。下次你再调用 message_handler
时,就无法访问到同一个对象了。
一个更好的做法是让你的函数接受这个对象并返回它:
def message_handler(connect_object, message_node, p):
R = (message_node.getBody())
if R == "video" :
movie_path = '/home/pi/Desktop/media/video.mp4'
p = subprocess.Popen(['omxplayer',movie_path])
elif R == "music" :
movie_path = '/home/pi/Desktop/media/music.mp3'
p = subprocess.Popen(['omxplayer',movie_path])
elif R == "pause":
p.kill() # it gives me erroe "p is not defined"
os.kill(p.pid, signal.SIGSTOP) # doesn't do nothing
else:
pass
return p
这样做的话,p
就是在函数外部定义的,存在于你调用函数的地方的命名空间里。
现在,正如 Kenneth Aalberg 提到的,你的代码可能不会正确暂停,你需要找其他方法。但至少这可以解答你其中一个问题。
1
关于这个问题,有两个方面需要注意。首先,你的变量“p”是在if语句块里面定义的,所以在这个语句块外面是无法使用的。其次,你并不是在暂停这个过程,而是在告诉它结束。你可能想要做的是创建一个命名管道,把指令通过这个管道发送给omxplayer。不过,这个方法相对来说要复杂一些。(或者说,随着研究的深入,它可能并没有那么复杂)
p = None #This initializes the variables globally.
def message_handler(connect_object, message_node):
R = (message_node.getBody())
if R== "video" :
movie_path= '/home/pi/Desktop/media/video.mp4'
p = subprocess.Popen(['omxplayer', movie_path],stdin=subprocess.PIPE)
elif R== "pause":
p.stdin.write('\x20') #Much cleaner alternative to named pipes...
else:
pass
请注意,这段代码并不完整,它只是给你指明了一个方向。