五家渠市网站建设_网站建设公司_MongoDB_seo优化
2026/1/21 5:32:09 网站建设 项目流程

CAM++ API接口怎么写?Flask封装代码实例

1. 为什么需要API接口?

你已经用上了科哥开发的CAM++说话人识别系统,界面友好、功能清晰,点点鼠标就能完成语音比对和特征提取。但如果你是个开发者,或者想把这套能力集成到自己的项目里——比如做个声纹登录系统、智能门禁、语音客服身份核验——那光靠网页操作就不够用了。

这时候,你就需要一个API接口

API(Application Programming Interface)就像是给这个系统装了个“遥控器”,让你不用打开浏览器,也能远程调用它的核心能力:说话人验证、特征提取。而Flask,就是我们用来打造这个遥控器的工具。

本文不讲大道理,只干一件事:手把手教你如何用Flask把CAM++的功能封装成可调用的HTTP接口,并提供完整可运行的代码示例。小白也能看懂,照着做就能用。


2. 系统能力拆解:我们能封装什么?

在动手前,先搞清楚CAM++到底能做什么。从用户手册来看,它有两个核心功能:

  • 说话人验证:输入两段音频,判断是不是同一个人
  • 特征提取:输入一段音频,输出192维的Embedding向量

我们的目标是:让别人通过发个HTTP请求,就能拿到这两个结果

比如这样:

curl -X POST http://localhost:5000/verify \ -F "audio1=@voice1.wav" \ -F "audio2=@voice2.wav"

返回:

{ "similarity": 0.8523, "is_same_speaker": true, "threshold": 0.31 }

这才是真正的“工程化落地”。


3. Flask快速入门:三步搭起服务架子

Flask是一个轻量级Python Web框架,几行代码就能启动一个Web服务。我们不需要复杂的前端,只要能接收文件、调用模型、返回JSON就行。

3.1 安装依赖

确保你已经在系统中安装了Flask:

pip install flask

3.2 最简服务示例

先写个最简单的“Hello World”服务,确认环境没问题:

from flask import Flask app = Flask(__name__) @app.route('/') def home(): return "CAM++ API服务已启动!" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

保存为app.py,运行:

python app.py

访问http://你的IP:5000,看到文字说明服务起来了。


4. 封装特征提取接口:上传音频 → 返回Embedding

我们先实现第一个功能:上传一段音频,返回192维特征向量

4.1 接口设计

  • URL:/extract
  • 方法: POST
  • 参数: 音频文件audio
  • 返回: JSON格式的Embedding数组

4.2 核心代码实现

from flask import Flask, request, jsonify import numpy as np import os from werkzeug.utils import secure_filename # 假设你已经有了CAM++的推理函数 # 这里用mock函数模拟实际调用 def extract_embedding(audio_path): """ 模拟调用CAM++模型提取特征 实际使用时替换为真实模型加载和推理代码 """ # 加载预训练模型(伪代码) # model = load_model('/root/speech_campplus_sv_zh-cn_16k/model.pth') # 读取音频并预处理 # audio_data = read_audio(audio_path, sample_rate=16000) # 推理得到192维向量 # embedding = model.inference(audio_data) # 这里用随机数代替真实输出,仅用于演示 np.random.seed(42) # 固定种子,保证每次结果一致 embedding = np.random.randn(192).astype(np.float32) return embedding.tolist() # 转为Python list以便JSON序列化 app = Flask(__name__) app.config['UPLOAD_FOLDER'] = '/tmp/audio_uploads' os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) @app.route('/extract', methods=['POST']) def api_extract(): if 'audio' not in request.files: return jsonify({'error': '缺少音频文件'}), 400 file = request.files['audio'] if file.filename == '': return jsonify({'error': '未选择文件'}), 400 # 保存上传的文件 filename = secure_filename(file.filename) filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(filepath) try: # 调用特征提取函数 embedding = extract_embedding(filepath) # 清理临时文件(可选) # os.remove(filepath) return jsonify({ 'success': True, 'filename': filename, 'embedding_dim': 192, 'embedding': embedding }) except Exception as e: return jsonify({'error': str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

4.3 如何测试?

保存为extract_api.py,运行后执行:

curl -X POST http://localhost:5000/extract \ -F "audio=@/path/to/your/audio.wav"

你会看到类似这样的返回:

{ "success": true, "filename": "test.wav", "embedding_dim": 192, "embedding": [0.4967, -0.1382, ..., 0.2345] }

注意:当前extract_embedding是模拟函数。要真正跑通,你需要把CAM++的模型加载和推理逻辑接入进来,这部分可以参考ModelScope官方文档或科哥提供的脚本。


5. 封装说话人验证接口:比对两段语音

接下来实现更实用的功能:上传两段音频,返回相似度和判定结果

5.1 接口设计

  • URL:/verify
  • 方法: POST
  • 参数:audio1,audio2,threshold(可选)
  • 返回: 相似度分数 + 是否同一人

5.2 完整代码实现

from flask import Flask, request, jsonify import numpy as np import os from werkzeug.utils import secure_filename # 模拟特征提取函数(实际应对接真实模型) def extract_embedding(audio_path): np.random.seed(hash(os.path.basename(audio_path)) % (2**32)) # 不同文件不同结果 return np.random.randn(192).astype(np.float32) def cosine_similarity(emb1, emb2): emb1_norm = emb1 / np.linalg.norm(emb1) emb2_norm = emb2 / np.linalg.norm(emb2) return np.dot(emb1_norm, emb2_norm) app = Flask(__name__) app.config['UPLOAD_FOLDER'] = '/tmp/audio_uploads' os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) @app.route('/verify', methods=['POST']) def api_verify(): if 'audio1' not in request.files or 'audio2' not in request.files: return jsonify({'error': '请上传两个音频文件'}), 400 file1 = request.files['audio1'] file2 = request.files['audio2'] if file1.filename == '' or file2.filename == '': return jsonify({'error': '文件名不能为空'}), 400 threshold = float(request.form.get('threshold', 0.31)) # 默认阈值0.31 # 保存文件 path1 = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(file1.filename)) path2 = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(file2.filename)) file1.save(path1) file2.save(path2) try: # 提取特征 emb1 = extract_embedding(path1) emb2 = extract_embedding(path2) # 计算相似度 similarity = cosine_similarity(emb1, emb2) # 判断是否同一人 is_same = bool(similarity > threshold) # 删除临时文件(生产环境可配置保留) # os.remove(path1) # os.remove(path2) return jsonify({ 'similarity': round(float(similarity), 4), 'threshold': threshold, 'is_same_speaker': is_same, 'message': '是同一人' if is_same else '不是同一人' }) except Exception as e: return jsonify({'error': str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True)

5.3 测试命令

curl -X POST http://localhost:5000/verify \ -F "audio1=@speaker1_a.wav" \ -F "audio2=@speaker1_b.wav" \ -F "threshold=0.31"

返回示例:

{ "similarity": 0.8523, "threshold": 0.31, "is_same_speaker": true, "message": "是同一人" }

6. 生产优化建议:让API更稳定好用

上面的代码能跑通,但在真实场景中还需要一些改进。

6.1 文件类型校验

防止用户上传非音频文件:

def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in {'wav', 'mp3', 'm4a', 'flac'} # 在接收文件时检查 if not allowed_file(file.filename): return jsonify({'error': '不支持的文件格式'}), 400

6.2 音频格式统一处理

推荐使用pydub自动转码为16kHz WAV:

pip install pydub
from pydub import AudioSegment def convert_to_wav(input_path, output_path): audio = AudioSegment.from_file(input_path) audio = audio.set_frame_rate(16000).set_channels(1) audio.export(output_path, format='wav')

6.3 错误码规范化

定义统一错误码,便于前端处理:

ERRORS = { 1001: "缺少音频文件", 1002: "文件格式不支持", 1003: "音频处理失败", 1004: "模型推理异常" }

6.4 日志记录

加日志方便排查问题:

import logging logging.basicConfig(level=logging.INFO) app.logger.info(f"接收到验证请求: {file1.filename} vs {file2.filename}")

7. 总结:你已经拥有了一个可用的声纹API服务

我们一步步完成了以下工作:

  • 理解了CAM++的核心能力
  • 用Flask搭建了Web服务基础
  • 实现了特征提取说话人验证两个关键API
  • 提供了完整的可运行代码
  • 给出了生产级优化建议

你现在可以把这个API集成到任何系统中:

  • App端上传录音做身份核验
  • 后台批量处理历史录音做聚类分析
  • 和数据库结合构建声纹库
  • 作为微服务部署在Docker中

记住:技术的价值不在于多复杂,而在于能不能解决问题。这个小小的Flask服务,可能就是你下一个AI产品的起点。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询