knowledge-work-plugins 中的 Zoom AI Services Scribe 转录实战指南:JWT 认证、Fast/Batch 双模式与浏览器麦克风伪流式架构
2026/9/14 12:01:58 网站建设 项目流程

knowledge-work-plugins 中的 Zoom AI Services Scribe 转录实战指南:JWT 认证、Fast/Batch 双模式与浏览器麦克风伪流式架构

【免费下载链接】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 中 scribe 技能 及其配套子文档为核心,完整讲解 Zoom AI Services Scribe 文件/存储转录服务的落地方法:从 Build-platform JWT 签发、Fast Mode 同步转录与 Batch 异步批处理两条主链路,到浏览器麦克风伪流式方案、Webhook 驱动的状态通知,以及围绕版本漂移的排障与预检 Runbook。读完本文,你将能独立搭建一条可运行的上传转录代理、批量 S3 转录与 Webhook 回写流水线,并掌握 9 类高频故障的定位方法。

Scribe 是什么:文件/存储转录服务的定位与路由护栏

Scribe 是 Zoom AI Services 家族中面向已上传或已存储媒体的转录服务,核心能力是把音频/视频文件转成带时间戳、声道与说话人信息的文本。它与 Zoom 的实时媒体流服务 RTMS 边界清晰:Scribe 处理「文件」,RTMS 处理「直播流」。

在 scribe 技能入口 中定义了四条路由护栏,用于避免产品选错:

用户诉求路由目标
上传或存储的媒体需要转成文本先路由到scribe
需要实时会议媒体(非文件上传/批处理)转 rtms 技能
需要 Zoom REST API 的 AI Services 路径清单串联 rest-api 技能
需要 Webhook 签名模式或通用 HMAC 接收加固可选串联 webhooks 技能

Scribe 覆盖的能力面包括:

  • 同步单文件转录(POST /aiservices/scribe/transcribe
  • 异步批量作业(/aiservices/scribe/jobs*
  • 基于重复短文件上传的浏览器麦克风伪流式转录
  • 由 Webhook 驱动的批量状态更新
  • Build-platform JWT 签发与凭据处理

认证模型:Build-platform JWT 与凭据命名漂移

HS256 JWT 结构

Scribe 使用Build-platform JWT Bearer Token认证,而非 OAuth。JWT 的三要素:

  • 算法HS256
  • issuer(iss)声明:Build-platform 凭据标识符,Scribe API 用它识别调用方
  • 过期时间(exp:保持在一小时或更短

认证与处理模式文档 给出了 Node.js 侧的最小签发实现(基于jsrsasignKJUR):

import { KJUR } from 'jsrsasign'; export function generateJWT(apiKey, apiSecret) { const iat = Math.round(Date.now() / 1000) - 30; const exp = iat + 60 * 60; return KJUR.jws.JWS.sign( 'HS256', JSON.stringify({ alg: 'HS256', typ: 'JWT' }), JSON.stringify({ iss: apiKey, iat, exp }), apiSecret, ); }

注意iat回拨了 30 秒,这是为时钟偏差留的缓冲;exp设为iat + 3600(一小时)。

凭据命名漂移:API Key 还是 SDK Key?

Zoom 官方文档在不同页面使用了不一致的命名:

  • AI Services 认证页:API key/API secret
  • Build-platform 凭据页:SDK key/SDK secret
  • Quickstart 示例代码:ZOOM_API_KEY/ZOOM_API_SECRET

版本漂移文档 明确指出:实现时统一把它们当作 Build-platform 的 JWT issuer/secret 对,但在上线前务必到当前门户 UI 核实确切的字段标签。

环境变量约定

环境变量文档 给出了完整的配置面:

JWT 认证必填:

变量必填说明
ZOOM_API_KEYBuild-platform issuer key,用于 JWTiss声明
ZOOM_API_SECRETHS256 签名的 Build-platform secret

通用应用变量:

变量必填说明
PORT本地服务端口
LANGUAGE默认语言代码,如en-US

Batch / S3 变量:

变量必填(batch 场景)说明
S3_INPUT_URI通常输入前缀或文件 URI
S3_OUTPUT_URI通常输出转录目的地
AWS_ACCESS_KEY_ID未使用预签名访问时需要AWS 凭据
AWS_SECRET_ACCESS_KEY未使用预签名访问时需要AWS 凭据
AWS_SESSION_TOKEN常需要临时凭据令牌

Webhook 变量:

变量必填说明
WEBHOOK_URL可选接收批量通知的公网 HTTPS 回调
WEBHOOK_SECRET可选但推荐校验 Zoom 回调签名的 HMAC secret

关键坑:不要把${ZOOM_API_KEY}这类 shell 占位符当作有效配置值。占位符会让健康检查「看起来已配置」,但每次真实调用都会失败——这是文档与 Runbook 反复强调的失败模式。

处理模式:Fast Mode 与 Batch Mode 的选择

认证与处理模式文档 对两种模式做了精确定位:

模式适用场景传输方式结果时机
Fast mode单个短文件、交互式 UXPOST /transcribe立即返回同步 JSON
Batch mode归档、长媒体、大量文件POST /jobs后查状态/等 Webhook异步

选择 Fast mode 的条件:

  • 用户只上传一个文件
  • 延迟比吞吐量更重要
  • 文件大小与时长可控
  • 在做基于短麦克风分片的浏览器伪流式

选择 Batch mode 的条件:

  • 需要处理大量文件
  • 转录结果可以稍后到达
  • 存储中心化工作流比直传更契合

端点清单与请求/响应形状

端点总览

API 参考文档 基于 AI Services OpenAPI 清单(api-hub/ai-services/methods/endpoints.json),基础 URL 为https://api.zoom.us/v2

MethodEndpoint说明Operation ID
POST/aiservices/scribe/transcribeScribe 同步转录createFastAsr
POST/aiservices/scribe/jobs提交批量 Scribe 作业submitBatchAsr
GET/aiservices/scribe/jobs列出批量作业listBatchJobs
GET/aiservices/scribe/jobs/{jobId}查询批量作业状态getBatchJobStatus
DELETE/aiservices/scribe/jobs/{jobId}取消排队/处理中的作业cancelBatchJob
GET/aiservices/scribe/jobs/{jobId}/files查看每个文件的转录结果listBatchJobFiles

Fast Mode 请求形状

必填顶层字段fileconfig

常见 config 字段(认证与处理模式文档):

字段作用
language语言代码,如en-US
word_time_offsets是否输出逐词时间偏移
channel_separation是否按声道分离(立体声通话录音)
timestamps时间戳
output_format输出格式
profanity_filter粗话过滤
diarization说话人分离/区分

响应关键键request_idduration_secmodelresult

Batch Mode 请求形状

必填顶层字段inputoutputconfig

input 子字段:

  • modeSINGLE/PREFIX/MANIFEST
  • source:当前 OpenAPI 中为S3
  • uri/manifest
  • filters.include_globsfilters.exclude_globs(均最多 10 项)
  • auth.aws.access_key_id/secret_access_key/session_token

output 子字段:

  • destinationuri
  • layoutSINGLE/PREFIX/ADJACENT
  • auth.aws.*

config 子字段languageword_time_offsetschannel_separationdiarizationprofanity_filteroutput_formatsegmentation_mode

可选字段reference_idnotifications.webhook_urlnotifications.secret

提交响应键job_idstatesubmitted_at

查询与状态端点

  • GET /jobs:查询参数statepage_sizenext_page_token;响应键jobsnext_page_token
  • GET /jobs/{jobId}:响应键job_idstatesubmitted_atsummary
  • GET /jobs/{jobId}/files:查询参数page_sizenext_page_token;响应键filesnext_page_token

当前限制与约束(来自源文档)

  • Batch manifest 上限:1000 个文件 URI
  • include_globs最多10项;exclude_globs最多10
  • 文档标注的媒体格式:WAVMP3M4AMP4
  • Fast mode 正式上限:100 MB文件、2 小时时长
  • OpenAPI 描述中批量作业的速率限制标签为LIGHT

实战一:Fast Mode 同步转录(Node/Express 代理)

Fast Mode Node 示例 提供了一个可直接复用的最小后端代理。核心思路:前端上传文件 → 后端签 JWT → 转发 multipart 到 Zoom → 回传转录 JSON。

import express from 'express'; import multer from 'multer'; import { KJUR } from 'jsrsasign'; const app = express(); const upload = multer({ storage: multer.memoryStorage() }); app.use(express.json()); function generateJWT() { const iat = Math.round(Date.now() / 1000) - 30; const exp = iat + 60 * 60; return KJUR.jws.JWS.sign( 'HS256', JSON.stringify({ alg: 'HS256', typ: 'JWT' }), JSON.stringify({ iss: process.env.ZOOM_API_KEY, iat, exp }), process.env.ZOOM_API_SECRET, ); } app.post('/transcribe', upload.single('file'), async (req, res) => { const token = generateJWT(); const config = { language: req.body.language || 'en-US', word_time_offsets: true, channel_separation: false, }; let response; if (req.file) { const form = new FormData(); form.append('file', new Blob([new Uint8Array(req.file.buffer)]), req.file.originalname); form.append('config', JSON.stringify(config)); response = await fetch('https://api.zoom.us/v2/aiservices/scribe/transcribe', { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: form, }); } else { response = await fetch('https://api.zoom.us/v2/aiservices/scribe/transcribe', { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ file: req.body.file, config, }), }); } const text = await response.text(); res.status(response.status).type('application/json').send(text); });

该示例同时演示了 fast mode 的两种合法提交形态,务必按服务边界选一种清晰的模型:

形态提交方式适用场景
调用方上传文件到你的后端后端以multipart/form-data转发(FormData携带file+config字符串)浏览器/客户端直传
调用方已有 URL 可访问的媒体后端以 JSON body 提交(file字段放 URL)服务端已存文件

样例验证文档 补充了关键实现细节:multer的 memory storage 对小型 fast mode 演示足够;官方 quickstart 也证明「即使文档展示的是 JSON 示例,fast mode 同样可以在你的服务器上以 multipart 上传处理方式代理」。

实战二:Batch 作业 + Webhook 流水线

端到端流程

Batch 作业 + Webhook 流水线示例 给出的链路为:

submit batch job -> receive job_id -> poll /jobs or wait for webhook -> inspect /jobs/{jobId}/files -> ingest transcript outputs

提交示例(curl)

curl -X POST https://api.zoom.us/v2/aiservices/scribe/jobs -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{ "input": { "mode": "PREFIX", "source": "S3", "uri": "s3://example-bucket/audio/", "auth": { "aws": { "access_key_id": "...", "secret_access_key": "...", "session_token": "..." } } }, "output": { "destination": "S3", "uri": "s3://example-bucket/transcripts/", "layout": "PREFIX", "auth": { "aws": { "access_key_id": "...", "secret_access_key": "...", "session_token": "..." } } }, "config": { "language": "en-US", "word_time_offsets": true, "channel_separation": true }, "notifications": { "webhook_url": "https://example.com/webhooks/scribe", "secret": "replace-me" } }'

要点:input.mode=PREFIX表示处理uri前缀下的全部匹配文件;output.layout=PREFIX表示转录结果按源前缀镜像落盘;AWS 凭据直接注入请求载荷——样例验证文档 指出这是 quickstart 的常规做法,但生产流水线更建议使用预签名 URL 或短时 STS 临时凭据,不要把长期 AK/SK 写进请求体。

Webhook 签名验证

Zoom 回调用的是x-zm-signature+x-zm-request-timestamp头,HMAC-SHA256 计算后带sha256=前缀。验证实现:

import crypto from 'crypto'; function verifyZoomWebhook(rawBody, timestamp, signature, secret) { const message = `v0:${timestamp}:${rawBody}`; const expected = `sha256=${crypto.createHmac('sha256', secret).update(message).digest('hex')}`; return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); }

验证失败时按顺序排查:raw body 是否在 JSON 解析前捕获、时间戳头是否纳入签名串、共享 secret 是否与作业的notifications.secret一致。

浏览器麦克风伪流式模式

Scribe 不暴露文档化的实时流 API,因此浏览器麦克风体验必须建模为重复的短文件上传,而不是一条长连接流。推荐的模式:

  1. MediaRecorder捕获浏览器麦克风音频
  2. 按短分片 flush 到你的后端
  3. 每个分片通过异步 fast mode 包装器提交
  4. 按请求 ID 轮询完成状态
  5. 按顺序拼接各分片转录结果

推荐起始节奏:

  • 分片大小:5 秒(可接受范围5-10 秒
  • 同时在途分片请求:2-3

该模式的适用边界(认证与处理模式文档 的护栏):

  • 它本质上是「基于文件上传的伪流式」
  • 它不是实时音频捕获的首选生产设计
  • 仅当轻量浏览器演示或粗略的增量转录可接受时使用
  • 需要稳定低延迟实时转录、更低开销、跨语句强连续性时应避免
  • 真正的直播媒体流、低延迟服务端摄入或会议中连续音频,改用 rtms

高等级应用场景

场景文档 给出了六类落地场景,覆盖了从交互式单文件到离线合规处理的全谱系:

场景 1:按需上传转录(Fast mode)浏览器上传 → 后端签发 Build JWT → 调用POST /aiservices/scribe/transcribe→ 返回转录 JSON。下游用途:通话后摘要、工单充实、可检索片段库、内部审阅/交接笔记。

场景 2:批量 S3 归档转录(Batch mode)构建带输入前缀与输出前缀的批量请求 → 提交POST /aiservices/scribe/jobs→ 通过 Webhook 或轮询跟踪状态 → 读/jobs/{jobId}/files获取逐文件成败 → 导入搜索、分析或存储。下游用途:合规与审计日志、可检索的网络研讨会/播客归档、批量转录回填、QA 评分输入。

场景 3:Zoom 录音导出后重新转录技能链:zoom-rest-api拉取/下载录音 +scribe转录导出媒体。典型动机:自建留存/搜索管线、需要不同于 Zoom 托管默认的转录设置、用自建摘要/打标流程增强录音。

场景 4:合规 / QA 处理(Batch mode)离线生成用于审计、QA 评分或归档搜索的转录。优先项:审阅者需要精确摘录时word_time_offsets=true;立体声通话录音用channel_separation=true;大流量下用 Webhook + 队列摄入而非同步轮询。

场景 5:客服语音到洞察流水线录音入库 →scribe转录 → 存储转录文本及说话人/时间元数据 → 下游自建情绪、关键词、升级、QA 逻辑。护栏:Scribe 只做转录,情绪分析、关键词检测、评分全部放到转录生成后的下游服务。

场景 6:浏览器麦克风增量转录浏览器MediaRecorder捕获 → 每5 秒flush 一个分片 → 后端把每个分片当作普通 fast mode 上传经异步包装器提交 → 前端按请求 ID 轮询并按序拼接。护栏:这是重复文件上传的伪流式,最适合轻量演示或受限兜底;真正的实时转录产品优先走rtms

故障排查与 5 分钟预检 Runbook

九类高频故障速查

常见漂移与故障文档 系统梳理了 9 类问题:

  1. 凭据看似正确但认证失败:核对iss值、exp窗口、门户当前凭据标签;确认不是把非 Build 应用凭据混用。若 API 返回{"code":124,"message":"Invalid Access token"},这是真实的上游认证失败,而非传输问题。
  2. Fast mode 请求形状不匹配:上传文件与 URL 文件是两条独立请求路径,不要强行用单一 JSON 形态承载。症状是浏览器请求长时间挂起、后端最终超时或空响应。
  3. 413 Request Entity Too Large:通常是反向代理在请求到达应用前就拒绝了上传。nginx 前置时需把client_max_body_size抬到不低于服务端上传上限。
  4. 504 Gateway time-out:请求已到后端,但同步处理超过边缘/代理路径时长。部署观测显示:约 17.2 MB MP4 约 26s 完成,约 38.6 MB 约 26-37s,约 59.2 MB 约 32-34s(后端),但部分约 59.2 MB 浏览器请求先以504超时而后端日志显示200前端 504 + 后端 200 = 浏览器/边缘超时竞态,不是转录失败。建议:为请求级日志记录文件名、大小、mime、上游耗时、响应载荷大小与顶层键;托管 UI 用异步请求/轮询包装器;若 nginx 访问日志出现499而应用日志稍后显示zoom_request_finished status: 200,说明转录已成功、只是浏览器侧请求路径丢失。
  5. 批量作业被接受但输出永不出现:检查 S3 URI/认证不匹配、STS 凭据过期、输出 layout/URI 不匹配、依赖回调时 Webhook 端点不可达;核对/jobs/{jobId}摘要与/jobs/{jobId}/files及云存储权限。
  6. Webhook 验证失败:确认 raw body 捕获先于 JSON 解析、时间戳头纳入签名串、共享 secret 与作业通知配置一致。
  7. 健康检查说凭据存在但 API 调用仍失败:环境文件里多半是${ZOOM_API_KEY}这类字面占位符。只把真实值视为已配置,并在调用 Zoom 前以明确的凭据错误快速失败。
  8. 产品选错:文件/存储转录用scribe,直播会议媒体用rtms
  9. 浏览器麦克风第 1 个分片正常、后续分片为空MediaRecorder.start(timeslice)长会话的后续 blob 可能是缺少容器头的部分 WebM/Opus 簇。首选修复:按分片轮转录音器——启动录音器 → 记录一个分片窗口 → 停止 → 上传该 blob → 为下一分片重新启动新录音器。这是文件容器边界问题,不是 Scribe 语言模型问题。

5 分钟预检 Runbook 与快速决策树

RUNBOOK.md 提供了深度调试前的预检清单与决策树,浓缩如下:

预检七步:

  1. 确认产品:文件/存储转录留在scribe;直播媒体用rtms;需要先入会录音的 bot 链路先走 Meeting SDK Linux。
  2. 确认凭据:Build-platform issuer 凭据对存在;JWT 用HS256且过期不超过一小时;secret 只留服务端;拒绝${ZOOM_API_KEY}这类占位符。
  3. 确认模式:fast mode(单短文件即时 JSON)/ batch mode(多文件/长录音/归档)/ 麦克风伪流式(短分片异步包装器)。托管浏览器 UI 下 fast mode 应包装为「一次上传 → 后端返回202+ 请求 ID → 前端轮询」,避免边缘超时竞态丢失成功转录。
  4. 确认存储/Webhook 输入:fast mode 文件 URL 或上传路径可解析;batch 输入输出 URI 有效;S3 模式 AWS 或预签名访问正确;Webhook 地址为公网 HTTPS。
  5. 确认后处理契约:下游代码期待text_display、segments 还是逐词时间戳;声道分离与 diarization 是否在发货前确定。
  6. 快速探针:本地 JWT 生成成功;已知小文件POST /aiservices/scribe/transcribe成功;浏览器上传经后端以multipart/form-data(而非 JSONdata:URI 包装)转发;batch 提交返回201且带job_id;Webhook 签名验证通过。
  7. 决策树(见下)。

快速决策树:

  • 401/认证失败 → 凭据对错误或 JWT 过期
  • fast mode 返回 schema 错误 → 请求体或 config 字段错误
  • 应用无日志就返回413→ 反向代理限制,不是 Scribe
  • 前端504而后端日志稍后200→ 浏览器/边缘超时竞态,按请求 ID 轮询而非判定失败
  • 麦克风功能需要真正的连续低延迟媒体 → 切换rtms,不是scribe
  • 麦克风第 1 分片正常、后续为空 → 录音器/容器边界问题,每个分片重启录音器
  • batch 作业排队但永不完成 → 存储认证 / URI / Webhook 问题
  • 部分文件缺转录 → 先查/jobs/{jobId}/files再重提整个 batch

版本漂移:三张易变的面与维护触发点

版本漂移文档 把「文档会变」本身当作必须管理的工程风险,识别出三类漂移:

命名漂移API key/secretSDK key/secretZOOM_API_KEY/SECRET并存,统一按 Build-platform issuer/secret 对处理,改生产代码前先到 Zoom 开发者 UI 核实标签。

产品定位漂移:Scribe 属于 AI Services,但相关产品可能把用户引向 RTMS(直播流)、Meeting SDK Linux bot(可见的会内捕获)、AI Companion / REST API(Zoom 生成摘要与转录)。守住边界:scribe= 文件/存储转录;rtms= 直播媒体流摄入;Meeting SDK Linux = 参与者 bot 捕获/原始录音。

工作流声明漂移:部分博客材料把 Scribe 包装进「通话后摘要、工单充实、合规日志、可检索归档、客服 QA 管线、情绪/关键词下游分析」等语音洞察工作流。这些是合法的架构用例,但不扩展当前文档化的端点面。实现规则:scribe只负责生成转录,情绪、分类、QA 评分、摘要全部放自己的下游管线;不要仅凭博客措辞推断未文档化的实时或分析端点。

API 表面漂移观察点:关注 S3 之外的新存储提供方、config字段名变更、Webhook 签名头约定、响应 summary/file schema、语言与输出格式支持。

重新审查触发点api-hub/ai-services/methods/endpoints.json变更、AI Services 文档再次改凭据命名、quickstart 样例改变 Webhook 或上传模式时,需重新校对本文所引用的全部结论。

延伸阅读

  • scribe 技能入口与路由护栏
  • 认证与处理模式
  • 高等级场景
  • Fast Mode Node 示例
  • Batch 作业 + Webhook 流水线示例
  • API 参考
  • 环境变量
  • 样例验证
  • 版本漂移
  • 常见漂移与故障
  • 5 分钟预检 Runbook
  • 相邻技能:rtms(直播流)、rest-api(REST 清单)、webhooks(签名加固)

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询