一、eyeD3 直接在google上搜索python mp3 process ,,推薦比較多的就是這個第三方庫了,。先來看看官方介紹吧。 AbouteyeD3 is a Python tool for working with audio files, specifically mp3 files containing ID3 metadata (i.e. song info). It provides a command-line tool ( For example, to set some song information in an mp3 file called $ eyeD3 -a Nobunny -A "Love Visions" -t "I Am a Girlfriend" -n 4 song.mp3 簡單來說,eyeD3 這個庫只要是用來處理MP3文件的,,特別是帶ID3 metadata的文件(一般MP3文件都會帶有一些額外信息,,比如說歌手、專輯之類的,,后面會說怎么提取這些信息),。eyeD3 提供了兩種使用方法,一種是使用command line 直接在命令行中執(zhí)行 eyeD3 --...就可以對MP3進行處理,,還有一種是在python中使用 import eyed3 導入,。 上面的例子就是官方提供的一個使用eyeD3 命令行執(zhí)行的語句,-a 是 --artist 的簡寫,,即添加歌手信息,,-A 是 --album的簡寫,即添加專輯信息,,-t 是 --title的簡寫,,即添加歌曲名字,-n 是 --track-num 的簡寫,,即添加磁道數(shù),。這些一般都是 MP3文件ID3 tag 的默認屬性。我們?nèi)绻苯虞斎?eyeD3 song.mp3 就會直接顯示歌曲的基本信息,,大概長下面這個樣子: $ eyeD3 song.mp3 song.mp3 [ 3.06 MB ] ------------------------------------------------------------------------- ID3 v2.4: title: I Am a Girlfriend artist: Nobunny album: Love Visions album artist: Various Artists track: 4 ------------------------------------------------------------------------- 但是這種傳遞方式有時候太過于麻煩。所以我在網(wǎng)上搜索了一下,,發(fā)現(xiàn)了Putty這個好東西,。PuTTY is an SSH and telnet client, developed originally by Simon Tatham for the Windows platform. PuTTY is open source software that is available with source code and is developed and supported by a group of volunteers.
圖 3 1 import eyed3 2 3 audiofile = eyed3.load("song.mp3") 4 audiofile.tag.artist = u"Nobunny" 5 audiofile.tag.album = u"Love Visions" 6 audiofile.tag.album_artist = u"Various Artists" 7 audiofile.tag.title = u"I Am a Girlfriend" 8 audiofile.tag.track_num = 4 9 10 audiofile.tag.save() 上面的代碼,使用 import eyed3 導入eyeD3 庫,,然后使用load方法加載mp3文件,,后面的幾行分別是設(shè)置 artist,album等等 ID3 tag ,,直接看代碼就能看出來,就不說了,。如果想顯示mp3文件內(nèi)部的ID3 tag信息,,直接print 相應(yīng)的tag就行了,比如 print(audiofile.tag.artist)等等,,當然,,前提是你的MP3 metadata得儲存了這些信息。其實還有一些更復雜和高級的用法,,我就不講了,,大家有興趣直接去官方文檔看吧,地址:http://eyed3./index.html,。eyeD3 主要就是處理 MP3文件的metadata的,,至于解析音頻之類的就得用其他的庫了。 二,、pydub 第一個介紹的eyeD3 一般只能處理MP3文件,,功能上相對來說也是比較簡單一點。下面介紹的pydub庫就要強大的多,。老規(guī)矩,,還是 DependenciesYou can open and save WAV files with pure python. For opening and saving non-wav files – like mp3 – you'll need ffmpeg orlibav. 這里是說python自帶的wave模塊只能處理 wav 格式的音頻文件,如果要想處理類似MP3格式的文件,,就得要裝 ffmpeg或者libav了,。 什么是ffmpeg 呢? A complete, cross-platform solution to record, convert and stream audio and video.ffmpeg 是一個跨平臺的 可以用來 記錄,、轉(zhuǎn)化音頻與視頻的工具,,如果你做過數(shù)字信號處理方面的工作,對它應(yīng)該不陌生,。還有一個libav,,其實是從ffmpeg分出來的一個分支,功能和 ffmpeg差不多,,二者你任選一個下載就可以了,。windows下直接選擇可執(zhí)行文件安裝即可,。 還是看官網(wǎng)的例子來介紹吧。 I:打開 mp3或者mp4等文件 可以采用如下的命令: 1 from pydub import AudioSegment 2 3 song = AudioSegment.from_wav("never_gonna_give_you_up.wav") 4 song = AudioSegment.from_mp3("never_gonna_give_you_up.mp3") 5 6 ogg_version = AudioSegment.from_ogg("never_gonna_give_you_up.ogg") 7 flv_version = AudioSegment.from_flv("never_gonna_give_you_up.flv") 8 9 mp4_version = AudioSegment.from_file("never_gonna_give_you_up.mp4", "mp4")10 wma_version = AudioSegment.from_file("never_gonna_give_you_up.wma", "wma")11 aac_version = AudioSegment.from_file("never_gonna_give_you_up.aiff", "aac") 可以打開任何 ffmpeg支持的文件類型,,從上面可以看出,,主要有 from_filetype()方法,filetype為具體的文件類型,比如 wav,mp3等 或者通用的 from_file()方法,,但是這個方法必須在第二個參數(shù)指定打開文件的類型,,返回的結(jié)果都是 AudioSegment對象,。 II:切割音頻 1 # pydub does things in milliseconds2 ten_seconds = 10 * 10003 4 first_10_seconds = song[:ten_seconds]5 6 last_5_seconds = song[-5000:] 注意pydub中的標準時間為毫秒,,上面的代碼就得到了音樂的前10秒和后5秒,非常簡單,。 III:調(diào)整音量 1 # boost volume by 6dB2 beginning = first_10_seconds + 63 4 # reduce volume by 3dB5 end = last_5_seconds - 3 +6 就表示將音樂的音量提高6分貝,,-3就表示將音樂的音量降低3分貝 IV: 拼接兩段音樂 without_the_middle = beginning + end without_the_middle.duration_seconds 拼接之后的音樂時長是兩段音樂時長之和,可以通過 .duration_seconds方法來獲取一段音樂的時長,。這與使用 len(audio)/1000.0得到的結(jié)果是一樣的,。 V:將音樂翻轉(zhuǎn)(reverse) 1 # song is not modified2 # AudioSegments are immutable3 backwards = song.reverse() 注意 AudioSegment 對象是不可變的,上面使用reverse 方法不會改變song這個對象,,而是會返回一個新的AudioSegment對象,,其他的方法也是這樣,需要注意,。reverse簡單來說就是 將音樂從尾部向頭部開始逆序播放,,我試了一下,發(fā)現(xiàn)轉(zhuǎn)換之后還真的挺有意思的,。 VI:crossfade(交叉漸入漸出方法) 1 # 1.5 second crossfade2 with_style = beginning.append(end, crossfade=1500) crossfade 就是讓一段音樂平緩地過渡到另一段音樂,,上面的crossfade = 1500 表示過渡的時間是1.5秒。 VII:repeat(重復音樂片段) # repeat the clip twicedo_it_over = with_style * 2 上面的代碼讓音樂重復播放兩次 VIII:fade in and fade out(逐漸增強與逐漸減弱) # 2 sec fade in, 3 sec fade outawesome = do_it_over.fade_in(2000).fade_out(3000) 逐漸增強2秒,,逐漸減弱3秒 XI:save(保存) awesome.export("mashup.mp3", format="mp3") awesome.export("mashup.mp3", format="mp3", tags={'artist': 'Various artists', 'album': 'Best of 2011', 'comments': 'This album is awesome!'}) 這里展示了兩種保存的形式,,都是使用export方法,要指定保存的格式,,使用format 參數(shù),,但第二種方法多了一個tags參數(shù),其實看一下應(yīng)該就很容易明白,,是保存 歌曲ID3 tag信息的,。 以上只是pydub 使用方法的初步介紹,還有其他非常多的功能,,請自行移步官方API 文檔:https://github.com/jiaaro/pydub/blob/master/API.markdown 介紹的非常詳細,。 三、PyAudio
PyAudio provides Python bindings for PortAudio, the cross-platform audio I/O library. With PyAudio, you can easily use Python to play and record audio on a variety of platforms. PyAudio is inspired by:
Pyaudio 提供了對于跨平臺的 PortAudio(處理 audio輸入輸出的庫)的綁定,,PyAudio可以讓你輕松錄制與播放音頻,。 廢話不多說,直接看官方文檔(https://people.csail./hubert/pyaudio/docs/)提供的一個quick start 的代碼 1 """PyAudio Example: Play a wave file.""" 2 3 import pyaudio 4 import wave 5 import sys 6 7 CHUNK = 1024 8 9 if len(sys.argv) < 2:10 print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])11 sys.exit(-1)12 13 wf = wave.open(sys.argv[1], 'rb')14 15 # instantiate PyAudio (1)16 p = pyaudio.PyAudio()17 18 # open stream (2)19 stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),20 channels=wf.getnchannels(),21 rate=wf.getframerate(),22 output=True)23 24 # read data25 data = wf.readframes(CHUNK)26 27 # play stream (3)28 while len(data) > 0:29 stream.write(data)30 data = wf.readframes(CHUNK)31 32 # stop stream (4)33 stream.stop_stream()34 stream.close()35 36 # close PyAudio (5)37 p.terminate() 當然,,這個提供的是使用命令行參數(shù)接收音頻文件的形式,,CHUNK 是一次讀取的音頻byte數(shù)量,p = pyaudio.PyAudio()初始化一個 PyAudio對象,,然后使用其open方法打開一個輸入輸出流,,這里指定了output=True說明這是一個輸出流,即我們是往stream中添加data,,如果這里改為 input = True就是變成輸入流了,,一般是從設(shè)備的標準 audio device ,對于電腦來說可能就是麥克風了,,來讀取音頻data,。使用wave打開一個 .wav 文件,然后使用 readframes方法每次讀取 CHUNK 這么多的數(shù)據(jù),,將數(shù)據(jù)寫入 stream,,直到讀完為止。寫入stream的audio data 就會不斷通過麥克風播放出來了,,于是我們就可以聽到音樂了,。最后在結(jié)束的時候,注意要關(guān)閉相應(yīng)的對象以釋放資源,。 還有一種方法是使用callback(回調(diào)函數(shù))函數(shù),,代碼如下: 1 """PyAudio Example: Play a wave file (callback version).""" 2 3 import pyaudio 4 import wave 5 import time 6 import sys 7 8 if len(sys.argv) < 2: 9 print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])10 sys.exit(-1)11 12 wf = wave.open(sys.argv[1], 'rb')13 14 # instantiate PyAudio (1)15 p = pyaudio.PyAudio()16 17 # define callback (2)18 def callback(in_data, frame_count, time_info, status):19 data = wf.readframes(frame_count)20 return (data, pyaudio.paContinue)21 22 # open stream using callback (3)23 stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),24 channels=wf.getnchannels(),25 rate=wf.getframerate(),26 output=True,27 stream_callback=callback)28 29 # start the stream (4)30 stream.start_stream()31 32 # wait for stream to finish (5)33 while stream.is_active():34 time.sleep(0.1)35 36 # stop stream (6)37 stream.stop_stream()38 stream.close()39 wf.close()40 41 # close PyAudio (7)42 p.terminate() 不細說了,。 下面來看一個使用pyaudio + numpy + pylab 可視化音頻的代碼,下面的代碼打開電腦的麥克風,然后接受音頻輸入,,再以圖像的形式展示出來,。 1 # -*- coding: utf-8 -*- 2 """ 3 Created on Fri May 12 10:30:00 2017 4 @author: Lyrichu 5 @description: show the sound in graphs 6 """ 7 import pyaudio 8 import numpy as np 9 import pylab10 import time11 12 RATE = 4410013 CHUNK = int(RATE/20) # RATE/number of updates per second14 15 def sound_plot(stream):16 t1 = time.time() # time starting17 data = np.fromstring(stream.read(CHUNK),dtype = np.int16)18 pylab.plot(data)19 pylab.title(i)20 pylab.grid()21 pylab.axis([0,len(data),-2**8,2**8])22 pylab.savefig("sound.png",dpi=50)23 pylab.show(block = False) 代碼應(yīng)該比較容易理解,。得到的大概是像下面這樣的圖形(圖4): 圖 4 需要注意的是,,如果不是在交互式命令下執(zhí)行pylab或者matplotlib的plot命令,其plt.show()函數(shù)是一個block函數(shù),,這會導致最后的 plt.close('all') 關(guān)閉所有的窗口只會在手動關(guān)閉了圖像之后才會執(zhí)行,,所有我們無法看到連續(xù)變化的圖像,為了解決這個問題,,我們將plt.show()函數(shù)block參數(shù)設(shè)為False,,這樣show函數(shù)就不是block函數(shù)了,可以直接執(zhí)行plt.close('all')命令,,為了不因為圖像刷新太快我們看不清變化,,所以使用time.sleep(0.5) 暫停0.5秒。 其實還沒介紹完,,還有pygame模塊(python的一個做游戲的模塊)以及l(fā)ibrosa庫(專業(yè)的數(shù)字信號處理庫)等沒有講,,等有機會再更吧,。 |
|