Dy commited on
Commit
2ac6b63
1 Parent(s): f18bf59

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +314 -0
app.py ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from bs4 import BeautifulSoup
3
+ import gradio as gr
4
+ from langchain import OpenAI, ConversationChain, LLMChain, PromptTemplate
5
+ from langchain.memory import ConversationBufferWindowMemory
6
+ import openai
7
+ import requests
8
+ from langchain.chat_models import ChatOpenAI
9
+ import ast
10
+ import imgkit
11
+ import pdfkit
12
+ import imgkit
13
+ import re
14
+ import glob
15
+
16
+ import openai
17
+
18
+
19
+ OPENAI_API_KEY="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"
20
+
21
+
22
+ dict_list_format = '''[{'header': 'slide1_title',
23
+ 'paragraphs': ['bullet_point1',
24
+ 'bullet_point2',
25
+ 'bullet_point3',]},
26
+ 'header': 'slide2_title',
27
+ 'paragraphs': ['bullet_point1',
28
+ 'bullet_point2',
29
+ 'bullet_point3',
30
+ ...]},
31
+ 'header': 'slide3_title',
32
+ 'paragraphs': ['bullet_point1',
33
+ 'bullet_point2',
34
+ 'bullet_point3',
35
+ ...]},
36
+ 'header': 'slide4_title',
37
+ 'paragraphs': ['bullet_point1',
38
+ 'bullet_point2',
39
+ 'bullet_point3',
40
+ ...]},
41
+ 'header': 'slide5_title',
42
+ 'paragraphs': ['bullet_point1',
43
+ 'bullet_point2',
44
+ 'bullet_point3',
45
+ ...]}]
46
+ '''
47
+
48
+ import google.cloud.texttospeech as tts
49
+ from google.oauth2 import service_account
50
+ credentials = service_account.Credentials.from_service_account_file("tts_google.json")
51
+
52
+ def text_to_wav(voice_name: str, text: str, file_name: str):
53
+ language_code = "-".join(voice_name.split("-")[:2])
54
+ text_input = tts.SynthesisInput(text=text)
55
+ voice_params = tts.VoiceSelectionParams(
56
+ language_code=language_code, name=voice_name
57
+ )
58
+ audio_config = tts.AudioConfig(audio_encoding=tts.AudioEncoding.LINEAR16)
59
+
60
+ client = tts.TextToSpeechClient(credentials=credentials)
61
+ response = client.synthesize_speech(
62
+ input=text_input,
63
+ voice=voice_params,
64
+ audio_config=audio_config,
65
+ )
66
+
67
+ filename = f"{file_name}"
68
+ with open(filename, "wb") as out:
69
+ out.write(response.audio_content)
70
+ print(f'Generated speech saved to "{filename}"')
71
+
72
+
73
+
74
+ def prompt_to_video(video_prompt):
75
+
76
+ template = '''
77
+ {history}
78
+ {human_input}
79
+ '''
80
+ prompt = PromptTemplate(
81
+ input_variables=["history", "human_input"],
82
+ template=template
83
+ )
84
+
85
+ chatgpt_chain = LLMChain(
86
+ llm=ChatOpenAI(model="gpt-4", temperature=0.5,openai_api_key=OPENAI_API_KEY),
87
+ prompt=prompt,
88
+ verbose=True,
89
+ memory=ConversationBufferWindowMemory(k=10),
90
+ )
91
+
92
+ prompt_input1 = f'''
93
+ You are a world expert oracle that knows everything.
94
+ You are also an excellent teacher that explains everything succintly and simply like towards a kid.
95
+ You are also an expert slide maker and think everything step by step.
96
+ You are tasked to create 5 slides today.
97
+
98
+ Here is the topic:
99
+ {video_prompt}
100
+
101
+ Here is the output python list format:
102
+ {dict_list_format}
103
+
104
+ The slides should be created in a python list format.
105
+ The list consists of python dictionary objects in the list.
106
+ Each dictionary object contains the header and paragraphs as keys.
107
+ Do not name the slide as "Slide 1" or any number. Insert header as header string.
108
+ The header is the title of the slide and the paragraph should be a list of string object.
109
+ Return the output in a python list format.
110
+ Make sure there is only 5 objects in the python list.
111
+ Do not declare a new variable, output the python list object only.
112
+ Do not say "Here's your". Directly output the python list object only.
113
+ Make sure there is nothing before or after the python list object. ONLY output the python list object.
114
+ '''
115
+ slide_str_list = []
116
+ while len(slide_str_list) != 5:
117
+ slide_dict=chatgpt_chain.predict(human_input=prompt_input1)
118
+ try:
119
+ slide_str_list = ast.literal_eval(slide_dict)
120
+ except:
121
+ print("Already formatted.")
122
+
123
+
124
+ print("this is the slides:", slide_str_list)
125
+ print("length is:", len(slide_str_list))
126
+
127
+ html_out_list = []
128
+ for i in slide_str_list:
129
+
130
+ template = '''
131
+ {history}
132
+ {human_input}
133
+ '''
134
+ prompt = PromptTemplate(
135
+ input_variables=["history", "human_input"],
136
+ template=template
137
+ )
138
+
139
+ chatgpt_chain = LLMChain(
140
+ llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0.5,openai_api_key=OPENAI_API_KEY),
141
+ prompt=prompt,
142
+ verbose=True,
143
+ memory=ConversationBufferWindowMemory(k=10),
144
+ )
145
+ prompt_input2 = f'''
146
+ You are a world expert oracle that knows everything.
147
+ You are also an excellent teacher that explains everything succintly and simply like towards a kid.
148
+ You are also an expert slide maker and thinks about everything step by step.
149
+ You are tasked to convert a python dictionary into a formatted HTML code.
150
+ The dictionary object consist of the header and paragraph key.
151
+ The paragraph key is a list of strings.
152
+ Here is the dictionary object:
153
+ {i}
154
+ The slide should be created in a HTML format with the correct format of 16:9 aspect ratio.
155
+ The wording of the slides should be formatted appropriately with the header and paragraph.
156
+ The paragraph in the slides should be formatted in bullet points and each bullet point should be 1.5 line spacing apart.
157
+ Header and paragraph should be aligned in an aesthetically pleasing way.
158
+ Return the output as a nicely formatted HTML string.
159
+ Font should be Roboto.
160
+ Do not say "Here's your" or "Sure". Directly output the HTML string only.
161
+ Make sure there is nothing before or after the HTML string. ONLY output the HTML string.
162
+ Do not explain what is the HTML code about.
163
+ Do not declare a new variable, output the HTML string only.
164
+ '''
165
+ html_out_list.append(chatgpt_chain.predict(human_input=prompt_input2))
166
+
167
+ os.makedirs("slide", exist_ok=True)
168
+
169
+ num = 1
170
+ for html_string in html_out_list:
171
+ print(html_string)
172
+ with open(f"slide/slide_{num}.html", "w") as file:
173
+ file.write(html_string)
174
+ num = num + 1
175
+
176
+ extract_path = 'slide'
177
+
178
+ # Create the directory to extract to if it doesn't exist
179
+ os.makedirs(extract_path, exist_ok=True)
180
+
181
+ # Configuration for imgkit
182
+ config = imgkit.config(wkhtmltoimage='C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltoimage.exe')
183
+
184
+ # The path to store the images
185
+ image_path = os.path.join(extract_path, 'images')
186
+ os.makedirs(image_path, exist_ok=True)
187
+
188
+ # Get the list of HTML files
189
+ html_files = sorted([f for f in os.listdir(extract_path) if f.endswith('.html')])
190
+
191
+ # Dictionary to store the file names and their corresponding images
192
+ file_images = {}
193
+
194
+ # Loop through the HTML files and convert them to images
195
+ for html_file in html_files:
196
+ # Full path of the HTML file
197
+ full_path = os.path.join(extract_path, html_file)
198
+
199
+ # Image file name
200
+ image_file = re.sub('.html$', '.jpg', html_file)
201
+
202
+ # Full path of the image file
203
+ full_image_path = os.path.join(image_path, image_file)
204
+
205
+ # Convert the HTML to an image
206
+ imgkit.from_file(full_path, full_image_path, config=config)
207
+
208
+ # Store the image file name
209
+ file_images[html_file] = image_file
210
+
211
+ print(file_images)
212
+
213
+ template = '''
214
+ {history}
215
+ {human_input}
216
+ '''
217
+ prompt = PromptTemplate(
218
+ input_variables=["history", "human_input"],
219
+ template=template
220
+ )
221
+
222
+ chatgpt_chain = LLMChain(
223
+ llm=ChatOpenAI(model="gpt-4", temperature=0.5,openai_api_key=OPENAI_API_KEY),
224
+ prompt=prompt,
225
+ verbose=True,
226
+ memory=ConversationBufferWindowMemory(k=10),
227
+ )
228
+
229
+ prompt_input3 = f'''
230
+ You are a world expert oracle that knows everything.
231
+ You are also an excellent teacher that explains everything succintly and simply like towards a kid.
232
+ You are an expert orator and presenter.
233
+ You are tasked to create a voiceover for 5 slides.
234
+ The slides are formatted in a python list of dictionary objects.
235
+ Each dictionary object is a slide.
236
+ {slide_str_list}
237
+
238
+ Input: Python list of dictionary objects
239
+ Output: Python list of string objects
240
+
241
+ The output list consists of string objects.
242
+ The voiceover text purpose is a speech presentation of the slide.
243
+ The voiceover text should be about the content of each slide but at the same time add additional information to make the presentation funny and engaging.
244
+ Each string is a voiceover text of each slide of the python dictionary.
245
+ Each voiceover string object should be around 80 words.
246
+
247
+ Make sure there is only 5 objects in the python list.
248
+ Do not declare a new variable, output the python list object only.
249
+ Make sure there is nothing before or after the python list object. ONLY output the python list object.
250
+ Return the output in a python list format.
251
+ Do not say "Here's your" or "Sure". Directly output python list of dictionary object only.
252
+ Do not declare a new variable, output the python list of dictionary object only.
253
+ '''
254
+
255
+ voiceover_list = []
256
+
257
+ voiceover_list=chatgpt_chain.predict(human_input=prompt_input3)
258
+
259
+ try:
260
+ voiceover_list = ast.literal_eval(voiceover_list)
261
+ except:
262
+ print("Already formatted.")
263
+
264
+
265
+ num = 1
266
+ for i in voiceover_list:
267
+ file_name = "slide/slide" + f"_{num}" + ".wav"
268
+ text_to_wav("en-US-Neural2-F",i, file_name)
269
+ print(file_name)
270
+ num = num + 1
271
+
272
+
273
+ # Get list of .jpg and .wav files from the correct directories
274
+ jpg_files = sorted(glob.glob("slide/images/*.jpg"))
275
+ wav_files = sorted(glob.glob("slide/*.wav"))
276
+
277
+ jpg_files, wav_files
278
+
279
+ from moviepy.editor import ImageSequenceClip, AudioFileClip, concatenate_videoclips
280
+
281
+ # Create a list to store the clips
282
+ clips = []
283
+
284
+ # Loop through each jpg and wav file
285
+ for jpg_file, wav_file in zip(jpg_files, wav_files):
286
+ # Load the audio file and get its duration
287
+ audio = AudioFileClip(wav_file)
288
+ duration = audio.duration
289
+ print(duration)
290
+
291
+ # Calculate the frame rate as the inverse of the duration
292
+ fps = 1 / duration if duration != 0 else 1
293
+
294
+ # Create a video clip from the image and set its duration and fps to match the audio
295
+ clip = ImageSequenceClip([jpg_file], durations=[duration], fps=fps)
296
+
297
+ # Set the audio of the clip to the wav file
298
+ clip = clip.set_audio(audio)
299
+
300
+ # Add the clip to the list of clips
301
+ clips.append(clip)
302
+
303
+ # Concatenate all clips into a single video
304
+ video = concatenate_videoclips(clips)
305
+
306
+ video_path = "slide/output.mp4"
307
+
308
+ # Write the video to a file
309
+ video.write_videofile(video_path)
310
+
311
+
312
+ return video_path
313
+ iface = gr.Interface(fn=prompt_to_video, inputs="text", outputs=["file"])
314
+ iface.launch()