如果您想使用Python播放或錄制聲音,那么您來(lái)對(duì)地方了!在本教程中,您將學(xué)習(xí)如何使用一些最流行的音頻庫(kù)在Python中播放和錄制聲音。您將了解最直接的播放和錄制聲音的方法,然后您將了解一些提供更多功能的庫(kù),以換取一些額外的代碼行。
在本教程結(jié)束時(shí),您將了解如何:
-
播放MP3和WAV文件,以及一系列其他音頻格式
-
播放包含聲音的NumPy和Python數(shù)組
-
使用Python錄制聲音
-
以各種不同的文件格式保存錄制文件或音頻文件
播放音頻文件
下面,您將看到如何使用一系列Python庫(kù)播放音頻文件。其中一些庫(kù)允許您播放一系列音頻格式,包括MP3和NumPy陣列。下面的所有庫(kù)都允許您播放WAV文件,其中一些代碼行代碼比其他文件更多:
-
playsound如果你只是想播放WAV或MP3文件,是最簡(jiǎn)單的包。除簡(jiǎn)單播放外,它不提供任何功能。
-
simpleaudio 讓您播放WAV文件和NumPy數(shù)組,并為您提供檢查文件是否仍在播放的選項(xiàng)。
-
winsound 允許您播放WAV文件或發(fā)出嗶嗶聲,但它僅適用于Windows。
-
python-sounddevice并pyaudio為PortAudio庫(kù)提供綁定,以便跨平臺(tái)播放WAV文件。
-
pydub需要pyaudio進(jìn)行音頻播放,但ffmpeg安裝后,只需幾行代碼即可播放各種音頻格式。
讓我們一起來(lái)看看這些用于音頻播放的庫(kù)。
- playsound
playsound是一個(gè)“純Python,跨平臺(tái),單一功能模塊,不依賴于播放聲音。” 使用此模塊,您可以使用一行代碼播放聲音文件:
from playsound import playsound
playsound('myfile.wav')
該文件中playsound指出,它已在WAV和MP3文件進(jìn)行測(cè)試,但它可能對(duì)其他文件格式正常工作。
該庫(kù)最后更新于2017年6月。在撰寫本文時(shí)似乎運(yùn)行良好,但目前尚不清楚它是否仍然支持更新的Python版本。
simpleaudio
simpleaudio是一個(gè)跨平臺(tái)的庫(kù),用于播放沒(méi)有依賴關(guān)系的(單聲道和立體聲)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文件包含表示原始音頻數(shù)據(jù)的一系列位,以及具有 RIFF(資源交換文件格式)格式的元數(shù)據(jù)的標(biāo)題。
對(duì)于CD錄制,行業(yè)標(biāo)準(zhǔn)是將每個(gè)音頻樣本(與氣壓相關(guān)的單個(gè)音頻數(shù)據(jù)點(diǎn))存儲(chǔ)為16位值,每秒44100個(gè)樣本。
為了減小文件大小,以較低的采樣率存儲(chǔ)一些記錄(例如人類語(yǔ)音)可能就足夠了,例如每秒8000個(gè)樣本,盡管這確實(shí)意味著較高的聲音頻率可能沒(méi)有準(zhǔn)確表示。
本教程中討論的一些庫(kù)播放和記錄bytes對(duì)象,而其他庫(kù)使用NumPy數(shù)組來(lái)存儲(chǔ)原始音頻數(shù)據(jù)。
兩者都對(duì)應(yīng)于一系列數(shù)據(jù)點(diǎn),這些數(shù)據(jù)點(diǎn)可以以指定的采樣率播放以播放聲音。對(duì)于bytes對(duì)象,每個(gè)樣本存儲(chǔ)為一組兩個(gè)8位值,而在NumPy數(shù)組中,每個(gè)元素可以包含對(duì)應(yīng)于單個(gè)樣本的16位值。
這兩種數(shù)據(jù)類型之間的一個(gè)重要區(qū)別是bytes對(duì)象是不可變的,而NumPy數(shù)組是可變的,使后者更適合生成聲音和更復(fù)雜的信號(hào)處理。有關(guān)如何使用NumPy的更多信息,請(qǐng)查看我們的NumPy教程。
simpleaudio允許您使用NumPy和Python數(shù)組和bytes對(duì)象simpleaudio.play_buffer()。確保安裝了NumPy以使以下示例正常工作simpleaudio。(pip安裝后,您可以通過(guò)pip install numpy從控制臺(tái)運(yùn)行來(lái)執(zhí)行此操作。)
有關(guān)如何使用pip安裝包的更多信息,
下面你將看到如何生成一個(gè)對(duì)應(yīng)于440 Hz音調(diào)的NumPy數(shù)組并使用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()
接下來(lái),讓我們看看如何winsound在Windows機(jī)器上播放WAV文件。
winsound
如果使用Windows,則可以使用內(nèi)置winsound模塊訪問(wèn)其基本的聲音播放機(jī)器。播放WAV文件可以在幾行代碼中完成:
import winsound
filename = 'myfile.wav'
winsound.PlaySound(filename, winsound.SND_FILENAME)
winsound不支持播放WAV文件以外的任何文件。它確實(shí)允許您使用揚(yáng)聲器發(fā)出嗶嗶聲winsound.Beep(frequency, duration)。例如,您可以使用以下代碼將1000 Hz音調(diào)發(fā)出100毫秒的響聲:
import winsound
winsound.Beep(1000, 100) # Beep at 1000 Hz for 100 ms
接下來(lái),您將學(xué)習(xí)如何使用該python-sounddevice模塊進(jìn)行跨平臺(tái)音頻播放。
python-sounddevice
正如其文檔中所述,python-sounddevice“為PortAudio庫(kù)提供綁定,并提供一些便利功能來(lái)播放和記錄包含音頻信號(hào)的NumPy數(shù)組”。為了播放WAV文件,numpy而且soundfile需要安裝,打開(kāi)WAV文件作為NumPy的陣列。
隨著python-sounddevice,numpy以及soundfile安裝,您現(xiàn)在可以讀取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()提取原始音頻數(shù)據(jù),以及存儲(chǔ)在其RIFF標(biāo)題中的文件的采樣率,并sounddevice.wait()確保腳本僅在聲音播放完畢后終止。
接下來(lái),我們將學(xué)習(xí)如何使用pydub播放聲音。通過(guò)安裝正確的依賴項(xiàng),它允許您播放各種音頻文件,并為您提供更多的音頻處理選項(xiàng)python-soundevice。
pydub
雖然pydub可以在沒(méi)有任何依賴性的情況下打開(kāi)和保存WAV文件,但您需要安裝音頻播放包才能播放音頻。simpleaudio強(qiáng)烈建議,但是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應(yīng)該安裝。看一看在文檔中pydub的說(shuō)明。作為文檔中描述的步驟的替代,ffmpeg-python提供綁定ffmpeg,并可以使用pip安裝:
$ pip install ffmpeg-python
隨著ffmpeg安裝,播放MP3文件,只需要在我們的前面的代碼一個(gè)小的變化:
from pydub import AudioSegment
from pydub.playback import play
sound = AudioSegment.from_mp3('myfile.mp3')
play(sound)
使用該AudioSegment.from_file(filename, filetype)結(jié)構(gòu),您可以播放任何類型的支持音頻文件ffmpeg。例如,您可以使用以下方式播放WMA文件:
sound = AudioSegment 。from_file ('myfile.wma' , 'wma' )
除了播放聲音文件之外,還pydub可以使用不同的文件格式保存音頻(稍后會(huì)詳細(xì)介紹),切片音頻,計(jì)算音頻文件的長(zhǎng)度,淡入或淡出以及應(yīng)用交叉淡入淡出。
AudioSegment.reverse()創(chuàng)建一個(gè)向后播放的AudioSegment的副本,該文檔描述為“對(duì)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()
您可能已經(jīng)注意到,播放聲音pyaudio比使用您之前看到的庫(kù)播放聲音要復(fù)雜一些。這意味著如果您只想在Python應(yīng)用程序中播放聲音效果,它可能不是您的首選。
但是,由于pyaudio為您提供了更多的低級(jí)控制,因此可以為輸入和輸出設(shè)備獲取和設(shè)置參數(shù),并檢查CPU負(fù)載和輸入或輸出延遲。
它還允許您在回調(diào)模式下播放和錄制音頻,其中當(dāng)需要播放或可用于錄制時(shí)需要新數(shù)據(jù)時(shí)調(diào)用指定的回調(diào)函數(shù)。pyaudio如果您的音頻需求不僅僅是簡(jiǎn)單的播放,這些選項(xiàng)可以使用合適的庫(kù)。
現(xiàn)在您已經(jīng)了解了如何使用許多不同的庫(kù)來(lái)播放音頻,現(xiàn)在是時(shí)候看看如何使用Python自己錄制音頻了。
錄制音頻
在python-sounddevice和pyaudio庫(kù)提供的方式來(lái)錄制音頻和Python。python-sounddevice記錄到NumPy數(shù)組和pyaudio記錄到bytes對(duì)象。這兩個(gè)都可以分別使用scipy和wave庫(kù)存儲(chǔ)為WAV文件。
python-sounddevice
python-sounddevice允許您錄制麥克風(fēng)的音頻并將其存儲(chǔ)為NumPy陣列。這是一種方便的聲音處理數(shù)據(jù)類型,可以使用該scipy.io.wavfile模塊轉(zhuǎn)換為WAV格式進(jìn)行存儲(chǔ)。確保安裝scipy以下示例的模塊(pip install scipy)。這會(huì)自動(dòng)將NumPy安裝為其依賴項(xiàng)之一:
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
在本文的前面部分,您學(xué)習(xí)了如何通過(guò)閱讀來(lái)播放聲音pyaudio.Stream()。錄制音頻可以通過(guò)寫入此流來(lái)完成:
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()
現(xiàn)在您已經(jīng)了解了如何用python-sounddevice和記錄音頻pyaudio,您將學(xué)習(xí)如何將錄音(或任何其他音頻文件)轉(zhuǎn)換為一系列不同的音頻格式。
保存和轉(zhuǎn)換音頻
您之前看到可以使用該scipy.io.wavfile模塊將NumPy陣列存儲(chǔ)為WAV文件。該wavio模塊同樣允許您在WAV文件和NumPy數(shù)組之間進(jìn)行轉(zhuǎn)換。如果您想以不同的文件格式存儲(chǔ)音頻,pydub并且soundfile派上用場(chǎng),因?yàn)樗鼈冊(cè)试S您讀取和寫入一系列流行的文件格式(例如MP3,F(xiàn)LAC,WMA和FLV)。
wavio
此模塊依賴于numpy并允許您將WAV文件讀取為NumPy陣列,并將NumPy陣列保存為WAV文件。
要將NumPy數(shù)組保存為WAV文件,您可以使用wavio.write():
import wavio
wavio.write("myfile.wav", my_np_array, fs, sampwidth=2)
在此示例中,my_np_array包含音頻的NumPy數(shù)組fs是記錄的采樣率(通常為44100或44800 Hz),并且sampwidth是音頻的采樣寬度(每個(gè)采樣的字節(jié)數(shù),通常為1或2個(gè)字節(jié))。
soundfile
該soundfile庫(kù)可以讀寫所有支持的文件格式libsndfile。雖然它無(wú)法播放音頻,但它允許您將音頻轉(zhuǎn)換為FLAC,AIFF和一些不太常見(jiàn)的音頻格式。要將WAV文件轉(zhuǎn)換為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)
類似的代碼將用于轉(zhuǎn)換支持的其他文件格式libsndfile。
pydub
pydub讓您以任何ffmpeg支持的格式保存音頻,其中包括您日常生活中可能遇到的幾乎所有音頻類型。例如,您可以使用以下代碼將WAV文件轉(zhuǎn)換為MP3:
from pydub import AudioSegment
sound = AudioSegment.from_wav('myfile.wav')
sound.export('myfile.mp3', format='mp3')
使用AudioSegment.from_file()是一種加載音頻文件的更通用的方法。例如,如果要將文件從MP3轉(zhuǎn)換回WAV,可以執(zhí)行以下操作:
from pydub import AudioSegment
sound = AudioSegment.from_file('myfile.mp3', format='mp3')
sound.export('myfile.wav', format='wav')
此代碼應(yīng)適用于任何格式的音頻文件是ffmpeg支持。
結(jié)論:在Python中播放和錄制聲音
在本教程中,您學(xué)習(xí)了如何使用一些最流行的音頻庫(kù)來(lái)播放和錄制Python中的音頻。您還了解了如何以多種不同格式保存音頻。
你現(xiàn)在能夠:
播放各種音頻格式,包括WAV,MP3和NumPy陣列
將麥克風(fēng)的音頻錄制到NumPy或Python陣列
將錄制的音頻存儲(chǔ)為各種格式,包括WAV和MP3
將聲音文件轉(zhuǎn)換為一系列不同的音頻格式
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
