2020-09-21 23:54:45 +00:00
|
|
|
// @flow
|
|
|
|
|
|
|
|
import type { Dispatch } from 'redux';
|
|
|
|
|
|
|
|
import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
|
2020-09-22 19:45:51 +00:00
|
|
|
import { MEDIA_TYPE } from '../base/media';
|
|
|
|
import { getTrackByMediaTypeAndParticipant } from '../base/tracks';
|
2020-09-21 23:54:45 +00:00
|
|
|
|
|
|
|
export * from './actions.any';
|
|
|
|
|
2020-09-22 19:45:51 +00:00
|
|
|
/**
|
|
|
|
* Captures a screenshot of the video displayed on the large video.
|
|
|
|
*
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function captureLargeVideoScreenshot() {
|
|
|
|
return (dispatch: Dispatch<any>, getState: Function): Promise<string> => {
|
|
|
|
const state = getState();
|
|
|
|
const largeVideo = state['features/large-video'];
|
2020-10-21 20:08:05 +00:00
|
|
|
const promise = Promise.resolve();
|
2020-09-22 19:45:51 +00:00
|
|
|
|
|
|
|
if (!largeVideo) {
|
2020-10-21 20:08:05 +00:00
|
|
|
return promise;
|
2020-09-22 19:45:51 +00:00
|
|
|
}
|
|
|
|
const tracks = state['features/base/tracks'];
|
2020-10-21 20:08:05 +00:00
|
|
|
const participantTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, largeVideo.participantId);
|
|
|
|
|
|
|
|
// Participants that join the call video muted do not have a jitsiTrack attached.
|
|
|
|
if (!(participantTrack && participantTrack.jitsiTrack)) {
|
|
|
|
return promise;
|
|
|
|
}
|
|
|
|
const videoStream = participantTrack.jitsiTrack.getOriginalStream();
|
|
|
|
|
|
|
|
if (!videoStream) {
|
|
|
|
return promise;
|
|
|
|
}
|
2020-09-22 19:45:51 +00:00
|
|
|
|
|
|
|
// Get the video element for the large video, cast HTMLElement to HTMLVideoElement to make flow happy.
|
|
|
|
/* eslint-disable-next-line no-extra-parens*/
|
|
|
|
const videoElement = ((document.getElementById('largeVideo'): any): HTMLVideoElement);
|
|
|
|
|
|
|
|
if (!videoElement) {
|
2020-10-21 20:08:05 +00:00
|
|
|
return promise;
|
2020-09-22 19:45:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create a HTML canvas and draw video on to the canvas.
|
|
|
|
const [ track ] = videoStream.getVideoTracks();
|
|
|
|
const { height, width } = track.getSettings() ?? track.getConstraints();
|
|
|
|
const canvasElement = document.createElement('canvas');
|
|
|
|
const ctx = canvasElement.getContext('2d');
|
|
|
|
|
|
|
|
canvasElement.style.display = 'none';
|
|
|
|
canvasElement.height = parseInt(height, 10);
|
|
|
|
canvasElement.width = parseInt(width, 10);
|
|
|
|
ctx.drawImage(videoElement, 0, 0);
|
|
|
|
const dataURL = canvasElement.toDataURL('image/png', 1.0);
|
|
|
|
|
|
|
|
// Cleanup.
|
|
|
|
ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);
|
|
|
|
canvasElement.remove();
|
|
|
|
|
|
|
|
return Promise.resolve(dataURL);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-09-21 23:54:45 +00:00
|
|
|
/**
|
|
|
|
* Resizes the large video container based on the dimensions provided.
|
|
|
|
*
|
|
|
|
* @param {number} width - Width that needs to be applied on the large video container.
|
|
|
|
* @param {number} height - Height that needs to be applied on the large video container.
|
|
|
|
* @returns {Function}
|
|
|
|
*/
|
|
|
|
export function resizeLargeVideo(width: number, height: number) {
|
|
|
|
return (dispatch: Dispatch<any>, getState: Function) => {
|
|
|
|
const state = getState();
|
|
|
|
const largeVideo = state['features/large-video'];
|
|
|
|
|
|
|
|
if (largeVideo) {
|
|
|
|
const largeVideoContainer = VideoLayout.getLargeVideo();
|
|
|
|
|
|
|
|
largeVideoContainer.updateContainerSize(width, height);
|
|
|
|
largeVideoContainer.resize();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|