Skip to content

外部演示文稿API

概述

您可以将在外部系统中创建的演示文稿注册到AITuberKit,分配给指定客户端,并通过API进行播放、暂停、幻灯片切换等操作。演示文稿和客户端分配信息保存在服务器端,因此重新启动AITuberKit后也可以恢复。

现有的本地幻灯片功能仍可继续使用。分配外部演示文稿期间,外部演示文稿优先;解除分配后,将返回当前选择的本地幻灯片。

前置设置

bash
# 启用来自外部的API操作
NEXT_PUBLIC_MESSAGE_RECEIVER_ENABLED=true

# 用于识别操作目标的客户端ID
NEXT_PUBLIC_CLIENT_ID="main-stage"

# 用于 /api/v1 Bearer认证的服务器端API密钥
AITUBERKIT_API_KEY="replace-with-a-random-api-key"

# 外部Presentation Manifest和Assignment的持久化存储位置
# 未指定时: <project-root>/.aituber-kit/presentations
AITUBERKIT_PRESENTATION_STORAGE_DIR=""

所有端点都需要指定以下认证请求头。

http
Authorization: Bearer YOUR_API_KEY

如果 NEXT_PUBLIC_MESSAGE_RECEIVER_ENABLED 处于禁用状态,浏览器端将不会接收外部命令。在限制模式下,外部控制和文件访问将被拒绝。

基本流程

  1. 注册Presentation Manifest
  2. 将已注册的修订版本分配给客户端
  3. 通过状态API确认加载完成
  4. 通过控制API开始、切换或停止演示
  5. 根据需要订阅SSE事件

端点

方法路径用途
PUT/api/v1/presentations/{presentationId}注册或更新Manifest
GET/api/v1/presentations/{presentationId}获取已保存的Manifest
POST/api/v1/presentations/{presentationId}/activate分配给客户端
POST/api/v1/presentation/control控制播放状态和显示
GET/api/v1/presentation/status获取分配状态和浏览器实际状态
GET/api/v1/events通过SSE订阅Presentation事件

注册Manifest

presentationId、Section ID、Slide ID等ID必须以字母或数字开头,可使用字母、数字、连字符和下划线。URL中的presentationId必须与Manifest中的presentationId一致。

bash
curl -X PUT \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "schemaVersion": 1,
    "presentationId": "product-demo",
    "revision": 1,
    "title": "Product Demo",
    "locale": "zh-CN",
    "createdAt": "2026-08-03T12:00:00.000Z",
    "theme": "default",
    "sections": [
      {
        "id": "introduction",
        "title": "概述",
        "qaBrief": "根据产品演示的内容回答问题。",
        "responsePolicy": "不要对资料中未包含的信息进行推测并将其表述为事实。",
        "slides": [
          {
            "id": "intro-1",
            "markdown": "# Product Demo\\n\\n这是通过外部API注册的幻灯片。",
            "narration": "现在开始产品演示。",
            "pauseAfter": true
          }
        ]
      }
    ]
  }' \
  'http://localhost:3000/api/v1/presentations/product-demo'
  • 新注册返回201,更新或重新发送相同内容时返回200
  • 重新发送相同修订版本和相同内容是不会产生更改的幂等操作
  • 如果修订版本早于已保存的版本,或同一修订版本的内容不同,将返回409
  • 请求正文上限为5 MB
  • theme 可使用defaultdark。不支持的值将以default显示

主要Manifest字段

字段要求说明
schemaVersion必填当前为1
presentationId必填与URL一致的Presentation ID
revision必填大于等于1的整数
title必填演示文稿名称
createdAt必填包含时区的ISO 8601日期时间
thumbnail可选在演示文稿列表或隐藏时使用的图片Asset
description / locale可选说明文本和语言信息
theme可选defaultdark
sections必填至少1个,最多50个
sections[].slides必填每个Section至少需要1个,整体最多200个
slides[].markdown必填每个最多50,000个字符
slides[].narration可选朗读文本,最多10,000个字符
slides[].pauseAfter可选true时,在该幻灯片之后暂停Section
slides[].assets可选最多可指定20个httphttps图片
qaBrief可选用于Section问答的资料信息
responsePolicy可选Section的回答方针
sources可选问答时引用的来源信息,整体最多500个
metadata可选值可以是字符串、数字、布尔值或null的附加信息,最多50项

Markdown中的HTML、事件处理程序以及javascript:data:file:链接将被拒绝。图片Asset必须包含alt

获取Manifest

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  'http://localhost:3000/api/v1/presentations/product-demo?revision=1'

revision为可选参数。如果指定值与已保存的修订版本不同,将返回409 REVISION_MISMATCH

分配给Receiver

如果启动了多个浏览器标签页或OBS Browser Source,请先通过 GET /api/v1/receivers 获取已连接的Receiver,然后选择要操作的 receiverId

bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"receiverId":"aituber-receiver-7be9e2c4-57de-4ddb-a808-e85da6fb2387","revision":1,"autoStart":false}' \
  'http://localhost:3000/api/v1/presentations/product-demo/activate'

receiverId也可以通过查询字符串指定。现有集成仍可继续使用用于兼容的clientIdautoStart的默认值为false,即使资料已加载,也不会自动开始发言。

控制演示文稿

bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"receiverId":"aituber-receiver-7be9e2c4-57de-4ddb-a808-e85da6fb2387","action":"start"}' \
  'http://localhost:3000/api/v1/presentation/control'
action操作
start从开头或当前位置开始发言和自动推进
pause当前发言结束后停止自动推进
resume从暂停位置继续
next_slide / previous_slide移动到前一张或后一张Slide
next_section / previous_section移动到前一个或后一个Section
goto移动到target.sectionIdtarget.slideId
reset停止发言并返回开头的ready状态
hide / show保持当前位置并隐藏或重新显示资料
unload解除对客户端的分配

使用goto时,按如下方式指定目标位置。指定speak: true后,会朗读移动后的幻灯片。

json
{
  "receiverId": "aituber-receiver-7be9e2c4-57de-4ddb-a808-e85da6fb2387",
  "action": "goto",
  "target": {
    "sectionId": "introduction",
    "slideId": "intro-1"
  },
  "speak": true
}

控制API接受命令后返回202。请通过状态API或SSE事件确认实际应用完成。

查看状态

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
  'http://localhost:3000/api/v1/presentation/status?receiverId=aituber-receiver-7be9e2c4-57de-4ddb-a808-e85da6fb2387'

响应中包含服务器保存的分配状态desired、浏览器报告的实际状态actual,以及表示两者是否一致的inSync

actual.stateunassignedloadingreadyplayingpausedsection_pausedcompletederror之一。

订阅事件

您可以通过现有的GET /api/v1/events接收以下Presentation事件。

  • presentation_registered
  • presentation_assigned
  • presentation_loaded
  • presentation_started
  • slide_changed
  • section_paused
  • presentation_paused
  • presentation_completed
  • presentation_unloaded
  • presentation_error
bash
curl -N -H "Authorization: Bearer YOUR_API_KEY" \
  'http://localhost:3000/api/v1/events?receiverId=aituber-receiver-7be9e2c4-57de-4ddb-a808-e85da6fb2387'

存储位置与运维注意事项

默认情况下,Manifest和分配信息保存在<project-root>/.aituber-kit/presentations。如需更改存储位置,请指定AITUBERKIT_PRESENTATION_STORAGE_DIR

此功能面向可写入的本地Node.js环境、桌面版和自托管环境。在只读环境或仅提供临时文件系统的环境中,注册或分配操作可能返回503 PRESENTATION_STORAGE_UNAVAILABLE

AITuberKit不会判断外部图片的使用许可。请由图片注册方确认相关权利和公开范围。