停止在pydub中播放音频。

4

在pydub中是否有类似终止或停止功能的特性,使得通过play()开始播放的音频可以在仍在播放时突然停止,而不是播放到完整长度后再停止。

5个回答

2

如前所述,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

1
据我所见,我第一次使用整个声音处理时,你可以使用pyaudio将wav文件作为流播放。pyaudio不是pydub。 :)
首先,使用pydub / ffmpeg将任何数据文件转换为wav文件,如下所示,然后使用pyaudio在逻辑之间将其作为流播放。
因为当我用pydub播放MP3时,它会等待几秒钟,然后声明该文件已被转换为/tmp文件夹中的wav。那么,为什么不只转换一次并将其保存到您自己的位置?无论哪种方式,都需要几秒钟时间,但是后者只需要执行一次转换(假设您有数千GB :),然后您只需检查文件是否已存在。
-> 转换 Python convert mp3 to wav with Pydub

-> 使用Python播放和录制声音 -> PyAudio(全面指南)
https://realpython.com/playing-and-recording-sound-python/#pyaudio

从代码中可以看出,在播放流的 while 循环中,您可以将自己的逻辑放入其中。

我将尝试在我制作的项目中使用该组合。希望它能够正常工作。 :)


0

1
请详细说明您的答案。如果可能,请提供一个小例子以便更清晰地表达。谢谢 :) - Nicholas TJ
1
请查看此链接:https://github.com/NeelRanka/pydub_edited_play-pause-stop.git - Neel Ranka

0

目前在pydub中没有直接停止播放音频的方法,因为它可以使用后端的pyaudioffplay(取决于安装和可访问性)。 有关后端代码的详细信息,请参见此处

但是,您可以按下Ctrl + c来停止播放,并将play方法包装在try-except块中。这将生成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并且它继续无限循环。 - Bill Turner
你的 Linux 终端是否已经设置了 ^C?例如,可以尝试在没有脚本的情况下独立运行它。否则,你可以使用 stty intr ^c 进行设置,然后再尝试上述操作。 - Anil_M
我不认为我理解你所说的“你是否设置了^C...”。我经常在命令行中使用这样的键盘命令,因此我认为答案是肯定的。 - Bill Turner

0

有可能因为没有提到pydub而被踩,但我想在这里分享我目前所知道的。我从未成功地使用pydub,就我所知,我使用了@Anil_M的答案。由于代码格式在评论中似乎无法正常工作,所以让我在这里再次分享它。

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.')从未被执行。它只是回到循环的顶部,在语句中播放声音(因此,显然,变量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确实会停止声音并结束循环。不清楚为什么这个逻辑对一个有效而另一个无效,但就是这样。我很想得到启示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接