-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstreamlit_app.py
324 lines (247 loc) · 15.2 KB
/
streamlit_app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
import streamlit as st
import tempfile
import os
import requests
import openai
from elevenlabs import set_api_key, generate, voices, clone
from st_files_connection import FilesConnection
import pathlib
from typing import List
from pydub.utils import mediainfo
import uuid
def main():
st.title("Welcome to :red[__Storify__]")
# Instantiate some variables in the session state
if "generated_story" not in st.session_state:
st.session_state.generated_story = "Hello, How are you doing? Let's do something amazing!"
if "voice_path" not in st.session_state:
st.session_state.voice_path = ""
if "voice" not in st.session_state:
st.session_state.voice = ""
if "custom_file" not in st.session_state:
st.session_state.custom_file = ""
# Create connection object and retrieve file contents.
conn = st.experimental_connection('s3', type=FilesConnection)
def generate_story(prompt):
response = openai.Completion.create(
engine="text-davinci-003", # GPT-3.5 Turbo engine
prompt=prompt,
max_tokens=150, # Adjust this based on how long you want the story to be
n=1,
stop=None, # You can specify a stop condition if needed
temperature=0.7, # Adjust the temperature to control the randomness of the output
frequency_penalty=0.0,
presence_penalty=0.0
)
return response.choices[0].text.strip()
@st.cache_data(show_spinner="Voices are loading...")
def get_list_of_voices():
return [v.name for v in voices()]
def generate_audio(text: str, voice: str = "Rachel", model: str = "eleven_multilingual_v1"):
audio = generate(text=text, voice=voice, model=model)
random_file_name = str(uuid.uuid4())
audio_path = random_file_name + ".mp3"
try:
with conn.open("storifybucket/"+audio_path, 'wb') as f:
f.write(audio)
return audio_path
except Exception as e:
print(e)
return ""
def generate_new_voice(text: str, name: str, description: str, files: List[str]):
audio_path = name + ".mp3"
voice = clone(
name=name,
description=description,
files=files
)
audio = generate(text=text, voice=voice)
try:
with conn.open("storifybucket/"+audio_path, 'wb') as f:
f.write(audio)
return audio_path
except Exception as e:
print(e)
return ""
with st.container():
st.header(":orange[Story Generation]")
st.write("-----")
#left_column, right_column = st.columns(1)
with st.container():
# User can select to provide full story or generate it
story_option = st.selectbox("Choose an option:", ["Upload your own story", "Generate story using OpenAI"])
if story_option == "Upload your own story":
with st.form(key="story_upload_option"):
uploaded_file = st.file_uploader("Upload your story file", type=["txt"])
if uploaded_file is not None:
try:
# Read the contents of the uploaded file
input_story = uploaded_file.read().decode("utf-8")
# Display the uploaded story
st.text_area("Your uploaded story:", value=input_story, key="user_story", height=300)
except Exception as e:
st.error(f"Error reading the file: {e}")
submit_button = st.form_submit_button(label="Set Story")
if submit_button:
if input_story in ("", "None", None):
st.error("Make sure you enter your story above..")
st.session_state.generated_story = input_story
elif story_option == "Generate story using OpenAI":
openai_api_key = st.text_input("Fill OpenAI API Key", type="password")
if openai_api_key != "":
openai.api_key = openai_api_key
with st.form(key="generate_story_form"):
story_type = st.selectbox("Select Story:", ["Fairy Tale", "Horror", "Success", "Science Fiction", "Action", "Love", "Thriller", "Comedy"])
age = st.selectbox("Age Group:", ["Children", "Teenagers", "Adults"])
language = st.selectbox("Language:", ["English"])
extra_text = st.text_area("Write story character name/details (Not Required):", "")
submit_button = st.form_submit_button(label="Let's Magic")
if submit_button:
try:
# Create a more descriptive prompt for generating the story
if extra_text:
story_prompt = f"Generate a {age} {story_type} story in {language} language. Additional Information about the story: {extra_text}"
else:
story_prompt = f"Generate a {age} {story_type} story in {language} language."
with st.spinner('Wait for magic...'):
# Generate story (replace this with your AI-based story generation logic)
generated_story = generate_story(prompt=story_prompt)
st.session_state.generated_story = generated_story.lstrip()
st.text_area("Generated Story:", value=st.session_state.story)
except UnboundLocalError: # Catch the specific error you're interested in
st.error("Please enter your OpenAI API Key to do magic.")
with st.container():
st.header(":orange[Audio Generation]")
st.write("-----")
with st.container():
elevenlabs_api_key = st.text_input("Fill ElevenLabs API Key", type="password")
if elevenlabs_api_key != "":
set_api_key(elevenlabs_api_key)
audio_option = st.selectbox("Generate audio:", ["Use default voices", "Custom voice"])
if audio_option == "Use default voices":
with st.form(key="voice_form"):
try:
voice = st.selectbox("Choose a voice:", get_list_of_voices())
except UnboundLocalError as e:
st.error(e)
voice = st.selectbox("Choose a voice:", ["Rachel"])
model = st.selectbox("Choose a model:", ["eleven_multilingual_v1"])
st.session_state.voice = voice
voice_submit_button = st.form_submit_button(label="Generate Audio")
if voice_submit_button:
try:
with st.spinner("Generating your audio..."):
# Generate audio
audio = generate_audio(
text=st.session_state.generated_story,
voice=voice,
model=model
)
print(audio)
st.audio(conn.open("storifybucket/"+audio, mode="rb").read(), format="audio/mp3")
st.session_state.voice_path = audio
except UnboundLocalError: # Catch the specific error you're interested in
st.error("Please enter your ElevenLabs API Key to generate a story.")
elif audio_option == "Custom voice":
with st.form(key="clone_form"):
voice_name = st.text_input("Voice name:", key="voice_name")
voice_description = st.text_input(
label="Voice description:",
key="voice_description",
placeholder="Gradma sound"
)
voice_file = st.file_uploader("Upload a voice sample for the custom voice", type=['mp3', 'wav'])
clone_submit_button = st.form_submit_button(label="Generate Audio")
if clone_submit_button and voice_file is not None:
print(voice_file)
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmpfile:
# Write the uploaded audio bytes to temp file
tmpfile.write(voice_file.getvalue())
tmp_filename = tmpfile.name
# Add validation for maximum length of the audio file
audio_info = mediainfo(tmp_filename)
if float(audio_info["duration"]) > 120:
st.error("Uploaded audio is too long. Please upload an audio of maximum 2 minutes.")
try:
with st.spinner("Creating custom voice..."):
audio = generate_new_voice(
text=st.session_state.generated_story,
name=voice_name,
description=voice_description,
files=[tmp_filename]
)
st.audio(conn.open("storifybucket/"+audio, mode="rb").read(), format="audio/mp3")
st.session_state.voice = "custom"
st.session_state.voice_path = audio
except Exception as e:
print(e)
st.error("Cloning went wrong...")
finally:
os.remove(tmp_filename)
if st.session_state.voice_path != "":
with st.container():
st.header(":orange[Video Generation]")
st.write("-----")
with st.container():
video_option = st.selectbox("Generate a video:", ["Upload my video/image", "Generate Using AI"])
if video_option == "Upload my video/image":
with st.form(key="custom_video_image_form"):
uploaded_file = st.file_uploader("Upload files:", [".png", ".jpg", ".mp4"], accept_multiple_files=False)
video_submitt_button = st.form_submit_button("Upload File")
if video_submitt_button:
with st.spinner("Uploading file..."):
random_file_name = str(uuid.uuid4())
custom_file_path = random_file_name + pathlib.Path(uploaded_file.name).suffix
st.session_state.custom_file = custom_file_path
try:
with conn.open("storifybucket/"+custom_file_path, 'wb') as f:
f.write(uploaded_file.read())
except Exception as e:
print(e)
elif video_option == "Generate Using AI":
if st.session_state.voice == "custom":
gender = st.selectbox("Choose voice gender:", ["male", "female"])
st.session_state.custom_file = "character/" + gender + ".png"
else:
if st.session_state.voice in ["Rachel", "Adam", "Antoni", "Arnold", "Charlotte", "Emily", "Joseph"]:
ext = ".mp4"
st.session_state.custom_file = "character/" + st.session_state.voice.lower() + ext
elif st.session_state.voice in ["Callum", "Charlie"]:
ext = ".png"
st.session_state.custom_file = "character/" + st.session_state.voice.lower() + ext
else:
m_random = ["random_m1.mp4", "random_m2.mp4", "random_m4.png", "random_m5.png", "random_m6.png"]
f_random = ["random_f2.mp4", "random_m3.mp4", "random_f3.mp4", "random_f4.mp4", "random_f5.mp4", "random_f6.mp4"]
gender = st.selectbox("Choose voice gender:", ["male", "female"])
st.session_state.custom_file = "random/" + random.choice(m_random) if gender == "male" else random.choice(f_random)
if st.session_state.custom_file != "" :
generate_button = st.button("Generate Video")
if generate_button:
try:
with st.spinner("Generating your video..."):
try:
payload = {
"input_face": "https://storifybucket.s3.amazonaws.com/" + st.session_state.custom_file,
"input_audio": "https://storifybucket.s3.amazonaws.com/"+st.session_state.voice_path,
}
response = requests.post("https://api.gooey.ai/v2/Lipsync/",
headers={"Authorization": "Bearer sk-hPpa7h88ZFrgtisdVMZsURODCskCVihRKQF8pWIlCX9pZvyj"},
json=payload,
)
result = response.json()
res = requests.get(result['output']['output_video'])
st.video(res.content, format="video/mp4")
# Download video
st.download_button(
label="Download Video",
data=res.content,
file_name=result['id'] + ".mp4",
mime="video/mp4",
on_click=None
)
except Exception as e:
print(e)
except Exception as e:
st.error("")
if __name__ == "__main__":
main()