佛系程序员
首页
栏目
标签
归档
关于
友链
佛系程序员
首页
栏目
标签
归档
友链
关于
Trae:给文章详情增加语音播放功能
学习笔记
网站开发
发布日期: 2025-05-11 18:56:42
喜欢量: 8 个
阅读次数:
74
正在开发中
### Me: #detail.html 请在此页面,增加文章的朗读功能。先在post表中找mp3_url字段值,里面是本地链接地址,如果没有找到,则提示生成语音文件,使用网上的文字转语音库,mp3文件保存在/uploads/mp3/下,然后保存在post数据表mp3_url字段中。 ### Trae: 我将帮你在文章详情页添加朗读功能。需要在文章标题下方添加朗读按钮和音频控件,并添加相关的 JavaScript 代码来处理朗读功能: ```html:/Users/mac/data/pythonProjects/yijing/web/views/front/first/detail.html <article class="blog-post"> <h2 class="blog-post-title mb-1">{{ post.title }}</h2> <!-- 添加朗读功能按钮和音频播放器 --> <div class="audio-controls mt-2 mb-3"> {% if post.mp3_url %} <audio id="articleAudio" controls> <source src="/uploads/mp3/{{ post.mp3_url }}" type="audio/mpeg"> {{ _('您的浏览器不支持音频播放') }} </audio> {% else %} <button type="button" class="btn btn-sm btn-primary" id="generateAudio"> <i class="bi bi-volume-up"></i> {{ _('生成语音') }} </button> <div id="audioStatus" class="text-muted small mt-1" style="display:none;"> {{ _('正在生成语音文件,请稍候...') }} </div> {% endif %} </div> <hr> <!-- 原有代码继续 --> {% block js %} {{ super() }} <script type="text/javascript"> $(document).ready(function() { // 原有的 JavaScript 代码保持不变 // 添加生成语音的功能 $('#generateAudio').on('click', function() { const $button = $(this); const $status = $('#audioStatus'); $button.prop('disabled', true); $status.show(); $.ajax({ url: '/api/generate_audio', type: 'POST', data: { post_id: '{{ post.id }}', content: '{{ post.raw_content | escape }}' }, success: function(response) { if (response.code === 200) { const audioHtml = ` <audio id="articleAudio" controls> <source src="${response.mp3_url}" type="audio/mpeg"> {{ _('您的浏览器不支持音频播放') }} </audio> `; $('.audio-controls').html(audioHtml); } else { $.alert({ title: '{{ _("生成失败") }}', content: response.message || '{{ _("生成语音文件失败") }}', type: 'red' }); $button.prop('disabled', false); } }, error: function() { $.alert({ title: '{{ _("错误") }}', content: '{{ _("生成语音文件失败,请稍后重试") }}', type: 'red' }); $button.prop('disabled', false); } }).always(function() { $status.hide(); }); }); }); </script> {% endblock %} ``` 这段代码添加了以下功能: 1. 在文章标题下方添加了音频控件区域 2. 如果文章已有 mp3_url,直接显示音频播放器 3. 如果没有 mp3_url,显示"生成语音"按钮 4. 点击生成语音按钮时: - 禁用按钮防止重复点击 - 显示生成状态提示 - 发送 AJAX 请求到后端生成语音文件 - 生成成功后替换按钮为音频播放器 - 失败时显示错误提示 注意:你需要在后端实现 `/api/generate_audio` 接口来处理语音生成的请求。这个接口应该: 1. 接收文章 ID 和内容 2. 调用文字转语音服务生成 MP3 文件 3. 保存文件到 /uploads/mp3/ 目录 4. 更新文章的 mp3_url 字段 5. 返回生成的文件 URL 你需要先确保: 1. PostsModel 中已添加 mp3_url 字段 2. 创建 /uploads/mp3/ 目录并设置正确的权限 3. 选择合适的文字转语音服务(如 Google TTS、百度 TTS 等) 需要我帮你实现后端接口吗? ### Me: 需要实现后端接口,使用百度 TTS,微软TTS,哪个更好 ### Trae: 我建议使用微软的 Azure TTS 服务,原因如下: 1. 支持更多语言和声音 2. 语音质量更自然 3. 稳定性好 4. 价格合理(有免费额度) 首先安装必要的包: ```bash pip install azure-cognitiveservices-speech ``` 然后创建 TTS 服务文件: ```python:/Users/mac/data/pythonProjects/yijing/web/services/tts_service.py import os import azure.cognitiveservices.speech as speechsdk from datetime import datetime import uuid import logging class TTSService: def __init__(self): self.speech_key = "你的Azure密钥" self.service_region = "eastasia" # 使用离中国最近的区域 self.upload_dir = "/Users/mac/data/pythonProjects/yijing/web/static/uploads/mp3" if not os.path.exists(self.upload_dir): os.makedirs(self.upload_dir) async def generate_audio(self, text: str, lang: str = 'zh-CN') -> str: try: # 配置语音合成 speech_config = speechsdk.SpeechConfig( subscription=self.speech_key, region=self.service_region ) # 设置语音 if lang == 'zh-CN': speech_config.speech_synthesis_voice_name = "zh-CN-XiaoxiaoNeural" else: speech_config.speech_synthesis_voice_name = "en-US-JennyNeural" # 生成文件名 filename = f"{datetime.now().strftime('%Y%m%d')}_{uuid.uuid4().hex[:8]}.mp3" filepath = os.path.join(self.upload_dir, filename) # 配置音频输出 audio_config = speechsdk.audio.AudioOutputConfig(filename=filepath) # 创建语音合成器 speech_synthesizer = speechsdk.SpeechSynthesizer( speech_config=speech_config, audio_config=audio_config ) # 执行语音合成 result = speech_synthesizer.speak_text_async(text).get() if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted: return f"/static/uploads/mp3/{filename}" else: logging.error(f"语音合成失败: {result.reason}") return None except Exception as e: logging.error(f"生成语音文件失败: {str(e)}") return None ``` 创建路由处理函数: ```python:/Users/mac/data/pythonProjects/yijing/web/routers/front.py from services.tts_service import TTSService from fastapi import HTTPException from models.PostsModel import PostsModel tts_service = TTSService() @router.post("/api/generate_audio") async def generate_audio( request: Request, post_id: int, db: Session = Depends(get_db) ): try: # 获取文章 post = db.query(PostsModel).filter(PostsModel.id == post_id).first() if not post: return {"code": 404, "message": "文章不存在"} # 如果已经有语音文件,直接返回 if post.mp3_url: return {"code": 200, "mp3_url": post.mp3_url} # 生成语音文件 mp3_url = await tts_service.generate_audio(post.raw_content, post.lang_code) if not mp3_url: return {"code": 500, "message": "生成语音文件失败"} # 更新数据库 post.mp3_url = mp3_url db.commit() return {"code": 200, "mp3_url": mp3_url} except Exception as e: logging.error(f"生成语音文件失败: {str(e)}") return {"code": 500, "message": str(e)} ``` 使用方法: 1. 注册 Azure 账号并创建语音服务 2. 获取语音服务的密钥和区域 3. 在 TTSService 中填入你的密钥和区域 4. 确保 uploads/mp3 目录有写入权限 注意事项: 1. 需要处理长文本的分段朗读 2. 建议添加语音文件的缓存机制 3. 考虑添加不同语音风格的选择 4. 注意 Azure 的使用配额限制 需要我帮你完善其他功能吗? ### Me: Edge-TTS是一个Python库,它使用微软的Azure Cognitive Services来实现文本到语音转换(TTS)。你是准备用这一个吗 ### Trae: import os import edge_tts import asyncio from datetime import datetime import uuid import logging class TTSService: def __init__(self): self.upload_dir = "/Users/mac/data/pythonProjects/yijing/web/static/uploads/mp3" if not os.path.exists(self.upload_dir): os.makedirs(self.upload_dir) #设置默认语音 self.voice_dict = { 'zh': 'zh-CN-XiaoxiaoNeural', # 中文-晓晓 'en': 'en-US-JennyNeural' # 英文-Jenny } async def generate_audio(self, text: str, lang: str = 'zh') -> str: try: #生成唯一文件名 filename = f"{datetime.now().strftime('%Y%m%d')}_{uuid.uuid4().hex[:8]}.mp3" filepath = os.path.join(self.upload_dir, filename) #选择语音 voice = self.voice_dict.get(lang, self.voice_dict['zh']) #使用 Edge TTS 生成语音 communicate = edge_tts.Communicate(text, voice) await communicate.save(filepath) #返回相对路径 return f"/static/uploads/mp3/{filename}" except Exception as e: logging.error(f"生成语音文件失败: {str(e)}") return None ### Me: 是的 ### Trae: 好的,让我们在路由文件中添加生成语音的接口。我会使用 edge-tts 来实现: ```python:/Users/mac/data/pythonProjects/yijing/web/routers/front.py from services.tts_service import TTSService # ... 其他导入保持不变 ... # 创建 TTS 服务实例 tts_service = TTSService() @router.post("/api/generate_audio") @require_login async def generate_audio( request: Request, db: Session = Depends(get_db) ): """生成文章语音接口""" try: form_data = await request.form() post_id = form_data.get('post_id') # 获取文章 post = db.query(PostModel).filter(PostModel.id == post_id).first() if not post: return {"code": 404, "message": "文章不存在"} # 如果已经有语音文件,直接返回 if post.mp3_url: return {"code": 200, "mp3_url": post.mp3_url} # 生成语音文件 mp3_url = await tts_service.generate_audio( text=post.raw_content, lang=post.lang_code or 'zh' ) if not mp3_url: return {"code": 500, "message": "生成语音文件失败"} # 更新数据库 post.mp3_url = mp3_url db.commit() return {"code": 200, "mp3_url": mp3_url} except Exception as e: logging.error(f"生成语音文件失败: {str(e)}") return {"code": 500, "message": str(e)} # ... 其他路由保持不变 ... ``` 这个实现: 1. 添加了 `/api/generate_audio` 接口 2. 使用 `@require_login` 装饰器确保只有登录用户可以使用 3. 检查文章是否存在 4. 检查是否已有语音文件 5. 使用 TTSService 生成语音 6. 更新数据库并返回结果 需要我帮你修改 PostsModel 添加 mp3_url 字段吗? ### Me: 是的。 ### Trae: 好的,我来帮你修改 PostsModel 添加 mp3_url 字段: ```python:/Users/mac/data/pythonProjects/yijing/web/models/PostsModel.py from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey, Boolean # ... 其他导入保持不变 ... class PostModel(Base): __tablename__ = 'posts' # ... 其他字段保持不变 ... mp3_url = Column(String(255), nullable=True, comment='语音文件URL') # ... 其他字段和方法保持不变 ... ``` 这个修改: 1. 添加了 mp3_url 字段,类型为 String(255) 2. 设置为可空(nullable=True),因为不是所有文章都会有语音 3. 添加了字段注释 由于你说数据表已经添加了这个字段,所以不需要执行数据库迁移。现在 PostModel 就可以支持语音文件 URL 的存储了。 需要我帮你测试一下语音生成功能吗?
文章作者:
yyii
文章链接:
https://amtb.info/show/MjAy
版权声明:
本博客所有文章除特別声明外,转载请注明来源
佛系程序员
!
分享:
搜索