You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

actions.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { _handleParticipantError } from '../base/conference';
  2. import { MEDIA_TYPE, VIDEO_TYPE } from '../base/media';
  3. import {
  4. getLocalVideoTrack,
  5. getTrackByMediaTypeAndParticipant
  6. } from '../base/tracks';
  7. import { SELECT_LARGE_VIDEO_PARTICIPANT } from './actionTypes';
  8. /**
  9. * Signals conference to select a participant.
  10. *
  11. * @returns {Function}
  12. */
  13. export function selectParticipant() {
  14. return (dispatch, getState) => {
  15. const state = getState();
  16. const conference = state['features/base/conference'].conference;
  17. if (conference) {
  18. const largeVideo = state['features/large-video'];
  19. const tracks = state['features/base/tracks'];
  20. const id = largeVideo.participantId;
  21. const videoTrack
  22. = getTrackByMediaTypeAndParticipant(
  23. tracks,
  24. MEDIA_TYPE.VIDEO,
  25. id);
  26. try {
  27. conference.selectParticipant(
  28. videoTrack && videoTrack.videoType === VIDEO_TYPE.CAMERA
  29. ? id
  30. : null);
  31. } catch (err) {
  32. _handleParticipantError(err);
  33. }
  34. }
  35. };
  36. }
  37. /**
  38. * Action to select the participant to be displayed in LargeVideo based on a
  39. * variety of factors: if there is a dominant or pinned speaker, or if there are
  40. * remote tracks, etc.
  41. *
  42. * @returns {Function}
  43. */
  44. export function selectParticipantInLargeVideo() {
  45. return (dispatch, getState) => {
  46. const state = getState();
  47. const participantId = _electParticipantInLargeVideo(state);
  48. const largeVideo = state['features/large-video'];
  49. if (participantId !== largeVideo.participantId) {
  50. dispatch({
  51. type: SELECT_LARGE_VIDEO_PARTICIPANT,
  52. participantId
  53. });
  54. dispatch(selectParticipant());
  55. }
  56. };
  57. }
  58. /**
  59. * Returns the most recent existing video track. It can be local or remote
  60. * video.
  61. *
  62. * @param {Track[]} tracks - All current tracks.
  63. * @private
  64. * @returns {(Track|undefined)}
  65. */
  66. function _electLastVisibleVideo(tracks) {
  67. // First we try to get most recent remote video track.
  68. for (let i = tracks.length - 1; i >= 0; --i) {
  69. const track = tracks[i];
  70. if (!track.local && track.mediaType === MEDIA_TYPE.VIDEO) {
  71. return track;
  72. }
  73. }
  74. // And if no remote video tracks are available, we select the local one.
  75. return getLocalVideoTrack(tracks);
  76. }
  77. /**
  78. * Returns the identifier of the participant who is to be on the stage i.e.
  79. * should be displayed in <tt>LargeVideo</tt>.
  80. *
  81. * @param {Object} state - The Redux state from which the participant to be
  82. * displayed in <tt>LargeVideo</tt> is to be elected.
  83. * @private
  84. * @returns {(string|undefined)}
  85. */
  86. function _electParticipantInLargeVideo(state) {
  87. // First get the pinned participant. If the local participant is pinned,
  88. // he/she will be shown in LargeVideo.
  89. const participants = state['features/base/participants'];
  90. let participant = participants.find(p => p.pinned);
  91. let id = participant ? participant.id : undefined;
  92. if (!id) {
  93. // No participant is pinned so get the dominant speaker. But the local
  94. // participant won't be displayed in LargeVideo even if he/she is the
  95. // dominant speaker.
  96. participant = participants.find(p => p.dominantSpeaker && !p.local);
  97. if (participant) {
  98. id = participant.id;
  99. }
  100. if (!id) {
  101. // There is no dominant speaker so get the participant with the last
  102. // visible video track. This may turn out to be the local
  103. // participant.
  104. const tracks = state['features/base/tracks'];
  105. const videoTrack = _electLastVisibleVideo(tracks);
  106. id = videoTrack && videoTrack.participantId;
  107. }
  108. }
  109. return id;
  110. }