使用Python播放音频


107

如何从Python脚本播放音频(听起来像1秒钟的声音)?

最好是独立于平台,但首先需要在Mac上运行。

我知道我可以afplay file.mp3在Python中执行命令,但是可以在原始Python中执行吗?如果它不依赖外部库,我也会更好。


Pyglet可以通过称为AVbin的外部库播放音频。Pyglet是它支持的每个平台上围绕本机系统调用的ctypes包装器。不幸的是,我认为标准库中的任何内容都不会播放音频。
technomaologic

如果您需要可移植的Python音频库,请尝试PyAudio。它当然有一个mac端口。至于mp3文件:在“原始” Python中肯定是可行的,只是恐怕您必须自己编写所有代码:)。如果您负担得起一些外部库,我在这里找到了一些PyAudio-PyLame示例
Grzegorz Gacek

Answers:



42

最好的选择可能是使用pygame / SDL。它是一个外部库,但是在各个平台上都有很好的支持。

pygame.mixer.init()
pygame.mixer.music.load("file.mp3")
pygame.mixer.music.play()

您可以在pygame.mixer.music文档中找到有关音频混音器支持的更多特定文档。


2
对我来说,这是行不通的。我的意思是,它正在播放,但没有声音。我time.sleep(5)在末尾添加,并且有效。Windows 8.1上的Python 3.6
Nagabhushan SN

火包!谢谢!
СергейЗеленчук

它不适用于标准“ .wav”,“。mp3”和“ .ogg”(无法打开文件“ filename.format”)的fedora
Calvin-Ruiz,

1
@ Calvin-Ruiz我刚刚确认我能够在FC31中使用以上代码播放MP3和Ogg文件。我认为您有一个更大的问题,可能需要对平台有一些详细的了解。
TML

18

看一下Simpleaudio,它是一个相对较新的轻量级库,用于此目的:

> pip install simpleaudio

然后:

import simpleaudio as sa

wave_obj = sa.WaveObject.from_wave_file("path/to/file.wav")
play_obj = wave_obj.play()
play_obj.wait_done()

确保使用未压缩的16位PCM文件。


尼斯,感谢-让您的游戏需要打短的声音效果,并且支持Python 3有用
托马斯的Perl

18

试试playsound,它是一个纯Python,跨平台,单一功能的模块,没有依赖于播放声音。

通过pip安装:

$ pip install playsound

安装后,您可以像这样使用它:

from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')

36
读这篇文章使我非常激动。我的双眼真幸福地泪流满面。没想到自己会有这种反应。(他们链接到我制作的模块。)
ArtOfWarfare

为+1 playsound。我只是在这里测试了一些解决方案,而这对我来说是最简单的。不幸的是pygame,在简短的测试中,该解决方案对我不起作用。
特雷弗·沙利文

13

pydub中,我们最近选择使用ffmpeg工具套件中的ffplay (通过子进程,该套件内部使用SDL。

它可以达到我们的目的-主要是使交互模式下测试pydub代码的结果更容易-但它有缺点,例如导致新程序出现在Mac上的扩展坞中。

我已经链接了上面的实现,但是下面是一个简化的版本:

import subprocess

def play(audio_file_path):
    subprocess.call(["ffplay", "-nodisp", "-autoexit", audio_file_path])

-nodisp标志阻止ffplay显示新窗口,并且-autoexit当音频文件播放完毕后,该标志使ffplay退出并返回状态代码。

编辑:pydub现在在安装时使用pyaudio进行播放,并回落到ffplay以避免我提到的缺点。上面的链接也显示了该实现。


1
Pydub看起来有很大的包装库潜力-我现在正在安装。
阴影

1
该死的PyDub看起来不错,它仍然非常活跃。
corysimmons

13

抱歉,回复晚,但是我认为这是宣传我的图书馆的好地方...

AFAIK,标准库只有一个用于播放音频的模块:ossaudiodev。可悲的是,这仅适用于Linux和FreeBSD。

更新:还有winsound,但显然这也是特定于平台的。

对于某些与平台无关的东西,您需要使用一个外部库。

我的建议是sounddevice模块(但请注意,我是作者)。

该软件包包括针对Mac OS X和Windows 的预编译的PortAudio库,可以通过以下方式轻松安装:

pip install sounddevice --user

它可以播放NumPy数组中的声音,但也可以使用普通的Python缓冲区(如果NumPy不可用)。

要播放NumPy数组,这就是您所需要的(假设音频数据的采样频率为44100 Hz):

import sounddevice as sd
sd.play(myarray, 44100)

有关更多详细信息,请参阅文档

它无法读取/写入声音文件,您需要一个单独的库。


大!这正是我制作有关wave的课堂演示程序所需要的。
比尔N


4

亚伦的答案似乎比必需的复杂了十倍。如果只需要适用于OS X的答案,请执行以下操作:

from AppKit import NSSound

sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_('/path/to/file.wav', True)
sound.play()

一件事...这立即返回。因此,如果您想阻止通话直到声音播放完毕,您可能还想这样做。

from time import sleep

sleep(sound.duration())

编辑:我采用了此功能,并将其与Windows和Linux的变体结合在一起。结果是一个纯Python跨平台模块,没有依赖关系,称为playsound。我已将其上传到pypi。

pip install playsound

然后像这样运行它:

from playsound import playsound
playsound('/path/to/file.wav', block = False)

MP3文件也可以在OS X上使用。WAV应该在所有平台上都可以使用。我不知道平台/文件格式的其他组合是否有效-我还没有尝试过。


我收到以下错误:在Python 3.5(Windows)上,“无法将'bytes'对象隐式转换为str”。
欧文·梅耶

@ErwinMayer-您是否在谈论playsound我编写的模块?我没有在比Python 2.7.11更高的版本上测试过它……我当然可以考虑在3.5上修复它……
ArtOfWarfare

确实。这一定是由于Python 3的差异。
欧文·梅耶

AppKit 一个依赖项。
克里斯·拉森

2
@ArtOfWarfare 事实并非如此。它与系统python一起安装,但没有与大多数发行版一起安装,包括python.org的官方发行版。我认识的大多数人都使用python安装发行版之一来摆脱SIP限制。要获得适用于大多数发行版的AppKit,用户需要点子安装pyobjc。这绝对使它成为依赖项。
克里斯·拉森

3

这是找到的最简单,最好的方法。它支持Linux / pulseaudio,Mac / coreaudio和Windows / WASAPI。

import soundfile as sf
import soundcard as sc

default_speaker = sc.default_speaker()
samples, samplerate = sf.read('bell.wav')

default_speaker.play(samples, samplerate=samplerate)

有关大量其他超级有用的功能,请参见https://github.com/bastibe/PySoundFilehttps://github.com/bastibe/SoundCard


对于任何为此目的(如我)的人来说,都是要小心。所有的库及其依赖关系都需要花费很长时间才能在Raspberry Pi 1B +上构建-尤其是numpy。
pojda

PS:这不适用于树莓派“ NotImplementedError:SoundCard还不支持linux2”,并且找不到解决方法。我要使用os.system(“ mpg123 file.mp3”)
pojda

啊,真糟糕。我想树莓派是一个有点特殊的环境。也许,如果您在问题跟踪器上发布了问题,则可以将其整理或解决。
n00p

进一步考虑,也许问题是您使用的是旧内核或旧python版本。使用较新的python版本,该错误不应看起来像我想的那样。
n00p

它正在运行Raspbian,它基本上是Debian Stretch分支。我放弃了,去了os.system,它在atm上工作得很好。谢谢你的协助!
pojda

2

使用以下代码的类似物,可以在没有任何第三方库的情况下在OS X中播放音频。原始音频数据可以通过wave_wave.writeframes输入。此代码从输入文件中提取4秒的音频。

import wave
import io
from AppKit import NSSound


wave_output = io.BytesIO()
wave_shell = wave.open(wave_output, mode="wb")
file_path = 'SINE.WAV'
input_audio = wave.open(file_path)
input_audio_frames = input_audio.readframes(input_audio.getnframes())

wave_shell.setnchannels(input_audio.getnchannels())
wave_shell.setsampwidth(input_audio.getsampwidth())
wave_shell.setframerate(input_audio.getframerate())

seconds_multiplier = input_audio.getnchannels() * input_audio.getsampwidth() * input_audio.getframerate()

wave_shell.writeframes(input_audio_frames[second_multiplier:second_multiplier*5])

wave_shell.close()

wave_output.seek(0)
wave_data = wave_output.read()
audio_stream = NSSound.alloc()
audio_stream.initWithData_(wave_data)
audio_stream.play()

这比必要的要复杂得多-他们询问如何简单地播放声音,而不是如何操纵然后播放声音。我的答案将这个答案中不必要的部分减少了90%,并完全满足了问询者的要求-使用Python在OS X中播放文件中的声音。stackoverflow.com/a/34984200/901641
ArtOfWarfare

2

尝试PySoundCard使用PortAudio进行回放的(在许多平台上都可以使用)。此外,它还可以识别具有许多通道的“专业”声音设备。

这是自述文件中的一个小示例:

from pysoundcard import Stream

"""Loop back five seconds of audio data."""

fs = 44100
blocksize = 16
s = Stream(samplerate=fs, blocksize=blocksize)
s.start()
for n in range(int(fs*5/blocksize)):
    s.write(s.read(blocksize))
s.stop()

尽管有趣,但是不鼓励仅链接的答案。至少,您应该在答案中包含使用它的简短示例。如果存储库已重命名且链接悬空,那也可以保护您的答案免遭其所有价值的损失。
光谱

2

同样在OSX-SO,使用OSX的afplay命令:

import subprocess
subprocess.call(["afplay", "path/to/audio/file"])

UPDATE:这一切确实是指定如何做OP想避免在第一时间做的事情。我猜我在这里发布了这个信息,因为OP想要避免的是我所寻找的信息。哎呀


尽管在播放时会暂停执行,但效果很好。也许有一种异步的方式来称呼它?
Praxiteles '02

好问题@Praxiteles。可能带有线程。请参阅此处如果有机会尝试,请报告。
MikeiLL,2016年

OP明确要求替代方案。
whitey04 '16

OP正在/正在寻找“从Python内部执行afplay file.mp3命令”的替代方法,而子处理仍然在Python内部进行,不是吗。我站得住了。但是在这里发表这篇文章可能不会有任何伤害,因为它可能会对其他人有所帮助。
MikeiLL '16

@ whitey04我(终于)明白了你的意思。
MikeiLL

1

Pypi列出了音乐中python的模块。我最喜欢的是jython,因为它有更多的音乐资源和库。作为播放课本中单个音符的代码示例:

# playNote.py 
# Demonstrates how to play a single note.

from music import *   # import music library
note = Note(C4, HN)   # create a middle C half note 
Play.midi(note)       # and play it!

1

Mac OS,我尝试了很多代码,但对我有效

import pygame
import time
pygame.mixer.init()
pygame.init()
pygame.mixer.music.load('fire alarm sound.mp3') *On my project folder*
i = 0
while i<10:
    pygame.mixer.music.play(loops=10, start=0.0)
    time.sleep(10)*to protect from closing*
    pygame.mixer.music.set_volume(10)
    i = i + 1

1

playsound使用安装软件包:

pip install playsound

用法:

from playsound import playsound
playsound("file location\audio.p3")

0
将其放在正在编写的python脚本的顶部:
import subprocess
如果wav文件位于python脚本的目录中:
f = './mySound.wav'
subprocess.Popen(['aplay','-q',f)
如果wav文件不在python脚本的目录中:
f = 'mySound.wav'
subprocess.Popen(['aplay','-q', 'wav/' + f)
如果您想了解有关游戏的更多信息:
man aplay

0

要使用python播放通知声音,请调用音乐播放器,例如vlc。VLC提示我改用其命令行版本cvlc。

from subprocess import call
call(["cvlc", "--play-and-exit", "myNotificationTone.mp3"])

需要在设备上预安装vlc。在Linux(Ubuntu 16.04 LTS)上测试;运行Python 3.5。


0

尝试声音设备

如果没有模块pip install sounddevice,请在终端中输入 。

然后在您首选的Python脚本(我使用Juypter)中,输入

import sounddevice as sd

sd.play(audio, sr) 将通过Python播放您想要的内容

获得所需音频和采样率的最佳方法是使用librosa模块。如果没有librosa模块,请在终端中输入此内容。

pip install librosa

audio, sr = librosa.load('wave_file.wav')

无论您要播放什么wav文件,只需确保它与Python脚本位于同一目录即可。这应该允许您通过Python播放所需的wav文件

干杯,查理

聚苯乙烯

一旦音频是“ librosa”数据对象,Python就会将其视为一个numpy数组。作为实验,尝试播放一个长(尝试20,000个数据点)的随机numpy数组。Python应该把它当作白噪声播放。sounddevice模块也播放numpy数组和列表。


这样做了,但是它什么都没玩。它只是跳过sd.play通话
Tobias Kolb



-1

如果您使用的是OSX,则可以使用“ os”模块或“子进程”等调用OSX的“播放”命令。从OSX Shell来看,

播放“ bah.wav”

它会在我的计算机上播放约半秒钟。


1
我很想看看这两种方法的语法。
MikeiLL,2015年

-1

简单地说,您可以在cvlc的帮助下完成此操作-我是这样完成的:

import os
os.popen2("cvlc /home/maulo/selfProject/task.mp3 --play-and-exit")

/home/maulo/selfProject/task.mp3。这是我的mp3文件的位置。借助“ --play-and-exit”,您将能够再次播放声音而无需结束vlc进程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.