Files
ALwrity/frontend/src/components/VideoStudio/modules/EnhanceVideo/EnhanceVideo.tsx
ajaysi b134e9dc7e Added video studio router and endpoints. Added research router and endpoints. Added youtube router and endpoints. Added onboarding utils router and endpoints. Added onboarding utils service. Added onboarding utils models. Added onboarding utils routes. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils. Added onboarding utils utils.
2026-01-01 17:56:25 +05:30

408 lines
14 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Grid, Box, Button, Typography, Stack, CircularProgress, LinearProgress, Alert } from '@mui/material';
import { VideoStudioLayout } from '../../VideoStudioLayout';
import { useEnhanceVideo } from './hooks/useEnhanceVideo';
import { VideoUpload, EnhancementSettings } from './components';
import { aiApiClient } from '../../../../api/client';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import ErrorIcon from '@mui/icons-material/Error';
const EnhanceVideo: React.FC = () => {
const {
videoFile,
videoPreview,
targetResolution,
enhancementType,
setVideoFile,
setTargetResolution,
setEnhancementType,
canEnhance,
costHint,
} = useEnhanceVideo();
const [enhancing, setEnhancing] = useState(false);
const [progress, setProgress] = useState(0);
const [statusMessage, setStatusMessage] = useState('');
const [error, setError] = useState<string | null>(null);
const [result, setResult] = useState<{ video_url: string; cost: number } | null>(null);
const [progressInterval, setProgressInterval] = useState<NodeJS.Timeout | null>(null);
// Cleanup progress interval on unmount
useEffect(() => {
return () => {
if (progressInterval) {
clearInterval(progressInterval);
}
};
}, [progressInterval]);
const handleEnhance = async () => {
if (!videoFile) return;
setEnhancing(true);
setError(null);
setResult(null);
setProgress(0);
setStatusMessage('Starting video enhancement...');
try {
// Create FormData
const formData = new FormData();
formData.append('file', videoFile);
formData.append('enhancement_type', enhancementType);
formData.append('target_resolution', targetResolution);
formData.append('provider', 'wavespeed');
formData.append('model', 'flashvsr');
// Submit enhancement request
setStatusMessage('Uploading video...');
const response = await aiApiClient.post('/api/video-studio/enhance', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress: (progressEvent) => {
if (progressEvent.total) {
const uploadProgress = Math.round((progressEvent.loaded * 20) / progressEvent.total);
setProgress(uploadProgress);
setStatusMessage(`Uploading video... ${uploadProgress}%`);
}
},
timeout: 600000, // 10 minutes timeout for long videos
});
setProgress(30);
setStatusMessage('Processing video with FlashVSR... This may take a few minutes...');
// FlashVSR processing can take 3-20 seconds per 1 second of video
// Simulate progress updates while waiting for response
let simulatedProgress = 30;
const interval = setInterval(() => {
simulatedProgress = Math.min(90, simulatedProgress + 5);
setProgress(simulatedProgress);
setStatusMessage(`Processing... ${simulatedProgress}% (This may take several minutes for long videos)`);
}, 2000);
setProgressInterval(interval);
try {
if (response.data.success) {
clearInterval(interval);
setProgressInterval(null);
setEnhancing(false);
setResult(response.data);
setProgress(100);
setStatusMessage('Video enhancement complete!');
} else {
clearInterval(interval);
setProgressInterval(null);
throw new Error(response.data.error || 'Enhancement failed');
}
} catch (err) {
clearInterval(interval);
setProgressInterval(null);
throw err;
}
} catch (err: any) {
if (progressInterval) {
clearInterval(progressInterval);
setProgressInterval(null);
}
setEnhancing(false);
setProgress(0);
setError(err.response?.data?.detail || err.message || 'Failed to enhance video');
setStatusMessage('Enhancement failed');
}
};
const handleReset = () => {
setEnhancing(false);
setProgress(0);
setStatusMessage('');
setError(null);
setResult(null);
if (progressInterval) {
clearInterval(progressInterval);
setProgressInterval(null);
}
};
return (
<VideoStudioLayout
headerProps={{
title: 'Enhance Studio',
subtitle: 'Upscale your videos to higher resolutions with FlashVSR. Improve video quality, restore clarity, and prepare content for professional delivery.',
}}
>
<Grid container spacing={4}>
{/* Left Panel - Upload & Settings */}
<Grid item xs={12} lg={5}>
<Stack spacing={3}>
<VideoUpload videoPreview={videoPreview} onVideoSelect={setVideoFile} />
<EnhancementSettings
targetResolution={targetResolution}
enhancementType={enhancementType}
costHint={costHint}
onTargetResolutionChange={setTargetResolution}
onEnhancementTypeChange={setEnhancementType}
/>
<Box>
<Button
fullWidth
variant="contained"
size="large"
startIcon={enhancing ? <CircularProgress size={20} color="inherit" /> : <PlayArrowIcon />}
onClick={handleEnhance}
disabled={!canEnhance || enhancing}
sx={{
py: 1.5,
backgroundColor: '#3b82f6',
'&:hover': {
backgroundColor: '#2563eb',
},
'&:disabled': {
backgroundColor: '#cbd5e1',
color: '#94a3b8',
},
}}
>
{enhancing ? 'Enhancing...' : 'Enhance Video'}
</Button>
</Box>
{enhancing && (
<Box>
<Stack spacing={1}>
<Typography variant="body2" color="text.secondary">
{statusMessage}
</Typography>
<LinearProgress
variant="determinate"
value={progress}
sx={{
height: 8,
borderRadius: 1,
backgroundColor: '#e2e8f0',
'& .MuiLinearProgress-bar': {
backgroundColor: '#3b82f6',
},
}}
/>
</Stack>
</Box>
)}
{error && (
<Alert severity="error" onClose={() => setError(null)}>
{error}
</Alert>
)}
</Stack>
</Grid>
{/* Right Panel - Preview & Results */}
<Grid item xs={12} lg={7}>
<Stack spacing={3}>
{result ? (
// Side-by-side comparison view
<Box>
<Typography
variant="h6"
sx={{
mb: 2,
color: '#0f172a',
fontWeight: 700,
}}
>
Comparison
</Typography>
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<Box
sx={{
borderRadius: 2,
overflow: 'hidden',
border: '2px solid #e2e8f0',
backgroundColor: '#000',
}}
>
<video
src={videoPreview || ''}
controls
style={{
width: '100%',
maxHeight: 400,
display: 'block',
}}
/>
<Box sx={{ p: 1.5, backgroundColor: '#f8fafc' }}>
<Typography variant="caption" sx={{ fontWeight: 600, color: '#64748b' }}>
Original Video
</Typography>
</Box>
</Box>
</Grid>
<Grid item xs={12} md={6}>
<Box
sx={{
borderRadius: 2,
overflow: 'hidden',
border: '2px solid #10b981',
backgroundColor: '#000',
}}
>
<video
src={result.video_url.startsWith('http') ? result.video_url : `${window.location.origin}${result.video_url}`}
controls
style={{
width: '100%',
maxHeight: 400,
display: 'block',
}}
/>
<Box sx={{ p: 1.5, backgroundColor: '#f0fdf4' }}>
<Typography variant="caption" sx={{ fontWeight: 600, color: '#059669' }}>
Enhanced ({targetResolution.toUpperCase()})
</Typography>
</Box>
</Box>
</Grid>
</Grid>
<Stack direction="row" spacing={2} sx={{ mt: 2 }}>
<Button
variant="contained"
fullWidth
href={result.video_url.startsWith('http') ? result.video_url : `${window.location.origin}${result.video_url}`}
download
sx={{
backgroundColor: '#10b981',
'&:hover': {
backgroundColor: '#059669',
},
}}
>
Download Enhanced Video
</Button>
<Button variant="outlined" fullWidth onClick={handleReset}>
Enhance Another
</Button>
</Stack>
<Box
sx={{
mt: 2,
p: 2,
borderRadius: 2,
backgroundColor: '#f0fdf4',
border: '1px solid #10b981',
}}
>
<Stack spacing={1}>
<Typography variant="body2" sx={{ fontWeight: 600, color: '#065f46' }}>
Enhancement Complete!
</Typography>
<Typography variant="caption" color="text.secondary">
Cost: ${result.cost.toFixed(4)} | Resolution: {targetResolution.toUpperCase()}
</Typography>
</Stack>
</Box>
</Box>
) : videoPreview ? (
// Original video preview
<Box>
<Typography
variant="h6"
sx={{
mb: 2,
color: '#0f172a',
fontWeight: 700,
}}
>
Original Video Preview
</Typography>
<Box
sx={{
borderRadius: 2,
overflow: 'hidden',
border: '2px solid #e2e8f0',
backgroundColor: '#000',
}}
>
<video
src={videoPreview}
controls
style={{
width: '100%',
maxHeight: 500,
display: 'block',
}}
/>
<Box sx={{ p: 2, backgroundColor: '#f8fafc' }}>
<Typography variant="body2" color="text.secondary">
Upload a video and select enhancement options to get started
</Typography>
</Box>
</Box>
</Box>
) : (
<Box
sx={{
border: '2px dashed #cbd5e1',
borderRadius: 2,
p: 6,
textAlign: 'center',
backgroundColor: '#f8fafc',
}}
>
<Typography variant="body2" color="text.secondary">
Upload a video to see preview
</Typography>
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 1 }}>
Your enhanced video will appear here
</Typography>
</Box>
)}
{/* Info Box */}
<Box
sx={{
p: 2,
borderRadius: 2,
backgroundColor: '#f1f5f9',
border: '1px solid #e2e8f0',
}}
>
<Typography variant="subtitle2" sx={{ mb: 1, fontWeight: 600, color: '#0f172a' }}>
About FlashVSR
</Typography>
<Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
FlashVSR is the most advanced video upscaler, delivering:
</Typography>
<Stack component="ul" spacing={0.5} sx={{ pl: 2, m: 0 }}>
<Typography component="li" variant="body2" color="text.secondary">
Temporal consistency for stable motion
</Typography>
<Typography component="li" variant="body2" color="text.secondary">
Detail reconstruction for fine textures
</Typography>
<Typography component="li" variant="body2" color="text.secondary">
Artifact cleanup for compression blocks
</Typography>
<Typography component="li" variant="body2" color="text.secondary">
Natural look without overprocessing
</Typography>
</Stack>
</Box>
</Stack>
</Grid>
</Grid>
</VideoStudioLayout>
);
};
export default EnhanceVideo;
export { EnhanceVideo };