""" 引导语 Opus 生成服务 为故事/音乐生成一句引导语(如"正在为您播放,卡皮巴拉蹦蹦蹦"), 转为 Opus 帧 JSON 字符串,直接存入数据库字段。 """ import asyncio import logging import random logger = logging.getLogger(__name__) TTS_VOICE = 'zh-CN-XiaoxiaoNeural' STORY_PROMPTS = [ "正在为您播放,{}", "请欣赏故事,{}", "即将为您播放,{}", "为您带来,{}", "让我们聆听,{}", "接下来请欣赏,{}", "为您献上,{}", ] MUSIC_PROMPTS = [ "正在为您播放,{}", "请享受音乐,{}", "即将为您播放,{}", "为您带来,{}", "让我们聆听,{}", "接下来请欣赏,{}", "为您献上,{}", ] def generate_intro_opus(title: str, content_type: str = 'story') -> str: """ 为指定标题生成引导语 Opus JSON。 Args: title: 故事或音乐标题 content_type: 'story' 或 'music' Returns: Opus 帧 JSON 字符串(与 opus_url 指向的格式一致) """ prompts = STORY_PROMPTS if content_type == 'story' else MUSIC_PROMPTS text = random.choice(prompts).format(title) logger.info(f'生成引导语: "{text}"') # edge-tts 合成 MP3 mp3_bytes = asyncio.run(_synthesize(text)) # MP3 → Opus 帧 JSON from apps.stories.services.opus_converter import convert_mp3_to_opus_json opus_json = convert_mp3_to_opus_json(mp3_bytes) return opus_json async def _synthesize(text: str) -> bytes: """使用 edge-tts 合成语音,返回 MP3 bytes""" import edge_tts communicate = edge_tts.Communicate(text, TTS_VOICE) audio_chunks = [] async for chunk in communicate.stream(): if chunk['type'] == 'audio': audio_chunks.append(chunk['data']) return b''.join(audio_chunks)