Athspi commited on
Commit
ac9beab
·
verified ·
1 Parent(s): e2954cc

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +162 -203
templates/index.html CHANGED
@@ -3,242 +3,201 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>AutoSubGen Pro - AI Video Subtitle Generator</title>
 
 
7
  <style>
8
  body {
9
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
10
- line-height: 1.6;
11
- background-color: #f7f7f7;
12
- color: #333;
13
- margin: 0;
14
- padding: 20px;
15
  }
16
- .container {
17
- max-width: 800px;
18
- margin: 0 auto;
19
- background-color: #fff;
20
- padding: 30px;
21
- border-radius: 10px;
22
- box-shadow: 0 4px 15px rgba(0,0,0,0.1);
23
  }
24
- h1, h2 {
25
- text-align: center;
26
- color: #444;
27
  }
28
- h1 {
29
- font-size: 2.5em;
30
- margin-bottom: 5px;
31
  }
32
- h2 {
33
- font-size: 1.2em;
34
- font-weight: 300;
35
- margin-top: 0;
36
- margin-bottom: 30px;
37
- }
38
- form {
39
- display: flex;
40
- flex-direction: column;
41
- gap: 20px;
42
- }
43
- .form-group {
44
- border: 1px solid #ddd;
45
- padding: 20px;
46
- border-radius: 8px;
47
- }
48
- label {
49
- display: block;
50
- margin-bottom: 8px;
51
- font-weight: 600;
52
- color: #555;
53
- }
54
- input[type="file"], select {
55
- width: 100%;
56
- padding: 10px;
57
- border: 1px solid #ccc;
58
- border-radius: 5px;
59
- box-sizing: border-box;
60
- }
61
- .checkbox-group {
62
- display: flex;
63
- align-items: center;
64
- gap: 10px;
65
- }
66
- input[type="checkbox"] {
67
- width: 18px;
68
- height: 18px;
69
- }
70
- button {
71
- background-color: #007bff;
72
- color: white;
73
- padding: 12px 20px;
74
- border: none;
75
- border-radius: 5px;
76
- cursor: pointer;
77
- font-size: 1.1em;
78
- font-weight: 600;
79
- transition: background-color 0.3s;
80
- }
81
- button:hover {
82
- background-color: #0056b3;
83
- }
84
- #loader {
85
- display: none;
86
- text-align: center;
87
- padding: 20px;
88
- font-size: 1.2em;
89
- }
90
- #results {
91
- margin-top: 30px;
92
- border-top: 1px solid #eee;
93
- padding-top: 20px;
94
- }
95
- .result-item {
96
- background-color: #e9f5ff;
97
- border: 1px solid #b3d7ff;
98
- padding: 15px;
99
- margin-bottom: 15px;
100
- border-radius: 5px;
101
- }
102
- .result-item h3 {
103
- margin-top: 0;
104
- color: #0056b3;
105
- }
106
- .result-item a {
107
- display: inline-block;
108
- background-color: #28a745;
109
- color: white;
110
- padding: 8px 15px;
111
- text-decoration: none;
112
- border-radius: 5px;
113
- transition: background-color 0.3s;
114
- }
115
- .result-item a:hover {
116
- background-color: #218838;
117
- }
118
- .result-item video, .result-item audio {
119
- width: 100%;
120
- margin-top: 10px;
121
- border-radius: 5px;
122
- }
123
- .error {
124
- color: #D8000C;
125
- background-color: #FFD2D2;
126
- border: 1px solid #D8000C;
127
- padding: 15px;
128
- margin-bottom: 20px;
129
- border-radius: 5px;
130
- text-align: center;
131
  }
132
  </style>
133
  </head>
134
- <body>
135
- <div class="container">
136
- <h1>🎥 AutoSubGen Pro</h1>
137
- <h2>AI-Powered Video Subtitle Generator</h2>
 
 
 
138
 
139
  {% with messages = get_flashed_messages(with_categories=true) %}
140
- {% if messages %}
141
- {% for category, message in messages %}
142
- <div class="error">{{ message }}</div>
143
- {% endfor %}
144
- {% endif %}
 
 
 
 
 
145
  {% endwith %}
146
 
147
- <form id="upload-form" action="{{ url_for('process') }}" method="post" enctype="multipart/form-data">
148
- <div class="form-group">
149
- <label for="video">1. Upload Your Video File</label>
150
- <input type="file" id="video" name="video" accept="video/*" required>
151
- </div>
 
152
 
153
- <div class="form-group">
154
- <label for="language_dropdown">2. Select Video Language (or let AI detect it)</label>
155
- <select id="language_dropdown" name="source_language">
156
- {% for lang in supported_languages %}
157
- <option value="{{ lang }}">{{ lang }}</option>
158
- {% endfor %}
159
- </select>
160
- </div>
161
 
162
- <div class="form-group">
163
- <label for="translate_to_dropdown">3. (Optional) Translate Subtitles To:</label>
164
- <select id="translate_to_dropdown" name="translate_to">
165
- <option value="None">None</option>
166
- {% for lang in supported_languages[1:] %}
167
- <option value="{{ lang }}">{{ lang }}</option>
168
- {% endfor %}
169
- </select>
170
- </div>
171
 
172
- <div class="form-group">
173
- <label>4. (Optional) Additional Outputs</label>
174
- <div class="checkbox-group">
175
- <input type="checkbox" id="tts_checkbox" name="add_tts">
176
- <label for="tts_checkbox">Generate Text-to-Speech Audio of Subtitles</label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  </div>
178
- <div class="checkbox-group">
179
- <input type="checkbox" id="subtitles_checkbox" name="add_subtitles">
180
- <label for="subtitles_checkbox">Add Subtitles to Video (burn-in)</label>
 
 
 
 
 
 
 
 
 
 
 
181
  </div>
182
- </div>
183
 
184
- <button type="submit">Process Video</button>
185
- </form>
 
 
 
 
 
 
186
 
187
- <div id="loader">
188
- <p>Processing your video... This may take a few minutes.</p>
189
- <img src="https://i.gifer.com/ZKZg.gif" alt="Loading..." width="50">
 
 
190
  </div>
191
 
 
192
  {% if results %}
193
- <div id="results">
194
- <h2>Processing Complete!</h2>
195
- {% if results.detected_language %}
196
- <div class="result-item">
197
- <h3>Detected Language</h3>
198
- <p>{{ results.detected_language }}</p>
199
- </div>
200
- {% endif %}
201
 
202
- {% if results.original_srt_file %}
203
- <div class="result-item">
204
- <h3>Original Subtitles (SRT)</h3>
205
- <a href="{{ url_for('download_file', session_id=session_id, filename=results.original_srt_file) }}" download>Download Original SRT</a>
 
 
 
 
206
  </div>
207
- {% endif %}
208
 
209
- {% if results.translated_srt_file %}
210
- <div class="result-item">
211
- <h3>Translated Subtitles (SRT)</h3>
212
- <a href="{{ url_for('download_file', session_id=session_id, filename=results.translated_srt_file) }}" download>Download Translated SRT</a>
213
- </div>
214
- {% endif %}
215
-
216
- {% if results.tts_audio_file %}
217
- <div class="result-item">
218
- <h3>Text-to-Speech Audio</h3>
219
- <audio controls src="{{ url_for('download_file', session_id=session_id, filename=results.tts_audio_file) }}"></audio>
220
- <br>
221
- <a href="{{ url_for('download_file', session_id=session_id, filename=results.tts_audio_file) }}" download>Download TTS Audio (MP3)</a>
222
- </div>
223
- {% endif %}
224
-
225
- {% if results.output_video_file %}
226
- <div class="result-item">
227
- <h3>Video with Subtitles</h3>
228
- <video controls src="{{ url_for('download_file', session_id=session_id, filename=results.output_video_file) }}"></video>
229
- <br>
230
- <a href="{{ url_for('download_file', session_id=session_id, filename=results.output_video_file) }}" download>Download Final Video (MP4)</a>
231
  </div>
232
- {% endif %}
 
 
 
 
233
  </div>
234
  {% endif %}
235
 
236
  </div>
237
 
 
 
 
 
238
  <script>
239
- document.getElementById('upload-form').addEventListener('submit', function() {
240
- document.getElementById('loader').style.display = 'block';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  });
242
  </script>
 
243
  </body>
244
- </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Video Translator & Dubber</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
9
  <style>
10
  body {
11
+ font-family: 'Inter', sans-serif;
 
 
 
 
 
12
  }
13
+ .loader {
14
+ border-top-color: #3498db;
15
+ -webkit-animation: spin 1s linear infinite;
16
+ animation: spin 1s linear infinite;
 
 
 
17
  }
18
+ @-webkit-keyframes spin {
19
+ 0% { -webkit-transform: rotate(0deg); }
20
+ 100% { -webkit-transform: rotate(360deg); }
21
  }
22
+ @keyframes spin {
23
+ 0% { transform: rotate(0deg); }
24
+ 100% { transform: rotate(360deg); }
25
  }
26
+ .form-container {
27
+ transition: opacity 0.5s ease-in-out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }
29
  </style>
30
  </head>
31
+ <body class="bg-gray-100 text-gray-800">
32
+
33
+ <div class="container mx-auto p-4 sm:p-6 lg:p-8 max-w-4xl">
34
+ <header class="text-center mb-8">
35
+ <h1 class="text-3xl sm:text-4xl font-bold text-gray-900">Video Translator & Dubber</h1>
36
+ <p class="mt-2 text-md text-gray-600">Powered by Gemini & MoviePy</p>
37
+ </header>
38
 
39
  {% with messages = get_flashed_messages(with_categories=true) %}
40
+ {% if messages %}
41
+ <div class="mb-6">
42
+ {% for category, message in messages %}
43
+ <div class="p-4 rounded-md {% if category == 'error' %} bg-red-100 text-red-700 {% elif category == 'warning' %} bg-yellow-100 text-yellow-800 {% else %} bg-blue-100 text-blue-700 {% endif %}" role="alert">
44
+ <strong class="font-bold">{% if category == 'error' %}Error!{% elif category == 'warning' %}Warning:{% else %}Info:{% endif %}</strong>
45
+ <span class="block sm:inline">{{ message }}</span>
46
+ </div>
47
+ {% endfor %}
48
+ </div>
49
+ {% endif %}
50
  {% endwith %}
51
 
52
+ {% if not api_key_set %}
53
+ <div class="p-4 mb-6 rounded-md bg-red-100 text-red-700" role="alert">
54
+ <strong class="font-bold">Configuration Error!</strong>
55
+ <span class="block sm:inline">The `GEMINI_API_KEY` environment variable is not set. This application will not work until it is configured correctly on the server.</span>
56
+ </div>
57
+ {% endif %}
58
 
59
+ {% if imagemagick_missing %}
60
+ <div class="p-4 mb-6 rounded-md bg-yellow-100 text-yellow-800" role="alert">
61
+ <strong class="font-bold">Configuration Warning!</strong>
62
+ <span class="block sm:inline">ImageMagick is not detected. The feature to add burned-in subtitles to the final video is disabled. The rest of the features will work normally.</span>
63
+ </div>
64
+ {% endif %}
 
 
65
 
66
+ <div id="form-container" class="form-container bg-white p-6 sm:p-8 rounded-xl shadow-lg">
67
+ <form action="{{ url_for('process') }}" method="post" enctype="multipart/form-data" id="video-form">
68
+ <!-- File Upload -->
69
+ <div class="mb-6">
70
+ <label for="video" class="block text-lg font-medium text-gray-700 mb-2">1. Upload Your Video</label>
71
+ <input type="file" name="video" id="video" accept="video/*" required class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100 transition duration-150">
72
+ </div>
 
 
73
 
74
+ <!-- Language Selection -->
75
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
76
+ <div>
77
+ <label for="source_language" class="block text-lg font-medium text-gray-700 mb-2">2. Original Language</label>
78
+ <select name="source_language" id="source_language" class="w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500">
79
+ {% for lang in supported_languages %}
80
+ <option value="{{ lang }}">{{ lang }}</option>
81
+ {% endfor %}
82
+ </select>
83
+ </div>
84
+ <div>
85
+ <label for="translate_to" class="block text-lg font-medium text-gray-700 mb-2">3. Translate To (Optional)</label>
86
+ <select name="translate_to" id="translate_to" class="w-full p-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500">
87
+ <option value="None">None</option>
88
+ {% for lang in supported_languages %}
89
+ {% if lang != 'Auto Detect' %}
90
+ <option value="{{ lang }}">{{ lang }}</option>
91
+ {% endif %}
92
+ {% endfor %}
93
+ </select>
94
+ </div>
95
  </div>
96
+
97
+ <!-- Processing Options -->
98
+ <div class="mb-8">
99
+ <label class="block text-lg font-medium text-gray-700 mb-3">4. Choose Output Options</label>
100
+ <div class="space-y-3">
101
+ <div class="flex items-center">
102
+ <input id="add_subtitles" name="add_subtitles" type="checkbox" class="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" {% if imagemagick_missing %}disabled{% endif %}>
103
+ <label for="add_subtitles" class="ml-3 block text-sm font-medium text-gray-700">Add burned-in subtitles to video</label>
104
+ </div>
105
+ <div class="flex items-center">
106
+ <input id="add_tts" name="add_tts" type="checkbox" class="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500">
107
+ <label for="add_tts" class="ml-3 block text-sm font-medium text-gray-700">Replace audio with AI-generated voice (dubbing)</label>
108
+ </div>
109
+ </div>
110
  </div>
 
111
 
112
+ <!-- Submit Button -->
113
+ <div class="text-center">
114
+ <button type="submit" id="submit-btn" class="w-full sm:w-auto inline-flex justify-center items-center px-8 py-3 border border-transparent text-base font-medium rounded-full shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition duration-150 disabled:opacity-50" {% if not api_key_set %}disabled{% endif %}>
115
+ Process Video
116
+ </button>
117
+ </div>
118
+ </form>
119
+ </div>
120
 
121
+ <!-- Loading Spinner -->
122
+ <div id="loader-container" class="text-center my-10 hidden">
123
+ <div class="loader ease-linear rounded-full border-8 border-t-8 border-gray-200 h-32 w-32 mx-auto"></div>
124
+ <h2 class="text-2xl font-semibold mt-6 text-gray-700">Processing your video...</h2>
125
+ <p class="text-gray-500 mt-2">This may take several minutes depending on the video length.</p>
126
  </div>
127
 
128
+ <!-- Results Section -->
129
  {% if results %}
130
+ <div id="results-section" class="mt-10 bg-white p-6 sm:p-8 rounded-xl shadow-lg">
131
+ <h2 class="text-2xl font-bold text-gray-800 mb-6 border-b pb-3">Processing Complete!</h2>
132
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
 
 
 
 
 
133
 
134
+ {% if results.output_video_file %}
135
+ <div class="md:col-span-2 bg-gray-50 p-4 rounded-lg">
136
+ <h3 class="font-semibold text-lg text-gray-700 mb-3">Final Processed Video</h3>
137
+ <video class="w-full rounded-lg shadow-md" controls>
138
+ <source src="{{ url_for('download_file', session_id=session_id, filename=results.output_video_file) }}" type="video/mp4">
139
+ Your browser does not support the video tag.
140
+ </video>
141
+ <a href="{{ url_for('download_file', session_id=session_id, filename=results.output_video_file) }}" class="mt-4 inline-block w-full text-center px-6 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500">Download Final Video (.mp4)</a>
142
  </div>
143
+ {% endif %}
144
 
145
+ {% if results.original_srt_file or results.translated_srt_file or results.tts_audio_file %}
146
+ <div class="md:col-span-2">
147
+ <h3 class="font-semibold text-lg text-gray-700 mb-3">Downloadable Assets</h3>
148
+ <div class="space-y-3">
149
+ {% if results.original_srt_file %}
150
+ <a href="{{ url_for('download_file', session_id=session_id, filename=results.original_srt_file) }}" class="block bg-blue-50 hover:bg-blue-100 p-3 rounded-md transition duration-150">
151
+ <span class="font-medium text-blue-800">Original Subtitles (.srt)</span>
152
+ </a>
153
+ {% endif %}
154
+
155
+ {% if results.translated_srt_file %}
156
+ <a href="{{ url_for('download_file', session_id=session_id, filename=results.translated_srt_file) }}" class="block bg-purple-50 hover:bg-purple-100 p-3 rounded-md transition duration-150">
157
+ <span class="font-medium text-purple-800">Translated Subtitles (.srt)</span>
158
+ </a>
159
+ {% endif %}
160
+
161
+ {% if results.tts_audio_file %}
162
+ <a href="{{ url_for('download_file', session_id=session_id, filename=results.tts_audio_file) }}" class="block bg-teal-50 hover:bg-teal-100 p-3 rounded-md transition duration-150">
163
+ <span class="font-medium text-teal-800">Generated Audio (Dub) (.mp3)</span>
164
+ </a>
165
+ {% endif %}
166
+ </div>
167
  </div>
168
+ {% endif %}
169
+ </div>
170
+ <div class="text-center mt-8">
171
+ <a href="{{ url_for('index') }}" class="text-blue-600 hover:text-blue-800 font-medium">Process another video &rarr;</a>
172
+ </div>
173
  </div>
174
  {% endif %}
175
 
176
  </div>
177
 
178
+ <footer class="text-center p-4 mt-8">
179
+ <p class="text-sm text-gray-500">A project by the open-source community. Please use responsibly.</p>
180
+ </footer>
181
+
182
  <script>
183
+ const form = document.getElementById('video-form');
184
+ const submitBtn = document.getElementById('submit-btn');
185
+ const formContainer = document.getElementById('form-container');
186
+ const loaderContainer = document.getElementById('loader-container');
187
+
188
+ form.addEventListener('submit', function() {
189
+ // Check if form is valid before proceeding
190
+ if(form.checkValidity()){
191
+ submitBtn.disabled = true;
192
+ submitBtn.innerHTML = 'Processing...';
193
+ formContainer.style.opacity = '0';
194
+ setTimeout(() => {
195
+ formContainer.classList.add('hidden');
196
+ loaderContainer.classList.remove('hidden');
197
+ }, 500);
198
+ }
199
  });
200
  </script>
201
+
202
  </body>
203
+ </html>