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

YoutubeVideoManager.js 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* eslint-disable no-invalid-this */
  2. import React from 'react';
  3. import YouTube from 'react-youtube';
  4. import { connect } from '../../../base/redux';
  5. import { PLAYBACK_STATUSES } from '../../constants';
  6. import AbstractVideoManager, {
  7. _mapDispatchToProps,
  8. _mapStateToProps
  9. } from './AbstractVideoManager';
  10. /**
  11. * Manager of shared video.
  12. *
  13. * @returns {void}
  14. */
  15. class YoutubeVideoManager extends AbstractVideoManager<Props> {
  16. /**
  17. * Initializes a new YoutubeVideoManager instance.
  18. *
  19. * @param {Object} props - This component's props.
  20. *
  21. * @returns {void}
  22. */
  23. constructor(props) {
  24. super(props);
  25. this.isPlayerAPILoaded = false;
  26. }
  27. /**
  28. * Indicates the playback state of the video.
  29. *
  30. * @returns {string}
  31. */
  32. getPlaybackStatus() {
  33. let status;
  34. if (!this.player) {
  35. return;
  36. }
  37. const playerState = this.player.getPlayerState();
  38. if (playerState === YouTube.PlayerState.PLAYING) {
  39. status = PLAYBACK_STATUSES.PLAYING;
  40. }
  41. if (playerState === YouTube.PlayerState.PAUSED) {
  42. status = PLAYBACK_STATUSES.PAUSED;
  43. }
  44. return status;
  45. }
  46. /**
  47. * Indicates whether the video is muted.
  48. *
  49. * @returns {boolean}
  50. */
  51. isMuted() {
  52. return this.player?.isMuted();
  53. }
  54. /**
  55. * Retrieves current volume.
  56. *
  57. * @returns {number}
  58. */
  59. getVolume() {
  60. return this.player?.getVolume();
  61. }
  62. /**
  63. * Retrieves current time.
  64. *
  65. * @returns {number}
  66. */
  67. getTime() {
  68. return this.player?.getCurrentTime();
  69. }
  70. /**
  71. * Seeks video to provided time.
  72. *
  73. * @param {number} time - The time to seek to.
  74. *
  75. * @returns {void}
  76. */
  77. seek(time) {
  78. return this.player?.seekTo(time);
  79. }
  80. /**
  81. * Plays video.
  82. *
  83. * @returns {void}
  84. */
  85. play() {
  86. return this.player?.playVideo();
  87. }
  88. /**
  89. * Pauses video.
  90. *
  91. * @returns {void}
  92. */
  93. pause() {
  94. return this.player?.pauseVideo();
  95. }
  96. /**
  97. * Mutes video.
  98. *
  99. * @returns {void}
  100. */
  101. mute() {
  102. return this.player?.mute();
  103. }
  104. /**
  105. * Unmutes video.
  106. *
  107. * @returns {void}
  108. */
  109. unMute() {
  110. return this.player?.unMute();
  111. }
  112. /**
  113. * Disposes of the current video player.
  114. *
  115. * @returns {void}
  116. */
  117. dispose() {
  118. if (this.player) {
  119. this.player.destroy();
  120. this.player = null;
  121. }
  122. }
  123. /**
  124. * Fired on play state toggle.
  125. *
  126. * @param {Object} event - The yt player stateChange event.
  127. *
  128. * @returns {void}
  129. */
  130. onPlayerStateChange = event => {
  131. if (event.data === YouTube.PlayerState.PLAYING) {
  132. this.onPlay();
  133. } else if (event.data === YouTube.PlayerState.PAUSED) {
  134. this.onPause();
  135. }
  136. }
  137. /**
  138. * Fired when youtube player is ready.
  139. *
  140. * @param {Object} event - The youtube player event.
  141. *
  142. * @returns {void}
  143. */
  144. onPlayerReady = event => {
  145. const { _isOwner } = this.props;
  146. this.player = event.target;
  147. this.player.addEventListener('onVolumeChange', () => {
  148. this.onVolumeChange();
  149. });
  150. if (_isOwner) {
  151. this.player.addEventListener('onVideoProgress', this.throttledFireUpdateSharedVideoEvent);
  152. }
  153. this.play();
  154. // sometimes youtube can get muted state from previous videos played in the browser
  155. // and as we are disabling controls we want to unmute it
  156. if (this.isMuted()) {
  157. this.unMute();
  158. }
  159. };
  160. getPlayerOptions = () => {
  161. const { _isOwner, videoId } = this.props;
  162. const showControls = _isOwner ? 1 : 0;
  163. const options = {
  164. id: 'sharedVideoPlayer',
  165. opts: {
  166. height: '100%',
  167. width: '100%',
  168. playerVars: {
  169. 'origin': location.origin,
  170. 'fs': '0',
  171. 'autoplay': 0,
  172. 'controls': showControls,
  173. 'rel': 0
  174. }
  175. },
  176. onError: () => this.onError(),
  177. onReady: this.onPlayerReady,
  178. onStateChange: this.onPlayerStateChange,
  179. videoId
  180. };
  181. return options;
  182. }
  183. /**
  184. * Implements React Component's render.
  185. *
  186. * @inheritdoc
  187. */
  188. render() {
  189. return (<YouTube
  190. { ...this.getPlayerOptions() } />);
  191. }
  192. }
  193. export default connect(_mapStateToProps, _mapDispatchToProps)(YoutubeVideoManager);