ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Zoom 会议实时 AI 集成实战:基于 RTMS 实时媒体流构建转录、情感分析与会议纪要流水线

Zoom 会议实时 AI 集成实战:基于 RTMS 实时媒体流构建转录、情感分析与会议纪要流水线 Zoom 会议实时 AI 集成实战基于 RTMS 实时媒体流构建转录、情感分析与会议纪要流水线【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins本文是 knowledge-work-plugins 仓库中 ai-integration.md 用例文档的完整实战化展开。核心主题是如何借助 Zoom 的 RTMSRealtime Media Streams实时媒体流能力把音频、视频、转写文本等会议实时媒体接入你自己的 AI/ML 流水线实现实时转录、情感分析、会议纪要、行动项提取、翻译等智能功能。读完本文你将掌握 RTMS 的两阶段 WebSocket 架构、Webhook 驱动的连接流程、SDK 与手写协议的接入方式以及一套可直接复制运行的端到端 AI 流水线代码骨架。概述为什么要在 Zoom 会议里跑实时 AI传统的会议后分析只能拿到录制文件和离线转写稿无法在会议进行中提供价值。而通过 RTMS 提供的实时媒体流开发者可以把 Zoom 会议中的实时音频、视频、转写文本、聊天与屏幕共享直接接入自建 AI/ML 流水线从而在会议进行中或刚结束时立刻输出实时转录live transcription情感倾向分析sentiment analysis会议摘要meeting summarization行动项提取action items多语言翻译translation基于视觉模型的画面分析等智能化自动操作这一能力在 knowledge-work-plugins 的 Zoom 插件技能体系中对应 general/use-cases/ai-integration.md 这一用例并由 rtms 技能 提供底层实现依据。前置技能RTMS 与 Meeting SDK 的角色分工技能角色说明rtms主用技能实时媒体接入音频、视频、转写、聊天、屏幕共享zoom-meeting-sdkLinux辅助技能用于构建会议机器人meeting bots场景两者的分工很明确RTMS 负责媒体面media plane的数据接入Meeting SDK 负责需要以机器人身份进会的场景。如果只是想把会议媒体实时喂给 AI 模型RTMS 是首选路径——它不需要机器人账号入会直接从 Zoom 基础设施取流。仓库中还提供了 transcription-bot-linux.md、meeting-bots.md 等相邻用例供对照参考而 Meeting SDKLinux的细节可见 meeting-sdk/linux。AI 应用场景总览原文档给出的典型 AI 用例与输入输出对应关系如下用例输入输出转录Transcription音频流实时文本情感分析Sentiment音频/转写文本情绪指标会议纪要Summarization转写文本会议摘要行动项Action items转写文本任务列表翻译Translation音频/转写文本多语言文本其中转录是其他所有用例的地基情感分析、纪要、行动项、翻译都建立在拿到高质量文本的前提上。而 RTMS 恰好同时提供了两条转录路径详见下文实时转录流水线你可以按延迟与成本需求自由选择。系统架构Zoom → RTMS → AI/ML 流水线原文档给出了三层架构AI Integration Architecture: ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Zoom │────▶│ RTMS / │────▶│ AI/ML │ │ Meeting │ │ Bot SDK │ │ Pipeline │ └─────────────┘ └─────────────┘ └─────────────┘ │ Audio/Video/Transcript从仓库中 rtms 技能 的关键定位Critical Positioning一节可以进一步确认一个重要的架构事实RTMS 本质上是一个后端媒体接入服务backend media ingestion service它不是前端 UI SDK。这意味着你的后端负责接收并处理实时媒体音频、视频、屏幕共享、聊天、转写处理是事件驱动的后端先等待 RTMS 启动 Webhook 事件再开始流处理常见的可选架构是用 Zoom App SDK 做前端 UI/控制后端通过 WebSocket或 SSE、gRPC、队列 worker把 RTMS 处理结果推给前端。即媒体/数据面用 RTMS展示与交互用 Zoom Apps / 前端框架。深入两阶段 WebSocket 架构控制面与数据面分离RTMS 的底层连接设计见 connection-architecture.md是两条独立的 WebSocket 连接这是理解整个 AI 流水线数据来源的关键阶段 1Signaling WebSocket控制面职责认证、会话控制、心跳、媒体服务器发现、事件通知URL 来源Webhook payload 中的server_urls关键消息流握手请求msg_type 1→ 握手响应msg_type 2包含media_server.server_urls→ 客户端就绪msg_type 7→ 心跳msg_type 12/13阶段 2Media WebSocket数据面职责实际的音频、视频、转写、聊天、屏幕共享数据URL 来源信令握手响应中的media_server.server_urls.all关键消息流媒体握手请求msg_type 3携带media_params→ 媒体握手响应msg_type 4→ 音频数据14、视频数据15、屏幕共享16、转写17、聊天18→ 心跳12/13为什么拆成两条连接connection-architecture.md 给出了四个理由关注点分离控制逻辑不干扰媒体流、独立扩展信令与媒体服务器可分别扩容、故障隔离媒体重连无需重新认证、以及支持 Split 模式每种媒体类型可独占一条连接。连接模式也有两种选择Split 模式推荐每种媒体类型各占一条 WebSocket可独立重连、可靠性更高、故障隔离更好Unified 模式所有媒体类型共用一条媒体 WebSocket适合对音视频同步有要求的实时混流场景或小型项目。前置条件要在自己的后端跑起这套 AI 流水线需要满足以下条件依据 rtms/SKILL.mdRTMS 访问权限或 Meeting SDKLinux能力一个 AI/ML 服务OpenAI、Azure 或自建模型服务实时处理基础设施服务器要能接收 WebSocket 流JavaScript SDK 需要Node.js 20.3.0推荐 24 LTSPython SDK 需要Python 3.10按产品类型创建 Zoom App会议/网络研讨会用General AppOAuth Client ID/SecretVideo SDK 会话用Video SDK AppSDK Key/Secret配置好的 Webhook 端点用于接收 RTMS 事件。实战搭建 RTMS 驱动的实时 AI 流水线下面按原文档Common Tasks的脉络从零开始搭建。第 1 步在 Marketplace 配置 RTMS 应用在 Zoom Marketplace 创建应用并开启 RTMS 相关能力细节见 rtms/SKILL.md 的 Zoom App Setup 一节进入 marketplace → Develop → Build App会议/网络研讨会选择 General App → User-ManagedVideo SDK选择 Video SDK App使用 SDK Key/Secret而非 OAuth 凭证在 Features → Access 中启用 Event Subscription添加事件订阅会议meeting.rtms_started/meeting.rtms_stopped网络研讨会webinar.rtms_started/webinar.rtms_stoppedVideo SDKsession.rtms_started/session.rtms_stopped添加 OAuth Scope会议场景meeting:read:meeting_audiomeeting:read:meeting_videomeeting:read:meeting_transcriptmeeting:read:meeting_chat网络研讨会需追加webinar:read:webinar_*对应 scope。关键差异会议与网络研讨会的 payload 一律使用meeting_uuid网络研讨会不是webinar_uuidVideo SDK 使用session_id。签名时务必按产品取对 ID 字段这是最常见的踩坑点。第 2 步处理 Webhook获取连接信息当会议 RTMS 流就绪时Zoom 会推送meeting.rtms_startedWebhookpayload 中携带server_urls信令服务器地址、rtms_stream_id流 ID、signature预计算签名等字段。原文档给出的处理代码// 1. Configure RTMS app in Marketplace // Enable: Audio stream, Video stream, Transcript stream // 2. Handle webhook to get connection details app.post(/webhook, (req, res) { if (req.body.event meeting.rtms_started) { const { server_urls, stream_id, signature } req.body.payload; // Start AI processing pipeline aiPipeline.connect({ url: server_urls[0], streamId: stream_id, signature: signature }); } res.status(200).send(); });这里有两个必须刻进肌肉记忆的 Webhook 铁律详见 webhooks.md 与 common-issues.md必须立刻返回 HTTP 200再做任何处理。若响应延迟Zoom 会重试 Webhook重试会创建第二条连接而每条流只允许 1 条连接——新连接会踢掉旧连接导致随机断连配置 Webhook URL 时 Zoom 会发送endpoint.url_validation校验事件需要返回用ZOOM_SECRET_TOKEN对plainToken做 HMAC-SHA256 后的encryptedToken。不同产品的 RTMS Webhook 事件与 payload 对照来自 webhooks.md产品启动事件停止事件Payload IDApp 类型Zoom 会议meeting.rtms_startedmeeting.rtms_stoppedmeeting_uuidGeneral AppZoom 网络研讨会webinar.rtms_startedwebinar.rtms_stoppedmeeting_uuid非 webinar_uuidGeneral AppZoom Video SDKsession.rtms_startedsession.rtms_stoppedsession_idVideo SDK Appmeeting.rtms_started的完整 payload 结构示例来自 lifecycle-flow.md{ event: meeting.rtms_started, payload: { account_id: abc123, object: { meeting_id: 123456789, meeting_uuid: AbC123..., host_id: user123, rtms_stream_id: stream123, server_urls: wss://rtms-sjc1.zoom.us/..., signature: pre_computed_signature } } }server_urls中包含地理区域码sjc圣何塞、iad华盛顿、sin新加坡、fra法兰克福、syd悉尼。生产环境建议把 Webhook 路由到与 Zoom 服务器同区域的 worker降低端到端延迟。第 3 步选择要接收的媒体类型BitmaskRTMS 用位掩码声明需要的媒体类型详见 media-types.md多个类型用按位或组合类型值说明Audio音频1PCM 音频采样Video视频2H.264/JPG 帧Screen Share屏幕共享4与视频独立Transcript转写8实时语音转文本Chat聊天16会议内聊天消息All全部32所有媒体类型例如音频 转写 1 | 89。AI 转录/情感/纪要场景通常订阅9需要看画面再做视觉分析时再加 Video2。注意屏幕共享和视频是两条独立的事件流msg_type 16 vs 15必须单独订阅。如果使用zoom/rtmsSDK还可在 join 前配置媒体参数例如音频L16/PCM、16kHz、单声道、混合流client.setAudioParams({ codec: 1, // L16 (PCM) sampleRate: 1, // 16kHz channel: 1, // Mono dataOpt: 1 // Mixed stream });实时转录流水线两条路径原文档给出了两条转录路径分别对应用 Zoom 自带的转写与把裸音频送外部 STT。Option 1直接消费 Zoom 内置转写通过 RTMS Transcript 流// Option 1: Use Zooms built-in transcript (via RTMS) rtmsClient.on(transcript, (data) { const { text, speaker_id, is_final } data; if (is_final) { transcriptStore.append(speaker_id, text); } });这条路零额外 STT 成本且天然带说话人信息。RTMS 转写数据是 JSON 文本结构如下来自 media-types.md{ user_id: user_id, user_name: Speaker Name, text: Transcribed text content, timestamp: 1234567890, is_final: true }使用 SDK 时对应client.onTranscriptData((buffer, timestamp, metadata) ...)把 buffer 按 utf8 解码即可拿到文本metadata.userName提供说话人。转写支持 36 种语言常见语言 ID 包括英文 9、简体中文 4、繁体中文 5、日文 20、韩文 21、西班牙文 28、法文法国13、德文 14。若希望固定语言而非自动切换可设置src_language并关闭enable_lid该开关控制语言识别 LID默认开启开启时可自动检测/切换语言但也会带来转写启动延迟。Option 2把音频流送到外部 STTWhisper、Deepgram 等// Option 2: Send audio to external STT (Whisper, Deepgram) const deepgram new Deepgram(DEEPGRAM_KEY); const transcriber deepgram.transcription.live({ punctuate: true, interim_results: true, language: en-US }); rtmsClient.on(audio, (audioChunk) { transcriber.send(audioChunk); }); transcriber.on(transcriptReceived, (data) { const transcript data.channel.alternatives[0].transcript; processTranscript(transcript); });仓库的 rtms/examples/ai-integration.md 对这一路径做了更完整的 SDK 级展开覆盖三种主流 STTDeepgram创建rtms.Client()后调用client.setAudioParams({ codec: 1, sampleRate: 1, channel: 1, dataOpt: 1 })配成 L16/16kHz/单声道/混合流然后connection deepgram.listen.live({ model: nova-2, language: en, smart_format: true, punctuate: true })在onAudioData回调里把 buffer 直接connection.send(buffer)最后在onLeave时connection.finish()AssemblyAIaai.realtime.createService({ sampleRate: 16000 })后transcriber.sendAudio(buffer)Whisper本地由于是批量模型需要自己累积音频缓冲每攒够16000 * 10字节10 秒 16kHz触发一次whisper.transcribe()然后清空缓冲重新累积。情感分析集成在拿到转写文本后可以用 LLM 对每个文本片段做实时情感分析。原文档给出的实现同时包含单次分析与随时间跟踪并告警两层// Real-time sentiment on transcript segments async function analyzeSentiment(text) { const response await openai.chat.completions.create({ model: gpt-4, messages: [{ role: system, content: Analyze sentiment. Return JSON: {sentiment: positive|negative|neutral, confidence: 0-1, emotions: []} }, { role: user, content: text }], response_format: { type: json_object } }); return JSON.parse(response.choices[0].message.content); } // Track sentiment over time class SentimentTracker { constructor() { this.history []; } async process(transcript) { const sentiment await analyzeSentiment(transcript); this.history.push({ timestamp: Date.now(), text: transcript, ...sentiment }); // Alert on negative sentiment if (sentiment.sentiment negative sentiment.confidence 0.8) { this.emit(alert, { type: negative_sentiment, data: sentiment }); } } getOverallSentiment() { // Aggregate sentiment over meeting duration } }工程要点response_format: { type: json_object }强制模型输出合法 JSON便于直接解析SentimentTracker把每次分析结果连同时间戳入历史既支持会议整体情绪趋势聚合也能在高置信度负面情绪出现时实时告警例如客服质检场景。仓库示例 rtms/examples/ai-integration.md 中还给出了一种更贴合延迟预算的做法攒够 10 个转写片段合并成一段再统一分析避免对每个小片段都打一次 LLM 请求降低调用频率与成本。会议纪要生成会议结束后或进行中按间隔用 LLM 对完整转写生成结构化纪要。原文档给出两份提示词模板——一份面向纪要一份面向行动项提取// Generate summary after meeting ends async function generateMeetingSummary(fullTranscript) { const response await openai.chat.completions.create({ model: gpt-4, messages: [{ role: system, content: Summarize this meeting transcript. Include: 1. Key discussion points 2. Decisions made 3. Action items with owners 4. Follow-up needed }, { role: user, content: fullTranscript }] }); return response.choices[0].message.content; } // Extract action items async function extractActionItems(transcript) { const response await openai.chat.completions.create({ model: gpt-4, messages: [{ role: system, content: Extract action items as JSON array: [{task, owner, deadline}] }, { role: user, content: transcript }], response_format: { type: json_object } }); return JSON.parse(response.choices[0].message.content); }仓库示例还展示了**进行中摘要 结束终稿**的生产模式用setInterval每 5 分钟对累积的转写生成一次阶段性摘要transcripts数组把speaker、text、time组织为说话人: 文本行并 join 成完整转写在onLeave事件里清除定时器并生成包含关键议题 / 已做决策 / 带负责人行动项 / 待跟进事项的终稿。延迟考量不同处理类型的目标预算实时 AI 流水线必须按数据类型设定延迟预算。原文档给出的基准表处理类型目标延迟建议实时字幕Live captions 500ms使用流式 STTDeepgram、AssemblyAI情感分析Sentiment 2s每 10~15 秒批量处理一次纪要Summarization会后会议结束后再处理行动项Action items 5s逐段paragraph处理对照 media-types.md 可以确认实时字幕场景建议用 Zoom 内置转写流或 Deepgram/AssemblyAI 这类流式 STT情感分析通过攒批换取成本与延迟的平衡纪要这类重任务放到会后行动项提取则可跟随每个转写片段就近完成。完整 AI 流水线架构把上述所有环节串起来原文档给出了端到端架构图┌─────────────────────────────────────────────────────────┐ │ RTMS WebSocket │ └─────────────┬───────────────┬───────────────┬──────────┘ │ │ │ Audio Stream Video Stream Transcript │ │ │ ▼ ▼ ▼ ┌───────────────┐ ┌──────────┐ ┌───────────────┐ │ Speech-to-Text│ │Face/OCR │ │ NLP Pipeline │ │ (Deepgram) │ │Detection │ │ (OpenAI GPT) │ └───────┬───────┘ └────┬─────┘ └───────┬───────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────────────────────┐ │ Results Aggregator │ │ - Transcripts - Sentiment - Action Items │ └─────────────────────┬───────────────────────────┘ │ ▼ ┌───────────────┐ │ Storage / │ │ Dashboard │ └───────────────┘三个输入流音频、视频、转写分别进入 STT、视觉模型、NLP 流水线产出统一汇入 Results Aggregator再落存储或推送到 Dashboard。视频流可做 Face/OCR 检测例如把屏幕共享帧送视觉模型提取幻灯片内容音频流驱动 STT转写流直接进 NLP 做情感与行动项。这一架构的每个环节都能在 rtms/examples/ai-integration.md 中找到对应的可运行代码片段。生产化要点从示例到可用系统环境变量集中管理无论 SDK 还是手动实现凭证都应走环境变量完整清单见 sdk-quickstart.md 与 rtms/examples/ai-integration.md# Zoom RTMSSDK 自动启动 Webhook 服务器 ZM_RTMS_CLIENTyour_client_id ZM_RTMS_SECRETyour_client_secret ZM_RTMS_PORT8080 # 可选默认 8080 ZM_RTMS_PATH/webhook # 可选默认 / # 手动实现时的凭证 ZOOM_CLIENT_IDyour_client_id ZOOM_CLIENT_SECRETyour_client_secret ZOOM_SECRET_TOKENyour_webhook_token # AI 服务 OPENAI_API_KEYsk-... DEEPGRAM_API_KEY... ASSEMBLYAI_API_KEY... # 可选OpenRouter可访问免费模型 OPENROUTER_API_KEYsk-or-...心跳与重连连接存活的生命线RTMS不会自动重连且两条连接都要求响应心跳详见 connection-architecture.md收到msg_type: 12Keep Alive Request后必须立即回msg_type: 13并带上对方的timestamp信令连接约60 秒、媒体连接约65 秒未响应心跳即被关闭2026 年 3 月起媒体心跳容忍从 35 秒放宽到 65 秒断连后要自己实现带指数退避的重连如retryDelay Math.min(retryDelay * 2, 30000)。会话跟踪与去重每条流只允许 1 条连接因此必须用Map/Set按rtms_stream_id跟踪活动会话收到重复的rtms_started事件直接忽略收到rtms_stopped事件时清理连接与状态参考 lifecycle-flow.md 的 Session Tracking 一节。后端处理完毕需要主动收尾时可通过信令通道发送msg_type: 21STREAM_CLOSE_REQ请求优雅关闭等待STREAM_CLOSE_RESP确认后再做本地清理。常见问题速查症状可能原因解决方案连接失败签名错误检查签名生成HMAC-SHA256(clientSecret, clientId,idValue,streamId)hex 输出无多余空格重复连接Webhook 响应慢立即返回 200再异步处理收不到数据媒体类型位掩码错误检查media_type是否包含目标类型音频1、转写8连接 ~60 秒后关闭未响应心跳收到 msg_type 12 即回 msg_type 13段错误崩溃Node.js 版本过旧升级到 20.3.0推荐 24 LTS混流音频缺说话人 ID使用 AUDIO_MIXED_STREAM用onActiveSpeakerEvent或切dataOpt: 2per-participant视频参数不生效SDK 已知问题先调setVideoParams再调setAudioParams转写启动慢LID 自动语言检测开启设置src_language并enable_lid: false完整对照见 common-issues.md关键状态码握手失败时通过status_code定位问题common-issues.md码名称含义0STATUS_OK成功3STATUS_INVALID_SIGNATURE签名无效8STATUS_DUPLICATE_SIGNAL_REQUEST信令已连接重复请求16STATUS_DUPLICATE_MEDIA_DATA_CONNECTION媒体连接已存在40STATUS_INVALID_RTMS_SESSION_IDRTMS 会话 ID 无效43STATUS_INVALID_MEDIA_TRANSCRIPT_SROUCE_LANGUAGE转写源语言无效进一步阅读仓库内资源rtms 技能总览RTMS 全量导航含媒体类型、数据常量、环境变量、关键注意事项与 2026 年 3 月协议变更Contact Center Voice 支持、单参与者视频订阅、优雅关闭等rtms/examples/ai-integration.mdDeepgram / AssemblyAI / Whisper 三种 STT 完整代码、间隔摘要与终稿生成、实时情感分析、带静音补齐的 PCM 录音、VTT/SRT/TXT 多格式字幕导出connection-architecture.md两阶段 WebSocket、Split/Unified 连接模式、签名生成与心跳协议lifecycle-flow.md从 Webhook 到媒体流的完整时序、会话跟踪、错误处理media-types.md五种媒体类型的参数矩阵与完整media_params配置示例sdk-quickstart.mdzoom/rtmsSDK 安装、最小示例、全媒体类型示例、Python SDKwebhooks.md各产品 Webhook 事件、payload 字段、scope 清单与地理路由common-issues.md连接、心跳、媒体数据、SDK 与平台相关问题的完整排障指南。动手建议从 sdk-quickstart.md 的最小示例起步一条onTranscriptData回调即可看到实时文本随后按本文实时转录流水线的 Option 2 接入 Deepgram 或本地 Whisper再依次叠加情感分析与纪要生成即可在数小时内跑通一版可用的会议 AI 助手。【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表