[ PROMPT_NODE_24258 ]
Realtime Sfu API 参考
[ SKILL_DOCUMENTATION ]
# API 参考
## 认证
bash
curl -X POST 'https://rtc.live/v1/apps/${CALLS_APP_ID}/sessions/new'
-H "Authorization: Bearer ${CALLS_APP_SECRET}"
## 核心概念
**会话 (Sessions):** 到 Cloudflare 边缘节点的 PeerConnection
**轨道 (Tracks):** 媒体/数据通道(音频/视频/数据通道)
**无房间概念:** 通过轨道共享构建在线状态
## 客户端库
**PartyTracks (推荐):** 用于生产环境的基于 Observable 的客户端库。自动处理设备变更、网络切换、ICE 重启。提供 Push/Pull API 和 React Hooks。完整示例请参见 patterns.md。
bash
npm install partytracks @cloudflare/calls
**Raw API:** 用于自定义需求的直接 HTTP + WebRTC 接口(如下所示)。
## 端点
### 创建会话
http
POST /v1/apps/{appId}/sessions/new
→ {sessionId, sessionDescription}
### 添加轨道 (发布)
http
POST /v1/apps/{appId}/sessions/{sessionId}/tracks/new
Body: {
sessionDescription: {sdp, type: "offer"},
tracks: [{location: "local", trackName: "my-video"}]
}
→ {sessionDescription, tracks: [{trackName}]}
### 添加轨道 (订阅)
http
POST /v1/apps/{appId}/sessions/{sessionId}/tracks/new
Body: {
tracks: [{
location: "remote",
trackName: "remote-track-id",
sessionId: "other-session-id"
}]
}
→ {sessionDescription} (服务器 offer)
### 重新协商
http
PUT /v1/apps/{appId}/sessions/{sessionId}/renegotiate
Body: {sessionDescription: {sdp, type: "answer"}}
### 关闭轨道
http
PUT /v1/apps/{appId}/sessions/{sessionId}/tracks/close
Body: {tracks: [{trackName}]}
→ {requiresImmediateRenegotiation: boolean}
### 获取会话
http
GET /v1/apps/{appId}/sessions/{sessionId}
→ {sessionId, tracks: TrackMetadata[]}
## TypeScript 类型
typescript
interface TrackMetadata {
trackName: string;
location: "local" | "remote";
sessionId?: string; // 远程轨道使用
mid?: string; // WebRTC mid
}
## WebRTC 流程
typescript
// 1. 创建 PeerConnection
const pc = new RTCPeerConnection({
iceServers: [{urls: 'stun:stun.cloudflare.com:3478'}]
});
// 2. 添加轨道
const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
stream.getTracks().forEach(track => pc.addTrack(track, stream));
// 3. 创建 offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// 4. 发送到后端 → Cloudflare API
const response = await fetch('/api/new-session', {
method: 'POST',
body: JSON.stringify({sdp: offer.sdp})
});