File size: 23,051 Bytes
952beb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>M3DDM Video Outpainting</title>
    <script src="https://cdn.jsdelivr.net/npm/react@18.0.0/umd/react.development.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/react-dom@18.0.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone/babel.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Inter', sans-serif;
        }
        .gradient-bg {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .glass-effect {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
        .video-container {
            background: linear-gradient(145deg, #1a1a2e, #16213e);
            border-radius: 12px;
            overflow: hidden;
        }
        .upload-area {
            border: 2px dashed #667eea;
            transition: all 0.3s ease;
        }
        .upload-area:hover {
            border-color: #764ba2;
            background: rgba(102, 126, 234, 0.1);
        }
        .slider-track {
            background: linear-gradient(90deg, #667eea, #764ba2);
        }
        .loading-spinner {
            border: 3px solid rgba(255, 255, 255, 0.3);
            border-top: 3px solid #fff;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .tab-active {
            background: linear-gradient(90deg, #667eea, #764ba2);
            color: white;
        }
        .tab-inactive {
            background: rgba(255, 255, 255, 0.1);
            color: rgba(255, 255, 255, 0.7);
        }
    </style>
</head>
<body>
    <div id="root"></div>

    <script type="text/babel">
        const { useState, useEffect, useRef } = React;

        const App = () => {
            const [activeTab, setActiveTab] = useState('upload');
            const [videoFile, setVideoFile] = useState(null);
            const [isProcessing, setIsProcessing] = useState(false);
            const [processedVideo, setProcessedVideo] = useState(null);
            const [outpaintAmount, setOutpaintAmount] = useState(30);
            const [quality, setQuality] = useState(75);
            const [style, setStyle] = useState('realistic');
            const [progress, setProgress] = useState(0);
            const [showPreview, setShowPreview] = useState(false);

            const handleFileUpload = (e) => {
                const file = e.target.files[0];
                if (file && file.type.startsWith('video/')) {
                    setVideoFile(file);
                    setShowPreview(false);
                    setProcessedVideo(null);
                }
            };

            const handleProcess = () => {
                if (!videoFile) return;
                
                setIsProcessing(true);
                setProgress(0);
                
                // Simulate processing
                const interval = setInterval(() => {
                    setProgress(prev => {
                        if (prev >= 100) {
                            clearInterval(interval);
                            setIsProcessing(false);
                            // Simulate processed video
                            setTimeout(() => {
                                setProcessedVideo(URL.createObjectURL(videoFile));
                                setShowPreview(true);
                            }, 500);
                            return 100;
                        }
                        return prev + 10;
                    });
                }, 200);
            };

            const handleDownload = () => {
                // In a real app, this would trigger download of processed video
                alert('Download functionality would be implemented here');
            };

            return (
                <div className="min-h-screen gradient-bg">
                    {/* Header */}
                    <header className="glass-effect p-4">
                        <div className="container mx-auto flex justify-between items-center">
                            <h1 className="text-2xl font-bold text-white">M3DDM Video Outpainting</h1>
                            <a href="https://huggingface.co/spaces/akhaliq/anycoder" className="text-white hover:underline">
                                Built with anycoder
                            </a>
                        </div>
                    </header>

                    {/* Main Content */}
                    <main className="container mx-auto p-4">
                        {/* Tabs */}
                        <div className="flex space-x-2 mb-6">
                            <button 
                                onClick={() => setActiveTab('upload')}
                                className={`px-6 py-2 rounded-lg font-medium transition-all ${activeTab === 'upload' ? 'tab-active' : 'tab-inactive'}`}
                            >
                                <i className="fas fa-upload mr-2"></i>
                                Upload Video
                            </button>
                            <button 
                                onClick={() => setActiveTab('settings')}
                                className={`px-6 py-2 rounded-lg font-medium transition-all ${activeTab === 'settings' ? 'tab-active' : 'tab-inactive'}`}
                            >
                                <i className="fas fa-cog mr-2"></i>
                                Settings
                            </button>
                            <button 
                                onClick={() => setActiveTab('about')}
                                className={`px-6 py-2 rounded-lg font-medium transition-all ${activeTab === 'about' ? 'tab-active' : 'tab-inactive'}`}
                            >
                                <i className="fas fa-info-circle mr-2"></i>
                                About
                            </button>
                        </div>

                        {/* Upload Section */}
                        {activeTab === 'upload' && (
                            <div className="grid lg:grid-cols-2 gap-6">
                                {/* Upload Area */}
                                <div className="glass-effect rounded-xl p-6">
                                    <h2 className="text-xl font-semibold text-white mb-4">Upload Video</h2>
                                    <div className="upload-area rounded-lg p-8 text-center cursor-pointer" onClick={() => document.getElementById('videoInput').click()}>
                                        <input 
                                            type="file" 
                                            id="videoInput" 
                                            className="hidden" 
                                            accept="video/*"
                                            onChange={handleFileUpload}
                                        />
                                        <i className="fas fa-cloud-upload-alt text-4xl text-white mb-4"></i>
                                        <p className="text-white mb-2">Click to upload or drag and drop</p>
                                        <p className="text-gray-300 text-sm">MP4, AVI, MOV up to 100MB</p>
                                        {videoFile && (
                                            <div className="mt-4 p-3 bg-white bg-opacity-10 rounded-lg">
                                                <p className="text-white text-sm">{videoFile.name}</p>
                                                <p className="text-gray-300 text-xs">{(videoFile.size / 1024 / 1024).toFixed(2)} MB</p>
                                            </div>
                                        )}
                                    </div>
                                </div>

                                {/* Controls */}
                                <div className="glass-effect rounded-xl p-6">
                                    <h2 className="text-xl font-semibold text-white mb-4">Processing Controls</h2>
                                    
                                    <div className="space-y-4">
                                        <div>
                                            <label className="text-white text-sm mb-2 block">Outpaint Amount: {outpaintAmount}%</label>
                                            <input 
                                                type="range" 
                                                min="10" 
                                                max="100" 
                                                value={outpaintAmount}
                                                onChange={(e) => setOutpaintAmount(e.target.value)}
                                                className="w-full h-2 rounded-lg slider-track appearance-none cursor-pointer"
                                            />
                                        </div>
                                        
                                        <div>
                                            <label className="text-white text-sm mb-2 block">Quality: {quality}%</label>
                                            <input 
                                                type="range" 
                                                min="50" 
                                                max="100" 
                                                value={quality}
                                                onChange={(e) => setQuality(e.target.value)}
                                                className="w-full h-2 rounded-lg slider-track appearance-none cursor-pointer"
                                            />
                                        </div>
                                        
                                        <div>
                                            <label className="text-white text-sm mb-2 block">Style</label>
                                            <select 
                                                value={style}
                                                onChange={(e) => setStyle(e.target.value)}
                                                className="w-full p-2 rounded-lg bg-white bg-opacity-10 text-white border border-white border-opacity-20"
                                            >
                                                <option value="realistic">Realistic</option>
                                                <option value="artistic">Artistic</option>
                                                <option value="cartoon">Cartoon</option>
                                            </select>
                                        </div>
                                        
                                        <button 
                                            onClick={handleProcess}
                                            disabled={!videoFile || isProcessing}
                                            className="w-full py-3 bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-lg font-medium hover:from-purple-600 hover:to-pink-600 transition-all disabled:opacity-50 disabled:cursor-not-allowed"
                                        >
                                            {isProcessing ? (
                                                <div className="flex items-center justify-center">
                                                    <div className="loading-spinner mr-3"></div>
                                                    Processing...
                                                </div>
                                            ) : 'Process Video'}
                                        </button>
                                    </div>
                                </div>
                            </div>
                        )}

                        {/* Settings Section */}
                        {activeTab === 'settings' && (
                            <div className="glass-effect rounded-xl p-6">
                                <h2 className="text-xl font-semibold text-white mb-4">Advanced Settings</h2>
                                <div className="grid md:grid-cols-2 gap-6">
                                    <div>
                                        <h3 className="text-white font-medium mb-3">Performance</h3>
                                        <div className="space-y-3">
                                            <div className="flex items-center justify-between">
                                                <span className="text-gray-300">GPU Acceleration</span>
                                                <label className="relative inline-flex items-center cursor-pointer">
                                                    <input type="checkbox" className="sr-only peer" defaultChecked />
                                                    <div className="w-11 h-6 bg-gray-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-600"></div>
                                                </label>
                                            </div>
                                            <div className="flex items-center justify-between">
                                                <span className="text-gray-300">High Resolution</span>
                                                <label className="relative inline-flex items-center cursor-pointer">
                                                    <input type="checkbox" className="sr-only peer" />
                                                    <div className="w-11 h-6 bg-gray-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-purple-600"></div>
                                                </label>
                                            </div>
                                        </div>
                                    </div>
                                    <div>
                                        <h3 className="text-white font-medium mb-3">Output</h3>
                                        <div className="space-y-3">
                                            <div>
                                                <label className="text-gray-300 text-sm mb-1 block">Output Format</label>
                                                <select className="w-full p-2 rounded-lg bg-white bg-opacity-10 text-white border border-white border-opacity-20">
                                                    <option>MP4</option>
                                                    <option>WebM</option>
                                                    <option>AVI</option>
                                                </select>
                                            </div>
                                            <div>
                                                <label className="text-gray-300 text-sm mb-1 block">Frame Rate</label>
                                                <select className="w-full p-2 rounded-lg bg-white bg-opacity-10 text-white border border-white border-opacity-20">
                                                    <option>24 FPS</option>
                                                    <option>30 FPS</option>
                                                    <option>60 FPS</option>
                                                </select>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        )}

                        {/* About Section */}
                        {activeTab === 'about' && (
                            <div className="glass-effect rounded-xl p-6">
                                <h2 className="text-xl font-semibold text-white mb-4">About M3DDM Video Outpainting</h2>
                                <div className="text-gray-300 space-y-4">
                                    <p>M3DDM Video Outpainting is an advanced AI-powered tool that extends video content beyond its original boundaries. Using state-of-the-art machine learning models, it intelligently generates realistic video extensions while maintaining visual consistency.</p>
                                    <div className="grid md:grid-cols-2 gap-4 mt-6">
                                        <div className="bg-white bg-opacity-10 p-4 rounded-lg">
                                            <h3 className="text-white font-medium mb-2">Key Features</h3>
                                            <ul className="space-y-1 text-sm">
                                                <li>• AI-powered video extension</li>
                                                <li>• Multiple style options</li>
                                                <li>• Adjustable outpaint amount</li>
                                                <li>• High-quality output</li>
                                            </ul>
                                        </div>
                                        <div className="bg-white bg-opacity-10 p-4 rounded-lg">
                                            <h3 className="text-white font-medium mb-2">Technical Details</h3>
                                            <ul className="space-y-1 text-sm">
                                                <li>• Based on diffusion models</li>
                                                <li>• GPU accelerated processing</li>
                                                <li>• Supports various formats</li>
                                                <li>• Real-time preview</li>
                                            </ul>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        )}

                        {/* Video Preview Section */}
                        {showPreview && (
                            <div className="mt-6">
                                <div className="glass-effect rounded-xl p-6">
                                    <div className="flex justify-between items-center mb-4">
                                        <h2 className="text-xl font-semibold text-white">Preview</h2>
                                        <button 
                                            onClick={handleDownload}
                                            className="px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors"
                                        >
                                            <i className="fas fa-download mr-2"></i>
                                            Download
                                        </button>
                                    </div>
                                    
                                    <div className="grid lg:grid-cols-2 gap-6">
                                        <div>
                                            <h3 className="text-white font-medium mb-2">Original Video</h3>
                                            <div className="video-container aspect-video">
                                                <video controls className="w-full h-full object-cover">
                                                    <source src={URL.createObjectURL(videoFile)} type={videoFile.type} />
                                                </video>
                                            </div>
                                        </div>
                                        <div>
                                            <h3 className="text-white font-medium mb-2">Processed Video</h3>
                                            <div className="video-container aspect-video">
                                                <video controls className="w-full h-full object-cover">
                                                    <source src={processedVideo} type={videoFile.type} />
                                                </video>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        )}

                        {/* Progress Bar */}
                        {isProcessing && (
                            <div className="mt-6 glass-effect rounded-xl p-6">
                                <div className="flex items-center justify-between mb-2">
                                    <span className="text-white">Processing...</span>
                                    <span className="text-white">{progress}%</span>
                                </div>
                                <div className="w-full bg-gray-700 rounded-full h-2">
                                    <div 
                                        className="bg-gradient-to-r from-purple-500 to-pink-500 h-2 rounded-full transition-all duration-300"
                                        style={{ width: `${progress}%` }}
                                    ></div>
                                </div>
                            </div>
                        )}
                    </main>

                    {/* Footer */}
                    <footer className="mt-12 py-6 text-center text-gray-300 text-sm">
                        <p>M3DDM Video Outpainting © 2024 | Powered by Advanced AI Technology</p>
                    </footer>
                </div>
            );
        };

        ReactDOM.render(<App />, document.getElementById('root'));
    </script>
</body>
</html>