如何利用Python播放和录制声音

系统 2350 0

如果您想使用Python播放或录制声音,那么您来对地方了!在本教程中,您将学习如何使用一些最流行的音频库在Python中播放和录制声音。您将了解最直接的播放和录制声音的方法,然后您将了解一些提供更多功能的库,以换取一些额外的代码行。

在本教程结束时,您将了解如何:

  • 播放MP3和WAV文件,以及一系列其他音频格式

  • 播放包含声音的NumPy和Python数组

  • 使用Python录制声音

  • 以各种不同的文件格式保存录制文件或音频文件

播放音频文件

下面,您将看到如何使用一系列Python库播放音频文件。其中一些库允许您播放一系列音频格式,包括MP3和NumPy阵列。下面的所有库都允许您播放WAV文件,其中一些代码行代码比其他文件更多:

  • playsound如果你只是想播放WAV或MP3文件,是最简单的包。除简单播放外,它不提供任何功能。

  • simpleaudio 让您播放WAV文件和NumPy数组,并为您提供检查文件是否仍在播放的选项。

  • winsound 允许您播放WAV文件或发出哔哔声,但它仅适用于Windows。

  • python-sounddevice并pyaudio为PortAudio库提供绑定,以便跨平台播放WAV文件。

  • pydub需要pyaudio进行音频播放,但ffmpeg安装后,只需几行代码即可播放各种音频格式。

让我们一起来看看这些用于音频播放的库。

  • playsound

playsound是一个“纯Python,跨平台,单一功能模块,不依赖于播放声音。” 使用此模块,您可以使用一行代码播放声音文件:

            
              from playsound import playsound
playsound('myfile.wav')

            
          

该文件中playsound指出,它已在WAV和MP3文件进行测试,但它可能对其他文件格式正常工作。

该库最后更新于2017年6月。在撰写本文时似乎运行良好,但目前尚不清楚它是否仍然支持更新的Python版本。

simpleaudio

simpleaudio是一个跨平台的库,用于播放没有依赖关系的(单声道和立体声)WAV文件。以下代码可用于播放WAV文件,并在终止脚本之前等待文件完成播放:

            
              import simpleaudio as sa
filename = 'myfile.wav'
wave_obj = sa.WaveObject.from_wave_file(filename)
play_obj = wave_obj.play()
play_obj.wait_done()  # Wait until sound has finished playing

            
          

WAV文件包含表示原始音频数据的一系列位,以及具有 RIFF(资源交换文件格式)格式的元数据的标题。

对于CD录制,行业标准是将每个音频样本(与气压相关的单个音频数据点)存储为16位值,每秒44100个样本。

为了减小文件大小,以较低的采样率存储一些记录(例如人类语音)可能就足够了,例如每秒8000个样本,尽管这确实意味着较高的声音频率可能没有准确表示。

本教程中讨论的一些库播放和记录bytes对象,而其他库使用NumPy数组来存储原始音频数据。

两者都对应于一系列数据点,这些数据点可以以指定的采样率播放以播放声音。对于bytes对象,每个样本存储为一组两个8位值,而在NumPy数组中,每个元素可以包含对应于单个样本的16位值。

这两种数据类型之间的一个重要区别是bytes对象是不可变的,而NumPy数组是可变的,使后者更适合生成声音和更复杂的信号处理。有关如何使用NumPy的更多信息,请查看我们的NumPy教程。

simpleaudio允许您使用NumPy和Python数组和bytes对象simpleaudio.play_buffer()。确保安装了NumPy以使以下示例正常工作simpleaudio。(pip安装后,您可以通过pip install numpy从控制台运行来执行此操作。)

有关如何使用pip安装包的更多信息,

下面你将看到如何生成一个对应于440 Hz音调的NumPy数组并使用simpleaudio.play_buffer()以下方式播放:

            
              import numpy as np
import simpleaudio as sa

frequency = 440  # Our played note will be 440 Hz
fs = 44100  # 44100 samples per second
seconds = 3  # Note duration of 3 seconds

# Generate array with seconds*sample_rate steps, ranging between 0 and seconds
t = np.linspace(0, seconds, seconds * fs, False)

# Generate a 440 Hz sine wave
note = np.sin(frequency * t * 2 * np.pi)

# Ensure that highest value is in 16-bit range
audio = note * (2**15 - 1) / np.max(np.abs(note))
# Convert to 16-bit data
audio = audio.astype(np.int16)

# Start playback
play_obj = sa.play_buffer(audio, 1, 2, fs)

# Wait for playback to finish before exiting
play_obj.wait_done()

            
          

接下来,让我们看看如何winsound在Windows机器上播放WAV文件。

winsound

如果使用Windows,则可以使用内置winsound模块访问其基本的声音播放机器。播放WAV文件可以在几行代码中完成:

            
              import winsound

filename = 'myfile.wav'
winsound.PlaySound(filename, winsound.SND_FILENAME)

            
          

winsound不支持播放WAV文件以外的任何文件。它确实允许您使用扬声器发出哔哔声winsound.Beep(frequency, duration)。例如,您可以使用以下代码将1000 Hz音调发出100毫秒的响声:

            
              import winsound
winsound.Beep(1000, 100)  # Beep at 1000 Hz for 100 ms

            
          

接下来,您将学习如何使用该python-sounddevice模块进行跨平台音频播放。

python-sounddevice

正如其文档中所述,python-sounddevice“为PortAudio库提供绑定,并提供一些便利功能来播放和记录包含音频信号的NumPy数组”。为了播放WAV文件,numpy而且soundfile需要安装,打开WAV文件作为NumPy的阵列。

随着python-sounddevice,numpy以及soundfile安装,您现在可以读取WAV文件作为与NumPy阵列和回放:

            
              import sounddevice as sd
import soundfile as sf
filename = 'myfile.wav'
# Extract data and sampling rate from file
data, fs = sf.read(filename, dtype='float32')  
sd.play(data, fs)
status = sd.wait()  # Wait until file is done playing

            
          

该行包含sf.read()提取原始音频数据,以及存储在其RIFF标题中的文件的采样率,并sounddevice.wait()确保脚本仅在声音播放完毕后终止。

接下来,我们将学习如何使用pydub播放声音。通过安装正确的依赖项,它允许您播放各种音频文件,并为您提供更多的音频处理选项python-soundevice。

pydub

虽然pydub可以在没有任何依赖性的情况下打开和保存WAV文件,但您需要安装音频播放包才能播放音频。simpleaudio强烈建议,但是pyaudio,ffplay和avplay有其他选择。

以下代码可用于播放WAV文件pydub:

            
              from pydub import AudioSegment
from pydub.playback import play
sound = AudioSegment.from_wav('myfile.wav')
play(sound)

            
          

为了播放其他音频类型,如MP3文件,ffmpeg或者libav应该安装。看一看在文档中pydub的说明。作为文档中描述的步骤的替代,ffmpeg-python提供绑定ffmpeg,并可以使用pip安装:

            
              $ pip install ffmpeg-python

            
          

随着ffmpeg安装,播放MP3文件,只需要在我们的前面的代码一个小的变化:

            
              from pydub import AudioSegment
from pydub.playback import play

sound = AudioSegment.from_mp3('myfile.mp3')
play(sound)

            
          

使用该AudioSegment.from_file(filename, filetype)结构,您可以播放任何类型的支持音频文件ffmpeg。例如,您可以使用以下方式播放WMA文件:

            
              sound  =  AudioSegment 。from_file ('myfile.wma' , 'wma' )

            
          

除了播放声音文件之外,还pydub可以使用不同的文件格式保存音频(稍后会详细介绍),切片音频,计算音频文件的长度,淡入或淡出以及应用交叉淡入淡出。

AudioSegment.reverse()创建一个向后播放的AudioSegment的副本,该文档描述为“对Pink Floyd有用,可以使用,以及一些音频处理算法”。

pyaudio

            
              import pyaudio
import wave

filename = 'myfile.wav'

# Set chunk size of 1024 samples per data frame
chunk = 1024  

# Open the sound file 
wf = wave.open(filename, 'rb')

# Create an interface to PortAudio
p = pyaudio.PyAudio()

# Open a .Stream object to write the WAV file to
# 'output = True' indicates that the sound will be played rather than recorded
stream = p.open(format = p.get_format_from_width(wf.getsampwidth()),
                channels = wf.getnchannels(),
                rate = wf.getframerate(),
                output = True)

# Read data in chunks
data = wf.readframes(chunk)

# Play the sound by writing the audio data to the stream
while data != '':
    stream.write(data)
    data = wf.readframes(chunk)

# Close and terminate the stream
stream.close()
p.terminate()

            
          

您可能已经注意到,播放声音pyaudio比使用您之前看到的库播放声音要复杂一些。这意味着如果您只想在Python应用程序中播放声音效果,它可能不是您的首选。

但是,由于pyaudio为您提供了更多的低级控制,因此可以为输入和输出设备获取和设置参数,并检查CPU负载和输入或输出延迟。

它还允许您在回调模式下播放和录制音频,其中当需要播放或可用于录制时需要新数据时调用指定的回调函数。pyaudio如果您的音频需求不仅仅是简单的播放,这些选项可以使用合适的库。

现在您已经了解了如何使用许多不同的库来播放音频,现在是时候看看如何使用Python自己录制音频了。

录制音频

在python-sounddevice和pyaudio库提供的方式来录制音频和Python。python-sounddevice记录到NumPy数组和pyaudio记录到bytes对象。这两个都可以分别使用scipy和wave库存储为WAV文件。

python-sounddevice

python-sounddevice允许您录制麦克风的音频并将其存储为NumPy阵列。这是一种方便的声音处理数据类型,可以使用该scipy.io.wavfile模块转换为WAV格式进行存储。确保安装scipy以下示例的模块(pip install scipy)。这会自动将NumPy安装为其依赖项之一:

            
              import sounddevice as sd
from scipy.io.wavfile import write

fs = 44100  # Sample rate
seconds = 3  # Duration of recording

myrecording = sd.rec(int(seconds * fs), samplerate=fs, channels=2)
sd.wait()  # Wait until recording is finished
write('output.wav', fs, myrecording)  # Save as WAV file 

            
          

pyaudio

在本文的前面部分,您学习了如何通过阅读来播放声音pyaudio.Stream()。录制音频可以通过写入此流来完成:

            
              import pyaudio
import wave

chunk = 1024  # Record in chunks of 1024 samples
sample_format = pyaudio.paInt16  # 16 bits per sample
channels = 2
fs = 44100  # Record at 44100 samples per second
seconds = 3
filename = "output.wav"

p = pyaudio.PyAudio()  # Create an interface to PortAudio

print('Recording')

stream = p.open(format=sample_format,
                channels=channels,
                rate=fs,
                frames_per_buffer=chunk,
                input=True)

frames = []  # Initialize array to store frames

# Store data in chunks for 3 seconds
for i in range(0, int(fs / chunk * seconds)):
    data = stream.read(chunk)
    frames.append(data)

# Stop and close the stream 
stream.stop_stream()
stream.close()
# Terminate the PortAudio interface
p.terminate()

print('Finished recording')

# Save the recorded data as a WAV file
wf = wave.open(filename, 'wb')
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(sample_format))
wf.setframerate(fs)
wf.writeframes(b''.join(frames))
wf.close()

            
          

现在您已经了解了如何用python-sounddevice和记录音频pyaudio,您将学习如何将录音(或任何其他音频文件)转换为一系列不同的音频格式。

保存和转换音频

您之前看到可以使用该scipy.io.wavfile模块将NumPy阵列存储为WAV文件。该wavio模块同样允许您在WAV文件和NumPy数组之间进行转换。如果您想以不同的文件格式存储音频,pydub并且soundfile派上用场,因为它们允许您读取和写入一系列流行的文件格式(例如MP3,FLAC,WMA和FLV)。

wavio

此模块依赖于numpy并允许您将WAV文件读取为NumPy阵列,并将NumPy阵列保存为WAV文件。

要将NumPy数组保存为WAV文件,您可以使用wavio.write():

            
              import wavio

wavio.write("myfile.wav", my_np_array, fs, sampwidth=2)

            
          

在此示例中,my_np_array包含音频的NumPy数组fs是记录的采样率(通常为44100或44800 Hz),并且sampwidth是音频的采样宽度(每个采样的字节数,通常为1或2个字节)。

soundfile

该soundfile库可以读写所有支持的文件格式libsndfile。虽然它无法播放音频,但它允许您将音频转换为FLAC,AIFF和一些不太常见的音频格式。要将WAV文件转换为FLAC,可以使用以下代码:

            
              import soundfile as sf

# Extract audio data and sampling rate from file 
data, fs = sf.read('myfile.wav') 
# Save as FLAC file at correct sampling rate
sf.write('myfile.flac', data, fs)  

            
          

类似的代码将用于转换支持的其他文件格式libsndfile。

pydub

pydub让您以任何ffmpeg支持的格式保存音频,其中包括您日常生活中可能遇到的几乎所有音频类型。例如,您可以使用以下代码将WAV文件转换为MP3:

            
              from pydub import AudioSegment
sound = AudioSegment.from_wav('myfile.wav')

sound.export('myfile.mp3', format='mp3')

            
          

使用AudioSegment.from_file()是一种加载音频文件的更通用的方法。例如,如果要将文件从MP3转换回WAV,可以执行以下操作:

            
              from pydub import AudioSegment
sound = AudioSegment.from_file('myfile.mp3', format='mp3')

sound.export('myfile.wav', format='wav')

            
          

此代码应适用于任何格式的音频文件是ffmpeg支持。

结论:在Python中播放和录制声音
在本教程中,您学习了如何使用一些最流行的音频库来播放和录制Python中的音频。您还了解了如何以多种不同格式保存音频。

你现在能够:

播放各种音频格式,包括WAV,MP3和NumPy阵列
将麦克风的音频录制到NumPy或Python阵列
将录制的音频存储为各种格式,包括WAV和MP3
将声音文件转换为一系列不同的音频格式


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论