您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(进阶篇)
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(进阶篇)
jd****
2026-07-30
IP归属:北京
415浏览
## 项目介绍 这是一个 **AI 驱动的音频内容创作助手**。你可以用自然语言与它对话,它会理解意图、调用相应的语音合成工具,把文字变成真实的播客音频,并保存在本地。 关于项目的详细介绍见第一篇文章:[http://sd.jd.com/article/66149?shareId=56999&isHideShareButton=1](第一个 AI Agent 项目:从零搭建 AI 音频创作助手) 这篇文章更多介绍进阶篇添加的功能 ## 更新概览 本次更新新增了完整的**播客后期制作能力**,包括音频拼接、智能BGM选择、音轨混音三大核心功能,同时新增了音频资源管理API和语音输入功能,实现了从前端上传、语音输入到后端处理的全链路闭环。 --- ## 后端更新 ### 1. 音频混音工具模块 新增 [`backend/app/tools/audio_mixing.py`](backend/app/tools/audio_mixing.py),提供三个核心音频处理工具: #### 1.1 音频拼接工具(`concatenate_audio`) 将多个音频片段按顺序拼接成完整对话,适用于播客场景。 **核心功能**: - 支持交叉淡入淡出过渡(crossfade),使音频过渡更自然 - 可配置音频片段之间的静音时长(默认1200ms,播客推荐1000-1500ms) - 自动生成带时间戳的唯一文件名 - 自动记录到音频索引系统 **代码示例**: ```python @tool("concatenate_audio", args_schema=ConcatenateAudioInput) def concatenate_audio_tool( audio_files: List[str], # 音频文件路径列表 crossfade_duration: int = 200, # 交叉淡入淡出时长(ms) silence_duration: int = 1200 # 静音间隔(ms) ) -> str: """ 拼接逻辑: 1. 加载所有音频片段 → AudioSegment.from_file() 2. 依次拼接,支持两种模式: - crossfade > 0:交叉淡入淡出过渡 - silence > 0:静音间隔拼接 3. 导出为 WAV 文件并记录索引 """ ``` **使用场景**:将多个角色的语音片段拼接成播客对话。 #### 1.2 智能BGM选择工具(`select_background_music`) 根据场景描述智能匹配合适的背景音乐。 **核心功能**: - 基于文件名的语义匹配(BGM文件名即场景描述) - 自动循环播放或裁剪以匹配目标时长 - 支持直接指定BGM文件路径 - 自动添加淡出效果 **代码示例**: ```python @tool("select_background_music", args_schema=SelectBGMInput) def select_bgm_tool( scene_description: str, # 场景描述,如"欢快的开场" duration_seconds: Optional[float] = None, # 期望时长 bgm_audio_path: Optional[str] = None # 指定BGM路径 ) -> str: """ 匹配逻辑: 1. 如果指定了 bgm_audio_path,直接使用 2. 否则扫描 storage/bgm/ 目录下所有 .mp3/.wav 文件 3. 基于文件名与 scene_description 的关键词匹配度打分 4. 选择得分最高的BGM,必要时循环/裁剪匹配时长 """ ``` **使用场景**:为播客对话选择合适的背景音乐。 #### 1.3 音频混音工具(`mix_audio_with_bgm`) 将人声对话与背景音乐混合,生成专业的播客成品。 **核心功能**: - **专业BGM开场效果**: - 前N秒(默认3秒):BGM原音量播放 - 过渡阶段:音量渐变至背景音量 - 后续阶段:BGM降低至约5%音量作为背景 - 音量归一化处理,确保音质一致性 - 自动淡出效果 - 支持自定义BGM音量(推荐-24到-28dB) **代码示例**: ```python @tool("mix_audio_with_bgm", args_schema=MixAudioWithBGMInput) def mix_audio_with_bgm_tool( voice_audio: str, # 主音频路径(人声) bgm_audio: str, # BGM路径 bgm_volume: float = -26, # BGM背景音量(dB) intro_duration: float = 3.0, # BGM开场时长(秒) normalize: bool = True # 是否归一化 ) -> str: """ 混音逻辑: 1. 加载人声和BGM音频 2. BGM分段处理: - 开场段:原音量播放 intro_duration 秒 - 过渡段:20步渐变从原音量到 bgm_volume - 背景段:固定 bgm_volume 音量 3. 人声前插入静音(与BGM开场对齐) 4. 叠加人声到BGM → bgm_processed.overlay(voice_with_intro) 5. 可选归一化 + 淡出,导出为 MP3 """ ``` **音量变化曲线**: ``` BGM 音量变化: 原音量 ─────┐ │\ │ \ 过渡时段(2秒) │ \ 背景音量 ───┘ └────────── 背景音量 ↑ 开场时段(3秒) ``` ### 2. 音频资源管理API 新增 [`backend/app/routers/resources.py`](backend/app/routers/resources.py),提供音频资源的RESTful API。 #### 2.1 接口列表 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/resources/audio` | 查询所有音频资源列表 | | POST | `/resources/audio/upload` | 上传音频文件(支持 .mp3 和 .wav) | | DELETE | `/resources/audio/{id}` | 删除指定音频资源 | #### 2.2 上传接口代码示例 ```python @router.post("/audio/upload", response_model=UploadResponse) async def upload_audio_resource(file: UploadFile = File(...)): """上传音频文件,存储到 BGM_DIR 并记录到索引""" # 1. 校验文件格式(仅支持 .mp3 和 .wav) ext = os.path.splitext(file.filename)[1].lower() if ext not in UPLOAD_ALLOWED_EXTENSIONS: raise HTTPException(status_code=400, detail=f"不支持的文件格式") # 2. 生成唯一文件名,避免冲突 voice_id = str(uuid.uuid4()) safe_filename = f"{name_without_ext}{voice_id}{ext}" # 3. 保存文件到 storage/bgm/ with open(save_path, "wb") as f: shutil.copyfileobj(file.file, f) # 4. 记录到音频索引 record_voice_index(local_path=save_path, voice=voice_id, model_name="", path="bgm") return UploadResponse(success=True, message="上传成功", voice_id=voice_id) ``` #### 2.3 删除接口代码示例 ```python @router.delete("/audio/{id}", response_model=DeleteResponse) async def delete_audio_resource(id: str): """删除音频资源:移除索引记录 + 删除物理文件""" # 1. 从 voice_index.json 中查找匹配记录 matched = [r for r in voice_index if r.get("id") == id] # 2. 删除对应的本地文件 for record in matched: filepath = os.path.abspath(record.get("local_path", "")) os.remove(filepath) # 3. 从索引中移除并写回 voice_index = [r for r in voice_index if r.get("id") != id] with open(index_path, "w", encoding="utf-8") as f: json.dump(voice_index, f, ensure_ascii=False, indent=2) return DeleteResponse(success=True, message="删除成功") ``` ### 3. 音频索引系统 新增 [`backend/app/tools/audio_index.py`](backend/app/tools/audio_index.py),提供统一的音频索引管理,供各工具模块共享调用。 **代码示例**: ```python def record_voice_index(local_path: str, voice: str, model_name: str = "", path: str = "audios") -> None: """将音频文件信息记录到 voice_index.json 索引文件中 Args: local_path: 音频文件本地路径 voice: 音色ID model_name: 模型名称 path: 音频存储路径类型 (audios/bgm/podcasts) """ # 读取已有索引 → 追加新记录 → 写回文件 new_record = { "id": str(uuid.uuid4()), "local_path": local_path, "voice_id": voice, "model_name": model_name, "path": path, "createTime": datetime.now().strftime("%Y-%m-%d %H:%M:%S") } index.append(new_record) VOICE_INDEX_FILE.write_text(json.dumps(index, ensure_ascii=False, indent=2)) ``` **path 字段说明**: | path 值 | 说明 | 存储目录 | |---------|------|----------| | `audios` | TTS生成的音频 | `storage/audios/` | | `bgm` | 上传的背景音乐 | `storage/bgm/` | | `podcasts` | 混音生成的播客成品 | `storage/podcasts/` | ### 4. 新增依赖 ```bash pip install pydub ``` > **注意**:pydub 需要系统安装 [FFmpeg](https://ffmpeg.org/)。macOS: `brew install ffmpeg`,Ubuntu: `sudo apt install ffmpeg`。 ### 5. 存储目录结构更新 ``` storage/ ├── audios/ # TTS生成的音频 ├── bgm/ # 背景音乐(新增) ├── podcasts/ # 播客成品(新增) ├── voice_index.json # 音频索引(统一管理) └── images/ # 图片文件 ``` --- ## 前端更新 ### 1. 音频资源API对接 新增上传音频文件和删除音频资源功能,对应 [`fronted/src/api/resource.ts`](fronted/src/api/resource.ts) 中的两个新接口 ### 2. 语音输入转文字 在聊天输入框中新增语音输入功能,用户可以通过麦克风将语音转换为文字发送消息。 **组件位置**:[`fronted/src/components/ai-elements/prompt-input/PromptInputSpeechButton.vue`](fronted/src/components/ai-elements/prompt-input/PromptInputSpeechButton.vue) **使用方式**:在 [`ChatAgent.vue`](fronted/src/views/ChatAgent.vue) 的输入区域中集成麦克风按钮: ```text <PromptInputFooter> <PromptInputSpeechButton /> </PromptInputFooter> ``` **技术实现**: - 基于 **Web Speech API**(`SpeechRecognition` / `webkitSpeechRecognition`)实现浏览器端语音识别 - 默认语言为中文(`zh-CN`),支持通过 `lang` 属性配置 - 支持连续识别(`continuous: true`)和中间结果(`interimResults: true`) - 识别完成后自动将文字填入输入框,智能处理中英文空格 **核心代码**: ```typescript // 初始化语音识别 const sr = new SpeechRecognition() sr.continuous = true // 连续识别 sr.interimResults = true // 返回中间结果 sr.lang = 'zh-CN' // 默认中文 // 识别结果回调 sr.onresult = (event) => { let finalTranscript = '' for (let i = event.resultIndex; i < event.results.length; i++) { if (event.results[i].isFinal) { finalTranscript += event.results[i][0]?.transcript ?? '' } } if (finalTranscript) { // 智能添加空格:中文不加空格,英文前加空格 const needsSpace = textInput.value && !/[\u4e00-\u9fa5]/.test(textInput.value.slice(-1)) setTextInput(textInput.value + (needsSpace ? ' ' : '') + finalTranscript) } } ``` **交互效果**: - 点击麦克风按钮开始录音,按钮显示脉冲动画 - 再次点击停止录音 - 识别结果自动追加到输入框文本中 - 不支持 Web Speech API 的浏览器自动禁用按钮 --- ## 使用场景 ### 完整的播客制作流程 1. **准备阶段**:通过前端上传背景音乐到 `storage/bgm/` 目录 2. **对话生成**:Agent 调用 TTS 工具生成多个角色的语音片段 3. **音频拼接**:Agent 调用 `concatenate_audio` 工具拼接对话 4. **BGM选择**:Agent 调用 `select_background_music` 工具匹配背景音乐 5. **混音合成**:Agent 调用 `mix_audio_with_bgm` 工具生成最终播客成品 6. **资源管理**:通过前端查看、播放、删除所有音频资源 ### 语音输入交互流程 1. 用户点击聊天输入框旁的麦克风按钮 2. 浏览器请求麦克风权限 3. 开始录音,按钮显示脉冲动画 4. 语音实时识别为文字 5. 识别结果自动填入输入框 6. 用户按 Enter 发送消息 --- ## 升级指南 ### 后端升级 1. **安装新依赖**: ```bash cd backend pip install pydub ``` 2. **安装 FFmpeg**(如未安装): ```bash # macOS brew install ffmpeg # Ubuntu sudo apt install ffmpeg ``` 3. **创建新目录**: ```bash cd backend mkdir -p storage/bgm storage/podcasts ``` 4. **准备背景音乐**: - 将 `.mp3` 或 `.wav` 格式的背景音乐文件放入 `storage/bgm/` 目录 - 文件名建议使用场景描述(如 `欢快的开场.mp3`、`深沉的讨论.mp3`) 5. **重启服务**: ```bash python main.py ``` ### 前端升级 无需额外操作,API 调用逻辑和语音输入组件已在现有代码中集成。 --- ## 技术亮点 1. **专业的音频处理**:支持交叉淡入淡出、音量归一化等专业特性 2. **智能BGM匹配**:基于文件名的语义匹配,易于扩展为向量检索 3. **统一索引管理**:所有音频资源统一管理,支持查询、上传、删除等操作 4. **浏览器端语音识别**:基于 Web Speech API,无需后端支持,零延迟 5. **全链路闭环**:从前端上传、语音输入到后端处理,完整的数据流转 --- ## 结果展示   具体音频在podcasts里面 
上一篇:【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(高级篇)
下一篇:【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手
jd****
文章数
5
阅读量
3955
作者其他文章
01
【MCP】同时支持stdio,streamableHttpless和sse三种协议的MCP服务框架
项目说明这是一个同时支持stdio,streamableHttpless和sse三种协议的MCP-Server的框架(ts语言)。 为什么我想做这个框架呢?因为随着AI发展,现在越来越多业务需要和AI相结合。而我在做AI应用中发现,MCP服务在AI方向的业务使用频率很高,但随着业务的加深,发现存在以下痛点:针对不同业务,对于mcp-server需要的类型不同,有的就需要stdio,有的需要网络请求
01
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手【最终版】
从零到一,全栈手搓 AI 智能播客平台——我的完整开发手记引言:这个项目是做什么的?Smart Podcast Platform 是一个端到端的智能播客制作平台。它的核心能力很简单:用户上传一段视频或音频,AI 自动理解内容、设计音色、生成播客,全程无需人工干预。传统的 AI 音频工具通常停留在”生成文字脚本”的层面——用户拿到脚本后,还需要自己找配音、做剪辑、调音效,整个流程割裂且低效。这个项目
01
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(高级篇)
项目介绍这是一个 AI 驱动的播客创作助手,专注于从文字/视频/音频内容识别到播客制作的全流程。你可以用自然语言与它对话,也可以上传视频和音频,它会理解意图、调用相应的语音合成工具,把他们变成真实的播客音频。关于项目的详细介绍见以下文章:1.http://sd.jd.com/article/66149?shareId=56999&isHideShareButton=1 : 这个是第一版本,里面主要
01
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(进阶篇)
项目介绍这是一个 AI 驱动的音频内容创作助手。你可以用自然语言与它对话,它会理解意图、调用相应的语音合成工具,把文字变成真实的播客音频,并保存在本地。关于项目的详细介绍见第一篇文章:http://sd.jd.com/article/66149?shareId=56999&isHideShareButton=1这篇文章更多介绍进阶篇添加的功能更新概览本次更新新增了完整的播客后期制作能力,包括音频拼
jd****
文章数
5
阅读量
3955
作者其他文章
01
【MCP】同时支持stdio,streamableHttpless和sse三种协议的MCP服务框架
01
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手【最终版】
01
【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(高级篇)
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号