您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

RTCStats.ts 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* eslint-disable lines-around-comment */
  2. import {
  3. PC_CON_STATE_CHANGE,
  4. PC_STATE_CONNECTED,
  5. PC_STATE_FAILED
  6. // @ts-expect-error
  7. } from '@jitsi/rtcstats/events';
  8. import JitsiMeetJS, { RTCStatsEvents } from '../base/lib-jitsi-meet';
  9. import logger from './logger';
  10. import {
  11. DominantSpeakerData,
  12. E2ERTTData,
  13. FaceLandmarksData,
  14. VideoTypeData
  15. } from './types';
  16. /**
  17. * Handle lib-jitsi-meet rtcstats events and send jitsi-meet specific statistics.
  18. */
  19. class RTCStats {
  20. private _connStateEvents: Array<any> = [];
  21. private _initialized = false;
  22. /**
  23. * Handles rtcstats events.
  24. *
  25. * @returns {void}
  26. */
  27. init() {
  28. this._connStateEvents = [];
  29. if (!this._initialized) {
  30. JitsiMeetJS.rtcstats.on(
  31. RTCStatsEvents.RTC_STATS_PC_EVENT,
  32. (pcEvent: any) => this.handleRTCStatsEvent(pcEvent));
  33. this._initialized = true;
  34. }
  35. }
  36. /**
  37. * Send console logs to rtcstats server.
  38. *
  39. * @param {Array<string|any>} logEntries - The log entries to send to the rtcstats server.
  40. * @returns {void}
  41. */
  42. sendLogs(logEntries: Array<string | any>) {
  43. JitsiMeetJS.rtcstats.sendStatsEntry('logs', logEntries);
  44. }
  45. /**
  46. * Send dominant speaker data, the data will be processed by rtcstats-server and saved in the dump file.
  47. *
  48. * @param {Object} dominantSpeakerData - Dominant speaker data to be saved in the rtcstats dump.
  49. * @returns {void}
  50. */
  51. sendDominantSpeakerData(dominantSpeakerData: DominantSpeakerData) {
  52. JitsiMeetJS.rtcstats.sendStatsEntry('dominantSpeaker', dominantSpeakerData);
  53. }
  54. /**
  55. * Send e2e rtt data, the data will be processed by rtcstats-server and saved in the dump file.
  56. *
  57. * @param {Object} e2eRttData - The object that holds the e2e data.
  58. * @returns {void}
  59. */
  60. sendE2ERTTData(e2eRttData: E2ERTTData) {
  61. JitsiMeetJS.rtcstats.sendStatsEntry('e2eRtt', e2eRttData);
  62. }
  63. /**
  64. * Send the timestamp of the start of the conference, the data will be processed by the rtcstats-server
  65. * and saved in the dump file.
  66. *
  67. * @param {Object} timestamp - The object which contains the timestamp.
  68. * @returns {void}
  69. */
  70. sendConferenceTimestamp(timestamp: number) {
  71. JitsiMeetJS.rtcstats.sendStatsEntry('conferenceStartTimestamp', timestamp);
  72. }
  73. /**
  74. * Send videoType data, the data will be processed by rtcstats-server and saved in the dump file.
  75. *
  76. * @param {Object} videoTypeData - The object that holds the videoType data.
  77. * @returns {void}
  78. */
  79. sendVideoTypeData(videoTypeData: VideoTypeData) {
  80. JitsiMeetJS.rtcstats.sendStatsEntry('setVideoType', videoTypeData);
  81. }
  82. /**
  83. * Send face landmarks data, the data will be processed by rtcstats-server and saved in the dump file.
  84. *
  85. * @param {Object} faceLandmarksData - Face landmarks data to be saved in the rtcstats dump.
  86. * @returns {void}
  87. */
  88. sendFaceLandmarksData(faceLandmarksData: FaceLandmarksData) {
  89. JitsiMeetJS.rtcstats.sendStatsEntry('faceLandmarks', faceLandmarksData);
  90. }
  91. /**
  92. * RTCStats client can notify the APP of any PeerConnection related event that occurs.
  93. *
  94. * @param {Object} event - The PeerConnection event.
  95. * @param {string} event.type - The event type.
  96. * @param {Object} event.body - Event body.
  97. * @param {string} event.body.isP2P - PeerConnection type.
  98. * @param {string} event.body.state - PeerConnection state change which triggered the event.
  99. * @returns {void}
  100. */
  101. handleRTCStatsEvent(event: any) {
  102. switch (event.type) {
  103. case PC_CON_STATE_CHANGE: {
  104. const { body: { isP2P = null, state = null } } = event;
  105. this._connStateEvents.push(event.body);
  106. // We only report PC related connection issues. If the rtcstats websocket is not connected at this point
  107. // it usually means that none of our services can be reached i.e. there's problem with the internet
  108. // connection and not necessarily with reaching the JVB (due to a firewall or other reasons).
  109. if (state === PC_STATE_FAILED) {
  110. const connectionType = isP2P ? 'P2P' : 'JVB';
  111. const wasConnected = this._connStateEvents.some((connectionEvent: { isP2P: any; state: string; }) =>
  112. (connectionEvent.isP2P === isP2P) && (connectionEvent.state === PC_STATE_CONNECTED));
  113. logger.info(`${connectionType} PeerConnection failed, previously connected: ${wasConnected}`);
  114. if (typeof APP !== 'undefined') {
  115. APP.API.notifyPeerConnectionFailure(isP2P, wasConnected);
  116. }
  117. }
  118. break;
  119. }
  120. }
  121. }
  122. }
  123. export default new RTCStats();