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

Video.js 5.2KB

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