Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

SendVideoController.js 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import * as JitsiConferenceEvents from '../../JitsiConferenceEvents';
  2. import RTCEvents from '../../service/RTC/RTCEvents';
  3. import MediaSessionEvents from '../xmpp/MediaSessionEvents';
  4. /**
  5. * The class manages send video constraints across media sessions({@link JingleSessionPC}) which belong to
  6. * {@link JitsiConference}. It finds the lowest common value, between the local user's send preference and
  7. * the remote party's receive preference. Also this module will consider only the active session's receive value,
  8. * because local tracks are shared and while JVB may have no preference, the remote p2p may have and they may be totally
  9. * different.
  10. */
  11. export class SendVideoController {
  12. /**
  13. * Creates new instance for a given conference.
  14. *
  15. * @param {JitsiConference} conference - the conference instance for which the new instance will be managing
  16. * the send video quality constraints.
  17. * @param {RTC} rtc - the rtc instance that is responsible for sending the messages on the bridge channel.
  18. */
  19. constructor(conference, rtc) {
  20. this.conference = conference;
  21. this.layerSuspensionEnabled = conference.options?.config?.enableLayerSuspension;
  22. this.rtc = rtc;
  23. this.conference.on(
  24. JitsiConferenceEvents._MEDIA_SESSION_STARTED,
  25. session => this._onMediaSessionStarted(session));
  26. this.conference.on(
  27. JitsiConferenceEvents._MEDIA_SESSION_ACTIVE_CHANGED,
  28. () => this._propagateSendMaxFrameHeight());
  29. this.rtc.on(
  30. RTCEvents.SENDER_VIDEO_CONSTRAINTS_CHANGED,
  31. videoConstraints => {
  32. this._senderVideoConstraints = videoConstraints;
  33. this._propagateSendMaxFrameHeight(videoConstraints);
  34. });
  35. }
  36. /**
  37. * Handles the {@link JitsiConferenceEvents.MEDIA_SESSION_STARTED}, that is when the conference creates new media
  38. * session. It doesn't mean it's already active though. For example the JVB connection may be created after
  39. * the conference has entered the p2p mode already.
  40. *
  41. * @param {JingleSessionPC} mediaSession - the started media session.
  42. * @private
  43. */
  44. _onMediaSessionStarted(mediaSession) {
  45. mediaSession.addListener(
  46. MediaSessionEvents.REMOTE_VIDEO_CONSTRAINTS_CHANGED,
  47. session => {
  48. if (session === this.conference._getActiveMediaSession()) {
  49. this._propagateSendMaxFrameHeight();
  50. }
  51. });
  52. // Set the degradation preference on the local video track.
  53. mediaSession.setSenderVideoDegradationPreference();
  54. // Set the max bitrates on video sender if they are specified in config.js videoQuality settings.
  55. mediaSession.setSenderMaxBitrates();
  56. }
  57. /**
  58. * Figures out the send video constraint as specified by {@link selectSendMaxFrameHeight} and sets it on all media
  59. * sessions for the reasons mentioned in this class description.
  60. *
  61. * @returns {Promise<void[]>}
  62. * @private
  63. */
  64. _propagateSendMaxFrameHeight() {
  65. const sendMaxFrameHeight = this.selectSendMaxFrameHeight();
  66. const promises = [];
  67. if (sendMaxFrameHeight >= 0) {
  68. for (const session of this.conference._getMediaSessions()) {
  69. promises.push(session.setSenderVideoConstraint(sendMaxFrameHeight));
  70. }
  71. }
  72. return Promise.all(promises);
  73. }
  74. /**
  75. * Selects the lowest common value for the local video send constraint by looking at local user's preference and
  76. * the active media session's receive preference set by the remote party.
  77. *
  78. * @returns {number|undefined}
  79. */
  80. selectSendMaxFrameHeight() {
  81. const activeMediaSession = this.conference._getActiveMediaSession();
  82. const remoteRecvMaxFrameHeight = activeMediaSession
  83. ? activeMediaSession.isP2P
  84. ? activeMediaSession.getRemoteRecvMaxFrameHeight()
  85. : this.layerSuspensionEnabled ? this._senderVideoConstraints?.idealHeight : undefined
  86. : undefined;
  87. if (this.preferredSendMaxFrameHeight >= 0 && remoteRecvMaxFrameHeight >= 0) {
  88. return Math.min(this.preferredSendMaxFrameHeight, remoteRecvMaxFrameHeight);
  89. } else if (remoteRecvMaxFrameHeight >= 0) {
  90. return remoteRecvMaxFrameHeight;
  91. }
  92. return this.preferredSendMaxFrameHeight;
  93. }
  94. /**
  95. * Sets local preference for max send video frame height.
  96. *
  97. * @param {number} maxFrameHeight - the new value to set.
  98. * @returns {Promise<void[]>} - resolved when the operation is complete.
  99. */
  100. setPreferredSendMaxFrameHeight(maxFrameHeight) {
  101. this.preferredSendMaxFrameHeight = maxFrameHeight;
  102. return this._propagateSendMaxFrameHeight();
  103. }
  104. }