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

Video.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* @flow */
  2. import React, { Component } from 'react';
  3. /**
  4. * The type of the React {@code Component} props of {@link Video}.
  5. */
  6. type Props = {
  7. /**
  8. * CSS classes to add to the video element.
  9. */
  10. className: string,
  11. /**
  12. * The value of the id attribute of the video. Used by the torture tests to
  13. * locate video elements.
  14. */
  15. id: string,
  16. /**
  17. * Optional callback to invoke once the video starts playing.
  18. */
  19. onVideoPlaying: Function,
  20. /**
  21. * The JitsiLocalTrack to display.
  22. */
  23. videoTrack: ?Object
  24. };
  25. /**
  26. * Component that renders a video element for a passed in video track.
  27. *
  28. * @extends Component
  29. */
  30. class Video extends Component<Props> {
  31. _videoElement: ?Object;
  32. /**
  33. * Default values for {@code Video} component's properties.
  34. *
  35. * @static
  36. */
  37. static defaultProps = {
  38. className: '',
  39. id: ''
  40. };
  41. /**
  42. * Initializes a new {@code Video} instance.
  43. *
  44. * @param {Object} props - The read-only properties with which the new
  45. * instance is to be initialized.
  46. */
  47. constructor(props: Props) {
  48. super(props);
  49. /**
  50. * The internal reference to the DOM/HTML element intended for
  51. * displaying a video.
  52. *
  53. * @private
  54. * @type {HTMLVideoElement}
  55. */
  56. this._videoElement = null;
  57. // Bind event handlers so they are only bound once for every instance.
  58. this._onVideoPlaying = this._onVideoPlaying.bind(this);
  59. this._setVideoElement = this._setVideoElement.bind(this);
  60. }
  61. /**
  62. * Invokes the library for rendering the video on initial display. Sets the
  63. * volume level to zero to ensure no sound plays.
  64. *
  65. * @inheritdoc
  66. * @returns {void}
  67. */
  68. componentDidMount() {
  69. if (this._videoElement) {
  70. this._videoElement.volume = 0;
  71. this._videoElement.onplaying = this._onVideoPlaying;
  72. }
  73. this._attachTrack(this.props.videoTrack);
  74. }
  75. /**
  76. * Remove any existing associations between the current video track and the
  77. * component's video element.
  78. *
  79. * @inheritdoc
  80. * @returns {void}
  81. */
  82. componentWillUnmount() {
  83. this._detachTrack(this.props.videoTrack);
  84. }
  85. /**
  86. * Updates the video display only if a new track is added. This component's
  87. * updating is blackboxed from React to prevent re-rendering of video
  88. * element, as the lib uses {@code track.attach(videoElement)} instead.
  89. *
  90. * @inheritdoc
  91. * @returns {boolean} - False is always returned to blackbox this component
  92. * from React.
  93. */
  94. shouldComponentUpdate(nextProps: Props) {
  95. const currentJitsiTrack = this.props.videoTrack
  96. && this.props.videoTrack.jitsiTrack;
  97. const nextJitsiTrack = nextProps.videoTrack
  98. && nextProps.videoTrack.jitsiTrack;
  99. if (currentJitsiTrack !== nextJitsiTrack) {
  100. this._detachTrack(this.props.videoTrack);
  101. this._attachTrack(nextProps.videoTrack);
  102. }
  103. return false;
  104. }
  105. /**
  106. * Renders the video element.
  107. *
  108. * @override
  109. * @returns {ReactElement}
  110. */
  111. render() {
  112. return (
  113. <video
  114. autoPlay = { true }
  115. className = { this.props.className }
  116. id = { this.props.id }
  117. ref = { this._setVideoElement } />
  118. );
  119. }
  120. /**
  121. * Calls into the passed in track to associate the track with the
  122. * component's video element and render video.
  123. *
  124. * @param {Object} videoTrack - The redux representation of the
  125. * {@code JitsiLocalTrack}.
  126. * @private
  127. * @returns {void}
  128. */
  129. _attachTrack(videoTrack) {
  130. if (!videoTrack || !videoTrack.jitsiTrack) {
  131. return;
  132. }
  133. videoTrack.jitsiTrack.attach(this._videoElement);
  134. }
  135. /**
  136. * Removes the association to the component's video element from the passed
  137. * in redux representation of jitsi video track to stop the track from
  138. * rendering.
  139. *
  140. * @param {Object} videoTrack - The redux representation of the
  141. * {@code JitsiLocalTrack}.
  142. * @private
  143. * @returns {void}
  144. */
  145. _detachTrack(videoTrack) {
  146. if (this._videoElement && videoTrack && videoTrack.jitsiTrack) {
  147. videoTrack.jitsiTrack.detach(this._videoElement);
  148. }
  149. }
  150. _onVideoPlaying: () => void;
  151. /**
  152. * Invokes the onvideoplaying callback if defined.
  153. *
  154. * @private
  155. * @returns {void}
  156. */
  157. _onVideoPlaying() {
  158. if (this.props.onVideoPlaying) {
  159. this.props.onVideoPlaying();
  160. }
  161. }
  162. _setVideoElement: () => void;
  163. /**
  164. * Sets an instance variable for the component's video element so it can be
  165. * referenced later for attaching and detaching a JitsiLocalTrack.
  166. *
  167. * @param {Object} element - DOM element for the component's video display.
  168. * @private
  169. * @returns {void}
  170. */
  171. _setVideoElement(element) {
  172. this._videoElement = element;
  173. }
  174. }
  175. export default Video;