@realsee/live 0.1.1 → 0.2.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +51 -56
  2. package/docs/.nojekyll +1 -0
  3. package/docs/assets/custom.css +43 -0
  4. package/docs/assets/highlight.css +127 -0
  5. package/docs/assets/icons.css +1043 -0
  6. package/docs/assets/{images/icons.png → icons.png} +0 -0
  7. package/docs/assets/{images/icons@2x.png → icons@2x.png} +0 -0
  8. package/docs/assets/main.js +52 -0
  9. package/docs/assets/search.js +1 -0
  10. package/docs/assets/style.css +1388 -0
  11. package/docs/assets/{images/widgets.png → widgets.png} +0 -0
  12. package/docs/assets/{images/widgets@2x.png → widgets@2x.png} +0 -0
  13. package/docs/classes/RTCProtocol.RTCExample.html +62 -814
  14. package/docs/classes/RTCProtocol.VRWebViewRTC.html +60 -0
  15. package/docs/classes/shared_utils.Subscribe.html +55 -596
  16. package/docs/enums/RTCProtocol.RTCJoinedInfoCodeEnum.html +9 -0
  17. package/docs/enums/RTCProtocol.RTCType.html +1 -185
  18. package/docs/enums/live.BuiltinActionType.html +15 -325
  19. package/docs/enums/live.BuiltinEventType.html +7 -268
  20. package/docs/enums/live.Command.html +7 -346
  21. package/docs/enums/live.MemUserStatus.html +1 -307
  22. package/docs/enums/live.MicroStatus.html +3 -258
  23. package/docs/enums/live.UserStatus.html +9 -287
  24. package/docs/enums/live.WebSocketCloseError.html +19 -382
  25. package/docs/enums/live.WebSocketErrorType.html +1 -307
  26. package/docs/enums/live.WebSocketState.html +13 -325
  27. package/docs/index.html +327 -512
  28. package/docs/interfaces/RTCProtocol.GetVoiceSignReturnType.html +1 -0
  29. package/docs/interfaces/RTCProtocol.RTCJoinedInfo.html +1 -0
  30. package/docs/interfaces/RTCProtocol.RTCProtocol-1.html +60 -765
  31. package/docs/interfaces/RTCProtocol.VRWebViewRTCOptions.html +1 -0
  32. package/docs/interfaces/live.Live.html +119 -1302
  33. package/docs/interfaces/live.LiveOptions.html +22 -499
  34. package/docs/interfaces/live.LiveReact.html +52 -984
  35. package/docs/modules/RTCProtocol.html +17 -361
  36. package/docs/modules/live.html +103 -1219
  37. package/docs/modules/shared_utils.html +10 -248
  38. package/docs/modules.html +1 -125
  39. package/lib/RTC/BrowserRTC.d.ts +30 -0
  40. package/lib/RTC/BrowserRTC.js +163 -0
  41. package/lib/RTC/BrowserRTC.js.map +1 -0
  42. package/lib/RTC/VRWebViewRTC.d.ts +23 -0
  43. package/lib/RTC/VRWebViewRTC.js +124 -0
  44. package/lib/RTC/VRWebViewRTC.js.map +1 -0
  45. package/lib/RTC/index.d.ts +22 -0
  46. package/lib/{RTCProtocol → RTC}/index.js +3 -7
  47. package/lib/RTC/index.js.map +1 -0
  48. package/lib/createLive.d.ts +1 -1
  49. package/lib/createLive.js +53 -24
  50. package/lib/createLive.js.map +1 -1
  51. package/lib/createLiveReact.d.ts +12 -11
  52. package/lib/createLiveReact.js +9 -15
  53. package/lib/createLiveReact.js.map +1 -1
  54. package/lib/shared-utils/Subscribe.d.ts +1 -1
  55. package/lib/shared-utils/appendUri.js +1 -1
  56. package/lib/shared-utils/appendUri.js.map +1 -1
  57. package/lib/typings/EventType.d.ts +10 -0
  58. package/lib/typings/GetVoiceSign.d.ts +11 -0
  59. package/lib/typings/GetVoiceSign.js +3 -0
  60. package/lib/typings/GetVoiceSign.js.map +1 -0
  61. package/lib/typings/Live.d.ts +6 -4
  62. package/lib/typings/LiveMsg.d.ts +4 -0
  63. package/lib/typings/LiveMsg.js +5 -1
  64. package/lib/typings/LiveMsg.js.map +1 -1
  65. package/lib/typings/LiveOptions.d.ts +3 -7
  66. package/lib/typings/RTCEventType.d.ts +2 -14
  67. package/lib/typings/RTCEventType.js +0 -7
  68. package/lib/typings/RTCEventType.js.map +1 -1
  69. package/lib/typings/RTCJoinedInfo.d.ts +28 -0
  70. package/lib/typings/RTCJoinedInfo.js +23 -0
  71. package/lib/typings/RTCJoinedInfo.js.map +1 -0
  72. package/lib/{RTCProtocol/index.d.ts → typings/RTCProtocol.d.ts} +1 -19
  73. package/lib/typings/RTCProtocol.js +9 -0
  74. package/lib/typings/RTCProtocol.js.map +1 -0
  75. package/lib/typings/VRWebViewRTCOptions.d.ts +6 -0
  76. package/lib/typings/VRWebViewRTCOptions.js +3 -0
  77. package/lib/typings/VRWebViewRTCOptions.js.map +1 -0
  78. package/lib/typings/WebSocket.d.ts +2 -1
  79. package/lib/typings/WebSocket.js +1 -0
  80. package/lib/typings/WebSocket.js.map +1 -1
  81. package/package.json +8 -4
  82. package/umd/{RTCProtocol.046933a5.js → RTCProtocol.543610f0.js} +1 -1
  83. package/umd/createLive.1ecf7dd4.js +1 -0
  84. package/umd/createLiveReact.9075a8fd.js +1 -0
  85. package/docs/assets/css/main.css +0 -2787
  86. package/docs/assets/js/main.js +0 -248
  87. package/docs/assets/js/search.js +0 -1
  88. package/lib/RTCProtocol/index.js.map +0 -1
  89. package/umd/createLive.6845145e.js +0 -1
  90. package/umd/createLiveReact.406cf5a3.js +0 -1
package/docs/index.html CHANGED
@@ -1,536 +1,351 @@
1
- <!doctype html>
2
- <html class="default no-js">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
- <title>如视 Live SDK - v0.1.1</title>
7
- <meta name="description" content="Documentation for 如视 Live SDK - v0.1.1">
8
- <meta name="viewport" content="width=device-width, initial-scale=1">
9
- <link rel="stylesheet" href="assets/css/main.css">
10
- <script async src="assets/js/search.js" id="search-script"></script>
11
- </head>
12
- <body>
13
- <header>
14
- <div class="tsd-page-toolbar">
15
- <div class="container">
16
- <div class="table-wrap">
17
- <div class="table-cell" id="tsd-search" data-index="assets/js/search.json" data-base=".">
18
- <div class="field">
19
- <label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
20
- <input id="tsd-search-field" type="text" />
21
- </div>
22
- <ul class="results">
23
- <li class="state loading">Preparing search index...</li>
24
- <li class="state failure">The search index is not available</li>
25
- </ul>
26
- <a href="index.html" class="title">如视 Live SDK - v0.1.1</a>
27
- </div>
28
- <div class="table-cell" id="tsd-widgets">
29
- <div id="tsd-filter">
30
- <a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
31
- <div class="tsd-filter-group">
32
- <div class="tsd-select" id="tsd-filter-visibility">
33
- <span class="tsd-select-label">All</span>
34
- <ul class="tsd-select-list">
35
- <li data-value="public">Public</li>
36
- <li data-value="protected">Public/Protected</li>
37
- <li data-value="private" class="selected">All</li>
38
- </ul>
39
- </div>
40
- <input type="checkbox" id="tsd-filter-inherited" checked />
41
- <label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
42
- </div>
43
- </div>
44
- <a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
45
- </div>
46
- </div>
47
- </div>
48
- </div>
49
- <div class="tsd-page-title">
50
- <div class="container">
51
- <h1>如视 Live SDK - v0.1.1</h1>
52
- </div>
53
- </div>
54
- </header>
55
- <div class="container container-main">
56
- <div class="row">
57
- <div class="col-8 col-content">
58
- <div class="tsd-panel tsd-typography">
59
- <a href="#livejs" id="livejs" style="color: inherit; text-decoration: none;">
60
- <h1>Live.js</h1>
61
- </a>
62
- <p><a href="https://www.npmjs.com/package/@realsee/live"><img src="https://img.shields.io/npm/v/@realsee/live.svg?style=flat-square&logo=npm&label=npm%20install%20@realsee/live" alt="npm version"></a></p>
63
- <a href="#功能说明" id="功能说明" style="color: inherit; text-decoration: none;">
64
- <h2>功能说明</h2>
65
- </a>
66
- <p><strong>Live</strong> 是 <a href="https://developers.realsee.com/docs/#/docs/live/README">如视开发者中心VRTC服务</a> 的核心客户端 Web SDK,搭配 Live Container
67
- SDKs(iOS/Android/微信小程序)和 Live API 可以快速实现实时同屏、实时语音、IM 等功能。</p>
68
- <a href="#名词释义" id="名词释义" style="color: inherit; text-decoration: none;">
69
- <h3>名词释义</h3>
70
- </a>
71
- <ul>
72
- <li><strong>帧数据(Keyframe)</strong>: 指用户界面需同屏交互信息的状态数据的集合。</li>
73
- </ul>
74
- <blockquote>
75
- <p>通常以键值对的形式表现——键为界面模块名字,值为该模块的状态信息。<br>比如帧数据 <code>{&quot;popupPanel&quot;: { hidden: true }}</code> 表示界面交互中有个弹窗面板,我们命名为<code>popupPanel</code>,它有个<code>hidden</code>状态,<code>true</code>表示其正处于隐藏状态。</p>
76
- </blockquote>
77
- <ul>
78
- <li><strong>快照(Snapshot)</strong>: 指某个时刻所有 <strong>帧数据</strong> 的集合。</li>
79
- </ul>
80
- <blockquote>
81
- <p>您可以理解 <strong>帧数据</strong> 是 <strong>快照</strong> 的子集,通过某时刻的&quot;快照&quot;信息能够还原该时刻的用户界面所有状态。</p>
82
- </blockquote>
83
- <ul>
84
- <li><strong>RTC</strong>: Real-Time Communication, 在本文中则特指渲染 HTML 页面的 WebView/Browser 等容器的音视频实时通信能力。</li>
85
- </ul>
86
- <blockquote>
87
- <p>需注意的是 <strong>Live</strong> 并不包含 <strong>RTC</strong> 功能的实现,需借助客户端原生能力的支持。更多细节详见后文 <a href="#rtc-%E5%8D%8F%E8%AE%AE">RTC 协议</a> 部分。</p>
88
- </blockquote>
89
- <a href="#快速上手" id="快速上手" style="color: inherit; text-decoration: none;">
90
- <h2>快速上手</h2>
91
- </a>
92
- <a href="#安装-sdk" id="安装-sdk" style="color: inherit; text-decoration: none;">
93
- <h3>安装 SDK</h3>
94
- </a>
95
- <p>可以通过Node包管理工具 <a href="https://www.npmjs.com/">npm</a> 或 <a href="https://yarnpkg.com/">yarn</a> 安装<strong>Live</strong>:</p>
96
- <pre><code class="hljs language-bash"><span style="color: #6A737D"># npm</span>
97
- <span style="color: #24292E">npm i @realsee/live</span>
98
- <span style="color: #6A737D"># yarn</span>
99
- <span style="color: #24292E">yarn add @realsee/live</span>
100
- </code></pre>
101
- <a href="#如何使用" id="如何使用" style="color: inherit; text-decoration: none;">
102
- <h3>如何使用</h3>
103
- </a>
104
- <p>简单使用样例(先不考虑实时语音能力):</p>
105
- <pre><code class="hljs language-js"><span style="color: #D73A49">import</span><span style="color: #24292E"> { createLive } </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;@realsee/live&#039;</span>
1
+ <!DOCTYPE html><html class="default"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>如视 Live SDK</title><meta name="description" content="Documentation for 如视 Live SDK"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><link rel="stylesheet" href="assets/custom.css"/><script async src="assets/search.js" id="search-script"></script></head><body><script>document.body.classList.add(localStorage.getItem("tsd-theme") || "os")</script><header><div class="tsd-page-toolbar"><div class="container"><div class="table-wrap"><div class="table-cell" id="tsd-search" data-base="."><div class="field"><label for="tsd-search-field" class="tsd-widget search no-caption">Search</label><input type="text" id="tsd-search-field"/></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">如视 Live SDK</a></div><div class="table-cell" id="tsd-widgets"><div id="tsd-filter"><a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a><div class="tsd-filter-group"><div class="tsd-select" id="tsd-filter-visibility"><span class="tsd-select-label">All</span><ul class="tsd-select-list"><li data-value="public">Public</li><li data-value="protected">Public/Protected</li><li data-value="private" class="selected">All</li></ul></div> <input type="checkbox" id="tsd-filter-inherited" checked/><label class="tsd-widget" for="tsd-filter-inherited">Inherited</label><input type="checkbox" id="tsd-filter-externals" checked/><label class="tsd-widget" for="tsd-filter-externals">Externals</label></div></div><a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a></div></div></div></div><div class="tsd-page-title"><div class="container"><h1> 如视 Live SDK</h1></div></div></header><div class="container container-main"><div class="row"><div class="col-8 col-content"><div class="tsd-panel tsd-typography">
2
+ <a href="#livejs" id="livejs" style="color: inherit; text-decoration: none;">
3
+ <h1>Live.js</h1>
4
+ </a>
5
+ <p><a href="https://www.npmjs.com/package/@realsee/live"><img src="https://img.shields.io/npm/v/@realsee/live.svg?style=flat-square&logo=npm&label=npm%20install%20@realsee/live" alt="npm version"></a></p>
106
6
 
107
- <span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">live</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> </span><span style="color: #6F42C1">createLive</span><span style="color: #24292E">({</span>
108
- <span style="color: #24292E"> url: </span><span style="color: #032F62">&#039;wss://ws-access.realsee.com/***/?=xxx&#039;</span><span style="color: #24292E">, </span><span style="color: #6A737D">/* 连接 WebSocket 服务的 URL */</span>
109
- <span style="color: #24292E"> </span><span style="color: #6F42C1">getTicket</span><span style="color: #24292E">: </span><span style="color: #D73A49">async</span><span style="color: #24292E"> () </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {</span><span style="color: #6A737D">/* 获取带看&quot;门票&quot;的回调函数 */</span><span style="color: #24292E">},</span>
110
- <span style="color: #24292E">})</span>
7
+ <a href="#功能说明" id="功能说明" style="color: inherit; text-decoration: none;">
8
+ <h2>功能说明</h2>
9
+ </a>
10
+ <p><strong>Live</strong> 是 <a href="https://developers.realsee.com/docs/#/docs/live/README">如视开发者中心 VRTC 服务</a> 的核心客户端 Web SDK,搭配 Live Container
11
+ SDKs(iOS/Android/微信小程序)和 Live API 可以快速实现实时同屏、实时语音、IM 等功能。</p>
111
12
 
112
- </code></pre>
113
- <p>在创建 <code>live</code> 实例时配置了两个参数:</p>
114
- <ul>
115
- <li><code>url</code>:连接 WebSocket 服务的 URL,如果在创建 <code>live</code> 实例阶段并不知道 URL ,您可以在合适的时机通过 <code>live.connect({ url })</code> 方法进行 WebScoket 连接。</li>
116
- <li><code>getTicket()</code>:是一个异步回调函数,其返回值是连接 WebScoket 服务的 **&quot;门票&quot;**,关于如何获取 <code>ticket</code> 请查阅 <a href="">VR 带看 API</a>。</li>
117
- </ul>
118
- <blockquote>
119
- <p>关于 <code>createLive()</code> 函数的更多参数配置请参考 <a href="https://unpkg.com/@realsee/live/docs/interfaces/live.LiveOptions.html">LiveOptions</a> 。</p>
120
- </blockquote>
121
- <p>获取实例 <code>live</code> 之后,可以做很多有趣的事情。但在讲述详细用途之前,先简单介绍下 <strong>Live</strong> 中的 <strong>消息系统</strong>。</p>
122
- <a href="#消息系统" id="消息系统" style="color: inherit; text-decoration: none;">
123
- <h2>消息系统</h2>
124
- </a>
125
- <p><strong>Live</strong> 核心职责是借助 WebSocket 长链双工通信能力实现多端用户的同屏连线。用户间的通信都是基于 WebSocket 消息。</p>
126
- <p><strong>Live</strong> 将消息分为<code>帧数据</code>、<code>广播</code>、<code>房间信息</code>三类。针对每一类信息提供相应的发送、接收 API,更多 API
127
- 细节请参考 <a href="https://unpkg.com/@realsee/live/docs/index.html">Live API 文档</a> 。</p>
128
- <p><strong>帧数据</strong> 是进行同屏的信息载体,由用户自行定义当前场景中哪些信息用以同屏,将这些信息组织成 <code>{key: value}</code> 的形式即可。</p>
129
- <p><strong>广播消息</strong> 用以房间成员之间以事件的形式指定某个用户向其发送自定义广播消息。如:主持人向观众发送问候消息。</p>
130
- <p><strong>房间信息</strong> 为内置消息体,由 WebSocket 服务主动推送,包括房间状态、当前用户及参与用户列表等。部分信息也可通过 <strong>Live</strong> 提供的更新方式进行修改。</p>
131
- <a href="#帧数据同步" id="帧数据同步" style="color: inherit; text-decoration: none;">
132
- <h3>帧数据同步</h3>
133
- </a>
134
- <p>当前 UI 交互状态的同步:</p>
135
- <p>以 <a href="https://developers.realsee.com/docs/#/docs/five/web/quickstart">Five</a> 同屏为例</p>
136
- <pre><code class="hljs language-js"><span style="color: #6A737D">// 发送本地 帧数据 (Five State)</span>
137
- <span style="color: #24292E">live.</span><span style="color: #6F42C1">sendKeyframe</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;five&#039;</span><span style="color: #24292E">, { panoIndex: </span><span style="color: #005CC5">13</span><span style="color: #24292E"> })</span>
13
+ <a href="#名词释义" id="名词释义" style="color: inherit; text-decoration: none;">
14
+ <h3>名词释义</h3>
15
+ </a>
16
+ <ul>
17
+ <li><strong>帧数据(Keyframe)</strong>: 指用户界面需同屏交互信息的状态数据的集合。</li>
18
+ </ul>
19
+ <blockquote>
20
+ <p>通常以键值对的形式表现——键为界面模块名字,值为该模块的状态信息。<br>比如帧数据 <code>{&quot;popupPanel&quot;: { hidden: true }}</code> 表示界面交互中有个弹窗面板,我们命名为<code>popupPanel</code>,它有个<code>hidden</code>状态,<code>true</code>表示其正处于隐藏状态。</p>
21
+ </blockquote>
22
+ <ul>
23
+ <li><strong>快照(Snapshot)</strong>: 指某个时刻所有 <strong>帧数据</strong> 的集合。</li>
24
+ </ul>
25
+ <blockquote>
26
+ <p>您可以理解 <strong>帧数据</strong> 是 <strong>快照</strong> 的子集,通过某时刻的&quot;快照&quot;信息能够还原该时刻的用户界面所有状态。</p>
27
+ </blockquote>
28
+ <ul>
29
+ <li><strong>RTC</strong>: Real-Time Communication, 在本文中则特指渲染 HTML 页面的 WebView/Browser 等容器的音视频实时通信能力。</li>
30
+ </ul>
31
+ <blockquote>
32
+ <p>需注意的是 <strong>Live</strong> 并不包含 <strong>RTC</strong> 功能的实现,需借助客户端原生能力的支持。更多细节详见后文 <a href="#rtc-%E5%8D%8F%E8%AE%AE">RTC 协议</a> 部分。</p>
33
+ </blockquote>
138
34
 
139
- <span style="color: #6A737D">// 接收远程 帧数据 (Five State)</span>
140
- <span style="color: #24292E">live.keyframes.</span><span style="color: #6F42C1">on</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;five&#039;</span><span style="color: #24292E">, (</span><span style="color: #E36209">newState</span><span style="color: #24292E">, </span><span style="color: #E36209">prevState</span><span style="color: #24292E">) </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {</span>
141
- <span style="color: #24292E"> </span><span style="color: #6A737D">// 可以拿最新的 `newState` 更新本地 UI 状态</span>
142
- <span style="color: #24292E">})</span>
143
- </code></pre>
144
- <p>您也可以通过 <code>live.snapshot</code> 属性来获取当前所有序列帧数据的&quot;快照&quot;。</p>
145
- <a href="#房间信息" id="房间信息" style="color: inherit; text-decoration: none;">
146
- <h3>房间信息</h3>
147
- </a>
148
- <p><strong>Live</strong> 有会话房间的概念,当您成功连接 WebSocket 服务之后等同于您作为一个用户加入了一个房间。此房间用户除了您之外还会有其他用户,您可以通过如下方式获取或更新用户信息:</p>
149
- <pre><code class="hljs language-js"><span style="color: #6A737D">// 属性:获取本地用户信息</span>
150
- <span style="color: #24292E">live.selfInfo</span>
35
+ <a href="#快速上手" id="快速上手" style="color: inherit; text-decoration: none;">
36
+ <h2>快速上手</h2>
37
+ </a>
151
38
 
152
- <span style="color: #6A737D">// 属性:获取当前房间内所有用户列表</span>
153
- <span style="color: #24292E">live.userList</span>
39
+ <a href="#安装-sdk" id="安装-sdk" style="color: inherit; text-decoration: none;">
40
+ <h3>安装 SDK</h3>
41
+ </a>
42
+ <p>可以通过 Node 包管理工具 <a href="https://www.npmjs.com/">npm</a> 或 <a href="https://yarnpkg.com/">yarn</a> 安装<strong>Live</strong>:</p>
43
+ <pre><code class="hljs language-bash"><span class="hl-0"># npm</span><br/><span class="hl-1">npm i @realsee/live</span><br/><span class="hl-0"># yarn</span><br/><span class="hl-1">yarn add @realsee/live</span>
44
+ </code></pre>
154
45
 
155
- <span style="color: #6A737D">// 方法:更新本地用户信息</span>
156
- <span style="color: #24292E">live.</span><span style="color: #6F42C1">setSelfInfo</span><span style="color: #24292E">({})</span>
46
+ <a href="#如何使用" id="如何使用" style="color: inherit; text-decoration: none;">
47
+ <h3>如何使用</h3>
48
+ </a>
49
+ <p>简单使用样例(先不考虑实时语音能力):</p>
50
+ <pre><code class="hljs language-js"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-3">createLive</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-4">&#39;@realsee/live&#39;</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">live</span><span class="hl-1"> = </span><span class="hl-7">createLive</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-3">url:</span><span class="hl-1"> </span><span class="hl-4">&#39;wss://ws-access.realsee.com/***/?=xxx&#39;</span><span class="hl-1"> </span><span class="hl-0">/* 连接 WebSocket 服务的 URL */</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-7">getTicket</span><span class="hl-3">:</span><span class="hl-1"> </span><span class="hl-5">async</span><span class="hl-1"> () </span><span class="hl-5">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">/* 获取带看&quot;门票&quot;的回调函数 */</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">})</span>
51
+ </code></pre>
52
+ <p>在创建 <code>live</code> 实例时配置了两个参数:</p>
53
+ <ul>
54
+ <li><code>url</code>:连接 WebSocket 服务的 URL,如果在创建 <code>live</code> 实例阶段并不知道 URL ,您可以在合适的时机通过 <code>live.connect({ url })</code> 方法进行 WebScoket 连接。</li>
55
+ <li><code>getTicket()</code>:是一个异步回调函数,其返回值是连接 WebScoket 服务的 **&quot;门票&quot;**,关于如何获取 <code>ticket</code> 请查阅 <a href="">VR 带看 API</a>。</li>
56
+ </ul>
57
+ <blockquote>
58
+ <p>关于 <code>createLive()</code> 函数的更多参数配置请参考 <a href="https://unpkg.com/@realsee/live/docs/interfaces/live.LiveOptions.html">LiveOptions</a> 。</p>
59
+ </blockquote>
60
+ <p>获取实例 <code>live</code> 之后,可以做很多有趣的事情。但在讲述详细用途之前,先简单介绍下 <strong>Live</strong> 中的 <strong>消息系统</strong>。</p>
157
61
 
158
- <span style="color: #6A737D">// 事件:本地用户信息发生变更</span>
159
- <span style="color: #24292E">live.</span><span style="color: #6F42C1">on</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;selfInfoUpdate&#039;</span><span style="color: #24292E">, (</span><span style="color: #E36209">userInfo</span><span style="color: #24292E">) </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {})</span>
62
+ <a href="#消息系统" id="消息系统" style="color: inherit; text-decoration: none;">
63
+ <h2>消息系统</h2>
64
+ </a>
65
+ <p><strong>Live</strong> 核心职责是借助 WebSocket 长链双工通信能力实现多端用户的同屏连线。用户间的通信都是基于 WebSocket 消息。</p>
66
+ <p><strong>Live</strong> 将消息分为<code>帧数据</code>、<code>广播</code>、<code>房间信息</code>三类。针对每一类信息提供相应的发送、接收 API,更多 API
67
+ 细节请参考 <a href="https://unpkg.com/@realsee/live/docs/index.html">Live API 文档</a> 。</p>
68
+ <p><strong>帧数据</strong> 是进行同屏的信息载体,由用户自行定义当前场景中哪些信息用以同屏,将这些信息组织成 <code>{key: value}</code> 的形式即可。</p>
69
+ <p><strong>广播消息</strong> 用以房间成员之间以事件的形式指定某个用户向其发送自定义广播消息。如:主持人向观众发送问候消息。</p>
70
+ <p><strong>房间信息</strong> 为内置消息体,由 WebSocket 服务主动推送,包括房间状态、当前用户及参与用户列表等。部分信息也可通过 <strong>Live</strong> 提供的更新方式进行修改。</p>
160
71
 
161
- <span style="color: #6A737D">// 事件:房间用户列表信息发生变更</span>
162
- <span style="color: #24292E">live.</span><span style="color: #6F42C1">on</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;userListUpdate&#039;</span><span style="color: #24292E">, (</span><span style="color: #E36209">userList</span><span style="color: #24292E">) </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {})</span>
163
- </code></pre>
164
- <a href="#广播消息" id="广播消息" style="color: inherit; text-decoration: none;">
165
- <h3>广播消息</h3>
166
- </a>
167
- <p>除了帧数据和房间信息之外,还可以用事件的形式向房间内的其他用户广播消息:</p>
168
- <pre><code class="hljs language-js"><span style="color: #24292E">live.</span><span style="color: #6F42C1">broadcast</span><span style="color: #24292E">(data </span><span style="color: #6A737D">/* 广播的数据 */</span><span style="color: #24292E">, [</span><span style="color: #032F62">&#039;user_id_1&#039;</span><span style="color: #24292E">, </span><span style="color: #032F62">&#039;user_id_2&#039;</span><span style="color: #24292E">] </span><span style="color: #6A737D">/* 收到此用户的userId */</span><span style="color: #24292E">)</span>
169
- </code></pre>
170
- <p>此时,房间内用户 Id 为 <code>user_id_1</code>、<code>user_id_2</code> 的用户会收到此广播消息(其他用户无感知):</p>
171
- <pre><code class="hljs language-js"><span style="color: #24292E">live.</span><span style="color: #6F42C1">on</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;broadcast&#039;</span><span style="color: #24292E">, (</span><span style="color: #E36209">data</span><span style="color: #24292E"> </span><span style="color: #6A737D">/* 广播的数据 */</span><span style="color: #24292E">) </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {})</span>
172
- </code></pre>
173
- <p>更多的例子请查看 <a href="https://unpkg.com/@realsee/live/docs/index.html">Live API</a> 文档 。</p>
174
- <a href="#事件监听" id="事件监听" style="color: inherit; text-decoration: none;">
175
- <h2>事件监听</h2>
176
- </a>
177
- <p><strong>Live</strong> 提供 <code>WebSocket 事件</code>、<code>live 事件</code> 和 <code>RTC 事件</code> 三类异步事件的监听。</p>
178
- <p>其中, <code>WebSocket 事件</code>、<code>live 事件</code> 都可以通过 <code>live.on(&#39;/*事件名*/&#39;, /*事件回调*/)</code> 的方式监听。</p>
179
- <p>比如监听 WebSocket 状态发生变更:</p>
180
- <pre><code class="hljs language-ts"><span style="color: #24292E">live.</span><span style="color: #6F42C1">on</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;ws.readyStateUpdate&#039;</span><span style="color: #24292E">, (</span><span style="color: #E36209">readyState</span><span style="color: #D73A49">:</span><span style="color: #24292E"> </span><span style="color: #E36209">WebSocketState</span><span style="color: #24292E">) </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {</span>
181
- <span style="color: #24292E"> console.</span><span style="color: #6F42C1">log</span><span style="color: #24292E">(readyState) </span><span style="color: #6A737D">// readyState 即是最新的 WebScoket 状态</span>
182
- <span style="color: #24292E">})</span>
183
- </code></pre>
184
- <a href="#websocket-事件" id="websocket-事件" style="color: inherit; text-decoration: none;">
185
- <h3>WebSocket 事件</h3>
186
- </a>
187
- <ul>
188
- <li><p><code>ws.beforeConnect(reConnect?: number): void</code> WebSocket 完成连接之后。</p>
189
- </li>
190
- <li><p><code>ws.afterConnect(reConnect?: number): void</code> WebSocket 完成连接之前。</p>
191
- </li>
192
- <li><p><code>ws.readyStateUpdate(readyState: WebSocketState): void</code> WebSocket 完成状态发生变更。</p>
193
- </li>
194
- </ul>
195
- <p><strong>WebSocket 连接状态枚举表:</strong></p>
196
- <table>
197
- <thead>
198
- <tr>
199
- <th>状态名称</th>
200
- <th>状态描述</th>
201
- </tr>
202
- </thead>
203
- <tbody><tr>
204
- <td>NOTINITIALIZED</td>
205
- <td>未被初始化</td>
206
- </tr>
207
- <tr>
208
- <td>CONNECTING</td>
209
- <td>正在连接中</td>
210
- </tr>
211
- <tr>
212
- <td>OPEN</td>
213
- <td>连接成功</td>
214
- </tr>
215
- <tr>
216
- <td>CLOSING</td>
217
- <td>关闭中</td>
218
- </tr>
219
- <tr>
220
- <td>CLOSED</td>
221
- <td>关闭成功</td>
222
- </tr>
223
- </tbody></table>
224
- <p><strong>Live</strong> 前后端服务交互是基于 WebSocket 长链接的。一次带看成功进入、退出的标识由 WebSocket 的状态 <code>OPEN</code>、<code>CLOSED</code>体现。 因此,所有 <strong>VRTC</strong> 相关的事件处理逻辑应保证在<code>OPEN</code>
225
- 事件之后进行。</p>
226
- <a href="#live-事件" id="live-事件" style="color: inherit; text-decoration: none;">
227
- <h3>live 事件</h3>
228
- </a>
229
- <ul>
230
- <li><p><code>broadcast(evtMsg: Record&lt;string, any&gt;, frontRequestId: string): void</code> 接收其他用户的广播消息。</p>
231
- </li>
232
- <li><p><code>builtinEvent(builtinMsg: BuiltinMsg): void</code> 接收服务端推送的内置事件消息。</p>
233
- </li>
234
- <li><p><code>keyframes(keyframes: Partial&lt;Snapshot&gt;, frontRequestId: string): void</code> 接收其他用户的帧数据。</p>
235
- </li>
236
- <li><p><code>readyKeyframeSync(lastKeyframe: Partial&lt;Snapshot&gt;): void</code> 表明帧同步行为已就绪。</p>
237
- </li>
238
- <li><p><code>selfInfoUpdate(userInfo: UserInfo, frontRequestId: string): void</code> 自身的信息发生变更。</p>
239
- </li>
240
- <li><p><code>userListUpdate(userList: UserInfo[], frontRequestId: string): void</code> 用户列信息表发生变更。</p>
241
- </li>
242
- </ul>
243
- <p><code>live</code> 实例提供了很多诸如<code>live.connect()</code>、<code>live.broadcast()</code>、<code>live.sendKeyframe()</code>等方法,这些方法都是异步反馈且可能会影响房间内的其他用户。
244
- 您可以通过监听以上事件来获知这些影响。</p>
245
- <p>需要注意的是 <code>readyKeyframeSync</code> 事件是可进行帧同步的节点标识,收到此事件后您的帧同步行为才生效。</p>
246
- <a href="#rtc-事件" id="rtc-事件" style="color: inherit; text-decoration: none;">
247
- <h3>RTC 事件</h3>
248
- </a>
249
- <ul>
250
- <li><p><code>error(error: Error): void</code> 异常事件。</p>
251
- </li>
252
- <li><p><code>initWillStart(): void</code> 即将初始化事件。</p>
253
- </li>
254
- <li><p><code>inited(): void</code> 初始化完成事件。</p>
255
- </li>
256
- <li><p><code>joinWillStart(): void</code> 即将加入语音房间事件。</p>
257
- </li>
258
- <li><p><code>joined(): void</code> 成功加入语音房间事件。</p>
259
- </li>
260
- <li><p><code>userVolumes(userVolumes: UserVolume[]): void</code> 房间内每个说话用户的音量。</p>
261
- </li>
262
- <li><p><code>weakNetwork(): void</code> 弱网提醒事件。</p>
263
- </li>
264
- </ul>
265
- <p><code>live.$RTC</code> 实例需满足 <a href="">RTC 协议</a>,其事件通过 <code>live.$RTC.on(&#39;/*事件名*/&#39;, /*事件回调*/)</code> 方式来监听,比如监听语音房间内正在说话的用户及其音量:</p>
266
- <pre><code class="hljs language-ts"><span style="color: #24292E">live.$RTC.</span><span style="color: #6F42C1">on</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;userVolumes&#039;</span><span style="color: #24292E">, (</span><span style="color: #E36209">userVolumes</span><span style="color: #D73A49">:</span><span style="color: #24292E"> </span><span style="color: #E36209">UserVolume</span><span style="color: #24292E">[]) </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {</span>
267
- <span style="color: #24292E"> console.</span><span style="color: #6F42C1">log</span><span style="color: #24292E">(userVolumes) </span><span style="color: #6A737D">// userVolumes 正在说话的用户及其音量数据。</span>
268
- <span style="color: #24292E">})</span>
72
+ <a href="#帧数据同步" id="帧数据同步" style="color: inherit; text-decoration: none;">
73
+ <h3>帧数据同步</h3>
74
+ </a>
75
+ <p>当前 UI 交互状态的同步:</p>
76
+ <p>以 <a href="https://developers.realsee.com/docs/#/docs/five/web/quickstart">Five</a> 同屏为例</p>
77
+ <pre><code class="hljs language-js"><span class="hl-0">// 发送本地 帧数据 (Five State)</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-7">sendKeyframe</span><span class="hl-1">(</span><span class="hl-4">&#39;five&#39;</span><span class="hl-1">, { </span><span class="hl-3">panoIndex:</span><span class="hl-1"> </span><span class="hl-8">13</span><span class="hl-1"> })</span><br/><br/><span class="hl-0">// 接收远程 帧数据 (Five State)</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-3">keyframes</span><span class="hl-1">.</span><span class="hl-7">on</span><span class="hl-1">(</span><span class="hl-4">&#39;five&#39;</span><span class="hl-1">, (</span><span class="hl-3">newState</span><span class="hl-1">, </span><span class="hl-3">prevState</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">// 可以拿最新的 `newState` 更新本地 UI 状态</span><br/><span class="hl-1">})</span>
269
78
  </code></pre>
270
- <a href="#异常处理" id="异常处理" style="color: inherit; text-decoration: none;">
271
- <h3>异常处理</h3>
272
- </a>
273
- <ul>
274
- <li><code>ws.error(error: WebSocketError): void</code> WebSocket 连接出现异常。</li>
275
- </ul>
276
- <p><strong>WebSocket 错误状态枚举表:</strong></p>
277
- <table>
278
- <thead>
279
- <tr>
280
- <th>错误字段</th>
281
- <th>错误描述</th>
282
- <th>触发场景</th>
283
- </tr>
284
- </thead>
285
- <tbody><tr>
286
- <td>Close</td>
287
- <td>错误类型枚举参照<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent">CloseEvent</a></td>
288
- <td>错误原因参照<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent">CloseEvent</a></td>
289
- </tr>
290
- <tr>
291
- <td>Error</td>
292
- <td></td>
293
- <td></td>
294
- </tr>
295
- <tr>
296
- <td>MicroAuth</td>
297
- <td>麦克风授权错误</td>
298
- <td>语音功能获取麦克风授权失败</td>
299
- </tr>
300
- <tr>
301
- <td>DuplicateConnect</td>
302
- <td>重复连接</td>
303
- <td>使用相同的 WS 链接申请连接</td>
304
- </tr>
305
- <tr>
306
- <td>IllegalURL</td>
307
- <td>非法的 WS 链接</td>
308
- <td>传入的 WS 链接不合法</td>
309
- </tr>
310
- <tr>
311
- <td>Unknown</td>
312
- <td>未知错误</td>
313
- <td>其他未被枚举的错误原样返回</td>
314
- </tr>
315
- </tbody></table>
316
- <ul>
317
- <li><code>error(liveMsg: LiveMsg): void</code> 服务端推送出现异常。</li>
318
- </ul>
319
- <p>与 WebSocket 通信的结构体<code>LiveMsg</code>格式如下:</p>
320
- <table>
321
- <thead>
322
- <tr>
323
- <th>名称</th>
324
- <th>类型</th>
325
- <th>描述</th>
326
- </tr>
327
- </thead>
328
- <tbody><tr>
329
- <td>appId</td>
330
- <td>string</td>
331
- <td></td>
332
- </tr>
333
- <tr>
334
- <td>code</td>
335
- <td>string</td>
336
- <td>返回码,详情参照<a href="https://developers.realsee.com/docs/#/docs/live/server/README">服务端 API Code 码表</a></td>
337
- </tr>
338
- <tr>
339
- <td>command</td>
340
- <td>指令</td>
341
- <td>WebSocket 通信指令类型,详情请查看<a href="https://unpkg.com/@realsee/live/docs/index.html">Live API</a> 文档</td>
342
- </tr>
343
- <tr>
344
- <td>data</td>
345
- <td>Record&lt;string, any&gt;</td>
346
- <td>本条指令对应的业务数据</td>
347
- </tr>
348
- <tr>
349
- <td>frontRequestId:</td>
350
- <td>string</td>
351
- <td>前端的请求 ID,由 WS 服务原样透传回前端</td>
352
- </tr>
353
- <tr>
354
- <td>message</td>
355
- <td>string</td>
356
- <td>返回描述</td>
357
- </tr>
358
- <tr>
359
- <td>requestId</td>
360
- <td>string</td>
361
- <td>后端请求 ID</td>
362
- </tr>
363
- <tr>
364
- <td>roomCode</td>
365
- <td>string</td>
366
- <td>带看房间号</td>
367
- </tr>
368
- <tr>
369
- <td>triggerUserId</td>
370
- <td>string</td>
371
- <td>触发指令的用户 ID</td>
372
- </tr>
373
- </tbody></table>
374
- <p>当 WebSocket 推送的数据结构体不满足 <code>LiveMsg</code> 或者 <code>code</code> 值不为 <code>SUCCESS</code> 时会以 <code>error</code> 事件的形式抛出来。</p>
375
- <ul>
376
- <li><code>error(error: Error): void</code> RTC 语音出现异常。</li>
377
- </ul>
378
- <blockquote>
379
- <p>RTC 语音不同容器或 RTC 解决方案不同,其错误信息内容可能不完全一致。</p>
380
- </blockquote>
381
- <a href="#rtc-协议" id="rtc-协议" style="color: inherit; text-decoration: none;">
382
- <h2>RTC 协议</h2>
383
- </a>
384
- <p>语音能力需依赖 WebView/Browser 容器,即需要容器端实现 RTC 能力。</p>
385
- <p>为了方便开发者接入,<strong>如视开发者中心VRTC服务</strong> 为主流平台提供 <a href="https://developers.realsee.com/docs/#/docs/live/client/container/README">容器SDK</a>
386
- 和 <a href="https://www.npmjs.com/package/@realsee/jsbridge-x">jsbridge-x</a> 。</p>
387
- <p><strong>Live</strong> 通过 <strong>jsbridge-x</strong> 与 集成了<strong>容器SDK</strong> 的客户端应用或微信小程序应用程序桥接,实现原生能力的调用。这个 <code>jsbridge-x</code>
388
- 实例需作为配置参数提供给<code>createLive()</code>。</p>
389
- <p>如果是 iOS/Android App(已接入如视VRTC容器SDK)</p>
390
- <pre><code class="hljs language-js"><span style="color: #D73A49">import</span><span style="color: #24292E"> AppBridge </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;@realsee/jsbridge-x/lib/cjs/app&#039;</span>
391
- <span style="color: #D73A49">import</span><span style="color: #24292E"> { createLive } </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;@realsee/live&#039;</span>
79
+ <p>您也可以通过 <code>live.snapshot</code> 属性来获取当前所有序列帧数据的&quot;快照&quot;。</p>
392
80
 
393
- <span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">live</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> </span><span style="color: #6F42C1">createLive</span><span style="color: #24292E">({</span>
394
- <span style="color: #24292E"> rtc: </span><span style="color: #D73A49">new</span><span style="color: #24292E"> </span><span style="color: #6F42C1">AppBridge</span><span style="color: #24292E">(),</span>
395
- <span style="color: #24292E"> </span><span style="color: #6F42C1">getTicket</span><span style="color: #24292E">: </span><span style="color: #D73A49">async</span><span style="color: #24292E"> () </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;&#039;</span>
396
- <span style="color: #24292E">})</span>
81
+ <a href="#房间信息" id="房间信息" style="color: inherit; text-decoration: none;">
82
+ <h3>房间信息</h3>
83
+ </a>
84
+ <p><strong>Live</strong> 有会话房间的概念,当您成功连接 WebSocket 服务之后等同于您作为一个用户加入了一个房间。此房间用户除了您之外还会有其他用户,您可以通过如下方式获取或更新用户信息:</p>
85
+ <pre><code class="hljs language-js"><span class="hl-0">// 属性:获取本地用户信息</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-3">selfInfo</span><br/><br/><span class="hl-0">// 属性:获取当前房间内所有用户列表</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-3">userList</span><br/><br/><span class="hl-0">// 方法:更新本地用户信息</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-7">setSelfInfo</span><span class="hl-1">({})</span><br/><br/><span class="hl-0">// 事件:本地用户信息发生变更</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-7">on</span><span class="hl-1">(</span><span class="hl-4">&#39;selfInfoUpdate&#39;</span><span class="hl-1">, (</span><span class="hl-3">userInfo</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> {})</span><br/><br/><span class="hl-0">// 事件:房间用户列表信息发生变更</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-7">on</span><span class="hl-1">(</span><span class="hl-4">&#39;userListUpdate&#39;</span><span class="hl-1">, (</span><span class="hl-3">userList</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> {})</span>
397
86
  </code></pre>
398
- <p>如果是 微信小程序(已接入如视VRTC容器SDK)</p>
399
- <pre><code class="hljs language-js"><span style="color: #D73A49">import</span><span style="color: #24292E"> MiniprogramBridge </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;@realsee/jsbridge-x/lib/cjs/miniprogram&#039;</span>
400
- <span style="color: #D73A49">import</span><span style="color: #24292E"> { createLive } </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;@realsee/live&#039;</span>
401
87
 
402
- <span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">live</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> </span><span style="color: #6F42C1">createLive</span><span style="color: #24292E">({</span>
403
- <span style="color: #24292E"> rtc: </span><span style="color: #D73A49">new</span><span style="color: #24292E"> </span><span style="color: #6F42C1">MiniprogramBridge</span><span style="color: #24292E">(),</span>
404
- <span style="color: #24292E"> </span><span style="color: #6F42C1">getTicket</span><span style="color: #24292E">: </span><span style="color: #D73A49">async</span><span style="color: #24292E"> () </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;&#039;</span>
405
- <span style="color: #24292E">})</span>
88
+ <a href="#广播消息" id="广播消息" style="color: inherit; text-decoration: none;">
89
+ <h3>广播消息</h3>
90
+ </a>
91
+ <p>除了帧数据和房间信息之外,还可以用事件的形式向房间内的其他用户广播消息:</p>
92
+ <pre><code class="hljs language-js"><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-7">broadcast</span><span class="hl-1">(</span><span class="hl-3">data</span><span class="hl-1"> </span><span class="hl-0">/* 广播的数据 */</span><span class="hl-1">, [</span><span class="hl-4">&#39;user_id_1&#39;</span><span class="hl-1">, </span><span class="hl-4">&#39;user_id_2&#39;</span><span class="hl-1">] </span><span class="hl-0">/* 收到此用户的userId */</span><span class="hl-1">)</span>
406
93
  </code></pre>
407
- <p>提供 RTC 实例配置参数之后,语音的连接、断开、重连等逻辑就托管给了 <strong>Live</strong> 。您可以通过 live 实例上的 <code>$RTC</code> 命名空间访问语音相关的状态和事件。</p>
408
- <pre><code class="hljs language-js"><span style="color: #6A737D">// 状态:用户是否成功加入语音房间</span>
409
- <span style="color: #24292E">live.$RTC.joined</span>
410
- <span style="color: #6A737D">// 状态:用户麦克风状态</span>
411
- <span style="color: #24292E">live.$RTC.micro</span>
412
- <span style="color: #6A737D">// 监听用户音量变化</span>
413
- <span style="color: #24292E">live.$RTC.</span><span style="color: #6F42C1">on</span><span style="color: #24292E">(</span><span style="color: #032F62">&#039;userVolumes&#039;</span><span style="color: #24292E">, (</span><span style="color: #E36209">userVolumes</span><span style="color: #24292E">) </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> {})</span>
94
+ <p>此时,房间内用户 Id 为 <code>user_id_1</code>、<code>user_id_2</code> 的用户会收到此广播消息(其他用户无感知):</p>
95
+ <pre><code class="hljs language-js"><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-7">on</span><span class="hl-1">(</span><span class="hl-4">&#39;broadcast&#39;</span><span class="hl-1">, (</span><span class="hl-3">data</span><span class="hl-1"> </span><span class="hl-0">/* 广播的数据 */</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> {})</span>
414
96
  </code></pre>
415
- <a href="#typescript-amp-react-支持" id="typescript-amp-react-支持" style="color: inherit; text-decoration: none;">
416
- <h2>TypeScript &amp; React 支持</h2>
417
- </a>
418
- <p><strong>Live</strong> 有完整的 <a href="https://www.typescriptlang.org/docs/handbook/2/generics.html">TypeScript Generics</a>
419
- 和 <a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a> 支持,如果您的技术栈基于 <code>TypeScript</code> 和 <code>React</code> 可以参考如下方式更优雅地使用 <strong>Live</strong>。</p>
420
- <p><img src="https://vrlab-static.ljcdn.com/release/web/tssupportminify.f2eaeed2.png" alt="TypeScript效果演示"></p>
421
- <p>步骤一:新建文件 <code>LiveReact.ts</code> 并创建您自己的 <code>LiveReact</code> 实例。</p>
422
- <pre><code class="hljs language-tsx"><span style="color: #D73A49">import</span><span style="color: #24292E"> {createLiveReact} </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;@realsee/live&#039;</span>
423
-
424
- <span style="color: #6A737D">/** 定义帧数据快照结构 */</span>
425
- <span style="color: #D73A49">interface</span><span style="color: #24292E"> </span><span style="color: #E36209">Snapshot</span><span style="color: #24292E"> {</span>
426
- <span style="color: #24292E"> </span><span style="color: #6A737D">/** 以 Five 状态快照为例 */</span>
427
- <span style="color: #24292E"> </span><span style="color: #E36209">five</span><span style="color: #D73A49">:</span><span style="color: #24292E"> {</span>
428
- <span style="color: #24292E"> </span><span style="color: #E36209">panoIndex</span><span style="color: #D73A49">:</span><span style="color: #24292E"> </span><span style="color: #005CC5">number</span><span style="color: #24292E">,</span>
429
- <span style="color: #24292E"> </span><span style="color: #E36209">fov</span><span style="color: #D73A49">:</span><span style="color: #24292E"> </span><span style="color: #005CC5">number</span><span style="color: #24292E">,</span>
430
- <span style="color: #24292E"> </span><span style="color: #E36209">mode</span><span style="color: #D73A49">:</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;Panorama&#039;</span><span style="color: #24292E"> </span><span style="color: #D73A49">|</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;Model&#039;</span><span style="color: #24292E">,</span>
431
- <span style="color: #24292E"> </span><span style="color: #E36209">latitude</span><span style="color: #D73A49">:</span><span style="color: #24292E"> </span><span style="color: #005CC5">number</span><span style="color: #24292E">,</span>
432
- <span style="color: #24292E"> </span><span style="color: #E36209">longitude</span><span style="color: #D73A49">:</span><span style="color: #24292E"> </span><span style="color: #005CC5">number</span><span style="color: #24292E">,</span>
433
- <span style="color: #24292E"> }</span>
434
- <span style="color: #24292E">}</span>
435
-
436
- <span style="color: #6A737D">/** 定义异步获取 `Ticket` 回调参数结构 */</span>
437
- <span style="color: #D73A49">interface</span><span style="color: #24292E"> </span><span style="color: #E36209">TicketArgs</span><span style="color: #24292E"> {</span>
438
- <span style="color: #24292E"> </span><span style="color: #6A737D">/* 没有特殊参数 */</span>
439
- <span style="color: #24292E">}</span>
97
+ <p>更多的例子请查看 <a href="https://unpkg.com/@realsee/live/docs/index.html">Live API</a> 文档 。</p>
440
98
 
99
+ <a href="#事件监听" id="事件监听" style="color: inherit; text-decoration: none;">
100
+ <h2>事件监听</h2>
101
+ </a>
102
+ <p><strong>Live</strong> 提供 <code>WebSocket 事件</code>、<code>live 事件</code> 和 <code>RTC 事件</code> 三类异步事件的监听。</p>
103
+ <p>其中, <code>WebSocket 事件</code>、<code>live 事件</code> 都可以通过 <code>live.on(&#39;/*事件名*/&#39;, /*事件回调*/)</code> 的方式监听。</p>
104
+ <p>比如监听 WebSocket 状态发生变更:</p>
105
+ <pre><code class="hljs language-ts"><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-7">on</span><span class="hl-1">(</span><span class="hl-4">&#39;ws.readyStateUpdate&#39;</span><span class="hl-1">, (</span><span class="hl-3">readyState</span><span class="hl-1">: </span><span class="hl-9">WebSocketState</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">console</span><span class="hl-1">.</span><span class="hl-7">log</span><span class="hl-1">(</span><span class="hl-3">readyState</span><span class="hl-1">) </span><span class="hl-0">// readyState 即是最新的 WebScoket 状态</span><br/><span class="hl-1">})</span>
106
+ </code></pre>
441
107
 
442
- <span style="color: #6A737D">/** 通过 `createLiveReact()` 函数创建实例,注意必须提供 `getTicket` 配置参数 */</span>
108
+ <a href="#websocket-事件" id="websocket-事件" style="color: inherit; text-decoration: none;">
109
+ <h3>WebSocket 事件</h3>
110
+ </a>
111
+ <ul>
112
+ <li><p><code>ws.beforeConnect(reConnect?: number): void</code> WebSocket 完成连接之后。</p>
113
+ </li>
114
+ <li><p><code>ws.afterConnect(reConnect?: number): void</code> WebSocket 完成连接之前。</p>
115
+ </li>
116
+ <li><p><code>ws.readyStateUpdate(readyState: WebSocketState): void</code> WebSocket 完成状态发生变更。</p>
117
+ </li>
118
+ </ul>
119
+ <p><strong>WebSocket 连接状态枚举表:</strong></p>
120
+ <table>
121
+ <thead>
122
+ <tr>
123
+ <th>状态名称</th>
124
+ <th>状态描述</th>
125
+ </tr>
126
+ </thead>
127
+ <tbody><tr>
128
+ <td>NOTINITIALIZED</td>
129
+ <td>未被初始化</td>
130
+ </tr>
131
+ <tr>
132
+ <td>CONNECTING</td>
133
+ <td>正在连接中</td>
134
+ </tr>
135
+ <tr>
136
+ <td>OPEN</td>
137
+ <td>连接成功</td>
138
+ </tr>
139
+ <tr>
140
+ <td>CLOSING</td>
141
+ <td>关闭中</td>
142
+ </tr>
143
+ <tr>
144
+ <td>CLOSED</td>
145
+ <td>关闭成功</td>
146
+ </tr>
147
+ </tbody></table>
148
+ <p><strong>Live</strong> 前后端服务交互是基于 WebSocket 长链接的。一次带看成功进入、退出的标识由 WebSocket 的状态 <code>OPEN</code>、<code>CLOSED</code>体现。 因此,所有 <strong>VRTC</strong> 相关的事件处理逻辑应保证在<code>OPEN</code>
149
+ 事件之后进行。</p>
443
150
 
444
- <span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">LiveReact</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> </span><span style="color: #6F42C1">createLiveReact</span><span style="color: #24292E">&lt;</span><span style="color: #E36209">Snapshot</span><span style="color: #24292E">, </span><span style="color: #E36209">TicketArgs</span><span style="color: #24292E">&gt;({</span>
445
- <span style="color: #24292E"> </span><span style="color: #6F42C1">getTicket</span><span style="color: #24292E">: </span><span style="color: #D73A49">async</span><span style="color: #24292E"> () </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;&#039;</span><span style="color: #24292E">, </span><span style="color: #6A737D">/* 必须提供 */</span>
446
- <span style="color: #24292E">})</span>
151
+ <a href="#live-事件" id="live-事件" style="color: inherit; text-decoration: none;">
152
+ <h3>live 事件</h3>
153
+ </a>
154
+ <ul>
155
+ <li><p><code>broadcast(evtMsg: Record&lt;string, any&gt;, frontRequestId: string): void</code> 接收其他用户的广播消息。</p>
156
+ </li>
157
+ <li><p><code>builtinEvent(builtinMsg: BuiltinMsg): void</code> 接收服务端推送的内置事件消息。</p>
158
+ </li>
159
+ <li><p><code>keyframes(keyframes: Partial&lt;Snapshot&gt;, frontRequestId: string): void</code> 接收其他用户的帧数据。</p>
160
+ </li>
161
+ <li><p><code>readyKeyframeSync(lastKeyframe: Partial&lt;Snapshot&gt;): void</code> 表明帧同步行为已就绪。</p>
162
+ </li>
163
+ <li><p><code>selfInfoUpdate(userInfo: UserInfo, frontRequestId: string): void</code> 自身的信息发生变更。</p>
164
+ </li>
165
+ <li><p><code>userListUpdate(userList: UserInfo[], frontRequestId: string): void</code> 用户列信息表发生变更。</p>
166
+ </li>
167
+ </ul>
168
+ <p><code>live</code> 实例提供了很多诸如<code>live.connect()</code>、<code>live.broadcast()</code>、<code>live.sendKeyframe()</code>等方法,这些方法都是异步反馈且可能会影响房间内的其他用户。
169
+ 您可以通过监听以上事件来获知这些影响。</p>
170
+ <p>需要注意的是 <code>readyKeyframeSync</code> 事件是可进行帧同步的节点标识,收到此事件后您的帧同步行为才生效。</p>
447
171
 
448
- <span style="color: #D73A49">export</span><span style="color: #E36209"> </span><span style="color: #D73A49">default</span><span style="color: #E36209"> </span><span style="color: #24292E">LiveReact</span>
172
+ <a href="#rtc-事件" id="rtc-事件" style="color: inherit; text-decoration: none;">
173
+ <h3>RTC 事件</h3>
174
+ </a>
175
+ <ul>
176
+ <li><p><code>error(error: Error): void</code> 异常事件。</p>
177
+ </li>
178
+ <li><p><code>initWillStart(): void</code> 即将初始化事件。</p>
179
+ </li>
180
+ <li><p><code>inited(): void</code> 初始化完成事件。</p>
181
+ </li>
182
+ <li><p><code>joinWillStart(): void</code> 即将加入语音房间事件。</p>
183
+ </li>
184
+ <li><p><code>joined(): void</code> 成功加入语音房间事件。</p>
185
+ </li>
186
+ <li><p><code>userVolumes(userVolumes: UserVolume[]): void</code> 房间内每个说话用户的音量。</p>
187
+ </li>
188
+ <li><p><code>weakNetwork(): void</code> 弱网提醒事件。</p>
189
+ </li>
190
+ </ul>
191
+ <p><code>live.$RTC</code> 实例需满足 <a href="">RTC 协议</a>,其事件通过 <code>live.$RTC.on(&#39;/*事件名*/&#39;, /*事件回调*/)</code> 方式来监听,比如监听语音房间内正在说话的用户及其音量:</p>
192
+ <pre><code class="hljs language-ts"><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-3">$RTC</span><span class="hl-1">.</span><span class="hl-7">on</span><span class="hl-1">(</span><span class="hl-4">&#39;userVolumes&#39;</span><span class="hl-1">, (</span><span class="hl-3">userVolumes</span><span class="hl-1">: </span><span class="hl-9">UserVolume</span><span class="hl-1">[]) </span><span class="hl-5">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-3">console</span><span class="hl-1">.</span><span class="hl-7">log</span><span class="hl-1">(</span><span class="hl-3">userVolumes</span><span class="hl-1">) </span><span class="hl-0">// userVolumes 正在说话的用户及其音量数据。</span><br/><span class="hl-1">})</span>
193
+ </code></pre>
449
194
 
450
- <span style="color: #6A737D">/** 如果您不喜欢 `LiveReact.LiveProvider` 这类编程习惯,可以将需要的函数&quot;抛&quot;出来 */</span>
451
- <span style="color: #D73A49">export</span><span style="color: #24292E"> </span><span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">LiveProvider</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> LiveReact.LiveProvider</span>
452
- <span style="color: #D73A49">export</span><span style="color: #24292E"> </span><span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">useConnect</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> LiveReact.useConnect</span>
453
- <span style="color: #D73A49">export</span><span style="color: #24292E"> </span><span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">useKeyframe</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> LiveReact.useKeyframe</span>
454
- <span style="color: #6A737D">// export ..</span>
195
+ <a href="#异常处理" id="异常处理" style="color: inherit; text-decoration: none;">
196
+ <h3>异常处理</h3>
197
+ </a>
198
+ <ul>
199
+ <li><code>ws.error(error: WebSocketError): void</code> WebSocket 连接出现异常。</li>
200
+ </ul>
201
+ <p><strong>WebSocket 错误状态枚举表:</strong></p>
202
+ <table>
203
+ <thead>
204
+ <tr>
205
+ <th>错误字段</th>
206
+ <th>错误描述</th>
207
+ <th>触发场景</th>
208
+ </tr>
209
+ </thead>
210
+ <tbody><tr>
211
+ <td>Close</td>
212
+ <td>错误类型枚举参照<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent">CloseEvent</a></td>
213
+ <td>错误原因参照<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent">CloseEvent</a></td>
214
+ </tr>
215
+ <tr>
216
+ <td>Error</td>
217
+ <td></td>
218
+ <td></td>
219
+ </tr>
220
+ <tr>
221
+ <td>MicroAuth</td>
222
+ <td>麦克风授权错误</td>
223
+ <td>语音功能获取麦克风授权失败</td>
224
+ </tr>
225
+ <tr>
226
+ <td>DuplicateConnect</td>
227
+ <td>重复连接</td>
228
+ <td>使用相同的 WS 链接申请连接</td>
229
+ </tr>
230
+ <tr>
231
+ <td>IllegalURL</td>
232
+ <td>非法的 WS 链接</td>
233
+ <td>传入的 WS 链接不合法</td>
234
+ </tr>
235
+ <tr>
236
+ <td>Unknown</td>
237
+ <td>未知错误</td>
238
+ <td>其他未被枚举的错误原样返回</td>
239
+ </tr>
240
+ </tbody></table>
241
+ <ul>
242
+ <li><code>error(liveMsg: LiveMsg): void</code> 服务端推送出现异常。</li>
243
+ </ul>
244
+ <p>与 WebSocket 通信的结构体<code>LiveMsg</code>格式如下:</p>
245
+ <table>
246
+ <thead>
247
+ <tr>
248
+ <th>名称</th>
249
+ <th>类型</th>
250
+ <th>描述</th>
251
+ </tr>
252
+ </thead>
253
+ <tbody><tr>
254
+ <td>appId</td>
255
+ <td>string</td>
256
+ <td></td>
257
+ </tr>
258
+ <tr>
259
+ <td>code</td>
260
+ <td>string</td>
261
+ <td>返回码,详情参照<a href="https://developers.realsee.com/docs/#/docs/live/server/README">服务端 API Code 码表</a></td>
262
+ </tr>
263
+ <tr>
264
+ <td>command</td>
265
+ <td>指令</td>
266
+ <td>WebSocket 通信指令类型,详情请查看<a href="https://unpkg.com/@realsee/live/docs/index.html">Live API</a> 文档</td>
267
+ </tr>
268
+ <tr>
269
+ <td>data</td>
270
+ <td>Record&lt;string, any&gt;</td>
271
+ <td>本条指令对应的业务数据</td>
272
+ </tr>
273
+ <tr>
274
+ <td>frontRequestId:</td>
275
+ <td>string</td>
276
+ <td>前端的请求 ID,由 WS 服务原样透传回前端</td>
277
+ </tr>
278
+ <tr>
279
+ <td>message</td>
280
+ <td>string</td>
281
+ <td>返回描述</td>
282
+ </tr>
283
+ <tr>
284
+ <td>requestId</td>
285
+ <td>string</td>
286
+ <td>后端请求 ID</td>
287
+ </tr>
288
+ <tr>
289
+ <td>roomCode</td>
290
+ <td>string</td>
291
+ <td>带看房间号</td>
292
+ </tr>
293
+ <tr>
294
+ <td>triggerUserId</td>
295
+ <td>string</td>
296
+ <td>触发指令的用户 ID</td>
297
+ </tr>
298
+ </tbody></table>
299
+ <p>当 WebSocket 推送的数据结构体不满足 <code>LiveMsg</code> 或者 <code>code</code> 值不为 <code>SUCCESS</code> 时会以 <code>error</code> 事件的形式抛出来。</p>
300
+ <ul>
301
+ <li><code>error(error: Error): void</code> RTC 语音出现异常。</li>
302
+ </ul>
303
+ <blockquote>
304
+ <p>RTC 语音不同容器或 RTC 解决方案不同,其错误信息内容可能不完全一致。</p>
305
+ </blockquote>
455
306
 
307
+ <a href="#rtc-协议" id="rtc-协议" style="color: inherit; text-decoration: none;">
308
+ <h2>RTC 协议</h2>
309
+ </a>
310
+ <p>语音能力需依赖 WebView/Browser 容器,即需要容器端实现 RTC 能力。</p>
311
+ <p>为了方便开发者接入,<strong>如视开发者中心 VRTC 服务</strong> 为主流平台提供 <a href="https://developers.realsee.com/docs/#/docs/live/client/container/README">容器 SDK</a>
312
+ 和 <a href="https://www.npmjs.com/package/@realsee/jsbridge-x">jsbridge-x</a> 。</p>
313
+ <p><strong>Live</strong> 通过 <strong>jsbridge-x</strong> 与 集成了<strong>容器 SDK</strong> 的客户端应用或微信小程序应用程序桥接,实现原生能力的调用。这个 <code>jsbridge-x</code>
314
+ 实例需作为配置参数提供给<code>createLive()</code>。</p>
315
+ <p>如果是 iOS/Android App(已接入如视 VRTC 容器 SDK)</p>
316
+ <pre><code class="hljs language-js"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-3">JSBridgeApp</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-4">&#39;@realsee/jsbridge-x/lib/app&#39;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-3">createLive</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-4">&#39;@realsee/live&#39;</span><br/><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-3">VRWebViewRTC</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-4">&#39;@realsee/live/RTC/VRWebViewRTC&#39;</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">jsBridgeInstance</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-7">JSBridgeApp</span><span class="hl-1">()</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">rtcInstance</span><span class="hl-1"> = </span><span class="hl-5">new</span><span class="hl-1"> </span><span class="hl-7">VRWebViewRTC</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-3">jsBridge</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-7">getVoiceSign</span><span class="hl-3">:</span><span class="hl-1"> () </span><span class="hl-5">=&gt;</span><span class="hl-1"> {},</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">live</span><span class="hl-1"> = </span><span class="hl-7">createLive</span><span class="hl-1">({</span><br/><span class="hl-1"> </span><span class="hl-3">rtc:</span><span class="hl-1"> </span><span class="hl-3">rtcInstance</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-7">getTicket</span><span class="hl-3">:</span><span class="hl-1"> </span><span class="hl-5">async</span><span class="hl-1"> () </span><span class="hl-5">=&gt;</span><span class="hl-1"> </span><span class="hl-4">&#39;&#39;</span><span class="hl-1">,</span><br/><span class="hl-1">})</span>
317
+ </code></pre>
318
+ <p>提供 RTC 实例配置参数之后,语音的连接、断开、重连等逻辑就托管给了 <strong>Live</strong> 。您可以通过 live 实例上的 <code>$RTC</code> 命名空间访问语音相关的状态和事件。</p>
319
+ <pre><code class="hljs language-js"><span class="hl-0">// 状态:用户是否成功加入语音房间</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-3">$RTC</span><span class="hl-1">.</span><span class="hl-3">joined</span><br/><span class="hl-0">// 状态:用户麦克风状态</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-3">$RTC</span><span class="hl-1">.</span><span class="hl-3">micro</span><br/><span class="hl-0">// 监听用户音量变化</span><br/><span class="hl-3">live</span><span class="hl-1">.</span><span class="hl-3">$RTC</span><span class="hl-1">.</span><span class="hl-7">on</span><span class="hl-1">(</span><span class="hl-4">&#39;userVolumes&#39;</span><span class="hl-1">, (</span><span class="hl-3">userVolumes</span><span class="hl-1">) </span><span class="hl-5">=&gt;</span><span class="hl-1"> {})</span>
456
320
  </code></pre>
457
- <p>步骤二:通过 <code>LiveProvider</code> 将 <code>live</code> 实例集成到 <code>React</code> 的 <a href="https://reactjs.org/docs/context.html">Context</a> 上下文环境中。</p>
458
- <pre><code class="hljs language-jsx"><span style="color: #D73A49">import</span><span style="color: #24292E"> { LiveProvider } </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;./LiveReact&#039;</span>
459
321
 
460
- <span style="color: #24292E">ReactDOM.</span><span style="color: #6F42C1">render</span><span style="color: #24292E">(&lt;</span><span style="color: #22863A">LiveProvider</span><span style="color: #24292E">&gt;&lt;</span><span style="color: #22863A">RootApp</span><span style="color: #24292E">/&gt;&lt;/</span><span style="color: #22863A">LiveProvider</span><span style="color: #24292E">&gt;, containter)</span>
322
+ <a href="#typescript-amp-react-支持" id="typescript-amp-react-支持" style="color: inherit; text-decoration: none;">
323
+ <h2>TypeScript &amp; React 支持</h2>
324
+ </a>
325
+ <p><strong>Live</strong> 有完整的 <a href="https://www.typescriptlang.org/docs/handbook/2/generics.html">TypeScript Generics</a>
326
+ 和 <a href="https://reactjs.org/docs/hooks-intro.html">React Hooks</a> 支持,如果您的技术栈基于 <code>TypeScript</code> 和 <code>React</code> 可以参考如下方式更优雅地使用 <strong>Live</strong>。</p>
327
+ <p><img src="https://vrlab-static.ljcdn.com/release/web/tssupportminify.f2eaeed2.png" alt="TypeScript效果演示"></p>
328
+ <p>步骤一:新建文件 <code>LiveReact.ts</code> 并创建您自己的 <code>LiveReact</code> 实例。</p>
329
+ <pre><code class="hljs language-tsx"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-3">createLiveReact</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-4">&#39;@realsee/live&#39;</span><br/><br/><span class="hl-0">/** 定义帧数据快照结构 */</span><br/><span class="hl-5">interface</span><span class="hl-1"> </span><span class="hl-9">Snapshot</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-0">/** 以 Five 状态快照为例 */</span><br/><span class="hl-1"> </span><span class="hl-3">five</span><span class="hl-1">: {</span><br/><span class="hl-1"> </span><span class="hl-3">panoIndex</span><span class="hl-1">: </span><span class="hl-9">number</span><br/><span class="hl-1"> </span><span class="hl-3">fov</span><span class="hl-1">: </span><span class="hl-9">number</span><br/><span class="hl-1"> </span><span class="hl-3">mode</span><span class="hl-1">: </span><span class="hl-4">&#39;Panorama&#39;</span><span class="hl-1"> | </span><span class="hl-4">&#39;Model&#39;</span><br/><span class="hl-1"> </span><span class="hl-3">latitude</span><span class="hl-1">: </span><span class="hl-9">number</span><br/><span class="hl-1"> </span><span class="hl-3">longitude</span><span class="hl-1">: </span><span class="hl-9">number</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-0">/** 通过 `createLiveReact()` 函数创建实例*/</span><br/><br/><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">LiveReact</span><span class="hl-1"> = </span><span class="hl-7">createLiveReact</span><span class="hl-1">&lt;</span><span class="hl-9">Snapshot</span><span class="hl-1">&gt;({</span><br/><span class="hl-1"> </span><span class="hl-7">getTicket</span><span class="hl-3">:</span><span class="hl-1"> </span><span class="hl-5">async</span><span class="hl-1"> () </span><span class="hl-5">=&gt;</span><span class="hl-1"> </span><span class="hl-4">&#39;&#39;</span><span class="hl-1"> </span><span class="hl-0">/* 必须提供 */</span><span class="hl-1">,</span><br/><span class="hl-1">})</span><br/><br/><span class="hl-2">export</span><span class="hl-1"> </span><span class="hl-2">default</span><span class="hl-1"> </span><span class="hl-3">LiveReact</span><br/><br/><span class="hl-0">/** 如果您不喜欢 `LiveReact.LiveProvider` 这类编程习惯,可以将需要的函数&quot;抛&quot;出来 */</span><br/><span class="hl-2">export</span><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">LiveProvider</span><span class="hl-1"> = </span><span class="hl-3">LiveReact</span><span class="hl-1">.</span><span class="hl-3">LiveProvider</span><br/><span class="hl-2">export</span><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">useConnect</span><span class="hl-1"> = </span><span class="hl-3">LiveReact</span><span class="hl-1">.</span><span class="hl-3">useConnect</span><br/><span class="hl-2">export</span><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">useKeyframe</span><span class="hl-1"> = </span><span class="hl-3">LiveReact</span><span class="hl-1">.</span><span class="hl-3">useKeyframe</span><br/><span class="hl-0">// export ..</span>
330
+ </code></pre>
331
+ <p>步骤二:通过 <code>LiveProvider</code> 将 <code>live</code> 实例集成到 <code>React</code> 的 <a href="https://reactjs.org/docs/context.html">Context</a> 上下文环境中。</p>
332
+ <pre><code class="hljs language-jsx"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-3">LiveProvider</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-4">&#39;./LiveReact&#39;</span><br/><br/><span class="hl-3">ReactDOM</span><span class="hl-1">.</span><span class="hl-7">render</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-10">&lt;</span><span class="hl-9">LiveProvider</span><span class="hl-10">&gt;</span><br/><span class="hl-1"> </span><span class="hl-10">&lt;</span><span class="hl-9">RootApp</span><span class="hl-1"> </span><span class="hl-10">/&gt;</span><br/><span class="hl-1"> </span><span class="hl-10">&lt;/</span><span class="hl-9">LiveProvider</span><span class="hl-10">&gt;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-3">containter</span><br/><span class="hl-1">)</span>
333
+ </code></pre>
334
+ <p>步骤三:在您的 <code>React</code> 函数组件中使用相关 <code>Hooks</code> 函数。</p>
335
+ <pre><code class="hljs language-jsx"><span class="hl-2">import</span><span class="hl-1"> { </span><span class="hl-3">useConnect</span><span class="hl-1"> } </span><span class="hl-2">from</span><span class="hl-1"> </span><span class="hl-4">&#39;./LiveReact&#39;</span><br/><br/><span class="hl-5">function</span><span class="hl-1"> </span><span class="hl-7">ReconnectBtn</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-5">const</span><span class="hl-1"> </span><span class="hl-6">connect</span><span class="hl-1"> = </span><span class="hl-7">useConnect</span><span class="hl-1">()</span><br/><br/><span class="hl-1"> </span><span class="hl-2">return</span><span class="hl-1"> </span><span class="hl-10">&lt;</span><span class="hl-11">button</span><span class="hl-1"> </span><span class="hl-12">onClick</span><span class="hl-1">=</span><span class="hl-5">{</span><span class="hl-13">() </span><span class="hl-5">=&gt;</span><span class="hl-13"> </span><span class="hl-7">connect</span><span class="hl-13">()</span><span class="hl-5">}</span><span class="hl-10">&gt;</span><span class="hl-1">重新连接</span><span class="hl-10">&lt;/</span><span class="hl-11">button</span><span class="hl-10">&gt;</span><br/><span class="hl-1">}</span>
461
336
  </code></pre>
462
- <p>步骤三:在您的 <code>React</code> 函数组件中使用相关 <code>Hooks</code> 函数。</p>
463
- <pre><code class="hljs language-jsx"><span style="color: #D73A49">import</span><span style="color: #24292E"> { useConnect } </span><span style="color: #D73A49">from</span><span style="color: #24292E"> </span><span style="color: #032F62">&#039;./LiveReact&#039;</span>
464
337
 
465
- <span style="color: #D73A49">function</span><span style="color: #24292E"> </span><span style="color: #6F42C1">ReconnectBtn</span><span style="color: #24292E"> () {</span>
466
- <span style="color: #24292E"> </span><span style="color: #D73A49">const</span><span style="color: #24292E"> </span><span style="color: #005CC5">connect</span><span style="color: #24292E"> </span><span style="color: #D73A49">=</span><span style="color: #24292E"> </span><span style="color: #6F42C1">useConnect</span><span style="color: #24292E">()</span>
338
+ <a href="#live-api-文档" id="live-api-文档" style="color: inherit; text-decoration: none;">
339
+ <h2>Live API 文档</h2>
340
+ </a>
341
+ <p>欢迎查看 <a href="https://unpkg.com/@realsee/live/docs/index.html">Live API</a> 文档 。<br>该文档由 <a href="https://typedoc.org/">TypeDoc</a> 生成,您可以详细查看 API 使用方式、事件 Hooks 及数据结构定义等。</p>
467
342
 
468
- <span style="color: #24292E"> </span><span style="color: #D73A49">return</span><span style="color: #24292E"> &lt;</span><span style="color: #22863A">button</span><span style="color: #24292E"> </span><span style="color: #005CC5">onClick</span><span style="color: #D73A49">=</span><span style="color: #24292E">{() </span><span style="color: #D73A49">=&gt;</span><span style="color: #24292E"> </span><span style="color: #6F42C1">connect</span><span style="color: #24292E">()}&gt;重新连接&lt;/</span><span style="color: #22863A">button</span><span style="color: #24292E">&gt;</span>
469
- <span style="color: #24292E">}</span>
470
- </code></pre>
471
- <a href="#live-api-文档" id="live-api-文档" style="color: inherit; text-decoration: none;">
472
- <h2>Live API 文档</h2>
473
- </a>
474
- <p>欢迎查看 <a href="https://unpkg.com/@realsee/live/docs/index.html">Live API</a> 文档 。<br>该文档由 <a href="https://typedoc.org/">TypeDoc</a> 生成,您可以详细查看 API 使用方式、事件 Hooks 及数据结构定义等。</p>
475
- <a href="#相关文档链接" id="相关文档链接" style="color: inherit; text-decoration: none;">
476
- <h2>相关文档链接</h2>
477
- </a>
478
- <ul>
479
- <li><a href="https://www.npmjs.com/package/@realsee/five">@realsee/five</a></li>
480
- <li><a href="https://www.npmjs.com/package/@realsee/jsbridge-x">@realsee/jsbridge-x</a></li>
481
- <li><a href="https://developers.realsee.com/docs/#/docs/live/README">如视开发者中心VRTC服务</a></li>
482
- </ul>
483
- </div>
484
- </div>
485
- <div class="col-4 col-menu menu-sticky-wrap menu-highlight">
486
- <nav class="tsd-navigation primary">
487
- <ul>
488
- <li class=" ">
489
- <a href="modules.html">Modules</a>
490
- </li>
491
- <li class=" tsd-kind-module">
492
- <a href="modules/RTCProtocol.html">RTCProtocol</a>
493
- </li>
494
- <li class=" tsd-kind-module">
495
- <a href="modules/live.html">live</a>
496
- </li>
497
- <li class=" tsd-kind-module">
498
- <a href="modules/shared_utils.html">shared-<wbr>utils</a>
499
- </li>
500
- </ul>
501
- </nav>
502
- <nav class="tsd-navigation secondary menu-sticky">
503
- <ul class="before-current">
504
- </ul>
505
- </nav>
506
- </div>
507
- </div>
508
- </div>
509
- <footer>
510
- <div class="container">
511
- <h2>Legend</h2>
512
- <div class="tsd-legend-group">
513
- <ul class="tsd-legend">
514
- <li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
515
- <li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
516
- <li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
517
- <li class="tsd-kind-type-alias tsd-has-type-parameter"><span class="tsd-kind-icon">Type alias with type parameter</span></li>
518
- </ul>
519
- <ul class="tsd-legend">
520
- <li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
521
- <li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
522
- </ul>
523
- <ul class="tsd-legend">
524
- <li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
525
- <li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
526
- </ul>
527
- <ul class="tsd-legend">
528
- <li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
529
- </ul>
530
- </div>
531
- </div>
532
- </footer>
533
- <div class="overlay"></div>
534
- <script src="assets/js/main.js"></script>
535
- </body>
536
- </html>
343
+ <a href="#相关文档链接" id="相关文档链接" style="color: inherit; text-decoration: none;">
344
+ <h2>相关文档链接</h2>
345
+ </a>
346
+ <ul>
347
+ <li><a href="https://www.npmjs.com/package/@realsee/five">@realsee/five</a></li>
348
+ <li><a href="https://www.npmjs.com/package/@realsee/jsbridge">@realsee/jsbridge</a></li>
349
+ <li><a href="https://developers.realsee.com/docs/#/docs/live/README">如视开发者中心 VRTC 服务</a></li>
350
+ </ul>
351
+ </div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class="current"><a href="modules.html">Modules</a></li><li class=" tsd-kind-module"><a href="modules/RTCProtocol.html">RTCProtocol</a></li><li class=" tsd-kind-module"><a href="modules/live.html">live</a></li><li class=" tsd-kind-module"><a href="modules/shared_utils.html">shared-<wbr/>utils</a></li></ul></nav></div></div></div><footer class=""><div class="container"><h2>Legend</h2><div class="tsd-legend-group"><ul class="tsd-legend"><li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li><li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li><li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li><li class="tsd-kind-type-alias tsd-has-type-parameter"><span class="tsd-kind-icon">Type alias with type parameter</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li><li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li><li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li></ul></div><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="overlay"></div><script src="assets/main.js"></script></body></html>