Pushp0120 commited on
Commit
ee57331
·
verified ·
1 Parent(s): fe4ef2f

Update generate.py

Browse files
Files changed (1) hide show
  1. generate.py +72 -75
generate.py CHANGED
@@ -1,76 +1,52 @@
1
  import sys
2
  import os
3
  import re
4
- import textwrap
5
- import numpy as np
6
  import requests
7
- from PIL import Image, ImageDraw, ImageFont
8
- from moviepy.editor import ImageClip, concatenate_videoclips, AudioFileClip
9
  from io import BytesIO
10
  import upload
 
11
 
12
- WIDTH, HEIGHT = 1080, 1920
13
  FPS = 30
14
- DURATION_PER_LINE = 4
15
  PEXELS_API_KEY = "f7RBHJ4s4DTTFLmpUVhpYPnBFdk1MveAn0hJL2FQMhUb6aIeztxwhgA4"
 
16
 
17
- def get_pexels_image(query):
18
- """Fetch image from Pexels based on query"""
19
  try:
20
  headers = {"Authorization": PEXELS_API_KEY}
21
- params = {"query": query, "per_page": 1, "orientation": "portrait"}
22
- response = requests.get("https://api.pexels.com/v1/search", headers=headers, params=params, timeout=15)
23
- if response.status_code == 200:
24
- data = response.json()
25
- if data["photos"]:
26
- img_url = data["photos"][0]["src"]["large"]
27
- img_response = requests.get(img_url, timeout=15)
28
- img = Image.open(BytesIO(img_response.content)).convert('RGB')
29
- img = img.resize((WIDTH, HEIGHT))
30
- print(f"Pexels image fetched for: {query[:50]}")
31
- return img
32
- print(f"Pexels no result for: {query[:50]}")
 
 
 
 
 
 
 
 
 
33
  return None
34
  except Exception as e:
35
- print(f"Pexels error: {e}")
36
  return None
37
 
38
- def make_text_frame(text, bg_image=None):
39
- if bg_image:
40
- img = bg_image.copy()
41
- else:
42
- img = Image.new('RGB', (WIDTH, HEIGHT), color=(15, 15, 25))
43
-
44
- overlay = Image.new('RGBA', (WIDTH, HEIGHT), (0, 0, 0, 160))
45
- img = img.convert('RGBA')
46
- img = Image.alpha_composite(img, overlay)
47
- img = img.convert('RGB')
48
-
49
- draw = ImageDraw.Draw(img)
50
- try:
51
- font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 65)
52
- except:
53
- font = ImageFont.load_default()
54
-
55
- draw.rectangle([60, 180, WIDTH-60, 195], fill=(255, 80, 80))
56
- draw.rectangle([60, HEIGHT-195, WIDTH-60, HEIGHT-180], fill=(255, 80, 80))
57
-
58
- lines = textwrap.wrap(text, width=22)
59
- y = HEIGHT // 2 - (len(lines) * 85) // 2
60
- for line in lines:
61
- bbox = draw.textbbox((0, 0), line, font=font)
62
- w = bbox[2] - bbox[0]
63
- x = (WIDTH - w) // 2
64
- draw.text((x+4, y+4), line, font=font, fill=(0, 0, 0))
65
- draw.text((x, y), line, font=font, fill=(255, 255, 255))
66
- y += 90
67
-
68
- return np.array(img)
69
-
70
  def generate_tts(text, output_path):
71
  try:
72
  from gtts import gTTS
73
- tts = gTTS(text=text, lang='en', slow=False)
 
 
74
  tts.save(output_path)
75
  return True
76
  except Exception as e:
@@ -78,8 +54,8 @@ def generate_tts(text, output_path):
78
  return False
79
 
80
  def generate_video(script, title, description):
81
- print("Starting cinematic video generation...")
82
- print(f"Script received: {script[:100]}")
83
 
84
  sentences = re.split(r'[.!?\n]', script)
85
  sentences = [s.strip() for s in sentences if len(s.strip()) > 5]
@@ -88,34 +64,56 @@ def generate_video(script, title, description):
88
  words = script.split()
89
  sentences = [' '.join(words[i:i+8]) for i in range(0, len(words), 8)]
90
 
91
- sentences = sentences[:10]
92
  print(f"Total clips: {len(sentences)}")
93
 
94
  clips = []
 
95
 
96
  for i, sentence in enumerate(sentences):
97
  print(f"Creating clip {i+1}/{len(sentences)}")
98
 
99
- # Get Pexels image
100
- bg_image = get_pexels_image(sentence)
101
-
102
- # Generate TTS
103
  audio_path = f'/app/audio_{i}.mp3'
104
  has_audio = generate_tts(sentence, audio_path)
105
 
106
- # Create frame
107
- frame = make_text_frame(sentence, bg_image)
108
-
109
- # Create clip
110
  if has_audio and os.path.exists(audio_path):
111
  audio = AudioFileClip(audio_path)
112
- duration = max(audio.duration + 0.5, DURATION_PER_LINE)
113
- clip = ImageClip(frame, duration=duration)
114
- clip = clip.set_audio(audio)
115
  else:
116
- clip = ImageClip(frame, duration=DURATION_PER_LINE)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
- clip = clip.fadein(0.5).fadeout(0.5)
119
  clips.append(clip)
120
 
121
  if not clips:
@@ -125,10 +123,9 @@ def generate_video(script, title, description):
125
  print("Combining clips...")
126
  final = concatenate_videoclips(clips, method="compose")
127
 
128
- output_path = '/app/video.mp4'
129
  print("Writing video...")
130
  final.write_videofile(
131
- output_path,
132
  fps=FPS,
133
  codec='libx264',
134
  audio_codec='aac',
@@ -136,13 +133,13 @@ def generate_video(script, title, description):
136
  logger=None
137
  )
138
 
139
- for i in range(len(sentences)):
140
  try:
141
- os.remove(f'/app/audio_{i}.mp3')
142
  except:
143
  pass
144
 
145
- print("Cinematic video generated successfully!")
146
  return True
147
 
148
  if __name__ == '__main__':
 
1
  import sys
2
  import os
3
  import re
 
 
4
  import requests
5
+ from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, ColorClip
 
6
  from io import BytesIO
7
  import upload
8
+ import random
9
 
 
10
  FPS = 30
 
11
  PEXELS_API_KEY = "f7RBHJ4s4DTTFLmpUVhpYPnBFdk1MveAn0hJL2FQMhUb6aIeztxwhgA4"
12
+ VIDEO_PATH = '/app/video.mp4'
13
 
14
+ def get_pexels_video(query):
15
+ """Fetch vertical video from Pexels"""
16
  try:
17
  headers = {"Authorization": PEXELS_API_KEY}
18
+ for q in [query, "india viral", "trending india", "nature cinematic"]:
19
+ params = {"query": q, "per_page": 5, "orientation": "portrait"}
20
+ response = requests.get("https://api.pexels.com/videos/search", headers=headers, params=params, timeout=15)
21
+ if response.status_code == 200:
22
+ data = response.json()
23
+ if data.get("videos"):
24
+ video = random.choice(data["videos"])
25
+ files = sorted(video["video_files"], key=lambda x: x.get("width", 9999))
26
+ for f in files:
27
+ if f.get("height", 0) >= 720:
28
+ url = f["link"]
29
+ print(f"Downloading Pexels video for: {q[:40]}")
30
+ r = requests.get(url, timeout=60, headers={
31
+ "User-Agent": "Mozilla/5.0",
32
+ "Referer": "https://www.pexels.com/"
33
+ })
34
+ path = f'/app/bg_{random.randint(1000,9999)}.mp4'
35
+ with open(path, 'wb') as file:
36
+ file.write(r.content)
37
+ return path
38
+ print("No Pexels video found")
39
  return None
40
  except Exception as e:
41
+ print(f"Pexels video error: {e}")
42
  return None
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  def generate_tts(text, output_path):
45
  try:
46
  from gtts import gTTS
47
+ hindi_chars = sum(1 for c in text if '\u0900' <= c <= '\u097F')
48
+ lang = 'hi' if hindi_chars > 5 else 'en'
49
+ tts = gTTS(text=text, lang=lang, slow=False)
50
  tts.save(output_path)
51
  return True
52
  except Exception as e:
 
54
  return False
55
 
56
  def generate_video(script, title, description):
57
+ print("Starting video generation...")
58
+ print(f"Script: {script[:100]}")
59
 
60
  sentences = re.split(r'[.!?\n]', script)
61
  sentences = [s.strip() for s in sentences if len(s.strip()) > 5]
 
64
  words = script.split()
65
  sentences = [' '.join(words[i:i+8]) for i in range(0, len(words), 8)]
66
 
67
+ sentences = sentences[:8]
68
  print(f"Total clips: {len(sentences)}")
69
 
70
  clips = []
71
+ temp_files = []
72
 
73
  for i, sentence in enumerate(sentences):
74
  print(f"Creating clip {i+1}/{len(sentences)}")
75
 
 
 
 
 
76
  audio_path = f'/app/audio_{i}.mp3'
77
  has_audio = generate_tts(sentence, audio_path)
78
 
 
 
 
 
79
  if has_audio and os.path.exists(audio_path):
80
  audio = AudioFileClip(audio_path)
81
+ duration = max(audio.duration + 0.3, 3)
82
+ temp_files.append(audio_path)
 
83
  else:
84
+ audio = None
85
+ duration = 4
86
+
87
+ bg_path = get_pexels_video(sentence[:30])
88
+
89
+ if bg_path and os.path.exists(bg_path):
90
+ try:
91
+ bg_clip = VideoFileClip(bg_path)
92
+ bg_duration = bg_clip.duration
93
+ if bg_duration < duration:
94
+ bg_clip = bg_clip.loop(duration=duration)
95
+ else:
96
+ bg_clip = bg_clip.subclip(0, duration)
97
+
98
+ # Crop to 9:16
99
+ w, h = bg_clip.size
100
+ target_w = int(h * 9 / 16)
101
+ if target_w < w:
102
+ x1 = (w - target_w) // 2
103
+ bg_clip = bg_clip.crop(x1=x1, y1=0, x2=x1+target_w, y2=h)
104
+ bg_clip = bg_clip.resize((1080, 1920))
105
+ clip = bg_clip
106
+ temp_files.append(bg_path)
107
+ except Exception as e:
108
+ print(f"Video clip error: {e}")
109
+ clip = ColorClip(size=(1080, 1920), color=[15, 15, 25], duration=duration)
110
+ else:
111
+ clip = ColorClip(size=(1080, 1920), color=[15, 15, 25], duration=duration)
112
+
113
+ if audio:
114
+ clip = clip.set_audio(audio)
115
 
116
+ clip = clip.fadein(0.3).fadeout(0.3)
117
  clips.append(clip)
118
 
119
  if not clips:
 
123
  print("Combining clips...")
124
  final = concatenate_videoclips(clips, method="compose")
125
 
 
126
  print("Writing video...")
127
  final.write_videofile(
128
+ VIDEO_PATH,
129
  fps=FPS,
130
  codec='libx264',
131
  audio_codec='aac',
 
133
  logger=None
134
  )
135
 
136
+ for f in temp_files:
137
  try:
138
+ os.remove(f)
139
  except:
140
  pass
141
 
142
+ print("Video generated successfully!")
143
  return True
144
 
145
  if __name__ == '__main__':