纯音乐库特征提取

jinhezx2周前python17

# 安装musly(Python绑定) pip install musly-python # 安装FAISS(CPU版,GPU版需单独编译) pip install faiss-cpu # 其他依赖 pip install librosa soundfile numpy pandas tqdm


import os import musly import faiss import numpy as np import pandas as pd from tqdm import tqdm import librosa # ===================== 配置参数 ===================== MUSIC_DIR = "./pure_music_library/"  # 你的纯音乐目录 INDEX_PATH = "./music_index.faiss"    # FAISS索引保存路径 METADATA_PATH = "./music_metadata.csv" # 音乐路径-特征映射表 SIMILAR_TOP_K = 10                     # 检索返回最相似的K首 # ===================== 工具函数 ===================== def get_audio_files(dir_path):    """获取目录下所有音频文件(WAV/MP3)"""    audio_ext = (".wav", ".mp3", ".flac", ".ogg")    audio_files = []    for root, _, files in os.walk(dir_path):        for file in files:            if file.lower().endswith(audio_ext):                audio_files.append(os.path.join(root, file))    return audio_files def extract_musly_feature(audio_path):    """使用Musly提取音频特征(timbre模式,纯音乐首选)"""    try:        # 初始化Musly(timbre模式:适合纯音乐音色/风格匹配)        music_analyzer = musly.Analyzer()        # 加载音频并提取特征(返回定长向量)        feature = music_analyzer.analyze(audio_path, musly.MuslyTimbre)        return feature.astype(np.float32)  # FAISS要求float32    except Exception as e:        print(f"提取特征失败 {audio_path}: {e}")        return None # ===================== 构建索引 ===================== def build_music_index():    """提取特征并构建FAISS索引"""    # 1. 获取所有音频文件    audio_files = get_audio_files(MUSIC_DIR)    if not audio_files:        print("未找到音频文件!")        return        # 2. 批量提取Musly特征    features = []    valid_files = []    for file in tqdm(audio_files, desc="提取Musly特征"):        feat = extract_musly_feature(file)        if feat is not None:            features.append(feat)            valid_files.append(file)        # 3. 保存元数据(文件路径-索引映射)    metadata = pd.DataFrame({"file_path": valid_files})    metadata.to_csv(METADATA_PATH, index=False, encoding="utf-8")        # 4. 构建FAISS索引(L2距离:适配Musly特征分布)    feature_matrix = np.vstack(features)    dim = feature_matrix.shape[1]  # Musly特征维度(默认~200维)        # 选择索引类型:IVF_FLAT适合百万级数据,速度快    index = faiss.IndexIVFFlat(        faiss.IndexFlatL2(dim),  # 基础索引(L2距离)        dim,        min(100, len(valid_files)//10),  # 聚类数(经验值)        faiss.METRIC_L2    )        # 训练+添加数据    index.train(feature_matrix)    index.add(feature_matrix)        # 5. 保存索引    faiss.write_index(index, INDEX_PATH)    print(f"索引构建完成!共处理 {len(valid_files)} 首音乐,索引保存至 {INDEX_PATH}") # ===================== 相似检索 ===================== def search_similar_music(query_audio_path):    """检索与查询音频最相似的音乐"""    # 1. 加载索引和元数据    if not os.path.exists(INDEX_PATH) or not os.path.exists(METADATA_PATH):        print("索引/元数据不存在,先构建索引!")        build_music_index()        index = faiss.read_index(INDEX_PATH)    metadata = pd.read_csv(METADATA_PATH, encoding="utf-8")        # 2. 提取查询音频特征    query_feat = extract_musly_feature(query_audio_path)    if query_feat is None:        print("查询音频特征提取失败!")        return []        # 3. FAISS检索(返回距离和索引)    query_feat = query_feat.reshape(1, -1)  # 转为2D数组    distances, indices = index.search(query_feat, SIMILAR_TOP_K)        # 4. 解析结果(距离越小越相似)    similar_results = []    for i, idx in enumerate(indices[0]):        file_path = metadata.iloc[idx]["file_path"]        similar_results.append({            "rank": i+1,            "file_path": file_path,            "distance": distances[0][i]  # 距离越小,相似度越高        })        return similar_results # ===================== 主函数 ===================== if __name__ == "__main__":    # 第一步:构建索引(首次运行执行)    build_music_index()        # 第二步:示例:检索相似音乐    query_audio = "./test_piano.mp3"  # 你的查询纯音乐文件    if os.path.exists(query_audio):        similar_music = search_similar_music(query_audio)        print(f"\n与 {query_audio} 最相似的{SIMILAR_TOP_K}首音乐:")        for res in similar_music:            print(f"排名{res['rank']} | 距离{res['distance']:.4f} | 路径:{res['file_path']}")    else:        print(f"查询文件 {query_audio} 不存在!")

返回列表

上一篇:ByteCover算法核心复现代码

没有最新的文章了...

相关文章

Windows下安装Flask

Flask介绍是一个轻量级的 Web应用框架, 使用 Python编写。基于 Werkzeug WSGI工具箱和 Jinja2 模板引擎。 Flask使用 BSD 授权。Flask也被称为 “micr...

ByteCover算法核心复现代码

# 安装依赖:pip install librosa numpy scipy import librosa import nu...