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

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