Python,根据接收到的消息暂停子进程

0 投票
2 回答
1060 浏览
提问于 2025-04-18 13:55

我刚来这里,对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

请注意,这段代码并不完整,它只是给你指明了一个方向。

撰写回答