【发布时间】:2016-11-04 08:25:46
【问题描述】:
我正在尝试使用 RPi 实现无线电播放器。目标是设置播放列表并在填充播放列表后开始播放。一旦停止代码被执行,播放器和广播进程应该退出。
广播进程很好地终止,但播放器进程即使在调用终止后仍处于等待状态。如果再次调用停止代码,则播放器进程终止
尝试过的事情:
- 重新排序等待命令(播放器、收音机)/(收音机、播放器)
- 类似地重新排序终止命令
- 使用 kill 而不是 terminate 会挂起 RPi
玩家代码:
while playlist:
player = subprocess.Popen(
["avconv", "-i", "Music/%s" % playlist[0], "-f", "s16le", "-ar",
"22.05k", "-ac", "1", "-"], stdout=subprocess.PIPE)
radio = subprocess.Popen(["./pifm", "-", freq], stdin=player.stdout)
radio.wait()
print "************ exiting from radio :)"
player.wait()
print "************ exiting from player :)"
playlist.pop(0)
player = None
radio = None
播放器停止代码(从另一个线程调用):
print "************ stop requested"
if radio and radio.poll() is None:
print "************ terminating radio :)"
radio.terminate()
if player and player.poll() is None:
print "************ terminating player :)"
player.terminate()
替代方案:
另一种选择是为广播设置一个持久接收器,并为播放器设置点播流程
def start_radio():
global radio
radio = subprocess.Popen(["./pifm"...], stdin=subprocess.PIPE)
def play():
global player
while playlist and radio:
player = subprocess.Popen(["avconv"...], stdout=radio.stdin)
player.wait()
playlist.pop(0)
def stop():
if player and player.poll() is None:
print "************ terminating player :)"
player.terminate()
但在这种情况下,调用 player.terminate() 会关闭播放器,同时在无线电进程上重复播放最后一个数据包(就像一个卡住的记录)。这张卡住的唱片一直播放到我启动新播放器或终止收音机为止。
【问题讨论】:
-
试试
player.join()然后player.terminate()? -
@ritlew
player是 Popen 对象,没有 join 方法。 -
1- "使用 kill 而不是 terminate 会挂起 RPi" -- 你应该先解决这个问题(它也可能让你回答当前的问题)。 2-你应该在
radio = Popen(...)之后调用player.stdout.close(),这样如果广播进程退出,播放器进程就会退出。 -
@J.F.Sebastian 它有效。请发布建议作为答案,我会接受。
-
@J.F.Sebastian 你能帮我看看替代部分吗?
标签: python raspberry-pi subprocess python-multithreading