-
Notifications
You must be signed in to change notification settings - Fork 1
/
View.js.html
417 lines (345 loc) · 43.3 KB
/
View.js.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Adding favicon -->
<!-- Adding meta -->
<!-- Adding external script-->
<!-- Adding external style-->
<!-- Adding scripts-->
<!-- Adding style-->
<!-- Adding overlay script-->
<!-- Adding overlay style-->
<title>
View.js
</title>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/third-party/ionicons.min.css">
<link type="text/css" rel="stylesheet" href="styles/third-party/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/reset.css">
<link type="text/css" rel="stylesheet" href="styles/clean-jsdoc-theme-base.css">
<link type="text/css" rel="stylesheet" href="styles/clean-jsdoc-theme-light.css">
<svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
style="display:none">
<defs>
<symbol id="copy-icon" viewbox="0 0 488.3 488.3">
<g>
<path
d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z" />
<path
d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z" />
</g>
</symbol>
<symbol id='search-icon' viewBox="0 0 512 512">
<g>
<g>
<path
d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z" />
</g>
</g>
<g>
<g>
<path
d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z" />
</g>
</g>
</symbol>
<symbol id="down-icon" viewBox="0 0 16 16">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"
>
</path>
</symbol>
</defs>
</svg>
</head>
<body>
<nav class="navbar" id="navbar">
<div class="navbar-heading" id="navbar-heading"><a href="index.html"><h2 class="navbar-heading-text">JavaScript SDK</h2></a></div><div class="search-box" id="search-box"><div class="search-box-input-container"><input class="search-box-input" type="text" placeholder="Search..." id="search-box-input" /><svg class="search-icon" alt="search-icon"><use xlink:href="#search-icon"></use></svg></div><div class="search-item-container" id="search-item-container"><ul class="search-item-ul" id="search-item-ul"></ul></div></div><div class="sidebar-main-content" id="sidebar-main-content"><div class="accordion collapsed" id="7557599" > <h3 class="accordion-heading">Modules<svg><use xlink:href="#down-icon"></use></svg></h3><ul class="accordion-content"><li class="accordion collapsed child" id=8443790><div class="accordion-heading child"><a href="module-Director.html">Director</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="module-Director.html#~getEndpoint">getEndpoint</a></li><li data-type='method'><a href="module-Director.html#~getLiveDomain">getLiveDomain</a></li><li data-type='method'><a href="module-Director.html#~getPublisher">getPublisher</a></li><li data-type='method'><a href="module-Director.html#~getSubscriber">getSubscriber</a></li><li data-type='method'><a href="module-Director.html#~setEndpoint">setEndpoint</a></li><li data-type='method'><a href="module-Director.html#~setLiveDomain">setLiveDomain</a></li></ul></li><li class="accordion collapsed child" id=5836212><div class="accordion-heading child"><a href="module-Logger.html">Logger</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="module-Logger.html#~get">get</a></li><li data-type='method'><a href="module-Logger.html#~getHistory">getHistory</a></li><li data-type='method'><a href="module-Logger.html#~getHistoryMaxSize">getHistoryMaxSize</a></li><li data-type='method'><a href="module-Logger.html#~getLevel">getLevel</a></li><li data-type='method'><a href="module-Logger.html#~setHandler">setHandler</a></li><li data-type='method'><a href="module-Logger.html#~setHistoryMaxSize">setHistoryMaxSize</a></li><li data-type='method'><a href="module-Logger.html#~setLevel">setLevel</a></li></ul></li><li class="accordion collapsed child" id=810655><div class="accordion-heading child"><a href="module-SdpParser.html">SdpParser</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="module-SdpParser.html#~adaptCodecName">adaptCodecName</a></li><li data-type='method'><a href="module-SdpParser.html#~getAvailableHeaderExtensionIdRange">getAvailableHeaderExtensionIdRange</a></li><li data-type='method'><a href="module-SdpParser.html#~getAvailablePayloadTypeRange">getAvailablePayloadTypeRange</a></li><li data-type='method'><a href="module-SdpParser.html#~removeSdpLine">removeSdpLine</a></li><li data-type='method'><a href="module-SdpParser.html#~renegotiate">renegotiate</a></li><li data-type='method'><a href="module-SdpParser.html#~setAbsoluteCaptureTime">setAbsoluteCaptureTime</a></li><li data-type='method'><a href="module-SdpParser.html#~setDependencyDescriptor">setDependencyDescriptor</a></li><li data-type='method'><a href="module-SdpParser.html#~setDTX">setDTX</a></li><li data-type='method'><a href="module-SdpParser.html#~setMultiopus">setMultiopus</a></li><li data-type='method'><a href="module-SdpParser.html#~setSimulcast">setSimulcast</a></li><li data-type='method'><a href="module-SdpParser.html#~setStereo">setStereo</a></li><li data-type='method'><a href="module-SdpParser.html#~setVideoBitrate">setVideoBitrate</a></li><li data-type='method'><a href="module-SdpParser.html#~updateMissingVideoExtensions">updateMissingVideoExtensions</a></li></ul></li></ul> </div><div class="accordion collapsed" id="1490423" > <h3 class="accordion-heading">Classes<svg><use xlink:href="#down-icon"></use></svg></h3><ul class="accordion-content"><li class="accordion collapsed child" id=4205529><div class="accordion-heading child"><a href="BaseWebRTC.html">BaseWebRTC</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="BaseWebRTC.html#getRTCPeerConnection">getRTCPeerConnection</a></li><li data-type='method'><a href="BaseWebRTC.html#isActive">isActive</a></li><li data-type='method'><a href="BaseWebRTC.html#reconnect">reconnect</a></li><li data-type='method'><a href="BaseWebRTC.html#setReconnect">setReconnect</a></li><li data-type='method'><a href="BaseWebRTC.html#stop">stop</a></li></ul></li><li class="accordion collapsed child" id=8899913><div class="accordion-heading child"><a href="PeerConnection.html">PeerConnection</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="PeerConnection.html#.getCapabilities">getCapabilities</a></li><li data-type='method'><a href="PeerConnection.html#addRemoteTrack">addRemoteTrack</a></li><li data-type='method'><a href="PeerConnection.html#closeRTCPeer">closeRTCPeer</a></li><li data-type='method'><a href="PeerConnection.html#createRTCPeer">createRTCPeer</a></li><li data-type='method'><a href="PeerConnection.html#getRTCLocalSDP">getRTCLocalSDP</a></li><li data-type='method'><a href="PeerConnection.html#getRTCPeer">getRTCPeer</a></li><li data-type='method'><a href="PeerConnection.html#getRTCPeerStatus">getRTCPeerStatus</a></li><li data-type='method'><a href="PeerConnection.html#getTracks">getTracks</a></li><li data-type='method'><a href="PeerConnection.html#initStats">initStats</a></li><li data-type='method'><a href="PeerConnection.html#replaceTrack">replaceTrack</a></li><li data-type='method'><a href="PeerConnection.html#setRTCRemoteSDP">setRTCRemoteSDP</a></li><li data-type='method'><a href="PeerConnection.html#stopStats">stopStats</a></li><li data-type='method'><a href="PeerConnection.html#updateBandwidthRestriction">updateBandwidthRestriction</a></li><li data-type='method'><a href="PeerConnection.html#updateBitrate">updateBitrate</a></li></ul></li><li class="accordion collapsed child" id=281125><div class="accordion-heading child"><a href="Publish.html">Publish</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="Publish.html#connect">connect</a></li><li data-type='method'><a href="Publish.html#getRTCPeerConnection">getRTCPeerConnection</a></li><li data-type='method'><a href="Publish.html#isActive">isActive</a></li><li data-type='method'><a href="Publish.html#reconnect">reconnect</a></li><li data-type='method'><a href="Publish.html#record">record</a></li><li data-type='method'><a href="Publish.html#setReconnect">setReconnect</a></li><li data-type='method'><a href="Publish.html#stop">stop</a></li><li data-type='method'><a href="Publish.html#unrecord">unrecord</a></li></ul></li><li class="accordion collapsed child" id=6958554><div class="accordion-heading child"><a href="Signaling.html">Signaling</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="Signaling.html#close">close</a></li><li data-type='method'><a href="Signaling.html#cmd">cmd</a></li><li data-type='method'><a href="Signaling.html#connect">connect</a></li><li data-type='method'><a href="Signaling.html#publish">publish</a></li><li data-type='method'><a href="Signaling.html#subscribe">subscribe</a></li></ul></li><li class="accordion collapsed child" id=3108999><div class="accordion-heading child"><a href="StreamEvents.html">StreamEvents</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="StreamEvents.html#.getEventsLocation">getEventsLocation</a></li><li data-type='method'><a href="StreamEvents.html#.init">init</a></li><li data-type='method'><a href="StreamEvents.html#.setEventsLocation">setEventsLocation</a></li><li data-type='method'><a href="StreamEvents.html#onUserCount">onUserCount</a></li><li data-type='method'><a href="StreamEvents.html#stop">stop</a></li></ul></li><li class="accordion collapsed child" id=9464527><div class="accordion-heading child"><a href="View.html">View</a><svg><use xlink:href="#down-icon"></use></svg></div><ul class='methods accordion-content'><li data-type='method'><a href="View.html#addRemoteTrack">addRemoteTrack</a></li><li data-type='method'><a href="View.html#connect">connect</a></li><li data-type='method'><a href="View.html#getRTCPeerConnection">getRTCPeerConnection</a></li><li data-type='method'><a href="View.html#isActive">isActive</a></li><li data-type='method'><a href="View.html#project">project</a></li><li data-type='method'><a href="View.html#reconnect">reconnect</a></li><li data-type='method'><a href="View.html#select">select</a></li><li data-type='method'><a href="View.html#setReconnect">setReconnect</a></li><li data-type='method'><a href="View.html#stop">stop</a></li><li data-type='method'><a href="View.html#unproject">unproject</a></li></ul></li></ul> </div><div class="accordion collapsed" id="2939770" > <h3 class="accordion-heading">Events<svg><use xlink:href="#down-icon"></use></svg></h3><ul class="accordion-content"><li class="accordion-list" id=""><a href="BaseWebRTC.html#event:reconnect">reconnect</a></li><li class="accordion-list" id=""><a href="PeerConnection.html#event:connectionStateChange">connectionStateChange</a></li><li class="accordion-list" id=""><a href="PeerConnection.html#event:stats">stats</a></li><li class="accordion-list" id=""><a href="PeerConnection.html#event:track">track</a></li><li class="accordion-list" id=""><a href="Publish.html#event:reconnect">reconnect</a></li><li class="accordion-list" id=""><a href="Signaling.html#event:broadcastEvent">broadcastEvent</a></li><li class="accordion-list" id=""><a href="Signaling.html#event:wsConnectionClose">wsConnectionClose</a></li><li class="accordion-list" id=""><a href="Signaling.html#event:wsConnectionError">wsConnectionError</a></li><li class="accordion-list" id=""><a href="Signaling.html#event:wsConnectionSuccess">wsConnectionSuccess</a></li><li class="accordion-list" id=""><a href="View.html#event:reconnect">reconnect</a></li></ul> </div><div class="accordion collapsed" id="3049150" > <h3 class="accordion-heading">Global<svg><use xlink:href="#down-icon"></use></svg></h3><ul class="accordion-content"><li class="accordion-list" id=""><a href="global.html#addCandidateReport">addCandidateReport</a></li><li class="accordion-list" id=""><a href="global.html#addInboundRtpReport">addInboundRtpReport</a></li><li class="accordion-list" id=""><a href="global.html#addOutboundRtpReport">addOutboundRtpReport</a></li><li class="accordion-list" id=""><a href="global.html#addPeerEvents">addPeerEvents</a></li><li class="accordion-list" id=""><a href="global.html#AudioCodec">AudioCodec</a></li><li class="accordion-list" id=""><a href="global.html#calculatePacketsLostDelta">calculatePacketsLostDelta</a></li><li class="accordion-list" id=""><a href="global.html#calculatePacketsLostRatio">calculatePacketsLostRatio</a></li><li class="accordion-list" id=""><a href="global.html#ConnectionStats">ConnectionStats</a></li><li class="accordion-list" id=""><a href="global.html#DirectorPublisherOptions">DirectorPublisherOptions</a></li><li class="accordion-list" id=""><a href="global.html#DirectorSubscriberOptions">DirectorSubscriberOptions</a></li><li class="accordion-list" id=""><a href="global.html#getBaseRtpReportData">getBaseRtpReportData</a></li><li class="accordion-list" id=""><a href="global.html#getCodecData">getCodecData</a></li><li class="accordion-list" id=""><a href="global.html#getMediaType">getMediaType</a></li><li class="accordion-list" id=""><a href="global.html#InboundStats">InboundStats</a></li><li class="accordion-list" id=""><a href="global.html#LayerInfo">LayerInfo</a></li><li class="accordion-list" id=""><a href="global.html#loggerHandler">loggerHandler</a></li><li class="accordion-list" id=""><a href="global.html#LogLevel">LogLevel</a></li><li class="accordion-list" id=""><a href="global.html#onUserCountCallback">onUserCountCallback</a></li><li class="accordion-list" id=""><a href="global.html#OnUserCountOptions">OnUserCountOptions</a></li><li class="accordion-list" id=""><a href="global.html#OutboundStats">OutboundStats</a></li><li class="accordion-list" id=""><a href="global.html#SignalingPublishOptions">SignalingPublishOptions</a></li><li class="accordion-list" id=""><a href="global.html#SignalingSubscribeOptions">SignalingSubscribeOptions</a></li><li class="accordion-list" id=""><a href="global.html#tokenGeneratorCallback">tokenGeneratorCallback</a></li><li class="accordion-list" id=""><a href="global.html#TrackReport">TrackReport</a></li><li class="accordion-list" id=""><a href="global.html#VideoCodec">VideoCodec</a></li><li class="accordion-list" id=""><a href="global.html#WowzaCapability">WowzaCapability</a></li><li class="accordion-list" id=""><a href="global.html#WowzaDirectorResponse">WowzaDirectorResponse</a></li></ul> </div>
</nav>
<div class="navbar-ham" id="navbar-ham">
<div>
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</div>
</div>
<div id="main" class="main-content">
<h1 id='page-title' class="page-title">
View.js
</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>import reemit from 're-emitter'
import Logger from './Logger'
import BaseWebRTC from './utils/BaseWebRTC'
import Signaling, { signalingEvents } from './Signaling'
import PeerConnection, { webRTCEvents } from './PeerConnection'
import FetchError from './utils/FetchError'
const logger = Logger.get('View')
const connectOptions = {
disableVideo: false,
disableAudio: false,
peerConfig: {}
}
/**
* @class View
* @extends BaseWebRTC
* @classdesc Manages connection with a secure WebSocket path to signal the Wowza server
* and establishes a WebRTC connection to view a live stream.
*
* Before you can view an active broadcast, you will need:
*
* - A connection path that you can get from {@link Director} module or from your own implementation.
* @constructor
* @param {String} streamName - Wowza existing Stream Name where you want to connect.
* @param {tokenGeneratorCallback} tokenGenerator - Callback function executed when a new token is needed.
* @param {HTMLMediaElement} [mediaElement=null] - Target HTML media element to mount stream.
* @param {Boolean} [autoReconnect=true] - Enable auto reconnect to stream.
*/
export default class View extends BaseWebRTC {
constructor (streamName, tokenGenerator, mediaElement = null, autoReconnect = true) {
super(streamName, tokenGenerator, logger, autoReconnect)
if (mediaElement) {
this.on(webRTCEvents.track, e => {
mediaElement.srcObject = e.streams[0]
})
}
}
/**
* @typedef {Object} LayerInfo
* @property {String} encodingId - rid value of the simulcast encoding of the track (default: automatic selection)
* @property {Number} spatialLayerId - The spatial layer id to send to the outgoing stream (default: max layer available)
* @property {Number} temporalLayerId - The temporaral layer id to send to the outgoing stream (default: max layer available)
* @property {Number} maxSpatialLayerId - Max spatial layer id (default: unlimited)
* @property {Number} maxTemporalLayerId - Max temporal layer id (default: unlimited)
*/
/**
* Connects to an active stream as subscriber.
*
* In the example, `addStreamToYourVideoTag` and `getYourSubscriberConnectionPath` is your own implementation.
* @param {Object} [options] - General subscriber options.
* @param {Boolean} [options.dtx = false] - True to modify SDP for supporting dtx in opus. Otherwise False.
* @param {Boolean} [options.absCaptureTime = false] - True to modify SDP for supporting absolute capture time header extension. Otherwise False.
* @param {Boolean} [options.disableVideo = false] - Disable the opportunity to receive video stream.
* @param {Boolean} [options.disableAudio = false] - Disable the opportunity to receive audio stream.
* @param {Number} [options.multiplexedAudioTracks] - Number of audio tracks to recieve VAD multiplexed audio for secondary sources.
* @param {String} [options.pinnedSourceId] - Id of the main source that will be received by the default MediaStream.
* @param {Array<String>} [options.excludedSourceIds] - Do not receive media from the these source ids.
* @param {Array<String>} [options.events] - Override which events will be delivered by the server (any of "active" | "inactive" | "vad" | "layers" | "viewercount").*
* @param {RTCConfiguration} [options.peerConfig] - Options to configure the new RTCPeerConnection.
* @param {LayerInfo} [options.layer] - Select the simulcast encoding layer and svc layers for the main video track, leave empty for automatic layer selection based on bandwidth estimation.
* @param {Object} [options.forcePlayoutDelay = false]- Ask the server to use the playout delay header extension.
* @param {Number} [options.forcePlayoutDelay.min] - Set minimum playout delay value.
* @param {Number} [options.forcePlayoutDelay.max] - Set maximum playout delay value.
* @returns {Promise<void>} Promise object which resolves when the connection was successfully established.
* @fires PeerConnection#track
* @fires Signaling#broadcastEvent
* @fires PeerConnection#connectionStateChange
* @example await wowzaView.connect(options)
* @example
* import View from '@wowzamediasystems/sdk-rts'
*
* // Create media element
* const videoElement = document.createElement("video")
*
* //Define callback for generate new token
* const tokenGenerator = () => getYourSubscriberInformation(accountId, streamName)
*
* //Create a new instance
* const streamName = "Wowza Stream Name where i want to connect"
* const wowzaView = new View(streamName, tokenGenerator, videoElement)
*
* //Start connection to broadcast
* try {
* await wowzaView.connect()
* } catch (e) {
* console.log('Connection failed, handle error', e)
* }
* @example
* import View from '@wowzamediasystems/sdk-rts'
*
* //Define callback for generate new token
* const tokenGenerator = () => getYourSubscriberInformation(accountId, streamName)
*
* //Create a new instance
* const streamName = "Wowza Stream Name where i want to connect"
* const wowzaView = new View(streamName, tokenGenerator)
*
* //Set track event handler to receive streams from Publisher.
* wowzaView.on('track', (event) => {
* addStreamToYourVideoTag(event.streams[0])
* })
*
* //Start connection to broadcast
* try {
* await wowzaView.connect()
* } catch (e) {
* console.log('Connection failed, handle error', e)
* }
*/
async connect (options = connectOptions) {
this.options = { ...connectOptions, ...options, setSDPToPeer: false }
await this.initConnection({ migrate: false })
}
/**
* Select the simulcast encoding layer and svc layers for the main video track
* @param {LayerInfo} layer - leave empty for automatic layer selection based on bandwidth estimation.
*/
async select (layer = {}) {
logger.debug('Viewer select layer values: ', layer)
await this.signaling.cmd('select', { layer })
logger.info('Connected to streamName: ', this.streamName)
}
/**
* Add remote receving track.
* @param {String} media - Media kind ('audio' | 'video').
* @param {Array<MediaStream>} streams - Streams the track will belong to.
* @return {Promise<RTCRtpTransceiver>} Promise that will be resolved when the RTCRtpTransceiver is assigned an mid value.
*/
async addRemoteTrack (media, streams) {
logger.info('Viewer adding remote % track', media)
return this.webRTCPeer.addRemoteTrack(media, streams)
}
/**
* Start projecting source in selected media ids.
* @param {String} sourceId - Selected source id.
* @param {Array<Object>} mapping - Mapping of the source track ids to the receiver mids
* @param {String} [mapping.trackId] - Track id from the source (received on the "active" event), if not set the media kind will be used instead.
* @param {String} [mapping.media] - Track kind of the source ('audio' | 'video'), if not set the trackId will be used instead.
* @param {String} [mapping.mediaId] - mid value of the rtp receiver in which the media is going to be projected. If no mediaId is defined, the first track from the main media stream with the same media type as the input source track will be used.
* @param {LayerInfo} [mapping.layer] - Select the simulcast encoding layer and svc layers, only applicable to video tracks.
* @param {Boolean} [mapping.promote] - To remove all existing limitations from the source, such as restricted bitrate or resolution, set this to true.
*/
async project (sourceId, mapping) {
for (const map of mapping) {
if (!map.trackId && !map.media) {
logger.error('Error in projection mapping, trackId or mediaId must be set')
throw new Error('Error in projection mapping, trackId or mediaId must be set')
}
const peer = this.webRTCPeer.getRTCPeer()
// Check we have the mediaId in the transceivers
if (map.mediaId && !peer.getTransceivers().find(t => t.mid === map.mediaId.toString())) {
logger.error(`Error in projection mapping, ${map.mediaId} mid not found in local transceivers`)
throw new Error(`Error in projection mapping, ${map.mediaId} mid not found in local transceivers`)
}
}
logger.debug('Viewer project source: layer mappings: ', sourceId, mapping)
await this.signaling.cmd('project', { sourceId, mapping })
logger.info('Projection done')
}
/**
* Stop projecting attached source in selected media ids.
* @param {Array<String>} mediaIds - mid value of the receivers that are going to be detached.
*/
async unproject (mediaIds) {
logger.debug('Viewer unproject mediaIds: ', mediaIds)
await this.signaling.cmd('unproject', { mediaIds })
logger.info('Unprojection done')
}
async replaceConnection () {
logger.info('Migrating current connection')
await this.initConnection({ migrate: true })
}
async initConnection (data) {
logger.debug('Viewer connect options values: ', this.options)
this.stopReconnection = false
let promises
if (!data.migrate && this.isActive()) {
logger.warn('Viewer currently subscribed')
throw new Error('Viewer currently subscribed')
}
let subscriberData
try {
subscriberData = await this.tokenGenerator()
// Set the iceServers from the subscribe data into the peerConfig
this.options.peerConfig.iceServers = subscriberData?.iceServers
} catch (error) {
logger.error('Error generating token.')
if (error instanceof FetchError) {
if (error.status === 401 || !this.autoReconnect) {
// should not reconnect
this.stopReconnection = true
} else {
// should reconnect with exponential back off if autoReconnect is true
this.reconnect()
}
}
throw error
}
if (!subscriberData) {
logger.error('Error while subscribing. Subscriber data required')
throw new Error('Subscriber data required')
}
const signalingInstance = new Signaling({
streamName: this.streamName,
url: `${subscriberData.urls[0]}?token=${subscriberData.jwt}`
})
const webRTCPeerInstance = data.migrate ? new PeerConnection() : this.webRTCPeer
await webRTCPeerInstance.createRTCPeer(this.options.peerConfig)
// Stop emiting events from the previous instances
this.stopReemitingWebRTCPeerInstanceEvents?.()
this.stopReemitingSignalingInstanceEvents?.()
// And start emitting from the new ones
this.stopReemitingWebRTCPeerInstanceEvents = reemit(webRTCPeerInstance, this, Object.values(webRTCEvents))
this.stopReemitingSignalingInstanceEvents = reemit(signalingInstance, this, [signalingEvents.broadcastEvent])
const getLocalSDPPromise = webRTCPeerInstance.getRTCLocalSDP({ ...this.options, stereo: true })
const signalingConnectPromise = signalingInstance.connect()
promises = await Promise.all([getLocalSDPPromise, signalingConnectPromise])
const localSdp = promises[0]
let oldSignaling = this.signaling
this.signaling = signalingInstance
const subscribePromise = this.signaling.subscribe(localSdp, { ...this.options, vad: this.options.multiplexedAudioTracks > 0 })
const setLocalDescriptionPromise = webRTCPeerInstance.peer.setLocalDescription(webRTCPeerInstance.sessionDescription)
promises = await Promise.all([subscribePromise, setLocalDescriptionPromise])
const sdpSubscriber = promises[0]
await webRTCPeerInstance.setRTCRemoteSDP(sdpSubscriber)
logger.info('Connected to streamName: ', this.streamName)
let oldWebRTCPeer = this.webRTCPeer
this.webRTCPeer = webRTCPeerInstance
this.setReconnect()
if (data.migrate) {
this.webRTCPeer.on(webRTCEvents.connectionStateChange, (state) => {
if (state === 'connected') {
setTimeout(() => {
oldSignaling?.close?.()
oldWebRTCPeer?.closeRTCPeer?.()
oldSignaling = oldWebRTCPeer = null
logger.info('Current connection migrated')
}, 1000)
} else if (['disconnected', 'failed', 'closed'].includes(state)) {
oldSignaling?.close?.()
oldWebRTCPeer?.closeRTCPeer?.()
oldSignaling = oldWebRTCPeer = null
}
})
}
}
};
</code></pre>
</article>
</section>
</div>
<footer class="footer" id="footer">
</footer>
<script src="scripts/third-party/prettify.js"></script>
<script src="scripts/third-party/lang-css.js"></script>
<script type="text/javascript" src="scripts/misc.js"></script>
<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/fix-code-block.js"></script>
<script src="scripts/fix-navbar.js"></script>
<script src="scripts/search.js"></script>
<script src="scripts/third-party/fuse.js"></script>
<script>
var list = [{"title":"Director","link":"<a href=\"module-Director.html\">Director</a>"},{"title":"module:Director~getEndpoint","link":"<a href=\"module-Director.html#~getEndpoint\">module:Director~getEndpoint ▸ undefined</a>"},{"title":"module:Director~getLiveDomain","link":"<a href=\"module-Director.html#~getLiveDomain\">module:Director~getLiveDomain ▸ undefined</a>"},{"title":"module:Director~getPublisher","link":"<a href=\"module-Director.html#~getPublisher\">module:Director~getPublisher ▸ undefined</a>"},{"title":"module:Director~getSubscriber","link":"<a href=\"module-Director.html#~getSubscriber\">module:Director~getSubscriber ▸ undefined</a>"},{"title":"module:Director~setEndpoint","link":"<a href=\"module-Director.html#~setEndpoint\">module:Director~setEndpoint ▸ undefined</a>"},{"title":"module:Director~setLiveDomain","link":"<a href=\"module-Director.html#~setLiveDomain\">module:Director~setLiveDomain ▸ undefined</a>"},{"title":"Logger","link":"<a href=\"module-Logger.html\">Logger</a>"},{"title":"module:Logger~get","link":"<a href=\"module-Logger.html#~get\">module:Logger~get ▸ undefined</a>"},{"title":"module:Logger~getHistory","link":"<a href=\"module-Logger.html#~getHistory\">module:Logger~getHistory ▸ undefined</a>"},{"title":"module:Logger~getHistoryMaxSize","link":"<a href=\"module-Logger.html#~getHistoryMaxSize\">module:Logger~getHistoryMaxSize ▸ undefined</a>"},{"title":"module:Logger~getLevel","link":"<a href=\"module-Logger.html#~getLevel\">module:Logger~getLevel ▸ undefined</a>"},{"title":"module:Logger~setHandler","link":"<a href=\"module-Logger.html#~setHandler\">module:Logger~setHandler ▸ undefined</a>"},{"title":"module:Logger~setHistoryMaxSize","link":"<a href=\"module-Logger.html#~setHistoryMaxSize\">module:Logger~setHistoryMaxSize ▸ undefined</a>"},{"title":"module:Logger~setLevel","link":"<a href=\"module-Logger.html#~setLevel\">module:Logger~setLevel ▸ undefined</a>"},{"title":"SdpParser","link":"<a href=\"module-SdpParser.html\">SdpParser</a>"},{"title":"module:SdpParser~adaptCodecName","link":"<a href=\"module-SdpParser.html#~adaptCodecName\">module:SdpParser~adaptCodecName ▸ undefined</a>"},{"title":"module:SdpParser~getAvailableHeaderExtensionIdRange","link":"<a href=\"module-SdpParser.html#~getAvailableHeaderExtensionIdRange\">module:SdpParser~getAvailableHeaderExtensionIdRange ▸ undefined</a>"},{"title":"module:SdpParser~getAvailablePayloadTypeRange","link":"<a href=\"module-SdpParser.html#~getAvailablePayloadTypeRange\">module:SdpParser~getAvailablePayloadTypeRange ▸ undefined</a>"},{"title":"module:SdpParser~removeSdpLine","link":"<a href=\"module-SdpParser.html#~removeSdpLine\">module:SdpParser~removeSdpLine ▸ undefined</a>"},{"title":"module:SdpParser~renegotiate","link":"<a href=\"module-SdpParser.html#~renegotiate\">module:SdpParser~renegotiate ▸ undefined</a>"},{"title":"module:SdpParser~setAbsoluteCaptureTime","link":"<a href=\"module-SdpParser.html#~setAbsoluteCaptureTime\">module:SdpParser~setAbsoluteCaptureTime ▸ undefined</a>"},{"title":"module:SdpParser~setDependencyDescriptor","link":"<a href=\"module-SdpParser.html#~setDependencyDescriptor\">module:SdpParser~setDependencyDescriptor ▸ undefined</a>"},{"title":"module:SdpParser~setDTX","link":"<a href=\"module-SdpParser.html#~setDTX\">module:SdpParser~setDTX ▸ undefined</a>"},{"title":"module:SdpParser~setMultiopus","link":"<a href=\"module-SdpParser.html#~setMultiopus\">module:SdpParser~setMultiopus ▸ undefined</a>"},{"title":"module:SdpParser~setSimulcast","link":"<a href=\"module-SdpParser.html#~setSimulcast\">module:SdpParser~setSimulcast ▸ undefined</a>"},{"title":"module:SdpParser~setStereo","link":"<a href=\"module-SdpParser.html#~setStereo\">module:SdpParser~setStereo ▸ undefined</a>"},{"title":"module:SdpParser~setVideoBitrate","link":"<a href=\"module-SdpParser.html#~setVideoBitrate\">module:SdpParser~setVideoBitrate ▸ undefined</a>"},{"title":"module:SdpParser~updateMissingVideoExtensions","link":"<a href=\"module-SdpParser.html#~updateMissingVideoExtensions\">module:SdpParser~updateMissingVideoExtensions ▸ undefined</a>"},{"title":"BaseWebRTC","link":"<a href=\"BaseWebRTC.html\">BaseWebRTC</a>"},{"title":"BaseWebRTC#getRTCPeerConnection","link":"<a href=\"BaseWebRTC.html#getRTCPeerConnection\">BaseWebRTC ▸ getRTCPeerConnection</a>"},{"title":"BaseWebRTC#isActive","link":"<a href=\"BaseWebRTC.html#isActive\">BaseWebRTC ▸ isActive</a>"},{"title":"BaseWebRTC#reconnect","link":"<a href=\"BaseWebRTC.html#reconnect\">BaseWebRTC ▸ reconnect</a>"},{"title":"BaseWebRTC#setReconnect","link":"<a href=\"BaseWebRTC.html#setReconnect\">BaseWebRTC ▸ setReconnect</a>"},{"title":"BaseWebRTC#stop","link":"<a href=\"BaseWebRTC.html#stop\">BaseWebRTC ▸ stop</a>"},{"title":"PeerConnection","link":"<a href=\"PeerConnection.html\">PeerConnection</a>"},{"title":"PeerConnection.getCapabilities","link":"<a href=\"PeerConnection.html#.getCapabilities\">PeerConnection ▸ getCapabilities</a>"},{"title":"PeerConnection#addRemoteTrack","link":"<a href=\"PeerConnection.html#addRemoteTrack\">PeerConnection ▸ addRemoteTrack</a>"},{"title":"PeerConnection#closeRTCPeer","link":"<a href=\"PeerConnection.html#closeRTCPeer\">PeerConnection ▸ closeRTCPeer</a>"},{"title":"PeerConnection#createRTCPeer","link":"<a href=\"PeerConnection.html#createRTCPeer\">PeerConnection ▸ createRTCPeer</a>"},{"title":"PeerConnection#getRTCLocalSDP","link":"<a href=\"PeerConnection.html#getRTCLocalSDP\">PeerConnection ▸ getRTCLocalSDP</a>"},{"title":"PeerConnection#getRTCPeer","link":"<a href=\"PeerConnection.html#getRTCPeer\">PeerConnection ▸ getRTCPeer</a>"},{"title":"PeerConnection#getRTCPeerStatus","link":"<a href=\"PeerConnection.html#getRTCPeerStatus\">PeerConnection ▸ getRTCPeerStatus</a>"},{"title":"PeerConnection#getTracks","link":"<a href=\"PeerConnection.html#getTracks\">PeerConnection ▸ getTracks</a>"},{"title":"PeerConnection#initStats","link":"<a href=\"PeerConnection.html#initStats\">PeerConnection ▸ initStats</a>"},{"title":"PeerConnection#replaceTrack","link":"<a href=\"PeerConnection.html#replaceTrack\">PeerConnection ▸ replaceTrack</a>"},{"title":"PeerConnection#setRTCRemoteSDP","link":"<a href=\"PeerConnection.html#setRTCRemoteSDP\">PeerConnection ▸ setRTCRemoteSDP</a>"},{"title":"PeerConnection#stopStats","link":"<a href=\"PeerConnection.html#stopStats\">PeerConnection ▸ stopStats</a>"},{"title":"PeerConnection#updateBandwidthRestriction","link":"<a href=\"PeerConnection.html#updateBandwidthRestriction\">PeerConnection ▸ updateBandwidthRestriction</a>"},{"title":"PeerConnection#updateBitrate","link":"<a href=\"PeerConnection.html#updateBitrate\">PeerConnection ▸ updateBitrate</a>"},{"title":"Publish","link":"<a href=\"Publish.html\">Publish</a>"},{"title":"Publish#connect","link":"<a href=\"Publish.html#connect\">Publish ▸ connect</a>"},{"title":"Publish#getRTCPeerConnection","link":"<a href=\"Publish.html#getRTCPeerConnection\">Publish ▸ getRTCPeerConnection</a>"},{"title":"Publish#isActive","link":"<a href=\"Publish.html#isActive\">Publish ▸ isActive</a>"},{"title":"Publish#reconnect","link":"<a href=\"Publish.html#reconnect\">Publish ▸ reconnect</a>"},{"title":"Publish#record","link":"<a href=\"Publish.html#record\">Publish ▸ record</a>"},{"title":"Publish#setReconnect","link":"<a href=\"Publish.html#setReconnect\">Publish ▸ setReconnect</a>"},{"title":"Publish#stop","link":"<a href=\"Publish.html#stop\">Publish ▸ stop</a>"},{"title":"Publish#unrecord","link":"<a href=\"Publish.html#unrecord\">Publish ▸ unrecord</a>"},{"title":"Signaling","link":"<a href=\"Signaling.html\">Signaling</a>"},{"title":"Signaling#close","link":"<a href=\"Signaling.html#close\">Signaling ▸ close</a>"},{"title":"Signaling#cmd","link":"<a href=\"Signaling.html#cmd\">Signaling ▸ cmd</a>"},{"title":"Signaling#connect","link":"<a href=\"Signaling.html#connect\">Signaling ▸ connect</a>"},{"title":"Signaling#publish","link":"<a href=\"Signaling.html#publish\">Signaling ▸ publish</a>"},{"title":"Signaling#subscribe","link":"<a href=\"Signaling.html#subscribe\">Signaling ▸ subscribe</a>"},{"title":"StreamEvents","link":"<a href=\"StreamEvents.html\">StreamEvents</a>"},{"title":"StreamEvents.getEventsLocation","link":"<a href=\"StreamEvents.html#.getEventsLocation\">StreamEvents ▸ getEventsLocation</a>"},{"title":"StreamEvents.init","link":"<a href=\"StreamEvents.html#.init\">StreamEvents ▸ init</a>"},{"title":"StreamEvents.setEventsLocation","link":"<a href=\"StreamEvents.html#.setEventsLocation\">StreamEvents ▸ setEventsLocation</a>"},{"title":"StreamEvents#onUserCount","link":"<a href=\"StreamEvents.html#onUserCount\">StreamEvents ▸ onUserCount</a>"},{"title":"StreamEvents#stop","link":"<a href=\"StreamEvents.html#stop\">StreamEvents ▸ stop</a>"},{"title":"View","link":"<a href=\"View.html\">View</a>"},{"title":"View#addRemoteTrack","link":"<a href=\"View.html#addRemoteTrack\">View ▸ addRemoteTrack</a>"},{"title":"View#connect","link":"<a href=\"View.html#connect\">View ▸ connect</a>"},{"title":"View#getRTCPeerConnection","link":"<a href=\"View.html#getRTCPeerConnection\">View ▸ getRTCPeerConnection</a>"},{"title":"View#isActive","link":"<a href=\"View.html#isActive\">View ▸ isActive</a>"},{"title":"View#project","link":"<a href=\"View.html#project\">View ▸ project</a>"},{"title":"View#reconnect","link":"<a href=\"View.html#reconnect\">View ▸ reconnect</a>"},{"title":"View#select","link":"<a href=\"View.html#select\">View ▸ select</a>"},{"title":"View#setReconnect","link":"<a href=\"View.html#setReconnect\">View ▸ setReconnect</a>"},{"title":"View#stop","link":"<a href=\"View.html#stop\">View ▸ stop</a>"},{"title":"View#unproject","link":"<a href=\"View.html#unproject\">View ▸ unproject</a>"},{"title":"reconnect","link":"<a href=\"BaseWebRTC.html#event:reconnect\">reconnect</a>"},{"title":"connectionStateChange","link":"<a href=\"PeerConnection.html#event:connectionStateChange\">connectionStateChange</a>"},{"title":"stats","link":"<a href=\"PeerConnection.html#event:stats\">stats</a>"},{"title":"track","link":"<a href=\"PeerConnection.html#event:track\">track</a>"},{"title":"reconnect","link":"<a href=\"Publish.html#event:reconnect\">reconnect</a>"},{"title":"broadcastEvent","link":"<a href=\"Signaling.html#event:broadcastEvent\">broadcastEvent</a>"},{"title":"wsConnectionClose","link":"<a href=\"Signaling.html#event:wsConnectionClose\">wsConnectionClose</a>"},{"title":"wsConnectionError","link":"<a href=\"Signaling.html#event:wsConnectionError\">wsConnectionError</a>"},{"title":"wsConnectionSuccess","link":"<a href=\"Signaling.html#event:wsConnectionSuccess\">wsConnectionSuccess</a>"},{"title":"reconnect","link":"<a href=\"View.html#event:reconnect\">reconnect</a>"},{"title":"addCandidateReport","link":"<a href=\"global.html#addCandidateReport\">addCandidateReport</a>"},{"title":"addInboundRtpReport","link":"<a href=\"global.html#addInboundRtpReport\">addInboundRtpReport</a>"},{"title":"addOutboundRtpReport","link":"<a href=\"global.html#addOutboundRtpReport\">addOutboundRtpReport</a>"},{"title":"addPeerEvents","link":"<a href=\"global.html#addPeerEvents\">addPeerEvents</a>"},{"title":"AudioCodec","link":"<a href=\"global.html#AudioCodec\">AudioCodec</a>"},{"title":"calculatePacketsLostDelta","link":"<a href=\"global.html#calculatePacketsLostDelta\">calculatePacketsLostDelta</a>"},{"title":"calculatePacketsLostRatio","link":"<a href=\"global.html#calculatePacketsLostRatio\">calculatePacketsLostRatio</a>"},{"title":"ConnectionStats","link":"<a href=\"global.html#ConnectionStats\">ConnectionStats</a>"},{"title":"DirectorPublisherOptions","link":"<a href=\"global.html#DirectorPublisherOptions\">DirectorPublisherOptions</a>"},{"title":"DirectorSubscriberOptions","link":"<a href=\"global.html#DirectorSubscriberOptions\">DirectorSubscriberOptions</a>"},{"title":"getBaseRtpReportData","link":"<a href=\"global.html#getBaseRtpReportData\">getBaseRtpReportData</a>"},{"title":"getCodecData","link":"<a href=\"global.html#getCodecData\">getCodecData</a>"},{"title":"getMediaType","link":"<a href=\"global.html#getMediaType\">getMediaType</a>"},{"title":"InboundStats","link":"<a href=\"global.html#InboundStats\">InboundStats</a>"},{"title":"LayerInfo","link":"<a href=\"global.html#LayerInfo\">LayerInfo</a>"},{"title":"loggerHandler","link":"<a href=\"global.html#loggerHandler\">loggerHandler</a>"},{"title":"LogLevel","link":"<a href=\"global.html#LogLevel\">LogLevel</a>"},{"title":"onUserCountCallback","link":"<a href=\"global.html#onUserCountCallback\">onUserCountCallback</a>"},{"title":"OnUserCountOptions","link":"<a href=\"global.html#OnUserCountOptions\">OnUserCountOptions</a>"},{"title":"OutboundStats","link":"<a href=\"global.html#OutboundStats\">OutboundStats</a>"},{"title":"SignalingPublishOptions","link":"<a href=\"global.html#SignalingPublishOptions\">SignalingPublishOptions</a>"},{"title":"SignalingSubscribeOptions","link":"<a href=\"global.html#SignalingSubscribeOptions\">SignalingSubscribeOptions</a>"},{"title":"tokenGeneratorCallback","link":"<a href=\"global.html#tokenGeneratorCallback\">tokenGeneratorCallback</a>"},{"title":"TrackReport","link":"<a href=\"global.html#TrackReport\">TrackReport</a>"},{"title":"VideoCodec","link":"<a href=\"global.html#VideoCodec\">VideoCodec</a>"},{"title":"WowzaCapability","link":"<a href=\"global.html#WowzaCapability\">WowzaCapability</a>"},{"title":"WowzaDirectorResponse","link":"<a href=\"global.html#WowzaDirectorResponse\">WowzaDirectorResponse</a>"}];
var options =
setupSearch(list, options)
</script>
</body>
</html>