@reactoo/watchtogether-sdk-js 2.4.40 → 2.5.0

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 (50) hide show
  1. package/dist/watchtogether-sdk.js +2187 -2418
  2. package/dist/watchtogether-sdk.min.js +2 -2
  3. package/example/bulk_join_room/bulk_join_room.html +200 -0
  4. package/example/bulk_join_room/persons_gifs/1.gif +0 -0
  5. package/example/bulk_join_room/persons_gifs/10.gif +0 -0
  6. package/example/bulk_join_room/persons_gifs/11.gif +0 -0
  7. package/example/bulk_join_room/persons_gifs/12.gif +0 -0
  8. package/example/bulk_join_room/persons_gifs/13.gif +0 -0
  9. package/example/bulk_join_room/persons_gifs/14.gif +0 -0
  10. package/example/bulk_join_room/persons_gifs/15.gif +0 -0
  11. package/example/bulk_join_room/persons_gifs/16.gif +0 -0
  12. package/example/bulk_join_room/persons_gifs/17.gif +0 -0
  13. package/example/bulk_join_room/persons_gifs/18.gif +0 -0
  14. package/example/bulk_join_room/persons_gifs/19.gif +0 -0
  15. package/example/bulk_join_room/persons_gifs/2.gif +0 -0
  16. package/example/bulk_join_room/persons_gifs/20.gif +0 -0
  17. package/example/bulk_join_room/persons_gifs/21.gif +0 -0
  18. package/example/bulk_join_room/persons_gifs/22.gif +0 -0
  19. package/example/bulk_join_room/persons_gifs/23.gif +0 -0
  20. package/example/bulk_join_room/persons_gifs/24.gif +0 -0
  21. package/example/bulk_join_room/persons_gifs/25.gif +0 -0
  22. package/example/bulk_join_room/persons_gifs/26.gif +0 -0
  23. package/example/bulk_join_room/persons_gifs/27.gif +0 -0
  24. package/example/bulk_join_room/persons_gifs/28.gif +0 -0
  25. package/example/bulk_join_room/persons_gifs/29.gif +0 -0
  26. package/example/bulk_join_room/persons_gifs/3.gif +0 -0
  27. package/example/bulk_join_room/persons_gifs/30.gif +0 -0
  28. package/example/bulk_join_room/persons_gifs/31.gif +0 -0
  29. package/example/bulk_join_room/persons_gifs/32.gif +0 -0
  30. package/example/bulk_join_room/persons_gifs/4.gif +0 -0
  31. package/example/bulk_join_room/persons_gifs/5.gif +0 -0
  32. package/example/bulk_join_room/persons_gifs/6.gif +0 -0
  33. package/example/bulk_join_room/persons_gifs/7.gif +0 -0
  34. package/example/bulk_join_room/persons_gifs/8.gif +0 -0
  35. package/example/bulk_join_room/persons_gifs/9.gif +0 -0
  36. package/example/index.html +19 -13
  37. package/package.json +8 -8
  38. package/src/index.js +7 -6
  39. package/src/models/auth.js +2 -2
  40. package/src/models/iot.js +81 -70
  41. package/src/models/room-session.js +31 -12
  42. package/src/models/room.js +138 -97
  43. package/src/models/system.js +45 -0
  44. package/src/models/user.js +11 -6
  45. package/src/modules/wt-iot.js +124 -74
  46. package/src/modules/wt-room.js +65 -131
  47. package/src/modules/wt-utils.js +2 -2
  48. package/example/shaka-basic-sync.html +0 -137
  49. package/src/models/iot2.js +0 -119
  50. package/src/modules/wt-iot2.js +0 -238
@@ -1,137 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Shaka Basic Sync</title>
6
- <script src="https://www.unpkg.com/shaka-player@3.1.1/dist/shaka-player.compiled.js"></script>
7
- <script src="../dist/watchtogether-sdk.js"></script>
8
- </head>
9
- <body>
10
-
11
- <div id="player"></div>
12
- <div id="player2"></div>
13
-
14
- <script>
15
-
16
- // Example Player Factory
17
-
18
- window.examplePlayerFactory = (wrapper, handlers = {
19
- handleStalled() {}, handleProgress() {}, handlePlaying() {}, handlePause() {}
20
- }) => {
21
-
22
- if (!wrapper) {
23
- throw 'Missing wrapper element'
24
- }
25
-
26
- if (typeof wrapper === 'string') {
27
- wrapper = document.querySelector(wrapper)
28
- }
29
-
30
- let videoElement = document.createElement('video');
31
-
32
- wrapper.appendChild(videoElement);
33
-
34
- shaka.polyfill.installAll();
35
-
36
- let shakaPlayer = new shaka.Player(videoElement);
37
-
38
- shakaPlayer.addEventListener('buffering', event => {
39
- if (event.buffering) {
40
- handlers.handleBuffering();
41
-
42
- // Enabling this and disabling native stalled event depends on player behavior.
43
- // handlers.handleStalled();
44
- }
45
- });
46
-
47
- videoElement.addEventListener('stalled', handlers.handleStalled);
48
- videoElement.addEventListener('progress', handlers.handleProgress);
49
- videoElement.addEventListener('playing', handlers.handlePlaying);
50
- videoElement.addEventListener('pause', handlers.handlePause);
51
-
52
- shakaPlayer.load('https://storage.googleapis.com/shaka-live-assets/player-source.mpd')
53
- .then(() => {
54
- videoElement.play();
55
- })
56
- .catch(console.error)
57
-
58
- return {
59
- // Options are currently ignored but will be added in final version to support wide selection of video-players
60
- options: {
61
- isVod: false,
62
- ignoreBuffer: false,
63
- useSeekBy: false,
64
- syncBySegments: false,
65
- disableFastSeek: false
66
- },
67
- play() {
68
- videoElement.play();
69
- },
70
- pause() {
71
- videoElement.pause();
72
- },
73
- seek(time) {
74
- videoElement.currentTime = time;
75
- },
76
- setPlaybackRate(playbackRate) {
77
- videoElement.playbackRate = playbackRate;
78
- },
79
-
80
- // Audio output is controlled from withing our app so we need some way to set it on 3rd party player
81
-
82
- setAudioOutput(sinkId) {
83
- if (typeof sinkId !== 'undefined') {
84
- videoElement.setSinkId(sinkId).then((r) => {
85
- console.log('Audio output setup OK');
86
- }).catch((e) => {
87
- console.log('Audio output setup failed', e);
88
- });
89
- }
90
- },
91
- get isPaused() {
92
- return videoElement.paused;
93
- },
94
- get currentTime() {
95
- return videoElement.currentTime;
96
- },
97
- get buffered() {
98
- return videoElement.buffered;
99
- },
100
- };
101
- };
102
-
103
- // TEST
104
- // Sync test with 2 players
105
-
106
- let Instance1 = WatchTogetherSDK({debug:true, storagePrefix: 'user1'})({instanceType:'reactooDemo', playerFactory: examplePlayerFactory});
107
- let Instance2 = WatchTogetherSDK({debug:true, storagePrefix: 'user2'})({instanceType:'reactooDemo', playerFactory: examplePlayerFactory});
108
-
109
- Instance1.auth.login('multitest1', 'abc123ABC')
110
- .then(() => Instance1.room.createSession({roomId:'907e778d-f3ec-4ea7-b60e-b18010e7108a'}))
111
- .then((session) => {
112
- session.renderPlayer('#player');
113
- return Promise.all([session, session.connect()]);
114
- })
115
- .then(([session, _]) => {
116
- session.publishLocal(null, {getStreamIfEmpty: false})
117
- });
118
-
119
- setTimeout(() => {
120
- Instance2.auth.login('multitest2', 'abc123ABC')
121
- .then(() => Instance2.room.createSession({roomId:'907e778d-f3ec-4ea7-b60e-b18010e7108a'}))
122
- .then((session) => {
123
- session.renderPlayer('#player2');
124
- return Promise.all([session, session.connect()]);
125
- })
126
- .then(([session, _]) => {
127
- session.publishLocal(null, {getStreamIfEmpty: false})
128
- });
129
-
130
- }, 5000);
131
-
132
-
133
- </script>
134
-
135
-
136
- </body>
137
- </html>
@@ -1,119 +0,0 @@
1
- 'use strict';
2
-
3
- let iot = function () {
4
- let __currentTopics = [];
5
- let __ = null;
6
- return {
7
-
8
- __promise: null,
9
-
10
- __reconnect: (err) => {
11
-
12
- this.__privates.iot.log('MQTT Error:', err, `Is event error: ${err instanceof Event}`);
13
-
14
- if(err instanceof Event && err.type === 'error') {
15
- this.__privates.iot.log('SDK MQTT Reconnection attempt');
16
- clearTimeout(__);
17
- __ = setTimeout(() => {
18
- this.iot.iotLogin(true, true).catch((e) => this.__privates.iot.log('MQTT Connection Error:', e))
19
- }, 1000);
20
- }
21
- },
22
-
23
- __updateCredentials: () => {
24
- this.iot.getCredentials()
25
- .then(response => this.__privates.iot.updateWebSocketCredentials(response.data.credentials.accessKeyId, response.data.credentials.secretAccessKey, response.data.credentials.sessionToken, response.data.credentials.expiration));
26
- },
27
-
28
- getCredentials: () => {
29
- return this.__privates.auth.__client
30
- .then(client => client.apis.auth.iotSignIn({}, {requestBody: {suggestedTopics:true, domain: location.hostname}}))
31
-
32
- },
33
-
34
- iotLogin: (subscribeToSuggestedTopics = true, forceDisconnect = false) => {
35
- this.iot.$off('error', this.iot.__reconnect, this);
36
- this.iot.__promise = new Promise((resolve, reject) => {
37
- this.iot.getCredentials()
38
- .then(response => {
39
- return Promise.all([
40
- response.data.suggestedTopics,
41
- this.__privates.iot.connect(response.data.endpoint, response.data.clientId, response.data.region, response.data.credentials.accessKeyId, response.data.credentials.secretAccessKey, response.data.credentials.sessionToken, response.data.credentials.expiration, forceDisconnect)
42
- ])
43
- })
44
- .then(resolve)
45
- .catch(reject)
46
- });
47
-
48
- let __currentTopicsCopy = [...__currentTopics];
49
- __currentTopics.length = 0;
50
-
51
- this.iot.__promise
52
- .then(([suggestedTopic, instance]) => (subscribeToSuggestedTopics ?
53
- Promise.all([...suggestedTopic, ...__currentTopicsCopy].map(topic => this.iot.subscribe(topic))).then(() => instance) :
54
- Promise.resolve(instance)
55
- ))
56
- .then((instance) => {
57
- this.iot.$on('error', this.iot.__reconnect, this);
58
- this.iot.$on('updateCredentials', this.iot.__updateCredentials, this);
59
- return instance;
60
- });
61
-
62
- return this.iot.__promise;
63
- },
64
-
65
- iotLogout: (keepCurrentTopics = false) => {
66
- this.iot.$off('error', this.iot.__reconnect, this);
67
- this.iot.$off('updateCredentials', this.iot.__updateCredentials, this);
68
- if(!keepCurrentTopics) {
69
- __currentTopics.length = 0;
70
- }
71
- return this.__privates.iot.disconnect()
72
- .then(() => {
73
- this.iot.__promise = null;
74
- return true;
75
- });
76
- },
77
-
78
- isConnected: () => {
79
- return this.__privates.iot.isConnected();
80
- },
81
-
82
- subscribe: (topic) => {
83
- if(__currentTopics.indexOf(topic) === -1) {
84
- __currentTopics.push(topic);
85
- if(!this.iot.__promise) return Promise.resolve('not_connected');
86
- return this.iot.__promise.then(() => this.__privates.iot.subscribe(topic));
87
- }
88
- },
89
-
90
- unsubscribe: (topic) => {
91
- let index = __currentTopics.indexOf(topic);
92
- (index > -1) && __currentTopics.splice(index, 1);
93
- if(!this.iot.__promise) return Promise.resolve('not_connected');
94
- return this.iot.__promise.then(() => this.__privates.iot.unsubscribe(topic));
95
- },
96
-
97
- send: (topic, message) => {
98
- return this.iot.__promise.then(() => this.__privates.iot.send(topic,message));
99
- },
100
-
101
- $once: (key, callback, that) => {
102
- return this.__privates.iot.once(key, callback, that || this);
103
- },
104
-
105
- $on: (key, callback, that) => {
106
- return this.__privates.iot.on(key, callback, that || this);
107
- },
108
-
109
- $off: (key, callback, that) => {
110
- return this.__privates.iot.off(key, callback, that || this);
111
- },
112
-
113
- $clear: () => {
114
- return this.__privates.iot.clear();
115
- }
116
- };
117
- };
118
-
119
- export default iot;
@@ -1,238 +0,0 @@
1
-
2
- import {device} from 'aws-iot-device-sdk';
3
- import emitter from './wt-emitter';
4
-
5
- class Iot2 {
6
-
7
- constructor(enableDebugFlag) {
8
- Object.assign(this, emitter());
9
- this.device = null;
10
- this.decoder = new TextDecoder('utf-8');
11
- this.connectionActive = false;
12
- this.log = Iot2.noop;
13
- this.debugFlag = enableDebugFlag;
14
- this.credentialsExpirationCheckIntervalId = null;
15
- this.currentCredentialsExpirationStamp = null
16
- if(enableDebugFlag) {
17
- this.enableDebug();
18
- }
19
- }
20
-
21
- static noop() {}
22
-
23
- enableDebug() {
24
- this.log = console.log.bind(console);
25
- }
26
-
27
- startCredentialsExpirationCheck(expiration) {
28
- this.stopCredentialsExpirationCheck();
29
- this.currentCredentialsExpirationStamp = new Date(expiration).getTime();
30
- this.credentialsExpirationCheckIntervalId = setInterval(() => {
31
- const curentTimeStamp = new Date().getTime();
32
- if(this.currentCredentialsExpirationStamp - curentTimeStamp <= 300000) {
33
- this.emit('updateCredentials');
34
- }
35
- }, 5000);
36
- }
37
-
38
- stopCredentialsExpirationCheck() {
39
- clearInterval(this.credentialsExpirationCheckIntervalId);
40
- this.credentialsExpirationCheckIntervalId = null;
41
- }
42
-
43
- updateWebSocketCredentials(accessKeyId, secretAccessKey, sessionToken, expiration) {
44
- if(this.device) {
45
- this.device.updateWebSocketCredentials(accessKeyId, secretAccessKey, sessionToken);
46
- this.startCredentialsExpirationCheck(expiration);
47
- }
48
- }
49
-
50
- connect(apiMqttUrl, apiMqttClientId, region, accessKeyId, secretAccessKey, sessionToken, expiration, forceDisconnect = false) {
51
- return this.disconnect(forceDisconnect).then(() => {
52
- return new Promise((resolve, reject) => {
53
- this.device = device({
54
- protocol:'wss',
55
- clientId: apiMqttClientId,
56
- region,
57
- host: apiMqttUrl,
58
- accessKeyId: accessKeyId,
59
- secretKey: secretAccessKey,
60
- sessionToken: sessionToken,
61
- keepalive: 15,
62
- maximumReconnectTimeMs: 8000,
63
- enableMetrics: false,
64
- debug: this.debugFlag,
65
- autoResubscribe: true
66
- });
67
-
68
- this.startCredentialsExpirationCheck(expiration);
69
-
70
- let __s = () => {
71
- this.device.off('connect', __s);
72
- this.device.off('error', __e);
73
- resolve(this.device)
74
- };
75
-
76
- let __e = (e) => {
77
- this.device.off('connect', __s);
78
- this.device.off('error', __e);
79
- reject(e);
80
- };
81
-
82
- this.device.once('connect', __s);
83
- this.device.once('error', __e);
84
-
85
- this.device.on('message', this.__messageCb.bind(this));
86
- this.device.on('connect', this.__connectCb.bind(this));
87
- this.device.on('reconnect', this.__reconnectCb.bind(this));
88
- this.device.on('error', this.__failureCb.bind(this));
89
- this.device.on('close', this.__closeCb.bind(this));
90
- this.device.on('offline', this.__offlineCb.bind(this));
91
-
92
- })
93
- })
94
-
95
- }
96
-
97
- disconnect(force = false) {
98
-
99
- this.stopCredentialsExpirationCheck();
100
-
101
- return new Promise((resolve, reject) => {
102
- if(!this.device) {
103
- resolve();
104
- return;
105
- }
106
- let __i = null;
107
- let __c = () => {
108
- clearTimeout(__i);
109
- this.device = null;
110
- resolve();
111
- };
112
- __i = setTimeout(__c, 4000);
113
- this.device.off('message', this.__messageCb.bind(this));
114
- this.device.off('connect', this.__connectCb.bind(this));
115
- this.device.off('reconnect', this.__reconnectCb.bind(this));
116
- this.device.off('error', this.__failureCb.bind(this));
117
- this.device.off('close', this.__closeCb.bind(this));
118
- this.device.off('offline', this.__offlineCb.bind(this));
119
- this.device.end(force, __c);
120
- });
121
- }
122
-
123
- isConnected() {
124
- return this.connectionActive;
125
- }
126
-
127
- subscribe(topic) {
128
- return this.device && this.device.subscribe(topic);
129
- }
130
-
131
- unsubscribe(topic) {
132
- return this.device && this.device.unsubscribe(topic);
133
- }
134
-
135
- send(topic, message) {
136
- let msg = typeof message === 'object' ? JSON.stringify(message) : message;
137
- return this.device && this.device.publish(topic, msg);
138
- }
139
-
140
- __reconnectCb() {
141
- this.emit('reconnect');
142
- }
143
- __connectCb() {
144
- this.connectionActive = true;
145
- this.emit('connect');
146
- }
147
- __failureCb(err) {
148
- this.emit('error', err);
149
- }
150
- __closeCb(responseObject) {
151
- this.connectionActive = false;
152
- this.emit('close');
153
- }
154
- __offlineCb(responseObject) {
155
- this.emit('offline');
156
- }
157
-
158
- __messageCb(t, message, packet) {
159
-
160
- const topic = t.split('/');
161
- const payload = JSON.parse(this.decoder.decode(message));
162
-
163
- if(topic[0] === 'user') { // user
164
- const userId = topic[1].replace("_", ':');
165
- this.emit('message', {userId, ...payload, event: payload.event ? `user:${payload.event}` : 'user'});
166
- } else if(topic[0] === 'wt') {
167
- const event = payload.event;
168
- const roomId = topic[2];
169
- if(topic[1] === 'room') { // room
170
- if(
171
- event === 'message' ||
172
- event === 'template_updated' ||
173
- event === 'record_start' ||
174
- event === 'record_stop' ||
175
- event === 'record_configured' ||
176
- event === 'record_livestream_available' ||
177
- event === 'record_livestream_kick' ||
178
- event === 'user_update_displayname' ||
179
- event === 'user_update_avatar' ||
180
- event === 'user_update_customattributes' ||
181
- event === 'user_update_privateattributes' ||
182
- event === 'channel_changed' ||
183
- event === "instance_homepage_changed" ||
184
- event === "instance_settings_changed" ||
185
- event === "externalmix_changed" ||
186
- event === "video_uploaded" ||
187
- event === "change_user_devices" ||
188
- event === "queue" ||
189
- event === "title_changed"
190
- ) {
191
- this.emit('message', {event, ...payload, roomId})
192
- }
193
- else if(event === 'joined' || event === 'leaving') {
194
- this.emit('message', {event, ...payload, isObserver:!!payload.isObserver, roomId});
195
- }
196
- else if(
197
- event === 'left' || //user removed room a.k.a. left the room
198
- event === 'kicked' ||
199
- event === 'banned' ||
200
- event === 'unbanned' ||
201
- event === 'approved' ||
202
- event === 'muted' ||
203
- event === 'unmuted' ||
204
- event === 'messageRemoved' ||
205
- event === 'messageReported' ||
206
- event === 'chatClear' ||
207
- event === 'handRaised' || event === 'handLowered' || event === 'handsCleared'
208
- ) {
209
- this.emit('message', {event, ...payload});
210
- }
211
- else if(event === 'volume_set') {
212
- this.emit('message', {event, ...payload});
213
- }
214
- }
215
- else if(topic[1] === 'instanceroom') { // instance
216
- if(event === 'add_room' || event === 'remove_room' || event === 'set_room' || event === "instance_homepage_changed" || event === 'instance_settings_changed') {
217
- this.emit('message', {event, ...payload});
218
- }
219
- }
220
- else if(topic[1] === 'externalmix') {
221
- const event = payload.event;
222
- this.emit('message', {event, ...payload});
223
- }
224
- } else if(topic[0] === 'wtr') {
225
- const recorderId = topic[1];
226
- const sessionId = topic[2];
227
- if(topic[3] === 'control') {
228
- this.emit('message', {event: 'recorder_control', ...payload, recorderId, sessionId});
229
- } // recorder control
230
- else if(topic[3] === 'monitor') {
231
- this.emit('message', {event: 'recorder_monitor', ...payload, recorderId, sessionId});
232
- } // recorder monitor
233
- }
234
- }
235
- }
236
-
237
-
238
- export default Iot2;