2014-07-19 24 views
0

我是新來的新Python編程和編程知識。 我正在設計一個代碼,它接收GTalk上的即時消息,並根據收到的消息運行一個子進程(OMXPlayer上的mp4或mp3文件)。目前我可以運行子進程,但是我無法暫停/停止mp3/mp4文件(子進程)。任何建議?Python,根據收到的消息暫停一個子進程

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 
+1

你是否在'message_handlers'範圍之外的其他地方定義了p? – Skurmedel

+2

有關Skurmedel的更多細節。每次調用'message_handler'時都會重新定義「p」。您希望將'subprocess.Popen'保存在具有更多永久性作用域的地方,以便暫停消息可以找到適當的子進程。請注意存在多個子流程(一次播放多個視頻)的可能性,因此您需要一些方法來跟蹤它。 – mpez0

回答

1

對此有兩個問題。首先,變量「p」在if塊內部定義,因此在特定塊之外不可用。第二,你並沒有實際上暫停這個過程,而是告訴它終止。你可能想要做的是爲你的omxplayer進程創建一個命名管道,並通過它向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 

注意,這是不完整的代碼,它只不過是一個正確的方向指針。

+0

*「首先,你的變量」p「是在if塊內部定義的,因此在特定塊之外是不可用的。」*這實際上並不是Python中的情況。在Python中,變量總是綁定到最內層的函數或模塊。因此,在'if'塊中定義的變量在'if'塊出現的函數內部的任何位置。請參見[here](http://stackoverflow.com/q/2829528/2073595) – dano

+1

'// //'不是如何向python代碼添加註釋,可能值得在OP更加困惑之前指出。 –

+1

另外,寫入的'Popen'命令將不起作用,因爲它使用shell重定向('<'),並將整個命令作爲字符串傳遞,但不使用'shell = True'。您還應該使用'stdin = subprocess.PIPE'關鍵字參數通過'Popen'將數據提供給進程stdin,而不是命名管道。 – dano

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指出的那樣,您的代碼可能不會正確暫停,您需要找到其他方法。但至少應該回答你的一個問題。

+2

使用'global'很少去 –

+0

它說「TypeError:message_handler()只需要3個參數(給出2)」 – Newbie

+0

@ user3828628是的,我在最後添加了另一個參數,因爲您要傳入子進程對象'p'。 – TheSoundDefense