python音频处理库_python音频处理相关类库

一、eyeD3

以下是eyed3的官方介绍

eyeD3 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 (eyeD3) and a Python library (import eyed3) that can be used to write your own applications or plugins that are callable from the command-line tool.

For example, to set some song information in an mp3 file called song.mp3:

$ eyeD3 -a Nobunny -A "Love Visions" -t "I Am a Girlfriend" -n 4 song.mp3

简单来说,eyeD3 这个库只要是用来处理MP3文件的,特别是带ID3 metadata的文件(一般MP3文件都会带有一些额外信息,比如说歌手、专辑之类的,后面会说怎么提取这些信息)。eyeD3提供了两种使用方法,一种是使用command line直接在命令行中执行eyeD3 --...就可以对MP3进行处理,还有一种是在python中使用import eyed3导入。

上面的例子就是官方提供的一个使用eyeD3 命令行执行的语句,-a是--artist的简写,即添加歌手信息,-A是--album的简写,即添加专辑信息,-t是--title的简写,即添加歌曲名字,-n是--track-num的简写,即添加磁道数。这些一般都是MP3文件ID3 tag的默认属性。我们如果直接输入eyeD3 song.mp3就会直接显示歌曲的基本信息,

windows下测试截图如下:

1101923-20170515001739566-792854847.png

可以看出确实常见的信息都显示出来了。

eyeD3 命令行讲完之后,再来说下如何在Python中使用。还是看官方给的例子吧:

import eyed3

audiofile = eyed3.load("song.mp3")

audiofile.tag.artist = u"Nobunny"

audiofile.tag.album = u"Love Visions"

audiofile.tag.album_artist = u"Various Artists"

audiofile.tag.title = u"I Am a Girlfriend"

audiofile.tag.track_num = 4

audiofile.tag.save()

上面的代码,使用 import eyed3 导入eyeD3库,然后使用load方法加载mp3文件,后面的几行分别是设置artist,album等等ID3 tag,直接看代码就能看出来,就不说了。如果想显示mp3文件内部的ID3 tag信息,直接print相应的tag就行了,比如print(audiofile.tag.artist)等等,当然,前提是你的MP3 metadata得储存了这些信息。其实还有一些更复杂和高级的用法,我就不讲了,大家有兴趣直接去官方文档看吧,地址:http://eyed3.nicfit.net/index.html。eyeD3主要就是处理MP3文件的metadata的,至于解析音频之类的就得用其他的库了。

二、pydub

第一个介绍的eyeD3 一般只能处理MP3文件,功能上相对来说也是比较简单一点。下面介绍的pydub库就要强大的多。老规矩,还是先看一下它的官方介绍:

Manipulate audio with a simple and easy high level interface http://pydub.com 就一句话,简单,易用的处理音频的高度抽象的接口,嘿,这不就是我们要找的么。github项目地址为:https://github.com/jiaaro/pydub/有1800多的star,说明这个

库还是很受欢迎的。安装直接很简单,直接 pip install pydub 就可以安装。但是需要注意的是:

Dependencies

You 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 是一个跨平台的 可以用来 记录、转化音频与视频的工具,如果你做过数字信号处理方面的工作,对它应该不陌生。还有一个libav,其实是从ffmpeg分出来的一个分支,功能和ffmpeg差不多,二者你任选一个下载就可以了。windows下直接选择可执行文件安装即可。

还是看官网的例子来介绍吧。

I:打开mp3或者mp4等文件

可以采用如下的命令:

from pydub import AudioSegment

song = AudioSegment.from_wav("never_gonna_give_you_up.wav")

song = AudioSegment.from_mp3("never_gonna_give_you_up.mp3")

ogg_version = AudioSegment.from_ogg("never_gonna_give_you_up.ogg")

flv_version = AudioSegment.from_flv("never_gonna_give_you_up.flv")

mp4_version = AudioSegment.from_file("never_gonna_give_you_up.mp4", "mp4")

wma_version = AudioSegment.from_file("never_gonna_give_you_up.wma", "wma")

aac_version = AudioSegment.from_file("never_gonna_give_you_up.aiff", "aac")

可以打开任何 ffmpeg支持的文件类型,从上面可以看出,主要有from_filetype()方法,filetype为具体的文件类型,比如wav,mp3等

或者通用的 from_file()方法,但是这个方法必须在第二个参数指定打开文件的类型,返回的结果都是AudioSegment对象。

II:切割音频

# pydub does things in milliseconds

ten_seconds = 10 * 1000

first_10_seconds = song[:ten_seconds]

last_5_seconds = song[-5000:]

注意pydub中的标准时间为毫秒,上面的代码就得到了音乐的前10秒和后5秒,非常简单。

III:调整音量

# boost volume by 6dB

beginning = first_10_seconds + 6

# reduce volume by 3dB

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得到的结果是一样的。

V:将音乐翻转(reverse)

# song is not modified

# AudioSegments are immutable

backwards = song.reverse()

注意 AudioSegment 对象是不可变的,上面使用reverse方法不会改变song这个对象,而是会返回一个新的AudioSegment对象,其他的方法也是这样,需要注意。reverse简单来说就是 将音乐从尾部向头部开始逆序播放,我试了一下,发现转换之后还真的挺有意思的。

VI:crossfade(交叉渐入渐出方法)

# 1.5 second crossfade

with_style = beginning.append(end, crossfade=1500)

crossfade 就是让一段音乐平缓地过渡到另一段音乐,上面的crossfade = 1500表示过渡的时间是1.5秒。

VII:repeat(重复音乐片段)

# repeat the clip twice

do_it_over = with_style * 2

上面的代码让音乐重复播放两次

VIII:fade in and fade out(逐渐增强与逐渐减弱)

# 2 sec fade in, 3 sec fade out

awesome = 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参数,但第二种方法多了一个tags参数,其实看一下应该就很容易明白,是保存 歌曲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:

pyPortAudio/fastaudio: Python bindings for PortAudio v18 API.

tkSnack: cross-platform sound toolkit for Tcl/Tk and Python.

Pyaudio 提供了对于跨平台的PortAudio(处理audio输入输出的库)的绑定,PyAudio可以让你轻松录制与播放音频。

废话不多说,直接看官方文档(https://people.csail.mit.edu/hubert/pyaudio/docs/)提供的一个quick start的代码

"""PyAudio Example: Play a wave file."""

import pyaudio

import wave

import sys

CHUNK = 1024

if len(sys.argv) < 2:

print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])

sys.exit(-1)

wf = wave.open(sys.argv[1], 'rb')

# instantiate PyAudio (1)

p = pyaudio.PyAudio()

# open stream (2)

stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),

channels=wf.getnchannels(),

rate=wf.getframerate(),

output=True)

# read data

data = wf.readframes(CHUNK)

# play stream (3)

while len(data) > 0:

stream.write(data)

data = wf.readframes(CHUNK)

# stop stream (4)

stream.stop_stream()

stream.close()

# close PyAudio (5)

p.terminate()

当然,这个提供的是使用命令行参数接收音频文件的形式,CHUNK 是一次读取的音频byte数量,p = pyaudio.PyAudio()初始化一个

PyAudio对象,然后使用其open方法打开一个输入输出流,这里指定了output=True说明这是一个输出流,即我们是往stream中添加data,如果这里改为input = True就是变成输入流了,一般是从设备的标准audio device,对于电脑来说可能就是麦克风了,来读取音频data。使用wave打开一个.wav文件,然后使用readframes方法每次读取CHUNK这么多的数据,将数据写入stream,直到读完为止。写入stream的audio data就会不断通过麦克风播放出来了,于是我们就可以听到音乐了。最后在结束的时候,注意要关闭相应的对象以释放资源。

还有一种方法是使用callback(回调函数)函数,代码如下:

"""PyAudio Example: Play a wave file (callback version)."""

import pyaudio

import wave

import time

import sys

if len(sys.argv) < 2:

print("Plays a wave file.\n\nUsage: %s filename.wav" % sys.argv[0])

sys.exit(-1)

wf = wave.open(sys.argv[1], 'rb')

# instantiate PyAudio (1)

p = pyaudio.PyAudio()

# define callback (2)

def callback(in_data, frame_count, time_info, status):

data = wf.readframes(frame_count)

return (data, pyaudio.paContinue)

# open stream using callback (3)

stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),

channels=wf.getnchannels(),

rate=wf.getframerate(),

output=True,

stream_callback=callback)

# start the stream (4)

stream.start_stream()

# wait for stream to finish (5)

while stream.is_active():

time.sleep(0.1)

# stop stream (6)

stream.stop_stream()

stream.close()

wf.close()

# close PyAudio (7)

p.terminate()

不细说了。

下面来看一个使用pyaudio + numpy + pylab 可视化音频的代码,下面的代码打开电脑的麦克风,然后接受音频输入,再以图像的形式展示出来。

# -*- coding: utf-8 -*-

import pyaudio

import numpy as np

import pylab

import time

RATE = 44100

CHUNK = int(RATE/20) # RATE/number of updates per second

def sound_plot(stream):

t1 = time.time() # time starting

data = np.fromstring(stream.read(CHUNK),dtype = np.int16)

pylab.plot(data)

pylab.title(i)

pylab.grid()

pylab.axis([0,len(data),-2**8,2**8])

pylab.savefig("sound.png",dpi=50)

pylab.show(block = False)

time.sleep(0.5)

pylab.close('all')

print("took %.2f ms." % (time.time() - t1)*1000)

if __name__ == '__main__':

p = pyaudio.PyAudio()

stream = p.open(format = pyaudio.paInt16,channels = 1,rate = RATE,

input = True,frames_per_buffer = CHUNK)

for i in range(int(20*RATE/CHUNK)):

# for 10 seconds

sound_plot(stream)

stream.stop_stream()

stream.close()

p.terminate()

代码应该比较容易理解。得到的大概是像下面这样的图形:

1101923-20170515001627238-1598878628.png

需要注意的是,如果不是在交互式命令下执行pylab或者matplotlib的plot命令,其plt.show()函数是一个block函数,这会导致最后的

plt.close('all') 关闭所有的窗口只会在手动关闭了图像之后才会执行,所有我们无法看到连续变化的图像,为了解决这个问题,我们将plt.show()函数block参数设为False,这样show函数就不是block函数了,可以直接执行plt.close('all')命令,为了不因为图像刷新太快我们看不清变化,所以使用time.sleep(0.5)暂停0.5秒。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值