sreepathi-ravikumar commited on
Commit
bf09443
·
verified ·
1 Parent(s): 90ac5e4

Update video.py

Browse files
Files changed (1) hide show
  1. video.py +42 -127
video.py CHANGED
@@ -1,93 +1,37 @@
1
- import os
2
- import asyncio
3
- import aiohttp
4
- import random
5
  from PIL import Image, ImageDraw, ImageFont
6
- from io import BytesIO
7
- from duckduckgo_search import DDGS
8
- import glob
9
- from moviepy.editor import *
10
- def video_generation(text, prompts):
11
-
12
- # -------- TEXT SPLITTING --------
13
- def split_text(text, word_count=30):
14
- words = text.split()
15
- lines = []
16
- for i in range(0, len(words) // word_count):
17
- line = " ".join(words[i * word_count:(i + 1) * word_count])
18
- lines.append(line)
19
- if len(words) % word_count != 0:
20
- lines.append(" ".join(words[(len(words) // word_count) * word_count:]))
21
- return lines
22
-
23
- # -------- ASYNC IMAGE SEARCH --------
24
- def get_headers():
25
- user_agents = [
26
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
27
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
28
- "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:90.0)"
29
- ]
30
- return {"User-Agent": random.choice(user_agents)}
31
 
32
- def is_valid_image(image):
33
- width, height = image.size
34
- aspect_ratio = round(width / height, 2)
35
- return width >= 854 and height >= 480 and abs(aspect_ratio - (16 / 9)) <= 0.2
36
 
37
- async def fetch_image(session, url, name):
38
- try:
39
- async with session.get(url, timeout=10) as response:
40
- content = await response.read()
41
- image = Image.open(BytesIO(content)).convert("RGB")
42
- if not is_valid_image(image):
43
- return None
44
- path = os.path.join("images", f"{name}.jpg")
45
- image.save(path)
46
- return path
47
- except:
48
- return None
49
 
50
- async def search_and_download(session, prompt):
51
- name = prompt.replace(" ", "_").lower()
52
- try:
53
- ddgs = DDGS()
54
- results = ddgs.images(prompt, max_results=15)
55
- for item in results:
56
- url = item.get("image")
57
- result = await fetch_image(session, url, name)
58
- if result:
59
- return result
60
- return None
61
- except:
62
- return None
63
 
64
- async def run_image_search(prompts):
65
- os.makedirs("images", exist_ok=True)
66
- async with aiohttp.ClientSession(headers=get_headers()) as session:
67
- tasks = [search_and_download(session, prompt) for prompt in prompts]
68
- return await asyncio.gather(*tasks)
69
 
70
- # -------- TEXT ON IMAGE --------
71
- def get_text_size(text, font):
72
- bbox = font.getbbox(text)
73
- width = bbox[2] - bbox[0]
74
- height = bbox[3] - bbox[1]
75
- return width, height
76
 
77
- def create_text_image(text, image_link):
78
- image = Image.open(image_link).convert("RGB")
79
- draw = ImageDraw.Draw(image)
80
- image_size = image.size
 
81
 
82
- font_path = "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf"
83
- max_font_size = 80
84
- min_font_size = 10
85
- best_font, best_lines = None, []
86
 
87
- for font_size in range(max_font_size, min_font_size, -2):
88
- font = ImageFont.truetype(font_path, font_size)
89
- words = text.split()
90
- lines, current_line = [], ""
91
 
92
  for word in words:
93
  test_line = f"{current_line} {word}" if current_line else word
@@ -100,49 +44,20 @@ def video_generation(text, prompts):
100
  if current_line:
101
  lines.append(current_line)
102
 
103
- total_height = sum(get_text_size(line, font)[1] + 10 for line in lines)
104
- if total_height <= image_size[1] * 0.95:
105
- best_font, best_lines = font, lines
106
- break
107
-
108
- y = (image_size[1] - total_height) // 2
109
- for line in best_lines:
110
- w, h = get_text_size(line, best_font)
111
- x = (image_size[0] - w) // 2
112
-
113
- for dx in range(-2, 3):
114
- for dy in range(-2, 3):
115
- if dx != 0 or dy != 0:
116
- draw.text((x + dx, y + dy), line, font=best_font, fill='black')
117
- draw.text((x, y), line, font=best_font, fill='white')
118
- y += h + 10
119
-
120
- image.save(image_link)
121
-
122
- # -------- VIDEO GENERATION --------
123
- def create_video_from_images(folder="images", output="output_video.mp4", duration=3):
124
- image_files = sorted(glob.glob(os.path.join(folder, "*.jpg")))
125
- if not image_files:
126
- raise ValueError("No images found!")
127
- clips = [ImageClip(m).set_duration(duration) for m in image_files]
128
- video = concatenate_videoclips(clips, method="compose")
129
- video.write_videofile(output, fps=24, audio=False)
130
- return output
131
-
132
- # -------- RUN COMPLETE PIPELINE --------
133
- lines = split_text(text)
134
- if len(lines) != len(prompts):
135
- print(len(lines),len(prompts))
136
- raise ValueError("The number of text chunks must match the number of prompts!")
137
-
138
- image_paths = asyncio.run(run_image_search(prompts))
139
- image_paths = [p for p in image_paths if p is not None]
140
-
141
- if len(image_paths) != len(lines):
142
- raise ValueError("Mismatch in number of images downloaded and text chunks!")
143
-
144
- for i in range(len(lines)):
145
- create_text_image(lines[i], image_paths[i])
146
-
147
- video_path = create_video_from_images()
148
- return os.path.abspath(video_path)
 
 
 
 
 
1
  from PIL import Image, ImageDraw, ImageFont
2
+ import os
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
+ os.makedirs("images",exist_ok=True)
 
 
 
5
 
6
+ def get_text_size(text, font):
7
+ bbox = font.getbbox(text)
8
+ width = bbox[2] - bbox[0]
9
+ height = bbox[3] - bbox[1]
10
+ return width, height
 
 
 
 
 
 
 
11
 
12
+ def create_text_image(text,id,image_olst, image_size=(1280, 720), bg_color="white", text_color="black"):
13
+ image = Image.new("RGB", image_size, color=bg_color)
14
+ draw = ImageDraw.Draw(image)
 
 
 
 
 
 
 
 
 
 
15
 
16
+ font_path = "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf"
17
+ max_font_size = 65
18
+ min_font_size = 10
 
 
19
 
20
+ best_font = None
21
+ best_lines = []
 
 
 
 
22
 
23
+ for font_size in range(max_font_size, min_font_size, -2):
24
+ font = ImageFont.truetype(font_path, font_size)
25
+ words = text.split()
26
+ lines = []
27
+ current_line = ""
28
 
29
+ lines_raw = text.splitlines()
30
+ lines = []
 
 
31
 
32
+ for raw_line in lines_raw:
33
+ words = raw_line.split()
34
+ current_line = ""
 
35
 
36
  for word in words:
37
  test_line = f"{current_line} {word}" if current_line else word
 
44
  if current_line:
45
  lines.append(current_line)
46
 
47
+ total_height = sum(get_text_size(line, font)[1] + 23 for line in lines)
48
+ if total_height <= image_size[1] * 0.95:
49
+ best_font = font
50
+ best_lines = lines
51
+ break
52
+
53
+ y = (image_size[1] - total_height) // 2
54
+ for line in best_lines:
55
+ w, h = get_text_size(line, best_font)
56
+ x = (image_size[0] - w) // 2
57
+ draw.text((x, y), line, font=best_font, fill=text_color)
58
+ y += h + 23
59
+ image_name="slide"+str(id)+".png"
60
+ image_olst.append(image_name)
61
+ image_path=os.path.join("images",image_name)
62
+ image.save(image_path)
63
+