Update app.py
Browse files
app.py
CHANGED
@@ -25,18 +25,25 @@ app.config.update({
|
|
25 |
'ALLOWED_EXTENSIONS': {'mp4', 'mov', 'webm', 'avi'}
|
26 |
})
|
27 |
|
28 |
-
# Create directories
|
29 |
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
|
30 |
os.makedirs(app.config['DOWNLOAD_FOLDER'], exist_ok=True)
|
31 |
|
32 |
# Initialize Gemini AI
|
33 |
genai.configure(api_key=app.config['GEMINI_API_KEY'])
|
34 |
|
35 |
-
#
|
36 |
-
|
37 |
-
"Male (
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
}
|
41 |
|
42 |
GEMINI_PROMPT = """
|
@@ -69,7 +76,7 @@ def generate_script(video_path):
|
|
69 |
if video_file.state.name != "ACTIVE":
|
70 |
raise Exception("Gemini processing failed")
|
71 |
|
72 |
-
model = genai.GenerativeModel("models/gemini-
|
73 |
response = model.generate_content([GEMINI_PROMPT, video_file])
|
74 |
genai.delete_file(video_file.name)
|
75 |
|
@@ -78,15 +85,16 @@ def generate_script(video_path):
|
|
78 |
print(f"Gemini Error: {str(e)}")
|
79 |
raise
|
80 |
|
81 |
-
def generate_audio(script,
|
82 |
-
"""Generate audio using TTS API"""
|
83 |
try:
|
84 |
response = requests.post(
|
85 |
app.config['TTS_API_URL'],
|
86 |
json={
|
87 |
"text": script,
|
88 |
-
"
|
89 |
-
"tone": tone
|
|
|
90 |
},
|
91 |
timeout=300
|
92 |
)
|
@@ -131,22 +139,22 @@ def process_video(input_path, audio_data, output_filename):
|
|
131 |
|
132 |
@app.route('/', methods=['GET'])
|
133 |
def home():
|
134 |
-
return render_template('index.html', voices=
|
135 |
|
136 |
@app.route('/process', methods=['POST'])
|
137 |
def process():
|
138 |
if 'video' not in request.files:
|
139 |
flash('No file selected', 'error')
|
140 |
-
return render_template('index.html', voices=
|
141 |
|
142 |
file = request.files['video']
|
143 |
if file.filename == '':
|
144 |
flash('No file selected', 'error')
|
145 |
-
return render_template('index.html', voices=
|
146 |
|
147 |
if not allowed_file(file.filename):
|
148 |
flash('Invalid file type. Allowed: MP4, MOV, WEBM, AVI', 'error')
|
149 |
-
return render_template('index.html', voices=
|
150 |
|
151 |
try:
|
152 |
# Save uploaded file
|
@@ -155,12 +163,13 @@ def process():
|
|
155 |
file.save(input_path)
|
156 |
|
157 |
# Get processing options
|
158 |
-
|
159 |
-
|
|
|
160 |
|
161 |
# Generate script and audio
|
162 |
script = generate_script(input_path)
|
163 |
-
audio_data = generate_audio(script,
|
164 |
|
165 |
# Process video
|
166 |
output_filename = f"dubbed_{filename}"
|
@@ -169,11 +178,13 @@ def process():
|
|
169 |
flash('Processing completed successfully!', 'success')
|
170 |
return render_template('result.html',
|
171 |
video_url=url_for('download', filename=output_filename),
|
172 |
-
script=script
|
|
|
|
|
173 |
|
174 |
except Exception as e:
|
175 |
flash(f'Processing failed: {str(e)}', 'error')
|
176 |
-
return render_template('index.html', voices=
|
177 |
finally:
|
178 |
if 'input_path' in locals() and os.path.exists(input_path):
|
179 |
os.remove(input_path)
|
@@ -183,4 +194,4 @@ def download(filename):
|
|
183 |
return send_from_directory(app.config['DOWNLOAD_FOLDER'], filename)
|
184 |
|
185 |
if __name__ == '__main__':
|
186 |
-
app.run(host=
|
|
|
25 |
'ALLOWED_EXTENSIONS': {'mp4', 'mov', 'webm', 'avi'}
|
26 |
})
|
27 |
|
28 |
+
# Create directories
|
29 |
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
|
30 |
os.makedirs(app.config['DOWNLOAD_FOLDER'], exist_ok=True)
|
31 |
|
32 |
# Initialize Gemini AI
|
33 |
genai.configure(api_key=app.config['GEMINI_API_KEY'])
|
34 |
|
35 |
+
# Voice Configuration
|
36 |
+
VOICE_OPTIONS = {
|
37 |
+
"Male (Charon)": {
|
38 |
+
"id": "charon",
|
39 |
+
"description": "Deep, authoritative male voice",
|
40 |
+
"tone_options": ["neutral", "serious", "cheerful"]
|
41 |
+
},
|
42 |
+
"Female (Zephyr)": {
|
43 |
+
"id": "zephyr",
|
44 |
+
"description": "Soft, clear female voice",
|
45 |
+
"tone_options": ["neutral", "gentle", "energetic"]
|
46 |
+
}
|
47 |
}
|
48 |
|
49 |
GEMINI_PROMPT = """
|
|
|
76 |
if video_file.state.name != "ACTIVE":
|
77 |
raise Exception("Gemini processing failed")
|
78 |
|
79 |
+
model = genai.GenerativeModel("models/gemini-pro-vision")
|
80 |
response = model.generate_content([GEMINI_PROMPT, video_file])
|
81 |
genai.delete_file(video_file.name)
|
82 |
|
|
|
85 |
print(f"Gemini Error: {str(e)}")
|
86 |
raise
|
87 |
|
88 |
+
def generate_audio(script, voice_id, tone):
|
89 |
+
"""Generate audio using TTS API with specific voice"""
|
90 |
try:
|
91 |
response = requests.post(
|
92 |
app.config['TTS_API_URL'],
|
93 |
json={
|
94 |
"text": script,
|
95 |
+
"voice_id": voice_id,
|
96 |
+
"tone": tone,
|
97 |
+
"language": "tamil"
|
98 |
},
|
99 |
timeout=300
|
100 |
)
|
|
|
139 |
|
140 |
@app.route('/', methods=['GET'])
|
141 |
def home():
|
142 |
+
return render_template('index.html', voices=VOICE_OPTIONS)
|
143 |
|
144 |
@app.route('/process', methods=['POST'])
|
145 |
def process():
|
146 |
if 'video' not in request.files:
|
147 |
flash('No file selected', 'error')
|
148 |
+
return render_template('index.html', voices=VOICE_OPTIONS)
|
149 |
|
150 |
file = request.files['video']
|
151 |
if file.filename == '':
|
152 |
flash('No file selected', 'error')
|
153 |
+
return render_template('index.html', voices=VOICE_OPTIONS)
|
154 |
|
155 |
if not allowed_file(file.filename):
|
156 |
flash('Invalid file type. Allowed: MP4, MOV, WEBM, AVI', 'error')
|
157 |
+
return render_template('index.html', voices=VOICE_OPTIONS)
|
158 |
|
159 |
try:
|
160 |
# Save uploaded file
|
|
|
163 |
file.save(input_path)
|
164 |
|
165 |
# Get processing options
|
166 |
+
voice_name = request.form.get('voice')
|
167 |
+
voice_id = VOICE_OPTIONS[voice_name]['id']
|
168 |
+
tone = request.form.get('tone', 'neutral')
|
169 |
|
170 |
# Generate script and audio
|
171 |
script = generate_script(input_path)
|
172 |
+
audio_data = generate_audio(script, voice_id, tone)
|
173 |
|
174 |
# Process video
|
175 |
output_filename = f"dubbed_{filename}"
|
|
|
178 |
flash('Processing completed successfully!', 'success')
|
179 |
return render_template('result.html',
|
180 |
video_url=url_for('download', filename=output_filename),
|
181 |
+
script=script,
|
182 |
+
voice_used=voice_name,
|
183 |
+
tone_used=tone)
|
184 |
|
185 |
except Exception as e:
|
186 |
flash(f'Processing failed: {str(e)}', 'error')
|
187 |
+
return render_template('index.html', voices=VOICE_OPTIONS)
|
188 |
finally:
|
189 |
if 'input_path' in locals() and os.path.exists(input_path):
|
190 |
os.remove(input_path)
|
|
|
194 |
return send_from_directory(app.config['DOWNLOAD_FOLDER'], filename)
|
195 |
|
196 |
if __name__ == '__main__':
|
197 |
+
app.run(host='0.0.0.0', port=5000, debug=True)
|