ginipick commited on
Commit
8f84113
Β·
verified Β·
1 Parent(s): 6d7652a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -74
app.py CHANGED
@@ -14,11 +14,20 @@ import requests
14
  from datetime import datetime
15
  import tempfile
16
  import time
17
- from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip
18
- import numpy as np
 
 
 
 
 
 
 
19
 
20
  # API token setup
21
  api_token = os.getenv("RAPI_TOKEN")
 
 
22
 
23
  # Aspect ratio options
24
  ASPECT_RATIOS = {
@@ -35,63 +44,89 @@ ASPECT_RATIOS = {
35
  DEFAULT_TEXT_PROMPT = ""
36
  DEFAULT_IMAGE_PROMPT = "Generate a video with smooth and natural movement. Objects should have visible motion while maintaining fluid transitions."
37
 
38
- def add_watermark(input_video_path, output_video_path):
39
- """Add watermark to video using moviepy"""
 
 
 
40
  try:
41
- # Load the video
42
- video = VideoFileClip(input_video_path)
43
 
44
- # Get video dimensions
45
- width, height = video.size
 
 
46
 
47
- # Calculate watermark size and position
48
- watermark_text = "ginigen.com"
49
- font_size = max(12, int(height * 0.025)) # 2.5% of video height, minimum 12px
50
-
51
- # Create text clip for watermark
52
- watermark = TextClip(
53
- watermark_text,
54
- fontsize=font_size,
55
- color='white',
56
- font='Arial',
57
- stroke_color='black',
58
- stroke_width=1,
59
- method='caption',
60
- size=(None, None)
61
- )
62
 
63
- # Position watermark at bottom right with padding
64
- padding = int(width * 0.02) # 2% padding
65
- watermark = watermark.set_position((width - watermark.w - padding, height - watermark.h - padding))
66
- watermark = watermark.set_duration(video.duration)
67
-
68
- # Set opacity (semi-transparent)
69
- watermark = watermark.set_opacity(0.7)
70
-
71
- # Composite the watermark onto the video
72
- final_video = CompositeVideoClip([video, watermark])
73
-
74
- # Write the output video
75
- final_video.write_videofile(
76
- output_video_path,
77
- codec='libx264',
78
- audio_codec='aac',
79
- temp_audiofile=tempfile.mktemp('.m4a'),
80
- remove_temp=True,
81
- logger=None # Suppress moviepy output
82
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- # Clean up
85
- video.close()
86
- final_video.close()
 
87
 
88
  return True
 
89
  except Exception as e:
90
  print(f"Watermark error: {str(e)}")
91
- # If watermarking fails, just copy the original
 
 
 
 
92
  import shutil
93
  shutil.copy2(input_video_path, output_video_path)
94
  return False
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
  def update_prompt_placeholder(mode):
97
  """Update prompt placeholder based on mode"""
@@ -263,33 +298,35 @@ def generate_video(mode, prompt, image, aspect_ratio, seed, api_key_input, progr
263
  tmp_file.write(video_data)
264
  temp_video_path = tmp_file.name
265
 
266
- progress(0.8, desc="Adding watermark...")
 
 
267
 
268
- # Create final output path
269
- final_video_path = tempfile.mktemp(suffix='.mp4')
270
-
271
- # Add watermark
272
- watermark_added = add_watermark(temp_video_path, final_video_path)
 
 
273
 
274
- # Also save as output.mp4
275
- if os.path.exists(final_video_path):
276
- with open(final_video_path, "rb") as f:
277
- watermarked_data = f.read()
278
- with open("output.mp4", "wb") as file:
279
- file.write(watermarked_data)
280
- else:
281
- # Fallback if watermarking failed
282
- with open("output.mp4", "wb") as file:
283
- file.write(video_data)
284
- final_video_path = temp_video_path
285
 
286
- # Clean up temp file if different
287
  if temp_video_path != final_video_path and os.path.exists(temp_video_path):
288
- os.unlink(temp_video_path)
 
 
 
289
 
290
  progress(1.0, desc="Complete!")
291
 
292
  # Generation info
 
293
  info = f"""βœ… Video generated successfully!
294
 
295
  πŸ“Š Generation Info:
@@ -298,7 +335,7 @@ def generate_video(mode, prompt, image, aspect_ratio, seed, api_key_input, progr
298
  - Seed: {seed}
299
  - Duration: 5 seconds
300
  - Resolution: 480p
301
- - Watermark: {"Added" if watermark_added else "Failed (original saved)"}
302
  - File: output.mp4"""
303
 
304
  return final_video_path, info
@@ -376,11 +413,12 @@ with gr.Blocks(title="Bytedance Seedance Video Free", theme=gr.themes.Soft()) as
376
  )
377
 
378
  # Fixed settings display
379
- gr.Markdown("""
 
380
  ### πŸ“‹ Fixed Settings
381
  - **Duration**: 5 seconds
382
  - **Resolution**: 480p
383
- - **Watermark**: ginigen.com
384
  """)
385
 
386
  with gr.Column(scale=2):
@@ -414,15 +452,20 @@ with gr.Blocks(title="Bytedance Seedance Video Free", theme=gr.themes.Soft()) as
414
 
415
  1. **Install required packages**:
416
  ```bash
417
- pip install gradio replicate pillow requests moviepy
 
 
 
 
 
418
  ```
419
 
420
- 2. **Set environment variable** (optional):
421
  ```bash
422
  export RAPI_TOKEN="your-replicate-api-token"
423
  ```
424
 
425
- 3. **Run**:
426
  ```bash
427
  python app.py
428
  ```
@@ -433,7 +476,7 @@ with gr.Blocks(title="Bytedance Seedance Video Free", theme=gr.themes.Soft()) as
433
  - **Image to Video**: Transform uploaded image into animated video
434
  - **Aspect Ratios**: Choose ratios optimized for various social media platforms
435
  - **Seed Value**: Use same seed to reproduce identical results
436
- - **Watermark**: Automatically adds "ginigen.com" watermark to generated videos
437
 
438
  ### Prompt Writing Tips
439
 
@@ -447,7 +490,7 @@ with gr.Blocks(title="Bytedance Seedance Video Free", theme=gr.themes.Soft()) as
447
  - **Timeout errors**: The model might be cold starting. Wait 1-2 minutes and try again.
448
  - **Model booting**: First requests after inactivity may take longer as the model boots up.
449
  - **Extended wait times**: Complex prompts or server load may cause longer generation times.
450
- - **Watermark issues**: If watermark fails, the original video will be saved without watermark.
451
  """)
452
 
453
  # Examples
 
14
  from datetime import datetime
15
  import tempfile
16
  import time
17
+
18
+ # Try to import video processing libraries
19
+ try:
20
+ import cv2
21
+ import numpy as np
22
+ VIDEO_PROCESSING_AVAILABLE = True
23
+ except ImportError:
24
+ VIDEO_PROCESSING_AVAILABLE = False
25
+ print("Warning: cv2 not available. Watermark feature will be disabled.")
26
 
27
  # API token setup
28
  api_token = os.getenv("RAPI_TOKEN")
29
+ if api_token:
30
+ os.environ["REPLICATE_API_TOKEN"] = api_token
31
 
32
  # Aspect ratio options
33
  ASPECT_RATIOS = {
 
44
  DEFAULT_TEXT_PROMPT = ""
45
  DEFAULT_IMAGE_PROMPT = "Generate a video with smooth and natural movement. Objects should have visible motion while maintaining fluid transitions."
46
 
47
+ def add_watermark_cv2(input_video_path, output_video_path):
48
+ """Add watermark to video using OpenCV"""
49
+ if not VIDEO_PROCESSING_AVAILABLE:
50
+ return False
51
+
52
  try:
53
+ # Open the video
54
+ cap = cv2.VideoCapture(input_video_path)
55
 
56
+ # Get video properties
57
+ fps = int(cap.get(cv2.CAP_PROP_FPS))
58
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
59
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
60
 
61
+ # Define codec and create VideoWriter
62
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
63
+ out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
+ # Watermark settings
66
+ watermark_text = "ginigen.com"
67
+ font = cv2.FONT_HERSHEY_SIMPLEX
68
+ font_scale = max(0.4, height * 0.001) # Scale based on video height
69
+ font_thickness = max(1, int(height * 0.002))
70
+
71
+ # Get text size
72
+ (text_width, text_height), baseline = cv2.getTextSize(watermark_text, font, font_scale, font_thickness)
73
+
74
+ # Position (bottom right with padding)
75
+ padding = int(width * 0.02)
76
+ x = width - text_width - padding
77
+ y = height - padding
78
+
79
+ # Process each frame
80
+ while True:
81
+ ret, frame = cap.read()
82
+ if not ret:
83
+ break
84
+
85
+ # Add semi-transparent background for text
86
+ overlay = frame.copy()
87
+ cv2.rectangle(overlay,
88
+ (x - 5, y - text_height - 5),
89
+ (x + text_width + 5, y + 5),
90
+ (0, 0, 0),
91
+ -1)
92
+ frame = cv2.addWeighted(frame, 0.7, overlay, 0.3, 0)
93
+
94
+ # Add text
95
+ cv2.putText(frame, watermark_text, (x, y), font, font_scale, (255, 255, 255), font_thickness, cv2.LINE_AA)
96
+
97
+ # Write frame
98
+ out.write(frame)
99
 
100
+ # Release everything
101
+ cap.release()
102
+ out.release()
103
+ cv2.destroyAllWindows()
104
 
105
  return True
106
+
107
  except Exception as e:
108
  print(f"Watermark error: {str(e)}")
109
+ return False
110
+
111
+ def add_watermark_simple(input_video_path, output_video_path):
112
+ """Simple fallback - just copy the video without watermark"""
113
+ try:
114
  import shutil
115
  shutil.copy2(input_video_path, output_video_path)
116
  return False
117
+ except Exception as e:
118
+ print(f"Copy error: {str(e)}")
119
+ return False
120
+
121
+ def add_watermark(input_video_path, output_video_path):
122
+ """Add watermark to video - tries cv2 first, then fallback"""
123
+ if VIDEO_PROCESSING_AVAILABLE:
124
+ success = add_watermark_cv2(input_video_path, output_video_path)
125
+ if success:
126
+ return True
127
+
128
+ # Fallback - just copy without watermark
129
+ return add_watermark_simple(input_video_path, output_video_path)
130
 
131
  def update_prompt_placeholder(mode):
132
  """Update prompt placeholder based on mode"""
 
298
  tmp_file.write(video_data)
299
  temp_video_path = tmp_file.name
300
 
301
+ # Try to add watermark
302
+ watermark_added = False
303
+ final_video_path = temp_video_path
304
 
305
+ if VIDEO_PROCESSING_AVAILABLE:
306
+ progress(0.8, desc="Adding watermark...")
307
+ final_video_path = tempfile.mktemp(suffix='.mp4')
308
+ watermark_added = add_watermark(temp_video_path, final_video_path)
309
+
310
+ if not watermark_added or not os.path.exists(final_video_path):
311
+ final_video_path = temp_video_path
312
 
313
+ # Save final video
314
+ with open(final_video_path, "rb") as f:
315
+ final_video_data = f.read()
316
+ with open("output.mp4", "wb") as file:
317
+ file.write(final_video_data)
 
 
 
 
 
 
318
 
319
+ # Clean up temp files
320
  if temp_video_path != final_video_path and os.path.exists(temp_video_path):
321
+ try:
322
+ os.unlink(temp_video_path)
323
+ except:
324
+ pass
325
 
326
  progress(1.0, desc="Complete!")
327
 
328
  # Generation info
329
+ watermark_status = "Added" if watermark_added else "Not available (cv2 not installed)" if not VIDEO_PROCESSING_AVAILABLE else "Failed"
330
  info = f"""βœ… Video generated successfully!
331
 
332
  πŸ“Š Generation Info:
 
335
  - Seed: {seed}
336
  - Duration: 5 seconds
337
  - Resolution: 480p
338
+ - Watermark: {watermark_status}
339
  - File: output.mp4"""
340
 
341
  return final_video_path, info
 
413
  )
414
 
415
  # Fixed settings display
416
+ watermark_info = "ginigen.com" if VIDEO_PROCESSING_AVAILABLE else "ginigen.com (requires cv2)"
417
+ gr.Markdown(f"""
418
  ### πŸ“‹ Fixed Settings
419
  - **Duration**: 5 seconds
420
  - **Resolution**: 480p
421
+ - **Watermark**: {watermark_info}
422
  """)
423
 
424
  with gr.Column(scale=2):
 
452
 
453
  1. **Install required packages**:
454
  ```bash
455
+ pip install gradio replicate pillow requests
456
+ ```
457
+
458
+ 2. **For watermark support (optional)**:
459
+ ```bash
460
+ pip install opencv-python
461
  ```
462
 
463
+ 3. **Set environment variable** (optional):
464
  ```bash
465
  export RAPI_TOKEN="your-replicate-api-token"
466
  ```
467
 
468
+ 4. **Run**:
469
  ```bash
470
  python app.py
471
  ```
 
476
  - **Image to Video**: Transform uploaded image into animated video
477
  - **Aspect Ratios**: Choose ratios optimized for various social media platforms
478
  - **Seed Value**: Use same seed to reproduce identical results
479
+ - **Watermark**: Automatically adds "ginigen.com" watermark (requires opencv-python)
480
 
481
  ### Prompt Writing Tips
482
 
 
490
  - **Timeout errors**: The model might be cold starting. Wait 1-2 minutes and try again.
491
  - **Model booting**: First requests after inactivity may take longer as the model boots up.
492
  - **Extended wait times**: Complex prompts or server load may cause longer generation times.
493
+ - **Watermark not showing**: Install opencv-python for watermark support.
494
  """)
495
 
496
  # Examples