NeuralFalcon commited on
Commit
ef77d50
ยท
verified ยท
1 Parent(s): 385564b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +268 -0
app.py ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ import gradio as gr
4
+ from deep_translator import GoogleTranslator
5
+ import os
6
+ import shutil
7
+ import subprocess
8
+ from PIL import Image, ImageDraw, ImageFont
9
+ import re
10
+ import uuid
11
+ # Path to the ZIP file
12
+ zip_file = "./fonts.zip"
13
+ # Destination folder
14
+ extract_to = "./fonts/"
15
+ # Extract the ZIP file
16
+ shutil.unpack_archive(zip_file, extract_to, 'zip')
17
+
18
+ # Generate unique filename for the video
19
+ def tts_file_name(text):
20
+ global temp_folder
21
+ # Remove all non-alphabetic characters and convert to lowercase
22
+ text = re.sub(r'[^a-zA-Z\s]', '', text) # Retain only alphabets and spaces
23
+ text = text.lower().strip() # Convert to lowercase and strip leading/trailing spaces
24
+ text = text.replace(" ", "_") # Replace spaces with underscores
25
+ # Truncate or handle empty text
26
+ truncated_text = text[:20] if len(text) > 20 else text if len(text) > 0 else ""
27
+
28
+ # Generate a random string for uniqueness
29
+ random_string = uuid.uuid4().hex[:8].upper()
30
+
31
+ # Construct the file name
32
+ file_name = f"{temp_folder}/{truncated_text}_{random_string}.mp4"
33
+ return file_name
34
+
35
+ temp_folder="./save_video"
36
+ os.makedirs(temp_folder,exist_ok=True)
37
+ # Translate text function
38
+ def translate_text(text, target_language):
39
+ try:
40
+ translator = GoogleTranslator(source='auto', target=target_language)
41
+ return translator.translate(text)
42
+ except Exception as e:
43
+ print(f"Translation error: {e}")
44
+ return text
45
+
46
+
47
+ ForeignLanguages = {
48
+ "en": "English", "zh-CN": "Mandarin Chinese", "hi": "Hindi", "es": "Spanish",
49
+ "fr": "French", "ar": "Standard Arabic", "bn": "Bengali", "pt": "Portuguese",
50
+ "ru": "Russian", "ur": "Urdu", "id": "Indonesian", "de": "German", "ja": "Japanese",
51
+ "pa": "Punjabi", "te": "Telugu", "tr": "Turkish", "ta": "Tamil", "vi": "Vietnamese", "ko": "Korean"
52
+ }
53
+
54
+ LocalIndianLanguages = {
55
+ "en": "English","hi": "Hindi", "bn": "Bengali", "mr": "Marathi", "te": "Telugu", "ta": "Tamil",
56
+ "gu": "Gujarati", "ur": "Urdu", "kn": "Kannada", "or": "Odia", "pa": "Punjabi", "ml": "Malayalam",
57
+ "mai": "Maithili","ne": "Nepali","sa": "Sanskrit","doi": "Dogri","sd": "Sindhi"
58
+
59
+ }
60
+
61
+
62
+
63
+ # Font Mapping
64
+ font_mapping = {
65
+ "Arial-Bold.TTF": [ "it", "pt", "tr", "id"],
66
+ "OpenSans-Bold.ttf": ["ru", "vi"],
67
+ "Poppins-Bold.ttf": ["en","es","fr","hi","de"],
68
+ "NotoSansJP-Bold.ttf":["ja"],
69
+ "NotoSansBengali-Bold.ttf":["bn"],
70
+ "NotoSansKR-Bold.ttf":["ko"],
71
+ "NotoSansTamil-Bold.ttf":["ta"],
72
+ "AnekTelugu-Bold.ttf":["te"],
73
+ "BraahOne-Regular.ttf":["pa"],
74
+ "NotoNastaliqUrdu-Bold.ttf":["ur"],
75
+ "NotoSansSC-Bold.ttf":["zh-CN"],
76
+ "NotoSansArabic-Bold.ttf":["ar","sd"],
77
+ "NotoSansGujarati-Bold.ttf":["gu"],
78
+ "NotoSansKannada-Bold.ttf":["kn"],
79
+ "AnekOdia-Bold.ttf":["or"],
80
+ "NotoSansMalayalam-Bold.ttf":["ml"],
81
+ "NotoSans-Bold.ttf":["mr"]
82
+
83
+ }
84
+
85
+
86
+ # Get font for language
87
+ def get_font_for_language(language):
88
+ for font, languages in font_mapping.items():
89
+ if language in languages:
90
+ return f"./fonts/{font}"
91
+ return "./fonts/NotoSans-Bold.ttf"
92
+
93
+ # Create image function
94
+ def create_image(text, language="en", font_size=100, text_color="#000000", bg_color="#FFFFFF", width=1024, height=1024, output_folder="./"):
95
+ img = Image.new('RGB', (width, height), color=bg_color)
96
+ draw = ImageDraw.Draw(img)
97
+ # font_path = "NotoSans-Regular.ttf"
98
+ font_path = get_font_for_language(language)
99
+ print(font_path)
100
+ font = ImageFont.truetype(font_path, font_size)
101
+ # try:
102
+ # font = ImageFont.truetype(font_path, font_size)
103
+ # except IOError:
104
+ # font = ImageFont.load_default()
105
+
106
+ bbox = draw.textbbox((0, 0), text, font=font)
107
+ text_width, text_height = bbox[2] - bbox[0], bbox[3] - bbox[1]
108
+ x, y = (width - text_width) // 2, (height - text_height) // 2
109
+ draw.text((x, y), text, fill=text_color, font=font)
110
+
111
+ filename = os.path.join(output_folder, f"frame_{language}.png")
112
+ img.save(filename)
113
+ return filename
114
+
115
+
116
+ import subprocess
117
+
118
+ def get_video_duration(video_file):
119
+ # Run FFmpeg to get video information in JSON format
120
+ result = subprocess.run(
121
+ ['ffmpeg', '-i', video_file],
122
+ stderr=subprocess.PIPE,
123
+ stdout=subprocess.PIPE
124
+ )
125
+
126
+ # Decode the stderr output to get the duration information
127
+ output = result.stderr.decode()
128
+
129
+ # Extract the duration from the output using regex
130
+ match = re.search(r'Duration: (\d+):(\d+):(\d+\.\d+)', output)
131
+
132
+ if match:
133
+ hours = int(match.group(1))
134
+ minutes = int(match.group(2))
135
+ seconds = float(match.group(3))
136
+
137
+ # Convert total duration to seconds
138
+ total_seconds = hours * 3600 + minutes * 60 + seconds
139
+ return total_seconds
140
+ else:
141
+ raise ValueError("Could not extract video duration.")
142
+
143
+
144
+
145
+
146
+ # Generate video function
147
+ def generate_video(input_text, language_set, font_size, theme, canvas_size):
148
+ width, height = map(int, canvas_size.split('x'))
149
+ theme_colors = {"Black Background": ("#FFFFFF", "#000000"), "White Background": ("#000000", "#FFFFFF")}
150
+ text_color, bg_color = theme_colors[theme]
151
+ output_folder = "temp_frames"
152
+ frames = "./frames"
153
+ # Cleanup previous frames
154
+ if os.path.exists(output_folder):
155
+ shutil.rmtree(output_folder)
156
+ os.makedirs(output_folder)
157
+ if os.path.exists(frames):
158
+ shutil.rmtree(frames)
159
+ os.makedirs(frames)
160
+
161
+ # Choose language set
162
+ language_list = list(ForeignLanguages.keys()) if language_set == "Foreign Languages" else list(LocalIndianLanguages.keys())
163
+ image_files = []
164
+
165
+ FPS = 30
166
+ DURATION_PER_IMAGE = 0.5 # 50ms duration per language
167
+ FRAMES_PER_IMAGE = round(FPS * DURATION_PER_IMAGE) # Frames needed per image
168
+ extra_frames = FRAMES_PER_IMAGE+10 # Extra frames for the last image to allow fade-out effect
169
+ frame_index = 0 # Start numbering frames
170
+
171
+ for i, lang in enumerate(language_list):
172
+ translated_text = translate_text(input_text, lang) if lang != 'en' else input_text
173
+ img_path = create_image(translated_text, lang, font_size, text_color, bg_color, width, height, output_folder)
174
+
175
+ # Check if it's the last image
176
+ frame_count = FRAMES_PER_IMAGE + extra_frames if i == len(language_list) - 1 else FRAMES_PER_IMAGE
177
+
178
+ # Duplicate frames for smooth video
179
+ for _ in range(frame_count):
180
+ frame_filename = os.path.join(frames, f"{frame_index:05d}.png")
181
+ shutil.copy(img_path, frame_filename)
182
+ frame_index += 1
183
+
184
+ # Generate video using FFmpeg
185
+ output_video = "multi_language_video.mp4"
186
+ subprocess.run([
187
+ "ffmpeg", "-y", "-r", str(FPS), "-i", f"{frames}/%05d.png",
188
+ "-c:v", "libx264", "-pix_fmt", "yuv420p", output_video
189
+ ])
190
+
191
+ # Add music to the generated video with fade-out effect
192
+ music_file = "./music.WAV" # Path to your music file
193
+
194
+ final_video = tts_file_name(input_text)
195
+ # subprocess.run([
196
+ # "ffmpeg", "-y", "-i", output_video, "-i", music_file,
197
+ # "-c:v", "libx264", "-c:a", "aac", "-strict", "experimental",
198
+ # "-af", "afade=t=out:st=4:d=1", # Fade out music at 4s, for 1 second
199
+ # "-shortest", final_video
200
+ # ])
201
+ # # Example usage
202
+
203
+ video_duration = get_video_duration(output_video)
204
+ # Adjust the start time and duration for the fade-out effect
205
+ fade_out_start = max(0, video_duration - 1) # Ensure the fade starts 1 second before the video ends
206
+ subprocess.run([
207
+ "ffmpeg", "-y", "-i", output_video, "-i", music_file,
208
+ "-c:v", "libx264", "-c:a", "aac", "-strict", "experimental",
209
+ "-af", f"afade=t=out:st={fade_out_start}:d=1", # Fade out for the last 1 second
210
+ "-shortest", final_video
211
+ ])
212
+
213
+
214
+ shutil.rmtree(output_folder) # Cleanup after generating video
215
+ shutil.rmtree(frames) # Cleanup after generating frames
216
+ return final_video, final_video
217
+
218
+ # Gradio UI Setup
219
+ def ui():
220
+ dummy_examples = [
221
+ ["Hello", "Foreign Languages"],
222
+ ["No", "Local Indian Languages"]
223
+ ]
224
+
225
+ with gr.Blocks() as demo:
226
+ gr.Markdown("<center><h1 style='font-size: 40px;'>See Your Name in Different Languages</h1></center>") # Larger title with CSS
227
+ with gr.Row():
228
+ with gr.Column():
229
+ input_text = gr.Textbox(label='๐Ÿ“ Enter Your Name', lines=3)
230
+ language_set = gr.Radio(
231
+ ["Foreign Languages", "Local Indian Languages"],
232
+ label="๐ŸŒLanguage Set",
233
+ value="Foreign Languages"
234
+ )
235
+ canvas_size = gr.Radio(
236
+ ["1920x1080", "1080x1920", "1024x1024"],
237
+ value="1024x1024",
238
+ label="๐Ÿ–ฅ๏ธ Canvas Size"
239
+ )
240
+ generate_btn = gr.Button('๐Ÿš€ Generate', variant='primary')
241
+
242
+ with gr.Accordion('๐Ÿ–Œ๏ธ Text Style', open=False):
243
+ font_size = gr.Slider(20, 200, value=100, step=1, label="๐Ÿ”  Font Size") # FIXED (Removed comma)
244
+ theme = gr.Radio(["Black Background", "White Background"], label="๐ŸŽจ Theme", value="Black Background")
245
+
246
+ with gr.Column():
247
+ download_video = gr.File(label="๐Ÿ“ฅ Download Video")
248
+ play_video = gr.Video(label="๐ŸŽฌ Generated Video")
249
+
250
+ # Define Inputs and Outputs
251
+ input_list = [input_text, language_set, font_size, theme, canvas_size]
252
+ output_list = [download_video, play_video]
253
+
254
+ # Bind Functions to UI Elements
255
+ input_text.submit(generate_video, inputs=input_list, outputs=output_list)
256
+ generate_btn.click(generate_video, inputs=input_list, outputs=output_list)
257
+
258
+ # Add examples
259
+ gr.Examples(examples=dummy_examples, inputs=[input_text, language_set])
260
+
261
+ return demo
262
+
263
+ # Launch the app
264
+ def main(share=True, debug=True):
265
+ demo = ui()
266
+ demo.queue().launch(debug=debug, share=share)
267
+
268
+ main()