/* @flow */ import React, { Component } from 'react'; /** * The type of the React {@code Component} props of {@link Video}. */ type Props = { /** * CSS classes to add to the video element. */ className: string, /** * The value of the id attribute of the video. Used by the torture tests to * locate video elements. */ id: string, /** * Optional callback to invoke once the video starts playing. */ onVideoPlaying: Function, /** * The JitsiLocalTrack to display. */ videoTrack: ?Object }; /** * Component that renders a video element for a passed in video track. * * @extends Component */ class Video extends Component { _videoElement: ?Object; /** * Default values for {@code Video} component's properties. * * @static */ static defaultProps = { className: '', id: '' }; /** * Initializes a new {@code Video} instance. * * @param {Object} props - The read-only properties with which the new * instance is to be initialized. */ constructor(props: Props) { super(props); /** * The internal reference to the DOM/HTML element intended for * displaying a video. * * @private * @type {HTMLVideoElement} */ this._videoElement = null; // Bind event handlers so they are only bound once for every instance. this._onVideoPlaying = this._onVideoPlaying.bind(this); this._setVideoElement = this._setVideoElement.bind(this); } /** * Invokes the library for rendering the video on initial display. Sets the * volume level to zero to ensure no sound plays. * * @inheritdoc * @returns {void} */ componentDidMount() { if (this._videoElement) { this._videoElement.volume = 0; this._videoElement.onplaying = this._onVideoPlaying; } this._attachTrack(this.props.videoTrack); } /** * Remove any existing associations between the current video track and the * component's video element. * * @inheritdoc * @returns {void} */ componentWillUnmount() { this._detachTrack(this.props.videoTrack); } /** * Updates the video display only if a new track is added. This component's * updating is blackboxed from React to prevent re-rendering of video * element, as the lib uses {@code track.attach(videoElement)} instead. * * @inheritdoc * @returns {boolean} - False is always returned to blackbox this component * from React. */ shouldComponentUpdate(nextProps: Props) { const currentJitsiTrack = this.props.videoTrack && this.props.videoTrack.jitsiTrack; const nextJitsiTrack = nextProps.videoTrack && nextProps.videoTrack.jitsiTrack; if (currentJitsiTrack !== nextJitsiTrack) { this._detachTrack(this.props.videoTrack); this._attachTrack(nextProps.videoTrack); } return false; } /** * Renders the video element. * * @override * @returns {ReactElement} */ render() { return (