2019-05-21 23:18:11 +02:00
|
|
|
// @flow
|
|
|
|
import React, { useRef } from 'react';
|
|
|
|
import { Modal } from 'modal/modal';
|
2019-12-02 18:30:08 +01:00
|
|
|
import { formatFileSystemPath } from 'util/url';
|
2022-01-13 06:10:55 +01:00
|
|
|
import { THUMBNAIL_CDN_SIZE_LIMIT_BYTES } from 'config';
|
2022-01-13 05:48:32 +01:00
|
|
|
|
2019-05-21 23:18:11 +02:00
|
|
|
type Props = {
|
2022-01-13 05:48:32 +01:00
|
|
|
upload: (WebFile) => void,
|
2019-05-21 23:18:11 +02:00
|
|
|
filePath: string,
|
|
|
|
closeModal: () => void,
|
|
|
|
showToast: ({}) => void,
|
|
|
|
};
|
|
|
|
|
|
|
|
function ModalAutoGenerateThumbnail(props: Props) {
|
|
|
|
const { closeModal, filePath, upload, showToast } = props;
|
|
|
|
const playerRef = useRef();
|
2019-10-07 22:02:32 +02:00
|
|
|
let videoSrc;
|
|
|
|
if (typeof filePath === 'string') {
|
2019-12-02 18:30:08 +01:00
|
|
|
videoSrc = formatFileSystemPath(filePath);
|
2019-10-07 22:02:32 +02:00
|
|
|
} else {
|
|
|
|
videoSrc = URL.createObjectURL(filePath);
|
|
|
|
}
|
2019-05-21 23:18:11 +02:00
|
|
|
|
|
|
|
function uploadImage() {
|
2022-01-13 05:48:32 +01:00
|
|
|
const generateImg = (quality: number) => {
|
|
|
|
const imageBuffer = captureSnapshot(quality);
|
2019-11-22 22:13:00 +01:00
|
|
|
// $FlowFixMe
|
2022-01-13 05:48:32 +01:00
|
|
|
const file = new File([imageBuffer], 'thumbnail.jpeg', { type: 'image/jpeg' });
|
|
|
|
return { imageBuffer, file };
|
|
|
|
};
|
|
|
|
|
|
|
|
let img = generateImg(1.0);
|
2022-01-13 06:10:55 +01:00
|
|
|
if (img.file && img.file.size > THUMBNAIL_CDN_SIZE_LIMIT_BYTES) {
|
2022-01-13 05:48:32 +01:00
|
|
|
img = generateImg(0.8);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (img.imageBuffer) {
|
|
|
|
upload(img.file);
|
2019-05-21 23:18:11 +02:00
|
|
|
closeModal();
|
|
|
|
} else {
|
|
|
|
onError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-13 05:48:32 +01:00
|
|
|
function captureSnapshot(quality: number): ?Buffer {
|
2019-05-21 23:18:11 +02:00
|
|
|
const player = playerRef.current;
|
|
|
|
if (!player) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const canvas = document.createElement('canvas');
|
|
|
|
canvas.width = player.videoWidth;
|
|
|
|
canvas.height = player.videoHeight;
|
|
|
|
const context = canvas.getContext('2d');
|
|
|
|
context.drawImage(player, 0, 0, canvas.width, canvas.height);
|
2022-01-13 05:48:32 +01:00
|
|
|
const dataURL = canvas.toDataURL('image/jpeg', quality);
|
2019-05-21 23:18:11 +02:00
|
|
|
const rawData = dataURL.replace(/data:image\/\w+;base64,/i, '');
|
|
|
|
canvas.remove();
|
|
|
|
return Buffer.from(rawData, 'base64');
|
|
|
|
}
|
|
|
|
|
|
|
|
function resize(): void {
|
|
|
|
const player = playerRef.current;
|
|
|
|
if (!player) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const fixedWidth = 450;
|
|
|
|
const videoWidth = player.videoWidth;
|
|
|
|
const videoHeight = player.videoHeight;
|
|
|
|
player.width = fixedWidth;
|
|
|
|
player.height = Math.floor(videoHeight * (fixedWidth / videoWidth));
|
|
|
|
}
|
|
|
|
|
|
|
|
function onError(): void {
|
|
|
|
showToast({ isError: true, message: __("Something didn't work. Please try again.") });
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Modal
|
|
|
|
isOpen
|
2020-08-26 22:28:33 +02:00
|
|
|
title={__('Upload thumbnail')}
|
2019-05-21 23:18:11 +02:00
|
|
|
contentLabel={__('Confirm Thumbnail Upload')}
|
|
|
|
type="confirm"
|
|
|
|
confirmButtonLabel={__('Upload')}
|
|
|
|
onConfirmed={uploadImage}
|
|
|
|
onAborted={closeModal}
|
|
|
|
>
|
2019-11-22 22:13:00 +01:00
|
|
|
<p className="section__subtitle">{__('Pause at any time to select a thumbnail from your video')}.</p>
|
2019-07-21 23:31:22 +02:00
|
|
|
<video ref={playerRef} src={videoSrc} onLoadedMetadata={resize} onError={onError} controls />
|
2019-05-21 23:18:11 +02:00
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default ModalAutoGenerateThumbnail;
|