File size: 18,056 Bytes
7353536
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0eb4c39
 
7353536
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0eb4c39
7353536
 
 
 
 
0eb4c39
7353536
 
 
 
0eb4c39
 
 
 
 
7353536
 
 
 
0eb4c39
7353536
 
 
 
 
 
 
0eb4c39
7353536
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0eb4c39
7353536
 
0eb4c39
7353536
 
 
 
 
 
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
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
import gradio as gr
import time
import random
import numpy as np
from PIL import Image
import io
import base64
from typing import Tuple, Optional

def generate_video_from_text(
    prompt: str,
    duration: int = 5,
    style: str = "realistic",
    quality: str = "high",
    motion_strength: float = 0.5,
    seed: Optional[int] = None
) -> str:
    """
    Generate a video from text prompt using simulated WAN model.
    
    Args:
        prompt: Text description of the video to generate
        duration: Video duration in seconds
        style: Video style (realistic, artistic, anime, cartoon)
        quality: Video quality (low, medium, high)
        motion_strength: Strength of motion in video (0.0 to 1.0)
        seed: Random seed for reproducible generation
    
    Returns:
        Path to generated video file
    """
    
    if not prompt.strip():
        raise gr.Error("Please enter a text prompt to generate a video.")
    
    # Simulate video generation process
    progress_steps = [
        "Analyzing prompt...",
        "Generating keyframes...",
        "Applying style transfer...",
        "Creating motion vectors...",
        "Rendering video...",
        "Post-processing...",
        "Finalizing video..."
    ]
    
    for i, step in enumerate(progress_steps):
        time.sleep(0.5)  # Simulate processing time
        if i == len(progress_steps) - 1:
            yield f"βœ… {step}"
        else:
            yield f"⏳ {step}"
    
    # Generate a placeholder video (in real implementation, this would call WAN API)
    # For demo purposes, we'll create a simple animated frame sequence
    frames = []
    num_frames = duration * 10  # 10 fps
    
    if seed is None:
        seed = random.randint(0, 999999)
    
    np.random.seed(seed)
    
    # Create simple animated frames based on prompt
    for i in range(num_frames):
        # Generate a frame with some motion
        width, height = 512, 512
        frame = np.zeros((height, width, 3), dtype=np.uint8)
        
        # Create gradient background
        for y in range(height):
            for x in range(width):
                frame[y, x, 0] = int(255 * (x / width) * (1 + 0.3 * np.sin(i * 0.1)))
                frame[y, x, 1] = int(255 * (y / height) * (1 + 0.3 * np.cos(i * 0.1)))
                frame[y, x, 2] = int(128 + 127 * np.sin((x + y + i * 10) * 0.01))
        
        # Add some moving elements based on prompt
        center_x = width // 2 + int(100 * np.sin(i * 0.05) * motion_strength)
        center_y = height // 2 + int(100 * np.cos(i * 0.05) * motion_strength)
        
        cv2 = __import__('cv2')
        cv2.circle(frame, (center_x, center_y), 50, (255, 255, 255), -1)
        
        frames.append(Image.fromarray(frame))
    
    # Save frames as a video (placeholder - in real implementation, return actual video)
    # For demo, we'll return a sample video URL
    sample_videos = {
        "realistic": "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4",
        "artistic": "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_2mb.mp4",
        "anime": "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_5mb.mp4",
        "cartoon": "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4"
    }
    
    return sample_videos.get(style, sample_videos["realistic"])

def generate_video_from_image(
    image: np.ndarray,
    prompt: str,
    duration: int = 5,
    motion_strength: float = 0.5,
    seed: Optional[int] = None
) -> str:
    """
    Generate a video from an image with text prompt for motion.
    
    Args:
        image: Input image as numpy array
        prompt: Text description of desired motion/animation
        duration: Video duration in seconds
        motion_strength: Strength of motion in video (0.0 to 1.0)
        seed: Random seed for reproducible generation
    
    Returns:
        Path to generated video file
    """
    
    if image is None:
        raise gr.Error("Please upload an image to generate a video.")
    
    if not prompt.strip():
        raise gr.Error("Please describe the motion you want to add to the image.")
    
    # Simulate processing
    progress_steps = [
        "Analyzing image...",
        "Extracting features...",
        "Generating motion from prompt...",
        "Creating video frames...",
        "Applying motion blur...",
        "Rendering final video..."
    ]
    
    for step in progress_steps:
        time.sleep(0.6)
    
    # Return sample video for demo
    return "https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_2mb.mp4"

def create_custom_css() -> str:
    """Create custom CSS for the application."""
    return """
    .gradio-container {
        max-width: 1200px !important;
        margin: auto !important;
    }
    
    .main-header {
        text-align: center;
        margin-bottom: 2rem;
        padding: 1.5rem;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        border-radius: 15px;
        color: white;
    }
    
    .generation-card {
        border: 2px solid #e5e7eb;
        border-radius: 15px;
        padding: 1.5rem;
        margin: 1rem 0;
        background: white;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    }
    
    .progress-container {
        margin: 1rem 0;
        padding: 1rem;
        background: #f3f4f6;
        border-radius: 10px;
        font-family: monospace;
    }
    
    .example-prompt {
        cursor: pointer;
        padding: 0.5rem;
        margin: 0.25rem;
        background: #f9fafb;
        border: 1px solid #e5e7eb;
        border-radius: 8px;
        transition: all 0.2s;
    }
    
    .example-prompt:hover {
        background: #ede9fe;
        border-color: #8b5cf6;
    }
    """

# Create the custom theme
custom_theme = gr.themes.Soft(
    primary_hue="purple",
    secondary_hue="indigo",
    neutral_hue="slate",
    font=gr.themes.GoogleFont("Inter"),
    text_size="lg",
    spacing_size="lg",
    radius_size="md"
).set(
    button_primary_background_fill="*primary_600",
    button_primary_background_fill_hover="*primary_700",
    block_title_text_weight="600",
    block_border_width="2px",
    block_border_color="*neutral_200",
)

# Gradio 6: NO parameters in gr.Blocks() constructor!
with gr.Blocks() as demo:
    # Header
    gr.HTML("""
    <div class="main-header">
        <h1>🎬 WAN Video Generator</h1>
        <p>Transform your ideas into stunning videos with advanced AI technology</p>
        <p style="font-size: 0.9rem; margin-top: 0.5rem;">
            Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: white; text-decoration: underline;">anycoder</a>
        </p>
    </div>
    """)
    
    with gr.Tabs() as tabs:
        # Text to Video Tab
        with gr.TabItem("πŸ“ Text to Video", elem_id="text-to-video"):
            with gr.Row():
                with gr.Column(scale=2):
                    gr.Markdown("### 🎯 Generate Video from Text")
                    
                    prompt_input = gr.Textbox(
                        label="Video Description",
                        placeholder="Describe the video you want to generate... (e.g., 'A serene beach with waves gently lapping at sunset')",
                        lines=3,
                        max_lines=5
                    )
                    
                    with gr.Row():
                        duration_slider = gr.Slider(
                            minimum=2,
                            maximum=30,
                            value=5,
                            step=1,
                            label="Duration (seconds)"
                        )
                        
                        motion_slider = gr.Slider(
                            minimum=0.0,
                            maximum=1.0,
                            value=0.5,
                            step=0.1,
                            label="Motion Strength"
                        )
                    
                    with gr.Row():
                        style_dropdown = gr.Dropdown(
                            choices=["realistic", "artistic", "anime", "cartoon"],
                            value="realistic",
                            label="Video Style"
                        )
                        
                        quality_dropdown = gr.Dropdown(
                            choices=["low", "medium", "high"],
                            value="high",
                            label="Quality"
                        )
                    
                    seed_input = gr.Number(
                        label="Seed (optional)",
                        placeholder="Leave blank for random",
                        precision=0
                    )
                    
                    generate_btn = gr.Button(
                        "🎬 Generate Video",
                        variant="primary",
                        size="lg"
                    )
                
                with gr.Column(scale=1):
                    gr.Markdown("### πŸ’‘ Example Prompts")
                    
                    example_prompts = [
                        "A majestic eagle soaring through mountain peaks at sunrise",
                        "A bustling city street with neon lights reflecting on wet pavement",
                        "A peaceful garden with butterflies fluttering around colorful flowers",
                        "An astronaut floating in space with Earth in the background",
                        "A cozy fireplace crackling on a snowy winter evening"
                    ]
                    
                    for prompt in example_prompts:
                        gr.HTML(f'<div class="example-prompt" onclick="document.querySelector(\'[data-testid=\"textbox\"]\').value = `{prompt}`">{prompt}</div>')
                    
                    gr.Markdown("### βš™οΈ Tips")
                    gr.Markdown("""
                    β€’ Be descriptive but concise
                    β€’ Include setting and mood
                    β€’ Specify camera movements if needed
                    β€’ Use seeds for reproducible results
                    """)
            
            # Progress and Output
            progress_text = gr.Textbox(
                label="Generation Progress",
                interactive=False,
                visible=False
            )
            
            with gr.Column(elem_classes="generation-card"):
                gr.Markdown("### πŸ“Ή Generated Video")
                video_output = gr.Video(
                    label="Your Generated Video",
                    visible=False,
                    height=400
                )
            
            # Event handlers - Fixed for Gradio 6
            def handle_generate_text(prompt, duration, style, quality, motion, seed):
                if not prompt.strip():
                    raise gr.Error("Please enter a prompt!")
                
                # Show progress
                progress_updates = []
                
                # Generate video with progress updates
                for progress in generate_video_from_text(prompt, duration, style, quality, motion, seed):
                    if isinstance(progress, str):
                        progress_updates.append(progress)
                        yield {
                            progress_text: gr.Textbox(value=progress, visible=True),
                            video_output: gr.Video(visible=False)
                        }
                
                # Show result
                video_url = generate_video_from_text(prompt, duration, style, quality, motion, seed)
                if isinstance(video_url, str):
                    yield {
                        video_output: gr.Video(value=video_url, visible=True),
                        progress_text: gr.Textbox(value="βœ… Video generated successfully!", visible=True)
                    }
            
            generate_btn.click(
                fn=handle_generate_text,
                inputs=[prompt_input, duration_slider, style_dropdown, quality_dropdown, motion_slider, seed_input],
                outputs=[progress_text, video_output],
                api_visibility="public"
            )
        
        # Image to Video Tab
        with gr.TabItem("πŸ–ΌοΈ Image to Video", elem_id="image-to-video"):
            with gr.Row():
                with gr.Column():
                    gr.Markdown("### 🎨 Animate Your Image")
                    
                    image_input = gr.Image(
                        label="Upload Image",
                        type="numpy",
                        height=300
                    )
                    
                    motion_prompt = gr.Textbox(
                        label="Motion Description",
                        placeholder="Describe how you want the image to move... (e.g., 'Make the clouds drift slowly and the water ripple')",
                        lines=2
                    )
                    
                    with gr.Row():
                        img_duration_slider = gr.Slider(
                            minimum=2,
                            maximum=20,
                            value=5,
                            step=1,
                            label="Duration (seconds)"
                        )
                        
                        img_motion_slider = gr.Slider(
                            minimum=0.0,
                            maximum=1.0,
                            value=0.5,
                            step=0.1,
                            label="Motion Strength"
                        )
                    
                    img_seed_input = gr.Number(
                        label="Seed (optional)",
                        precision=0
                    )
                    
                    img_generate_btn = gr.Button(
                        "🎬 Animate Image",
                        variant="primary",
                        size="lg"
                    )
                
                with gr.Column():
                    gr.Markdown("### 🎯 Best Practices")
                    gr.Markdown("""
                    β€’ Use high-quality images for best results
                    β€’ Describe motion clearly and specifically
                    β€’ Start with lower motion strength
                    β€’ Images with clear subjects work better
                    β€’ Landscape orientation recommended
                    """)
                    
                    gr.Markdown("### πŸ’‘ Motion Examples")
                    gr.Markdown("""
                    β€’ "Gentle swaying of trees in the wind"
                    β€’ "Water flowing and rippling"
                    β€’ "Clouds moving across the sky"
                    β€’ "Leaves falling from trees"
                    β€’ "Fire flickering and dancing"
                    """)
            
            img_progress_text = gr.Textbox(
                label="Generation Progress",
                interactive=False,
                visible=False
            )
            
            img_video_output = gr.Video(
                label="Your Animated Video",
                visible=False,
                height=400
            )
            
            img_generate_btn.click(
                fn=generate_video_from_image,
                inputs=[image_input, motion_prompt, img_duration_slider, img_motion_slider, img_seed_input],
                outputs=[img_video_output, img_progress_text],
                api_visibility="public"
            )
        
        # Gallery Tab
        with gr.TabItem("🎭 Gallery", elem_id="gallery"):
            gr.Markdown("### 🌟 Featured Generations")
            
            with gr.Row():
                with gr.Column():
                    gr.Video(
                        label="Ocean Waves",
                        value="https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_1mb.mp4",
                        height=250
                    )
                    gr.Markdown("**Ocean Waves** - 'Peaceful ocean waves crashing on a sandy beach'")
                
                with gr.Column():
                    gr.Video(
                        label="Forest Path",
                        value="https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_2mb.mp4",
                        height=250
                    )
                    gr.Markdown("**Forest Path** - 'A misty forest path with sunlight filtering through trees'")
                
                with gr.Column():
                    gr.Video(
                        label="City Lights",
                        value="https://sample-videos.com/zip/10/mp4/SampleVideo_1280x720_5mb.mp4",
                        height=250
                    )
                    gr.Markdown("**City Lights** - 'Neon city lights at night with traffic flowing'")
            
            gr.Markdown("### πŸ“Š Generation Statistics")
            gr.DataFrame(
                value=[
                    ["Total Videos Generated", "1,234,567"],
                    ["Average Generation Time", "45 seconds"],
                    ["Most Popular Style", "Realistic"],
                    ["Average Duration", "8 seconds"],
                    ["Success Rate", "98.5%"]
                ],
                headers=["Metric", "Value"],
                datatype=["str", "str"],
                interactive=False
            )

# Gradio 6: ALL app parameters go in launch()!
demo.launch(
    theme=custom_theme,
    css=create_custom_css(),
    footer_links=[
        {"label": "Documentation", "url": "https://huggingface.co/spaces/akhaliq/anycoder"},
        {"label": "GitHub", "url": "https://github.com/gradio-app/gradio"},
        {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}
    ]
)