import React, { useEffect, useRef, useState } from 'react'; import { Box, Typography } from '@mui/material'; import Slider from 'rc-slider'; import 'rc-slider/assets/index.css'; import BaseFileInput from './BaseFileInput'; import { BaseFileInputProps, formatTime } from './file-input-utils'; import Cropper, { MediaSize, Point, Size, Area } from 'react-easy-crop'; interface VideoFileInputProps extends BaseFileInputProps { showTrimControls?: boolean; onTrimChange?: (trimStart: number, trimEnd: number) => void; trimStart?: number; trimEnd?: number; showCropOverlay?: boolean; cropPosition?: { x: number; y: number }; cropSize?: { width: number; height: number }; onCropChange?: ( position: { x: number; y: number }, size: { width: number; height: number } ) => void; } export default function ToolVideoInput({ showTrimControls = false, onTrimChange, trimStart = 0, trimEnd = 100, showCropOverlay, cropPosition = { x: 0, y: 0 }, cropSize = { width: 100, height: 100 }, onCropChange, ...props }: VideoFileInputProps) { let videoRef = useRef(null); const [videoDuration, setVideoDuration] = useState(0); const [videoWidth, setVideoWidth] = useState(0); const [videoHeight, setVideoHeight] = useState(0); const [crop, setCrop] = useState<{ x: number; y: number; width: number; height: number; }>({ x: 0, y: 0, width: 0, height: 0 }); const onVideoLoad = (e: React.SyntheticEvent) => { const duration = e.currentTarget.duration; setVideoDuration(duration); if (onTrimChange && trimStart === 0 && trimEnd === 100) { onTrimChange(0, duration); } }; useEffect(() => { if ( cropPosition.x !== 0 || cropPosition.y !== 0 || cropSize.width !== 100 || cropSize.height !== 100 ) { setCrop({ ...cropPosition, ...cropSize }); } }, [cropPosition, cropSize]); const onCropMediaLoaded = (mediaSize: MediaSize) => { const { width, height } = mediaSize; setVideoWidth(width); setVideoHeight(height); if (!crop.width && !crop.height && onCropChange) { const initialCrop = { x: Math.floor(width / 4), y: Math.floor(height / 4), width: Math.floor(width / 2), height: Math.floor(height / 2) }; console.log('initialCrop', initialCrop); setCrop(initialCrop); onCropChange( { x: initialCrop.x, y: initialCrop.y }, { width: initialCrop.width, height: initialCrop.height } ); } }; const handleTrimChange = (start: number, end: number) => { if (onTrimChange) { onTrimChange(start, end); } }; const handleCropChange = (newCrop: Point) => { setCrop((prevState) => ({ ...prevState, x: newCrop.x, y: newCrop.y })); }; const handleCropSizeChange = (newCrop: Size) => { setCrop((prevState) => ({ ...prevState, height: newCrop.height, width: newCrop.width })); }; const handleCropComplete = (crop: Area, croppedAreaPixels: Area) => { if (onCropChange) { onCropChange(croppedAreaPixels, croppedAreaPixels); } }; return ( {({ preview }) => ( {showCropOverlay ? ( { videoRef = ref; }} video={preview} crop={crop} cropSize={crop} onCropSizeChange={handleCropSizeChange} onCropChange={handleCropChange} onCropComplete={handleCropComplete} onMediaLoaded={onCropMediaLoaded} initialCroppedAreaPercentages={{ height: 0.5, width: 0.5, x: 0.5, y: 0.5 }} // controls={!showTrimControls} /> ) : ( )} ); }