123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- import React, { Component } from 'react';
-
- import { translate } from '../../base/i18n';
-
- const VIDEO_MUTE_CLASS = 'video-muted';
-
- /**
- * React component for displaying video. This component defers to lib-jitsi-meet
- * logic for rendering the video.
- *
- * @extends Component
- */
- class VideoInputPreview extends Component {
- /**
- * VideoInputPreview component's property types.
- *
- * @static
- */
- static propTypes = {
- /**
- * Invoked to obtain translated strings.
- */
- t: React.PropTypes.func,
-
- /*
- * The JitsiLocalTrack to display.
- */
- track: React.PropTypes.object
- }
-
- /**
- * Initializes a new VideoInputPreview instance.
- *
- * @param {Object} props - The read-only React Component props with which
- * the new instance is to be initialized.
- */
- constructor(props) {
- super(props);
-
- this._rootElement = null;
- this._videoElement = null;
-
- this._setRootElement = this._setRootElement.bind(this);
- this._setVideoElement = this._setVideoElement.bind(this);
- }
-
- /**
- * Invokes the library for rendering the video on initial display.
- *
- * @inheritdoc
- * @returns {void}
- */
- componentDidMount() {
- this._attachTrack(this.props.track);
- }
-
- /**
- * Remove any existing associations between the current previewed track and
- * the component's video element.
- *
- * @inheritdoc
- * @returns {void}
- */
- componentWillUnmount() {
- this._detachTrack(this.props.track);
- }
-
- /**
- * Implements React's {@link Component#render()}.
- *
- * @inheritdoc
- * @returns {ReactElement}
- */
- render() {
- return (
- <div
- className = 'video-input-preview'
- ref = { this._setRootElement }>
- <video
- autoPlay = { true }
- className = 'video-input-preview-display flipVideoX'
- ref = { this._setVideoElement } />
- <div className = 'video-input-preview-muted'>
- { this.props.t('videothumbnail.muted') }
- </div>
- </div>
- );
- }
-
- /**
- * Only update when the deviceId has changed. This component is somewhat
- * black-boxed from React's rendering so lib-jitsi-meet can instead handle
- * updating of the video preview, which takes browser differences into
- * consideration. For example, temasys's video object must be visible to
- * update the displayed track, but React's re-rendering could potentially
- * remove the video object from the page.
- *
- * @inheritdoc
- * @returns {void}
- */
- shouldComponentUpdate(nextProps) {
- if (nextProps.track !== this.props.track) {
- this._detachTrack(this.props.track);
- this._attachTrack(nextProps.track);
- }
-
- return false;
- }
-
- /**
- * Calls into the passed in track to associate the track with the
- * component's video element and render video. Also sets the instance
- * variable for the video element as the element the track attached to,
- * which could be an Object if on a temasys supported browser.
- *
- * @param {JitsiLocalTrack} track - The library's track model which will be
- * displayed.
- * @private
- * @returns {void}
- */
- _attachTrack(track) {
- if (!track) {
- return;
- }
-
- // Do not attempt to display a preview if the track is muted, as the
- // library will simply return a falsy value for the element anyway.
- if (track.isMuted()) {
- this._showMuteOverlay(true);
- } else {
- this._showMuteOverlay(false);
-
- const updatedVideoElement = track.attach(this._videoElement);
-
- this._setVideoElement(updatedVideoElement);
- }
- }
-
- /**
- * Removes the association to the component's video element from the passed
- * in JitsiLocalTrack to stop the track from rendering. With temasys, the
- * video element must still be visible for detaching to complete.
- *
- * @param {JitsiLocalTrack} track - The library's track model which needs
- * to stop previewing in the video element.
- * @private
- * @returns {void}
- */
- _detachTrack(track) {
- // Detach the video element from the track only if it has already
- // been attached. This accounts for a special case with temasys
- // where if detach is being called before attach, the video
- // element is converted to Object without updating this
- // component's reference to the video element.
- if (this._videoElement
- && track
- && track.containers.includes(this._videoElement)) {
- track.detach(this._videoElement);
- }
- }
-
- /**
- * Sets the component's root element.
- *
- * @param {Object} element - The highest DOM element in the component.
- * @private
- * @returns {void}
- */
- _setRootElement(element) {
- this._rootElement = element;
- }
-
- /**
- * Sets an instance variable for the component's video element so it can be
- * referenced later for attaching and detaching a JitsiLocalTrack.
- *
- * @param {Object} element - DOM element for the component's video display.
- * @private
- * @returns {void}
- */
- _setVideoElement(element) {
- this._videoElement = element;
- }
-
- /**
- * Adds or removes a class to the component's parent node to indicate mute
- * status.
- *
- * @param {boolean} shouldShow - True if the mute class should be added and
- * false if the class should be removed.
- * @private
- * @returns {void}
- */
- _showMuteOverlay(shouldShow) {
- if (shouldShow) {
- this._rootElement.classList.add(VIDEO_MUTE_CLASS);
- } else {
- this._rootElement.classList.remove(VIDEO_MUTE_CLASS);
- }
- }
- }
-
- export default translate(VideoInputPreview);
|