音频识别可以识别出一段未知的音频属于哪个音乐的,从第几秒开始。目前音频识别主要使用音频指纹技术,音频指纹技术通过特定的算法将一段音频中独一无二的数字特征以标识符的形式提取出来,用于识别海量的声音样本或跟踪定位样本在数据库中的位置。其中dejavu是一个非常好的音频指纹的开源项目:
项目地址:https://github.com/worldveil/dejavu
dejavu将音频通过FFT(快速傅里叶变换)转换到频域,然后获取信号在频域的峰值,将这些峰值通过哈希函数生成指纹。由于需要识别的音频通常都只是一首歌的部分片段,所以这个生成指纹的过程会将一首歌一小段一小段的加窗进行。具体原理可以参考:
算法原理:https://willdrevo.com/fingerprinting-and-audio-recognition-with-python/
下面以一个demo介绍dejavu的使用:
1、dejavu是基于python2的,这点需要注意;
2、克隆代码,并根据requirements.txt的内容安装对应的库,同时,操作系统需要安装VCForPython27.msi(根据对应的版本下载);
3、dejavu的数据库目前只支撑mysql数据库,所以需要安装mysql,并且在dejavu.cnf.SAMPLE配置文件中配置mysql连接参数(博主使用的是mysql5.7)。
4、测试demo代码
# -*- coding: UTF-8 -*-
import warnings
import json
from dejavu import Dejavu
from dejavu.recognize import FileRecognizer, MicrophoneRecognizer
class Index:
def __init__(self):
warnings.filterwarnings("ignore")
with open("dejavu.cnf.SAMPLE") as f:
config = json.load(f)
self.djv = Dejavu(config)
#保存指纹到数据库
def sava_fingerprint(self):
self.djv.fingerprint_directory("mp3", [".mp3"])
#识别音乐
def dis_fingerprint(self):
song = self.djv.recognize(FileRecognizer, "mp3test/testm1.mp3")
print "result: %s\n" % song
if __name__ == "__main__":
ind = Index()
ind.dis_fingerprint()
首先在构造函数中,读取配置文件,通过配置初始化Dejavu对象。fingerprint_directory函数对音频文件进行指纹提取,并将提取的指纹存储进数据库,函数第一个参数是文件位置,第二个参数是需要提取的音频文件格式。recognize函数进行音频的识别,第二个参数是需要识别的音频文件,识别结果如下:
result: {'song_id': 2, 'song_name': 'test2', 'file_sha1': 'A19AC6B8BA1DC564C6C079B714861D68A505E010', 'confidence': 2097, 'offset_seconds': 100.12444, 'match_time': 4.577000141143799, 'offset': 2156}
song_id是数据库中歌曲的id,song_name是歌曲的名称,offset_seconds是被识别音频位于歌曲的第几秒。
音频指纹技术比较消耗存储和性能,一首几M的歌曲,数据库中生成的指纹可以达到20万条。所以在实际应用的过程中,需要就指纹的检索进行优化,数据库也应该基于大数据库架构。