关于 podcast-generation
使用 Azure OpenAI's Realtime API 将文本生成旁白音频的 Skill。它介绍通过 WebSocket 收集音频和转录片段、将 PCM 转为 WAV,并准备可供播放的 Base64 音频。
主要功能
- 01Azure OpenAI Realtime 工作流
- 02通过 WebSocket 生成音频
- 03收集音频与转录片段
- 04将 PCM 转为 WAV
- 05准备可播放的 Base64 音频
适用场景
- 01将文本转为旁白音频
- 02向前端返回生成的音频
- 03将生成的 PCM 数据转换为 WAV
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill podcast-generation安装后在 Claude Code 中输入/podcast-generation确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
UPSTREAM-NOTICE.mdUPSTREAM-LICENSE.txtreferences/architecture.mdcode-examples.mdscripts/pcm_to_wav.py详细介绍
上游支持文件
支持文件包含在相对于技能目录的路径中。其固定来源、许可证、哈希值和导入变更请参阅 UPSTREAM-NOTICE.md。
使用 GPT Realtime Mini 生成播客
使用 Azure OpenAI 的 Realtime API,根据文本内容生成真实音频叙述。
快速开始
- 配置 Realtime API 的环境变量
- 通过 WebSocket 连接到 Azure OpenAI Realtime 端点
- 发送文本提示词,收集 PCM 音频片段和转录文本
- 将 PCM 转换为 WAV 格式
- 将 Base64 编码的音频返回给前端播放
环境配置
AZURE_OPENAI_AUDIO_API_KEY=your_realtime_api_key
AZURE_OPENAI_AUDIO_ENDPOINT=https://your-resource.cognitiveservices.azure.com
AZURE_OPENAI_AUDIO_DEPLOYMENT=gpt-realtime-mini
注意:端点不应包含 /openai/v1/,只需使用基础 URL。
核心工作流
后端音频生成
from openai import AsyncOpenAI
import base64
# Convert HTTPS endpoint to WebSocket URL
ws_url = endpoint.rstrip("/").replace("https://", "wss://", 1) + "/openai/v1"
client = AsyncOpenAI(
websocket_base_url=ws_url,
api_key=api_key
)
audio_chunks = []
transcript_parts = []
async with client.realtime.connect(model=deployment_name) as conn:
# Configure for audio-only output
await conn.session.update(session={
"type": "realtime",
"audio": {"output": {"voice": voice_name, "format": {"type": "audio/pcm", "rate": 24000}}},
"output_modalities": ["audio"],
"instructions": "You are a narrator. Speak naturally."
})
# Send text to narrate
await conn.conversation.item.create(item={
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": prompt}]
})
await conn.response.create()
# Collect streaming events
async for event in conn:
if event.type == "response.output_audio.delta":
audio_chunks.append(base64.b64decode(event.delta))
elif event.type == "response.output_audio_transcript.delta":
transcript_parts.append(event.delta)
elif event.type == "error":
raise RuntimeError("Realtime service error; inspect redacted private diagnostics")
elif event.type == "response.done":
if event.response.status != "completed":
raise RuntimeError("Incomplete audio response")
break
# Convert PCM to WAV (see scripts/pcm_to_wav.py)
pcm_audio = b''.join(audio_chunks)
wav_audio = pcm_to_wav(pcm_audio, sample_rate=24000)
前端音频播放
// Convert base64 WAV to playable blob
const base64ToBlob = (base64, mimeType) => {
const bytes = atob(base64);
const arr = new Uint8Array(bytes.length);
for (let i = 0; i < bytes.length; i++) arr[i] = bytes.charCodeAt(i);
return new Blob([arr], { type: mimeType });
};
const audioBlob = base64ToBlob(response.audio_data, 'audio/wav');
const audioUrl = URL.createObjectURL(audioBlob);
const player = new Audio(audioUrl);
player.onended = () => URL.revokeObjectURL(audioUrl);
player.onerror = () => URL.revokeObjectURL(audioUrl);
// Invoke from a user gesture and handle autoplay rejection/teardown.
player.play().catch(() => URL.revokeObjectURL(audioUrl));
历史语音示例(请验证部署支持情况)
| 语音 | 特点 |
|---|---|
| alloy | 中性 |
| echo | 温暖 |
| fable | 富有表现力 |
| onyx | 深沉 |
| nova | 友好 |
| shimmer | 清晰 |
Realtime API 事件
response.output_audio.delta- Base64 音频片段response.output_audio_transcript.delta- 转录文本response.done- 生成完成error- 使用event.error.message处理
音频格式
- 输入:文本提示词
- 输出:PCM 音频(24kHz、16 位、单声道)
- 存储:Base64 编码的 WAV
参考资料
- 完整架构:请参阅 references/architecture.md,了解完整的技术栈设计
- 代码示例:请参阅 references/code-examples.md,查看集成示意
- PCM 转换:使用 scripts/pcm_to_wav.py 转换音频格式
使用场景
此技能适用于执行概述中描述的工作流或操作。
限制
- 仅在任务明确符合上述范围时使用此技能。
- 不要将输出视为环境特定验证、测试或专家审核的替代品。
- 如果缺少必要输入、权限、安全边界或成功标准,请停止并要求澄清。
生成边界
未执行的 SDK/服务示例:部署名称、可用语音、GA 与预览版的会话/身份验证格式以及 SDK 版本,都必须与实际 Azure 资源相符。语音表并非当前 Realtime 支持列表。在将字节解释为 24kHz 有符号 16 位单声道数据之前,请显式配置 PCM 输出;拒绝不完整或为空的输出。 示例未包含强制性的总生成超时(例如 60 秒)、单个事件及累计音频/文本限制(例如 32 MiB)、取消/关闭路径和费用配额;在处理请求前,请实现这些措施。单独收到 response.done 事件并不表示成功。不要将部分输出存储为完整叙述。
按租户授权源对象,以及音频生成、列表和流式传输的所有权;ID 不能作为访问控制。数据库方法/模型/路由、设置和前端 API 都是应用适配层,并非随附的实现。将源文本视为数据,保留来源归属,验证叙述准确性,并在将私人文本发送到 Azure 或发布合成语音前取得权利/同意。未经许可,绝不要冒充真人;在需要时披露语音为生成内容。密钥仅存储在后端;音频/转录文本应私密保存并设置保留期限。模型生成的文本不是 HTML。前端的播放/暂停功能需要实际的暂停处理、Promise 错误处理、通过 finally 重置加载状态、URL 撤销和资源清理;React 示例未包含这些控制。
PCM 辅助脚本用法:python3 <skill-dir>/scripts/pcm_to_wav.py input.pcm output.wav 会拒绝覆盖文件和不完整帧;它不会检测任意字节是否确实为所声明的 PCM 格式。