停止在 pydub 中播放音频
Posted
技术标签:
【中文标题】停止在 pydub 中播放音频【英文标题】:Stop the audio from playing in pydub 【发布时间】:2017-12-01 14:55:00 【问题描述】:pydub 中是否有类似终止或停止功能的功能,这样在 play() 启动后的流可以在仍在播放时突然停止,而不是将音频播放到全长然后停止。
【问题讨论】:
【参考方案1】:如前所述,pydub 本身没有提供这样的功能。 但是,可以通过使用多处理来停止音乐:
from pydub import Audiosegment
from pydub.playback import play
from multiprocessing import Process
some_audio = AudioSegment.from_file('yourAudioFile.mp3')
process = Process(target=play, args=(some_audio,))
if __name__ == '__main__':
process.start()
time.sleep(2000) # do some stuff inbetween
process.terminate()
terminate()
方法停止进程并随之停止播放音频。
编辑
我找到了一个非常更好的方法,让我们免去了不必要的繁重流程。
from pydub import AudioSegment
from pydub.playback import _play_with_simpleaudio
some_audio = AudioSegment.from_file('yourAudioFile.mp3')
playback = _play_with_simpleaudio(some_audio)
time.sleep(2000) # do some stuff inbetween
playback.stop()
更多详情:https://github.com/jiaaro/pydub/issues/160#issuecomment-497953546
【讨论】:
【参考方案2】:目前没有直接的方法可以在pydub
中停止播放音频,因为它可以在后端使用pyaudio
或ffplay
(取决于已安装和可访问的内容)。
详情见后端代码here
但是,您可以按 Ctrl + c 来中断播放并在 try - except
块中环绕 play
方法。它会生成KeyboardInterrupt
异常,您可以根据需要对其进行处理。
这是一个在 windows
上测试的工作示例。
from pydub import AudioSegment
from pydub.playback import play
song = AudioSegment.from_wav("audio.wav")
while True:
try:
play(song)
except KeyboardInterrupt:
print "Stopping playing"
break #to exit out of loop, back to main program
【讨论】:
这对我不起作用。我尝试了以下代码的多种变体,包括上述代码:def ring(): sound_alarm = True while True: try: print(f'sound_alarm is sound_alarm') if sound_alarm == False: return play(sound) except KeyboardInterrupt: sound_alarm = False print('done playing sound.') break
我得到以下代码:sound_alarm is True ^Csound_alarm is True ^Csound_alarm is True sound_alarm is True
它继续无休止地循环
你的 linux 终端上是否有 ^C 设置。例如看看它是否在没有脚本的情况下独立工作。否则,您可以使用stty intr ^c
进行设置,然后在上面尝试。
我想我不明白你所说的“你有 ^C 设置...”是什么意思。我确实经常在命令行上使用这样的关键命令,所以,我想答案是肯定的。【参考方案3】:
冒着因为不提及 pydub 而被否决的风险,我想我会在这一点上分享我所知道的。我从来没有让它与 pydub 一起工作,据我所知,我使用了@Anil_M 的答案。让我在这里再次分享一下,因为代码格式化显然不适用于 cmets。
from pydub import AudioSegment
from pydub.playback import play
# music files
f = '/home/worldwidewilly/workspace/deliberate-action/action/on-the-run-snippet.mp3'
# run pydub
sound = AudioSegment.from_file(f, format="mp3")
def ring():
sound_alarm = True
while True:
try:
print(f'sound_alarm is sound_alarm')
if sound_alarm == False:
return
play(sound)
except KeyboardInterrupt:
sound_alarm = False
print('done playing sound.')
break
if __name__ == "__main__":
import sys
ring()
当执行上述操作并按下 ctrl+C 时,声音会停止播放,但它永远不会到达 KeyboardInterrupt 逻辑,即永远不会执行 print('done playing sound.')
。它只是进入循环的顶部,插入语句并播放声音(因此,很明显,var sound_alarm 永远不会等于 False)。
我遇到的解决方案是使用 simpleaudio。缺点是除了 .wav 文件之外,我还没有弄清楚如何播放任何东西。这是代码:
# run simpleaudio
wave_obj = sa.WaveObject.from_wave_file(f)
def ring():
# sound_alarm = True
while True:
try:
play_obj = wave_obj.play()
play_obj.wait_done()
except KeyboardInterrupt:
play_obj.stop()
print('done playing sound.')
break
if __name__ == "__main__":
import sys
ring()
在此处按 ctrl-C 确实会停止声音并结束循环。目前尚不清楚为什么这种逻辑适用于其中一种而不适用于另一种,但你有它。我很想开悟。
【讨论】:
【参考方案4】:据我所知,我是第一次使用整个声音处理,您可以使用 pyaudio 将 wav 文件作为流播放。 pyaudio 不是 pydub。 :)
首先,使用 pydub/ffmpeg 将您的 anydata 文件转换为 wav 文件,见下文,然后使用 pyaudio 将其作为流播放,其中包含逻辑。
因为,当我用 pydub 播放 MP3 时,它会等待几秒钟,然后在 /tmp 文件夹中声明文件已转换为 wav。那么,为什么不只转换一次并将其保存到您自己的位置呢?无论如何,这两种方式都会持续几秒钟,但后一种转换只需完成一次(假设你有大量千兆字节:)),然后你可以检查文件是否已经存在。
-> 转换Python convert mp3 to wav with Pydub
-> 使用 python 播放和录制声音 -> pyaudio(综合指南)https://realpython.com/playing-and-recording-sound-python/#pyaudio
正如您在代码中看到的,您可以将自己的逻辑放入播放流的 while 循环中。
我会尝试在我制作的项目中使用这种组合。希望它有效。 :)
【讨论】:
【参考方案5】:您可以在pydub的播放文件中使用多线程来播放/暂停甚至停止音乐。
在此处检查文件并将pydub中的playback.py替换为该文件
https://github.com/NeelRanka/pydub_edited_play-pause-stop.git
【讨论】:
请详细说明您的答案。如果可能,请包含一个小示例以清楚起见。谢谢:) github.com/NeelRanka/pydub_edited_play-pause-stop.git:检查一下以上是关于停止在 pydub 中播放音频的主要内容,如果未能解决你的问题,请参考以下文章