import React from 'react'; import { Trans } from '@lingui/macro'; import makeStyles from '@mui/styles/makeStyles'; import Backdrop from '@mui/material/Backdrop'; import Button from '@mui/material/Button'; import CircularProgress from '@mui/material/CircularProgress'; import Grid from '@mui/material/Grid'; import Icon from '@mui/icons-material/Cached'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; import Dialog from '../../../misc/modals/Dialog'; import Filesize from '../../../misc/Filesize'; import FormInlineButton from '../../../misc/FormInlineButton'; import UploadButton from '../../../misc/UploadButton'; const imageTypes = [ { mimetype: 'image/*', extension: 'image', maxSize: 2 * 1024 * 1024 }, { mimetype: 'video/*', extension: 'video', maxSize: 25 * 1024 * 1024 }, ]; const useStyles = makeStyles((theme) => ({ gridContainer: { marginTop: '0.5em', }, })); const initSettings = (initialSettings) => { if (!initialSettings) { initialSettings = {}; } const settings = { address: '', mimetype: '', ...initialSettings, }; return settings; }; const createInputs = (settings) => { const address = '{diskfs}' + settings.address; const input = { address: address, options: [], }; if (settings.mimetype.startsWith('image/')) { input.options.push('-framerate', '1'); input.options.push('-loop', '1'); } else { input.options.push('-stream_loop', '-1'); } input.options.push('-re'); return [input]; }; function Source(props) { const classes = useStyles(); const settings = initSettings(props.settings); const [$saving, setSaving] = React.useState(false); const [$error, setError] = React.useState({ open: false, title: '', message: '', }); const handleFileUpload = async (data, extension, mimetype) => { const path = await props.onStore('videoloop.source', data); props.onChange({ ...settings, address: path, mimetype: mimetype, }); setSaving(false); }; const handleUploadStart = () => { setSaving(true); }; const handleUploadError = (title) => (err) => { let message = null; switch (err.type) { case 'nofiles': message = Please select a file to upload.; break; case 'mimetype': message = ( The selected file type ({err.actual}) is not allowed. Allowed file types are {err.allowed.join(', ')} ); break; case 'size': message = ( The selected file is too big ( ). Only are allowed. ); break; case 'read': message = There was an error during upload: {err.message}; break; default: message = Unknown upload error; } setSaving(false); showUploadError(title, message); }; const showUploadError = (title, message) => { setError({ ...$error, open: true, title: title, message: message, }); }; const hideUploadError = () => { setError({ ...$error, open: false, }); }; const handleProbe = () => { props.onProbe(settings, createInputs(settings)); }; return ( Upload an image or video file ({imageTypes.map((t) => t.mimetype).join(', ')}) in order to loop it. File path} value={settings.address} readOnly /> Upload} acceptTypes={imageTypes} onStart={handleUploadStart} onError={handleUploadError(Uploading the file failed)} onUpload={handleFileUpload} /> Probe OK } > {$error.message} ); } Source.defaultProps = { knownDevices: [], settings: {}, onChange: function (settings) {}, onProbe: function (settings, inputs) {}, onRefresh: function () {}, onStore: function (name, data) { return ''; }, }; function SourceIcon(props) { return ; } const id = 'videoloop'; const name = Loop; const capabilities = ['video']; const ffversion = '^4.1.0 || ^5.0.0 || ^6.1.0'; const func = { initSettings, createInputs, }; export { id, name, capabilities, ffversion, SourceIcon as icon, Source as component, func };