@reactoo/watchtogether-sdk-js 2.7.85 → 2.7.86-beta.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactoo/watchtogether-sdk-js",
3
- "version": "2.7.85",
3
+ "version": "2.7.86-beta.1",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "dist/watchtogether-sdk.min.js",
6
6
  "module": "dist/watchtogether-sdk.min.js",
@@ -264,11 +264,11 @@ class RoomSession {
264
264
  this.isVideoEnabled = false;
265
265
  this.isAudioEnabed = false;
266
266
  this._statsMaxLength = 31;
267
- this._upStatsLength = 30;
268
- this._downStatsLength = 5;
267
+ this._upStatsLength = 10;
268
+ this._downStatsLength = 2;
269
269
  this._statsTimeoutStopped = true;
270
270
  this._statsTimeoutId = null;
271
- this._statsInterval = 1000;
271
+ this._statsInterval = 3000;
272
272
  this._aqInterval = 2500;
273
273
  this._aqIntervalCounter = 0;
274
274
  this._aqIntervalDivisor = 4;
@@ -1641,16 +1641,13 @@ class RoomSession {
1641
1641
  }
1642
1642
  this._statsTimeoutStopped = false;
1643
1643
  const loop = () => {
1644
- let startTime = performance.now();
1645
- let endTime = null;
1646
1644
  this._getStats('video')
1647
1645
  .then(participantsStats => {
1648
- endTime = performance.now();
1649
1646
  this._parseVideoStats(participantsStats);
1650
1647
  })
1651
1648
  .finally(() => {
1652
1649
  if (!this._statsTimeoutStopped) {
1653
- this._statsTimeoutId = setTimeout(loop, this._statsInterval - Math.min((endTime - startTime), this._statsInterval));
1650
+ this._statsTimeoutId = setTimeout(loop, this._statsInterval);
1654
1651
  }
1655
1652
  })
1656
1653
  };
@@ -1789,106 +1786,242 @@ class RoomSession {
1789
1786
  return medianStats;
1790
1787
  }
1791
1788
 
1789
+
1792
1790
  _parseVideoStats(participantsStats) {
1793
- participantsStats.forEach(sourceStats => {
1794
- sourceStats.forEach(participantStats => {
1795
- if(participantStats !== null && participantStats?.handle?.handleId !== this.handleId) {
1796
- let handle = this._getHandle(participantStats.handle.handleId);
1797
- if(handle) {
1798
-
1799
- if(!handle.webrtcStuff.stats[participantStats.mid]) {
1800
- handle.webrtcStuff.stats[participantStats.mid] = [];
1801
- }
1791
+ for (const sourceStats of participantsStats) {
1792
+
1793
+ for (const participantStats of sourceStats) {
1794
+
1795
+ if (!participantStats?.handleId || participantStats.handleId === this.handleId) continue;
1796
+
1797
+ const handle = this._getHandle(participantStats.handleId);
1798
+ if (!handle) continue;
1799
+
1800
+ const mid = participantStats.mid;
1801
+ handle.webrtcStuff.stats[mid] ??= [];
1802
+
1803
+ const lastStats = handle.webrtcStuff.stats[mid][handle.webrtcStuff.stats[mid].length - 1];
1804
+
1805
+ const stats = {
1806
+ framesPerSecond: null,
1807
+ framesDropped: null,
1808
+ totalFreezesDuration: null,
1809
+ freezeDurationSinceLast: null,
1810
+ freezeCount: null,
1811
+ freezeCountSinceLast: null,
1812
+ jitter: null,
1813
+ packetsLost: null,
1814
+ nackCount: null,
1815
+ roundTripTime: null,
1816
+ width: null,
1817
+ height: null,
1818
+ networkType: null,
1819
+ powerEfficientDecoder: null,
1820
+ selectedSubstream: null,
1821
+ desiredSubstream: null,
1822
+ simulcastMode: null
1823
+ };
1802
1824
 
1803
- const stats = {
1804
- framesPerSecond: null,
1805
- framesDropped: null,
1806
- totalFreezesDuration: null,
1807
- freezeDurationSinceLast: null,
1808
- freezeCount: null,
1809
- jitter: null,
1810
- packetsLost: null,
1811
- nackCount: null,
1812
- roundTripTime: null,
1813
- width: null,
1814
- height: null,
1815
- networkType: null,
1816
- powerEfficientDecoder: null,
1817
- };
1818
- participantStats.stats.forEach(report => {
1819
-
1820
- const simulcastConfigForSource = this._findSimulcastConfig(participantStats.source, this.simulcastSettings);
1821
- const defaultSelectedSubstream = handle.webrtcStuff?.overriddenSimulcastMode[participantStats.mid]?.defaultSubstream ?? simulcastConfigForSource?.defaultSubstream;
1822
- const simulcastMode = handle.webrtcStuff?.overriddenSimulcastMode[participantStats.mid]?.mode ?? simulcastConfigForSource?.mode ;
1823
-
1824
- if(report.type === 'inbound-rtp' && report.kind === 'video') {
1825
- stats.framesPerSecond = report.framesPerSecond || 0;
1826
- stats.framesDropped = report.framesDropped || 0;
1827
- stats.totalFreezesDuration = report.totalFreezesDuration || 0;
1828
- stats.freezeDurationSinceLast = (report.totalFreezesDuration || 0) - (handle.webrtcStuff.stats?.[participantStats.mid]?.[handle.webrtcStuff.stats?.[participantStats.mid]?.length - 1]?.totalFreezesDuration || 0);
1829
- stats.freezeCount = report.freezeCount || 0;
1830
- stats.freezeCountSinceLast = (report.freezeCount || 0) - (handle.webrtcStuff.stats?.[participantStats.mid]?.[handle.webrtcStuff.stats?.[participantStats.mid]?.length - 1]?.freezeCount || 0);
1831
- stats.jitter = report.jitter;
1832
- stats.packetsLost = report.packetsLost;
1833
- stats.nackCount = report.nackCount;
1834
- stats.width = report.frameWidth;
1835
- stats.height = report.frameHeight;
1836
- stats.powerEfficientDecoder = report.powerEfficientDecoder;
1837
- }
1838
- if(report.type === 'candidate-pair') {
1839
- stats.roundTripTime = report.currentRoundTripTime;
1840
- }
1841
- if(report.type === 'local-candidate') {
1842
- stats.networkType = report.networkType;
1843
- }
1825
+ const simulcastConfig = this._findSimulcastConfig(participantStats.source, this.simulcastSettings);
1826
+ const defaultSelectedSubstream = handle.webrtcStuff?.overriddenSimulcastMode[mid]?.defaultSubstream ?? simulcastConfig?.defaultSubstream;
1827
+ const simulcastMode = handle.webrtcStuff?.overriddenSimulcastMode[mid]?.mode ?? simulcastConfig?.mode;
1828
+
1829
+ participantStats.stats.forEach(report => {
1830
+
1831
+ if (report.type === 'inbound-rtp' && report.kind === 'video') {
1832
+ stats.framesPerSecond = report.framesPerSecond || 0;
1833
+ stats.framesDropped = report.framesDropped || 0;
1834
+ stats.totalFreezesDuration = report.totalFreezesDuration || 0;
1835
+ stats.freezeDurationSinceLast = (report.totalFreezesDuration || 0) - (lastStats?.totalFreezesDuration || 0);
1836
+ stats.freezeCount = report.freezeCount || 0;
1837
+ stats.freezeCountSinceLast = (report.freezeCount || 0) - (lastStats?.freezeCount || 0);
1838
+ stats.jitter = report.jitter;
1839
+ stats.packetsLost = report.packetsLost;
1840
+ stats.nackCount = report.nackCount;
1841
+ stats.width = report.frameWidth;
1842
+ stats.height = report.frameHeight;
1843
+ stats.powerEfficientDecoder = report.powerEfficientDecoder;
1844
+ }
1845
+
1846
+ if (report.type === 'candidate-pair') {
1847
+ stats.roundTripTime = report.currentRoundTripTime;
1848
+ }
1844
1849
 
1845
- stats.selectedSubstream = handle.webrtcStuff.selectedSubstream[participantStats.mid];
1846
- stats.desiredSubstream = defaultSelectedSubstream;
1847
- stats.simulcastMode = simulcastMode;
1850
+ if (report.type === 'local-candidate') {
1851
+ stats.networkType = report.networkType;
1852
+ }
1853
+ });
1848
1854
 
1849
- });
1855
+ stats.selectedSubstream = handle.webrtcStuff.selectedSubstream[mid];
1856
+ stats.desiredSubstream = defaultSelectedSubstream;
1857
+ stats.simulcastMode = simulcastMode;
1850
1858
 
1851
- // pushing stats into handle stats array but keeping only 6 last stats
1852
- handle.webrtcStuff.stats[participantStats.mid].push(stats);
1853
- if(handle.webrtcStuff.stats[participantStats.mid].length > this._statsMaxLength) {
1854
- handle.webrtcStuff.stats[participantStats.mid].shift();
1855
- }
1859
+ handle.webrtcStuff.stats[mid].push(stats);
1856
1860
 
1857
- this.emit('rtcStats', {handleId: participantStats.handle.handleId, stats, userId: decodeJanusDisplay(participantStats.handle.userId)?.userId, source: participantStats.source, mid: participantStats.mid});
1858
- }
1861
+ if (handle.webrtcStuff.stats[mid].length > this._statsMaxLength) {
1862
+ handle.webrtcStuff.stats[mid].shift();
1859
1863
  }
1860
- });
1861
- })
1862
1864
 
1865
+ this.emit('rtcStats', {
1866
+ handleId: participantStats.handleId,
1867
+ stats,
1868
+ userId: decodeJanusDisplay(handle.userId)?.userId,
1869
+ source: participantStats.source,
1870
+ mid
1871
+ });
1872
+ }
1873
+ }
1863
1874
  }
1864
1875
 
1865
- _getStats(type = null) {
1866
- return Promise.all(this._participants.map(participant => {
1867
- let mediaTrack = [];
1868
- if (type === 'video') {
1869
- mediaTrack = participant?.webrtcStuff?.stream?.getVideoTracks() || [];
1870
- } else if (type === 'audio') {
1871
- mediaTrack = participant?.webrtcStuff?.stream?.getAudioTracks() || [];
1872
- }
1873
- if(type !== null ) {
1874
- const transceivers = participant?.webrtcStuff?.pc?.getTransceivers();
1875
- return Promise.all(mediaTrack.map(track => {
1876
- const source = Object.keys(participant.webrtcStuff.streamMap).find(s => participant.webrtcStuff.streamMap[s].find(t => t === track.id));
1877
- const mid = transceivers.find(t => t.receiver?.track?.id === track.id || t.sender?.track?.id === track.id)?.mid;
1878
- return participant.webrtcStuff.pc.getStats(track)
1879
- .then(r =>({stats: r, source, mid, handle: participant}))
1880
- .catch(e => Promise.reject({stats: null, error: e, handle: participant, source, mid}))
1881
- }))
1882
- }
1883
- else {
1884
- return participant?.webrtcStuff?.pc?.getStats(null)
1885
- .then(r => ({handle: participant, stats: r}))
1886
- .catch(e => Promise.reject({handle: participant, error: e}))
1887
- }
1888
- }))
1876
+ // _parseVideoStats(participantsStats) {
1877
+ // participantsStats.forEach(sourceStats => {
1878
+ // sourceStats.forEach(participantStats => {
1879
+ // if(participantStats !== null && participantStats?.handle?.handleId !== this.handleId) {
1880
+ // let handle = this._getHandle(participantStats.handle.handleId);
1881
+ // if(handle) {
1882
+ //
1883
+ // if(!handle.webrtcStuff.stats[participantStats.mid]) {
1884
+ // handle.webrtcStuff.stats[participantStats.mid] = [];
1885
+ // }
1886
+ //
1887
+ // const stats = {
1888
+ // framesPerSecond: null,
1889
+ // framesDropped: null,
1890
+ // totalFreezesDuration: null,
1891
+ // freezeDurationSinceLast: null,
1892
+ // freezeCount: null,
1893
+ // jitter: null,
1894
+ // packetsLost: null,
1895
+ // nackCount: null,
1896
+ // roundTripTime: null,
1897
+ // width: null,
1898
+ // height: null,
1899
+ // networkType: null,
1900
+ // powerEfficientDecoder: null,
1901
+ // };
1902
+ // participantStats.stats.forEach(report => {
1903
+ //
1904
+ // const simulcastConfigForSource = this._findSimulcastConfig(participantStats.source, this.simulcastSettings);
1905
+ // const defaultSelectedSubstream = handle.webrtcStuff?.overriddenSimulcastMode[participantStats.mid]?.defaultSubstream ?? simulcastConfigForSource?.defaultSubstream;
1906
+ // const simulcastMode = handle.webrtcStuff?.overriddenSimulcastMode[participantStats.mid]?.mode ?? simulcastConfigForSource?.mode ;
1907
+ //
1908
+ // if(report.type === 'inbound-rtp' && report.kind === 'video') {
1909
+ // stats.framesPerSecond = report.framesPerSecond || 0;
1910
+ // stats.framesDropped = report.framesDropped || 0;
1911
+ // stats.totalFreezesDuration = report.totalFreezesDuration || 0;
1912
+ // stats.freezeDurationSinceLast = (report.totalFreezesDuration || 0) - (handle.webrtcStuff.stats?.[participantStats.mid]?.[handle.webrtcStuff.stats?.[participantStats.mid]?.length - 1]?.totalFreezesDuration || 0);
1913
+ // stats.freezeCount = report.freezeCount || 0;
1914
+ // stats.freezeCountSinceLast = (report.freezeCount || 0) - (handle.webrtcStuff.stats?.[participantStats.mid]?.[handle.webrtcStuff.stats?.[participantStats.mid]?.length - 1]?.freezeCount || 0);
1915
+ // stats.jitter = report.jitter;
1916
+ // stats.packetsLost = report.packetsLost;
1917
+ // stats.nackCount = report.nackCount;
1918
+ // stats.width = report.frameWidth;
1919
+ // stats.height = report.frameHeight;
1920
+ // stats.powerEfficientDecoder = report.powerEfficientDecoder;
1921
+ // }
1922
+ // if(report.type === 'candidate-pair') {
1923
+ // stats.roundTripTime = report.currentRoundTripTime;
1924
+ // }
1925
+ // if(report.type === 'local-candidate') {
1926
+ // stats.networkType = report.networkType;
1927
+ // }
1928
+ //
1929
+ // stats.selectedSubstream = handle.webrtcStuff.selectedSubstream[participantStats.mid];
1930
+ // stats.desiredSubstream = defaultSelectedSubstream;
1931
+ // stats.simulcastMode = simulcastMode;
1932
+ //
1933
+ // });
1934
+ //
1935
+ // // pushing stats into handle stats array but keeping only 6 last stats
1936
+ // handle.webrtcStuff.stats[participantStats.mid].push(stats);
1937
+ // if(handle.webrtcStuff.stats[participantStats.mid].length > this._statsMaxLength) {
1938
+ // handle.webrtcStuff.stats[participantStats.mid].shift();
1939
+ // }
1940
+ //
1941
+ // this.emit('rtcStats', {handleId: participantStats.handle.handleId, stats, userId: decodeJanusDisplay(participantStats.handle.userId)?.userId, source: participantStats.source, mid: participantStats.mid});
1942
+ // }
1943
+ // }
1944
+ // });
1945
+ // })
1946
+ //
1947
+ // }
1889
1948
 
1890
1949
 
1891
- }
1950
+ _getStats(type = null) {
1951
+ return this._participants.reduce((promise, participant) => {
1952
+ return promise.then(results => {
1953
+ let mediaTrack = [];
1954
+ if (type === 'video') {
1955
+ mediaTrack = participant?.webrtcStuff?.stream?.getVideoTracks() || [];
1956
+ } else if (type === 'audio') {
1957
+ mediaTrack = participant?.webrtcStuff?.stream?.getAudioTracks() || [];
1958
+ }
1959
+
1960
+ if (type !== null) {
1961
+ const transceivers = participant?.webrtcStuff?.pc?.getTransceivers();
1962
+ return Promise.all(mediaTrack.map(track => {
1963
+ const source = Object.keys(participant.webrtcStuff.streamMap).find(s =>
1964
+ participant.webrtcStuff.streamMap[s].find(t => t === track.id)
1965
+ );
1966
+ const mid = transceivers.find(t =>
1967
+ t.receiver?.track?.id === track.id || t.sender?.track?.id === track.id
1968
+ )?.mid;
1969
+
1970
+ return participant.webrtcStuff.pc.getStats(track)
1971
+ .then(r => ({
1972
+ stats: r,
1973
+ source,
1974
+ mid,
1975
+ handleId: participant.handleId
1976
+ }))
1977
+ .catch(e => Promise.reject({
1978
+ stats: null,
1979
+ error: e,
1980
+ handleId: participant.handleId,
1981
+ source,
1982
+ mid
1983
+ }));
1984
+ })).then(participantResults => [...results, participantResults]);
1985
+ } else {
1986
+ return participant?.webrtcStuff?.pc?.getStats(null)
1987
+ .then(r => [...results, {
1988
+ handleId: participant.handleId,
1989
+ stats: r
1990
+ }])
1991
+ .catch(e => [...results, {
1992
+ handleId: participant.handleId,
1993
+ error: e
1994
+ }]);
1995
+ }
1996
+ });
1997
+ }, Promise.resolve([]));
1998
+ }
1999
+
2000
+ // _getStats(type = null) {
2001
+ // return Promise.all(this._participants.map(participant => {
2002
+ // let mediaTrack = [];
2003
+ // if (type === 'video') {
2004
+ // mediaTrack = participant?.webrtcStuff?.stream?.getVideoTracks() || [];
2005
+ // } else if (type === 'audio') {
2006
+ // mediaTrack = participant?.webrtcStuff?.stream?.getAudioTracks() || [];
2007
+ // }
2008
+ // if(type !== null ) {
2009
+ // const transceivers = participant?.webrtcStuff?.pc?.getTransceivers();
2010
+ // return Promise.all(mediaTrack.map(track => {
2011
+ // const source = Object.keys(participant.webrtcStuff.streamMap).find(s => participant.webrtcStuff.streamMap[s].find(t => t === track.id));
2012
+ // const mid = transceivers.find(t => t.receiver?.track?.id === track.id || t.sender?.track?.id === track.id)?.mid;
2013
+ // return participant.webrtcStuff.pc.getStats(track)
2014
+ // .then(r =>({stats: r, source, mid, handleId: participant.handleId}))
2015
+ // .catch(e => Promise.reject({stats: null, error: e,handleId: participant.handleId, source, mid}))
2016
+ // }))
2017
+ // }
2018
+ // else {
2019
+ // return participant?.webrtcStuff?.pc?.getStats(null)
2020
+ // .then(r => ({handleId: participant.handleId, stats: r}))
2021
+ // .catch(e => Promise.reject({ handleId: participant.handleId, error: e}))
2022
+ // }
2023
+ // }))
2024
+ // }
1892
2025
 
1893
2026
  _resetStats(handleId, mid) {
1894
2027
  let handle = this._getHandle(handleId);