Pushp0120 commited on
Commit
e7e354e
·
verified ·
1 Parent(s): d2b91aa

Update generate.py

Browse files
Files changed (1) hide show
  1. generate.py +61 -26
generate.py CHANGED
@@ -11,41 +11,58 @@ import upload
11
 
12
  WIDTH, HEIGHT = 1080, 1920
13
  FPS = 30
14
- DURATION_PER_LINE = 3
15
- PEXELS_API_KEY = os.environ.get('PEXELS_API_KEY', '')
16
 
17
- def get_background_image(keyword):
 
18
  try:
19
- headers = {'Authorization': PEXELS_API_KEY}
20
- r = requests.get(
21
- f'https://api.pexels.com/v1/search?query={keyword}&per_page=5&orientation=portrait',
22
- headers=headers, timeout=10
23
- )
24
- data = r.json()
25
- if data.get('photos'):
26
- photo_url = data['photos'][0]['src']['portrait']
27
- img_response = requests.get(photo_url, timeout=15)
28
- img = Image.open(BytesIO(img_response.content)).convert('RGB')
 
 
 
 
29
  img = img.resize((WIDTH, HEIGHT))
30
- overlay = Image.new('RGB', (WIDTH, HEIGHT), (0, 0, 0))
31
- img = Image.blend(img, overlay, 0.55)
32
  return img
 
 
 
33
  except Exception as e:
34
- print(f"Pexels error: {e}")
35
- return None
36
 
37
  def make_text_frame(text, bg_image=None):
38
  if bg_image:
39
  img = bg_image.copy()
40
  else:
41
  img = Image.new('RGB', (WIDTH, HEIGHT), color=(15, 15, 25))
 
 
 
 
 
 
 
42
  draw = ImageDraw.Draw(img)
43
  try:
44
  font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 65)
45
  except:
46
  font = ImageFont.load_default()
47
- draw.rectangle([60, 180, WIDTH-60, 193], fill=(255, 80, 80))
48
- draw.rectangle([60, HEIGHT-193, WIDTH-60, HEIGHT-180], fill=(255, 80, 80))
 
 
 
 
49
  lines = textwrap.wrap(text, width=22)
50
  y = HEIGHT // 2 - (len(lines) * 85) // 2
51
  for line in lines:
@@ -55,6 +72,7 @@ def make_text_frame(text, bg_image=None):
55
  draw.text((x+4, y+4), line, font=font, fill=(0, 0, 0))
56
  draw.text((x, y), line, font=font, fill=(255, 255, 255))
57
  y += 90
 
58
  return np.array(img)
59
 
60
  def generate_tts(text, output_path):
@@ -68,24 +86,35 @@ def generate_tts(text, output_path):
68
  return False
69
 
70
  def generate_video(script, title, description):
71
- print("Starting video generation...")
72
  print(f"Script received: {script[:100]}")
 
73
  sentences = re.split(r'[.!?\n]', script)
74
  sentences = [s.strip() for s in sentences if len(s.strip()) > 5]
 
75
  if not sentences:
76
  words = script.split()
77
  sentences = [' '.join(words[i:i+8]) for i in range(0, len(words), 8)]
78
- sentences = sentences[:15]
 
79
  print(f"Total clips: {len(sentences)}")
80
- keyword = title.replace('#shorts', '').replace('Facts', '').strip()
81
- print(f"Fetching background for: {keyword}")
82
- bg_image = get_background_image(keyword)
83
  clips = []
 
84
  for i, sentence in enumerate(sentences):
85
  print(f"Creating clip {i+1}/{len(sentences)}")
 
 
 
 
 
86
  audio_path = f'/app/audio_{i}.mp3'
87
  has_audio = generate_tts(sentence, audio_path)
 
 
88
  frame = make_text_frame(sentence, bg_image)
 
 
89
  if has_audio and os.path.exists(audio_path):
90
  audio = AudioFileClip(audio_path)
91
  duration = max(audio.duration + 0.5, DURATION_PER_LINE)
@@ -93,13 +122,17 @@ def generate_video(script, title, description):
93
  clip = clip.set_audio(audio)
94
  else:
95
  clip = ImageClip(frame, duration=DURATION_PER_LINE)
96
- clip = clip.fadein(0.3).fadeout(0.3)
 
97
  clips.append(clip)
 
98
  if not clips:
99
  print("No clips generated!")
100
  return False
 
101
  print("Combining clips...")
102
  final = concatenate_videoclips(clips, method="compose")
 
103
  output_path = '/app/video.mp4'
104
  print("Writing video...")
105
  final.write_videofile(
@@ -110,12 +143,14 @@ def generate_video(script, title, description):
110
  verbose=False,
111
  logger=None
112
  )
 
113
  for i in range(len(sentences)):
114
  try:
115
  os.remove(f'/app/audio_{i}.mp3')
116
  except:
117
  pass
118
- print("Video generated successfully!")
 
119
  return True
120
 
121
  if __name__ == '__main__':
 
11
 
12
  WIDTH, HEIGHT = 1080, 1920
13
  FPS = 30
14
+ DURATION_PER_LINE = 4
15
+ HF_TOKEN = os.environ.get('HF_TOKEN', '')
16
 
17
+ def generate_ai_image(prompt):
18
+ """Generate cinematic image using SDXL on HF"""
19
  try:
20
+ API_URL = "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0"
21
+ headers = {"Authorization": f"Bearer {HF_TOKEN}"}
22
+ payload = {
23
+ "inputs": f"cinematic shot, {prompt}, 9:16 vertical, high quality, dramatic lighting, photorealistic",
24
+ "parameters": {
25
+ "width": 576,
26
+ "height": 1024,
27
+ "num_inference_steps": 20
28
+ }
29
+ }
30
+ print(f"Generating AI image for: {prompt[:50]}")
31
+ response = requests.post(API_URL, headers=headers, json=payload, timeout=60)
32
+ if response.status_code == 200:
33
+ img = Image.open(BytesIO(response.content)).convert('RGB')
34
  img = img.resize((WIDTH, HEIGHT))
 
 
35
  return img
36
+ else:
37
+ print(f"SDXL error: {response.status_code} - {response.text[:100]}")
38
+ return None
39
  except Exception as e:
40
+ print(f"AI image error: {e}")
41
+ return None
42
 
43
  def make_text_frame(text, bg_image=None):
44
  if bg_image:
45
  img = bg_image.copy()
46
  else:
47
  img = Image.new('RGB', (WIDTH, HEIGHT), color=(15, 15, 25))
48
+
49
+ # Dark overlay for text readability
50
+ overlay = Image.new('RGBA', (WIDTH, HEIGHT), (0, 0, 0, 160))
51
+ img = img.convert('RGBA')
52
+ img = Image.alpha_composite(img, overlay)
53
+ img = img.convert('RGB')
54
+
55
  draw = ImageDraw.Draw(img)
56
  try:
57
  font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 65)
58
  except:
59
  font = ImageFont.load_default()
60
+
61
+ # Accent lines
62
+ draw.rectangle([60, 180, WIDTH-60, 195], fill=(255, 80, 80))
63
+ draw.rectangle([60, HEIGHT-195, WIDTH-60, HEIGHT-180], fill=(255, 80, 80))
64
+
65
+ # Text
66
  lines = textwrap.wrap(text, width=22)
67
  y = HEIGHT // 2 - (len(lines) * 85) // 2
68
  for line in lines:
 
72
  draw.text((x+4, y+4), line, font=font, fill=(0, 0, 0))
73
  draw.text((x, y), line, font=font, fill=(255, 255, 255))
74
  y += 90
75
+
76
  return np.array(img)
77
 
78
  def generate_tts(text, output_path):
 
86
  return False
87
 
88
  def generate_video(script, title, description):
89
+ print("Starting cinematic video generation...")
90
  print(f"Script received: {script[:100]}")
91
+
92
  sentences = re.split(r'[.!?\n]', script)
93
  sentences = [s.strip() for s in sentences if len(s.strip()) > 5]
94
+
95
  if not sentences:
96
  words = script.split()
97
  sentences = [' '.join(words[i:i+8]) for i in range(0, len(words), 8)]
98
+
99
+ sentences = sentences[:10]
100
  print(f"Total clips: {len(sentences)}")
101
+
 
 
102
  clips = []
103
+
104
  for i, sentence in enumerate(sentences):
105
  print(f"Creating clip {i+1}/{len(sentences)}")
106
+
107
+ # Generate AI image for this sentence
108
+ bg_image = generate_ai_image(sentence)
109
+
110
+ # Generate TTS
111
  audio_path = f'/app/audio_{i}.mp3'
112
  has_audio = generate_tts(sentence, audio_path)
113
+
114
+ # Create frame
115
  frame = make_text_frame(sentence, bg_image)
116
+
117
+ # Create clip
118
  if has_audio and os.path.exists(audio_path):
119
  audio = AudioFileClip(audio_path)
120
  duration = max(audio.duration + 0.5, DURATION_PER_LINE)
 
122
  clip = clip.set_audio(audio)
123
  else:
124
  clip = ImageClip(frame, duration=DURATION_PER_LINE)
125
+
126
+ clip = clip.fadein(0.5).fadeout(0.5)
127
  clips.append(clip)
128
+
129
  if not clips:
130
  print("No clips generated!")
131
  return False
132
+
133
  print("Combining clips...")
134
  final = concatenate_videoclips(clips, method="compose")
135
+
136
  output_path = '/app/video.mp4'
137
  print("Writing video...")
138
  final.write_videofile(
 
143
  verbose=False,
144
  logger=None
145
  )
146
+
147
  for i in range(len(sentences)):
148
  try:
149
  os.remove(f'/app/audio_{i}.mp3')
150
  except:
151
  pass
152
+
153
+ print("Cinematic video generated successfully!")
154
  return True
155
 
156
  if __name__ == '__main__':