0

我只想在我的树莓派上构建一个小的 python 音乐客户端。我安装了“mpg321”,效果很好,但现在是我的问题。发送命令后

os.system("mpg321 -R testPlayer")

python 等待用户输入,如播放、暂停或退出。如果我在我的终端上写这个,播放器会暂停音乐或退出。完美,但我希望 python 这样做,所以我发送命令

os.system("LOAD test.mp3")

其中 LOAD 是加载此 mp3 的命令。但什么也没有发生。当我通过终端退出播放器时,出现错误:

sh: 1: LOAD: not found

我认为这意味着

os.system("mpg321 -R testPlayer")

完成整个过程,在我退出后,python 尝试执行命令 LOAD。那么我如何让这些东西一起工作呢?

我的代码:

import os

class PyMusic:
    def __init__(self):
        print "initial stuff later"

    def playFile(self, fileName, directory = ""):
        os.system("mpg321 -R testPlayer")
        os.system("LOAD test.mp3")


if __name__ == "__main__":
    pymusic = PyMusic()
    pymusic.playFile("test.mp3")

谢谢你的帮助!

4

2 回答 2

5

首先,您几乎不应该使用os.system. 请参阅子流程模块。

使用的一个主要优点subprocess是你可以选择你想要的任何行为——在后台运行它,启动它并等待它完成(如果它返回非零则抛出异常),与它交互stdinstdout显式地进行交互,无论做什么感觉。

在这里,您不是尝试运行另一个命令"LOAD test.mp3",而是尝试将其作为输入传递给现有进程。所以:

p = subprocess.Popen(['mpg321', '-R', 'testPlayer'], stdin=PIPE)

然后你可以这样做:

p.stdin.write('LOAD test.mp3\n')

这大致相当于从 shell 执行此操作:

echo -e 'LOAD test.mp3\n' | mpg321 -R testPlayer

但是,您可能应该阅读有关通信的内容,因为只要有可能弄清楚如何使您的代码工作communicate,它就比尝试处理通用 I/O 简单得多(特别是如果您从未使用管道、套接字、等等)。

或者,如果您尝试与命令行 UI 交互(例如,在得到正确提示之前您不能发送命令),您可能希望查看“expect”库。其中有一些可供选择,因此您应该在 PyPI 上搜索以找到适合您的那个(尽管我可以说我过去曾成功使用过pexpect,并且文档中充满了获得想法的示例比大多数expect文档要快得多)。

于 2012-12-13T20:49:28.017 回答
2

您正在寻找一种将数据发送到stdin. 这是一个使用 Popen的示例:

from subprocess import Popen, PIPE, STDOUT

p = Popen(['mpg321', '-R testPlayer'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)

mpg123_stdout = p.communicate(input='LOAD test.mp3\n')[0]
print(mpg123_stdout)

你建立指向stdin和的指针stdout,然后在你开始你的过程之后,你与 进行通信stdin并从中读取stdout。确保发送新行(回车)

于 2012-12-13T20:47:46.443 回答