<commit_before>/* eslint-disable no-invalid-this */
import Logger from 'jitsi-meet-logger';
import React from 'react';
import YouTube from 'react-youtube';

import { connect } from '../../../base/redux';

import AbstractVideoManager, {
    _mapDispatchToProps,
    _mapStateToProps,
    PLAYBACK_STATES
} from './AbstractVideoManager';

const logger = Logger.getLogger(__filename);

/**
 * Manager of shared video.
 *
 * @returns {void}
 */
class YoutubeVideoManager extends AbstractVideoManager<Props> {
    /**
     * Initializes a new YoutubeVideoManager instance.
     *
     * @param {Object} props - This component's props.
     *
     * @returns {void}
     */
    constructor(props) {
        super(props);

        this.isPlayerAPILoaded = false;
    }

    /**
     * Indicates the playback state of the video.
     *
     * @returns {string}
     */
    getPlaybackState() {
        let state;

        if (!this.player) {
            return;
        }

        const playerState = this.player.getPlayerState();

        if (playerState === YouTube.PlayerState.PLAYING) {
            state = PLAYBACK_STATES.PLAYING;
        }

        if (playerState === YouTube.PlayerState.PAUSED) {
            state = PLAYBACK_STATES.PAUSED;
        }

        return state;
    }

    /**
     * Indicates whether the video is muted.
     *
     * @returns {boolean}
     */
    isMuted() {
        return this.player?.isMuted();
    }

    /**
     * Retrieves current volume.
     *
     * @returns {number}
     */
    getVolume() {
        return this.player?.getVolume();
    }

    /**
     * Sets player volume.
     *
     * @param {number} value - The volume.
     *
     * @returns {void}
     */
    setVolume(value) {
        return this.player?.setVolume(value);
    }

    /**
     * Retrieves current time.
     *
     * @returns {number}
     */
    getTime() {
        return this.player?.getCurrentTime();
    }

    /**
     * Seeks video to provided time.
     *
     * @param {number} time - The time to seek to.
     *
     * @returns {void}
     */
    seek(time) {
        return this.player?.seekTo(time);
    }

    /**
     * Plays video.
     *
     * @returns {void}
     */
    play() {
        return this.player?.playVideo();
    }

    /**
     * Pauses video.
     *
     * @returns {void}
     */
    pause() {
        return this.player?.pauseVideo();
    }

    /**
     * Mutes video.
     *
     * @returns {void}
     */
    mute() {
        return this.player?.mute();
    }

    /**
     * Unmutes video.
     *
     * @returns {void}
     */
    unMute() {
        return this.player?.unMute();
    }

    /**
     * Disposes of the current video player.
     *
     * @returns {void}
     */
    dispose() {
        if (this.player) {
            this.player.destroy();
            this.player = null;
        }

        if (this.errorInPlayer) {
            this.errorInPlayer.destroy();
            this.errorInPlayer = null;
        }
    }

    /**
     * Fired on play state toggle.
     *
     * @param {Object} event - The yt player stateChange event.
     *
     * @returns {void}
     */
    onPlayerStateChange = event => {
        if (event.data === YouTube.PlayerState.PLAYING) {
            this.onPlay();
        } else if (event.data === YouTube.PlayerState.PAUSED) {
            this.onPause();
        }
    }

    /**
     * Fired when youtube player is ready.
     *
     * @param {Object} event - The youtube player event.
     *
     * @returns {void}
     */
    onPlayerReady = event => {
        const { _isOwner } = this.props;

        this.player = event.target;

        this.player.addEventListener('onVolumeChange', () => {
            this.onVolumeChange();
        });

        if (_isOwner) {
            this.player.addEventListener('onVideoProgress', this.throttledFireUpdateSharedVideoEvent);
        }

        this.play();
    };

    /**
     * Fired when youtube player throws an error.
     *<commit_msg>fix: Fixes playing muted youtube video.<commit_after>/* eslint-disable no-invalid-this */
import Logger from 'jitsi-meet-logger';
import React from 'react';
import YouTube from 'react-youtube';

import { connect } from '../../../base/redux';

import AbstractVideoManager, {
    _mapDispatchToProps,
    _mapStateToProps,
    PLAYBACK_STATES
} from './AbstractVideoManager';

const logger = Logger.getLogger(__filename);

/**
 * Manager of shared video.
 *
 * @returns {void}
 */
class YoutubeVideoManager extends AbstractVideoManager<Props> {
    /**
     * Initializes a new YoutubeVideoManager instance.
     *
     * @param {Object} props - This component's props.
     *
     * @returns {void}
     */
    constructor(props) {
        super(props);

        this.isPlayerAPILoaded = false;
    }

    /**
     * Indicates the playback state of the video.
     *
     * @returns {string}
     */
    getPlaybackState() {
        let state;

        if (!this.player) {
            return;
        }

        const playerState = this.player.getPlayerState();

        if (playerState === YouTube.PlayerState.PLAYING) {
            state = PLAYBACK_STATES.PLAYING;
        }

        if (playerState === YouTube.PlayerState.PAUSED) {
            state = PLAYBACK_STATES.PAUSED;
        }

        return state;
    }

    /**
     * Indicates whether the video is muted.
     *
     * @returns {boolean}
     */
    isMuted() {
        return this.player?.isMuted();
    }

    /**
     * Retrieves current volume.
     *
     * @returns {number}
     */
    getVolume() {
        return this.player?.getVolume();
    }

    /**
     * Sets player volume.
     *
     * @param {number} value - The volume.
     *
     * @returns {void}
     */
    setVolume(value) {
        return this.player?.setVolume(value);
    }

    /**
     * Retrieves current time.
     *
     * @returns {number}
     */
    getTime() {
        return this.player?.getCurrentTime();
    }

    /**
     * Seeks video to provided time.
     *
     * @param {number} time - The time to seek to.
     *
     * @returns {void}
     */
    seek(time) {
        return this.player?.seekTo(time);
    }

    /**
     * Plays video.
     *
     * @returns {void}
     */
    play() {
        return this.player?.playVideo();
    }

    /**
     * Pauses video.
     *
     * @returns {void}
     */
    pause() {
        return this.player?.pauseVideo();
    }

    /**
     * Mutes video.
     *
     * @returns {void}
     */
    mute() {
        return this.player?.mute();
    }

    /**
     * Unmutes video.
     *
     * @returns {void}
     */
    unMute() {
        return this.player?.unMute();
    }

    /**
     * Disposes of the current video player.
     *
     * @returns {void}
     */
    dispose() {
        if (this.player) {
            this.player.destroy();
            this.player = null;
        }

        if (this.errorInPlayer) {
            this.errorInPlayer.destroy();
            this.errorInPlayer = null;
        }
    }

    /**
     * Fired on play state toggle.
     *
     * @param {Object} event - The yt player stateChange event.
     *
     * @returns {void}
     */
    onPlayerStateChange = event => {
        if (event.data === YouTube.PlayerState.PLAYING) {
            this.onPlay();
        } else if (event.data === YouTube.PlayerState.PAUSED) {
            this.onPause();
        }
    }

    /**
     * Fired when youtube player is ready.
     *
     * @param {Object} event - The youtube player event.
     *
     * @returns {void}
     */
    onPlayerReady = event => {
        const { _isOwner } = this.props;

        this.player = event.target;

        this.player.addEventListener('onVolumeChange', () => {
            this.onVolumeChange();
        });

        if (_isOwner) {
            this.player.addEventListener('onVideoProgress', this.throttledFireUpdateSharedVideoEvent);
        }

        this.play();

        // sometimes youtube can get muted state from previous videos played in the browser
        // and as we are disabling controls we want to unmute it
        if (this.isMuted()) {
            this.unMute();
        }
    };

    /**
     * Fired when youtube player throws an error.
     *
{'fraction_non_alphanumeric': 0.13160772876412688, 'fraction_numerical': 0.0, 'mean_word_length': 1.6454516232722598, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7391582', 'n_tokens_mistral': 2531, 'n_tokens_neox': 2446, 'n_words': 538}