archivartaunik commited on
Commit
8a727d2
·
verified ·
1 Parent(s): 4033d78

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -202
app.py CHANGED
@@ -1,250 +1,179 @@
1
  import os
2
  import gradio as gr
3
- from google import genai
4
- from google.genai import types
5
  import mimetypes
6
  from pydub import AudioSegment
7
- import asyncio
8
- import logging
9
 
10
- # Configure logging
11
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
12
- logger = logging.getLogger(__name__)
13
-
14
- # Атрыманне ключоў і мадэляў з пераменных асяроддзя
15
  GEMINI_API_KEY = os.getenv("gemini")
16
- MODEL_NAME_TH = os.getenv("modTH") # Мадэль для транскрыпцыі
17
- MODEL_NAME = os.getenv("mod") # Мадэль для выпраўлення фармату і перакладу
18
- PROMPT_TRANSCRIBE = os.getenv("p") # Промпт для транскрыпцыі
19
 
20
- # Стварэнне кліента
21
- client = genai.Client(api_key=GEMINI_API_KEY)
22
 
23
- def transcribe_audio(audio_file: str) -> str:
24
- """Транскрыбуе аўдыяфайл з дапамогай Google GenAI."""
25
  try:
26
- if not audio_file or not os.path.exists(audio_file):
27
- return "Памылка: Файл не знойдзены або не указаны."
28
-
29
  mime_type, _ = mimetypes.guess_type(audio_file)
30
- if not mime_type or not mime_type.startswith("audio"):
31
- return (
32
- "Немагчыма вызначыць тып файла або файл не з'яўляецца аўдыяфайлам. "
33
- "Падтрымліваюцца толькі аўдыяфайлы."
34
- )
35
-
36
  with open(audio_file, "rb") as f:
37
  audio_data = f.read()
38
-
39
- # Стварэнне contents для перадачы ў API
40
- contents = [
41
- {"text": PROMPT_TRANSCRIBE},
42
- {"mime_type": mime_type, "data": audio_data},
43
- ]
44
-
45
- # Выклік API
46
- response = client.models.generate_content(
47
- model=MODEL_NAME_TH,
48
- contents=contents,
49
- config={"temperature": 0.2}
 
 
 
 
50
  )
51
-
52
- # Атрыманне адказу
53
- return response.text.strip()
54
-
 
 
 
 
 
55
  except FileNotFoundError:
56
- logger.error(f"Файл не знойдзены: {audio_file}")
57
  return "Памылка: Файл не знойдзены."
 
 
58
  except Exception as e:
59
- logger.error(f"Памылка пры транскрыпцыі: {str(e)}", exc_info=True)
60
  return f"Нечаканая памылка: {str(e)}"
61
 
62
-
63
- def fix_subtitles_format(transcript: str) -> str:
64
- """Выпраўляе фармат часу ў субцітрах."""
65
- if not transcript:
66
- return ""
67
-
68
- prompt_fix = (
69
- "Не змяняй тэксты, выправі толькі часовы фармат у субцітрах на правільны, "
70
- "вось прыклад 00:00:01,589. \nУ адказ напішы толькі субцітры:\n"
71
- f"{transcript}"
72
- )
73
  try:
74
- response_fix = client.models.generate_content(
75
- model=MODEL_NAME,
76
- contents=[{"text": prompt_fix}],
77
- config={"temperature": 0.2}
78
  )
79
- return response_fix.text.strip()
 
 
 
 
 
 
80
  except Exception as e:
81
- logger.error(f"Памылка пры выпраўленні субцітраў: {str(e)}", exc_info=True)
82
  return transcript
83
 
84
-
85
- def create_srt(transcript: str, filename: str = "subtitles.srt") -> tuple[str, str]:
86
- """Стварае SRT-файл з транскрыпцыі."""
87
- if not transcript:
88
- return "", ""
89
-
90
  try:
91
  with open(filename, "w", encoding="utf-8") as f:
92
  f.write(transcript)
93
  return transcript, filename
94
  except Exception as e:
95
- logger.error(f"Памылка пры запісе SRT-файла: {str(e)}", exc_info=True)
96
- return f"Памылка пры запісе SRT-файла: {str(e)}", ""
97
-
98
-
99
- def process_audio(audio_path: str) -> tuple[str, str]:
100
- """Апрацоўвае аўдыёфайл: транскрыбуе і стварае SRT."""
101
- if not audio_path:
102
- return "Не указаны шлях да аўдыёфайла.", ""
103
-
104
- transcript = transcribe_audio(audio_path)
105
- if transcript.startswith("Памылка") or transcript.startswith("Немагчыма") or transcript.startswith("Нечаканая"):
106
- return transcript, ""
107
 
 
 
 
 
 
108
  fixed_transcript = fix_subtitles_format(transcript)
109
  text, srt_file = create_srt(fixed_transcript)
110
  return text, srt_file
111
 
112
-
113
- def extract_audio_from_video(video_file: str) -> tuple[str, str]:
114
- """Выдзяляе аўдыёдарожку з відэафайла."""
115
- if not video_file or not os.path.exists(video_file):
116
- return "", "Памылка: Відэафайл не знойдзены або не указаны."
117
-
118
  try:
119
  audio = AudioSegment.from_file(video_file)
120
  audio_path = "extracted_audio.mp3"
121
  audio.export(audio_path, format="mp3")
122
- return audio_path, ""
123
  except Exception as e:
124
- logger.error(f"Памылка пры выдзяленні аўдыё з відэафайла: {str(e)}", exc_info=True)
125
- return "", f"Памылка пры выдзяленні аўдыё з відэафайла: {str(e)}"
126
-
127
 
128
- def process_video(video_path: str) -> tuple[str, str]:
129
- """Апрацоўвае відэафайл: выдзяляе аўдыё, транскрыбуе і стварае SRT."""
130
- if not video_path:
131
- return "Не указаны шлях да відэафайла.", ""
132
-
133
- audio_path, error = extract_audio_from_video(video_path)
134
  if error:
135
- return error, ""
136
  return process_audio(audio_path)
137
 
138
-
139
- def process_file(audio_path: str | None, video_path: str | None) -> tuple[str, str]:
140
- """Апрацоўвае файл (аўдыё або відэа)."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  try:
142
- if audio_path:
143
- return process_audio(audio_path)
144
- elif video_path:
145
- return process_video(video_path)
146
- else:
147
- return "Няма файла для апрацоўкі.", ""
148
- except Exception as e:
149
- logger.error(f"Памылка пры апрацоўцы файла: {str(e)}", exc_info=True)
150
- return f"Памылка пры апрацоўцы файла: {str(e)}", ""
151
-
152
-
153
- def update_on_audio_change(audio_path: str | None) -> gr.update:
154
- """Абнаўляе інтэрфейс пры змене аўдыёфайла."""
155
- try:
156
- return gr.update(value=None, interactive=not bool(audio_path))
157
- except Exception as e:
158
- logger.error(f"Памылка пры абнаўленні інтэрфейса: {str(e)}", exc_info=True)
159
- return gr.update(value=None, interactive=True)
160
-
161
-
162
- def update_on_video_change(video_path: str | None) -> gr.update:
163
- """Абнаўляе інтэрфейс пры змене відэафайла."""
164
- try:
165
- return gr.update(value=None, interactive=not bool(video_path))
166
- except Exception as e:
167
- logger.error(f"Памылка пры абнаўленні інтэрфейса: {str(e)}", exc_info=True)
168
- return gr.update(value=None, interactive=True)
169
-
170
-
171
- def translate_transcript(transcript: str, target_language: str) -> tuple[str, str]:
172
- """Перакладае транскрыпцыю на іншую мову і стварае SRT."""
173
- if not transcript:
174
- return "Няма тэксту для перакладу.", ""
175
-
176
- prompt_text = (
177
- f"Перакладзі толькі тэксты субцітраў на {target_language} мову. "
178
- "Астатняе пакінь як ёсць.\nТэкст:\n{transcript}"
179
- )
180
- try:
181
- response = client.models.generate_content(
182
- model=MODEL_NAME,
183
- contents=[{"text": prompt_text}],
184
- config={"temperature": 0.2}
185
  )
186
- translated = response.text.strip()
 
 
 
 
 
187
  translated_srt_filename = "translated_subtitles.srt"
188
- return create_srt(translated, translated_srt_filename)
 
 
189
  except Exception as e:
190
- logger.error(f"Памылка пры перакладзе: {str(e)}", exc_info=True)
191
- return f"Памылка пры перакладзе: {str(e)}", ""
192
-
193
-
194
- try:
195
- with gr.Blocks() as demo:
196
- gr.Markdown("# Транскрыпцыя аўдыя для беларускай мовы")
197
- gr.Markdown(
198
- """
199
- ## Загрузіце аўдыёфайл або відэафайл да 15 хвілін. Калі загружаны аўдыёфайл, відэа неактыўна, і наадварот.
200
- Субцітры будуць аўтаматычна згенераваны разам з SRT-файлам.
201
- [Далучайцеся да беларускаймоўнай суполкі ў ТГ](https://t.me/belarusai)
202
- **Падтрымаць праект:** [Buy me a coffee](https://buymeacoffee.com/tuteishygpt)
203
- """
204
- )
205
- with gr.Row():
206
- audio_input = gr.Audio(type="filepath", label="Аўдыёфайл")
207
- video_input = gr.Video(label="Відэафайл")
208
-
209
- audio_input.change(
210
- fn=update_on_audio_change, inputs=audio_input, outputs=video_input
211
- )
212
- video_input.change(
213
- fn=update_on_video_change, inputs=video_input, outputs=audio_input
214
- )
215
-
216
- btn = gr.Button("Апрацаваць")
217
- transcript_output = gr.Textbox(label="Транскрыпцыя", lines=10)
218
- file_output = gr.File(label="SRT-файл")
219
- btn.click(
220
- fn=process_file, inputs=[audio_input, video_input], outputs=[transcript_output, file_output]
221
- )
222
-
223
- gr.Markdown("## Пераклад субцітраў")
224
- with gr.Row():
225
- language_dropdown = gr.Dropdown(
226
- choices=["English", "Руcкая", "Польская", "Літоўская", "Нямецкая"],
227
- label="Выберы мову перакладу",
228
- value="English",
229
- )
230
- translate_btn = gr.Button("Пераклад")
231
- translation_output = gr.Textbox(label="Пераклад", lines=10)
232
- translation_file_output = gr.File(label="Translated SRT-файл")
233
- translate_btn.click(
234
- fn=translate_transcript,
235
- inputs=[transcript_output, language_dropdown],
236
- outputs=[translation_output, translation_file_output],
237
  )
238
-
239
- # Запуск з дадатковымі параметрамі для стабільнасці
240
- demo.launch(
241
- server_name="0.0.0.0",
242
- server_port=7860,
243
- share=False,
244
- debug=False,
245
- show_error=True,
246
- prevent_thread_lock=True
247
  )
248
- except Exception as e:
249
- logger.critical(f"Крытычная памылка пры запуску праграмы: {str(e)}", exc_info=True)
250
- print(f"Крытычная памылка: {str(e)}")
 
1
  import os
2
  import gradio as gr
3
+ import google.generativeai as genai
 
4
  import mimetypes
5
  from pydub import AudioSegment
 
 
6
 
 
 
 
 
 
7
  GEMINI_API_KEY = os.getenv("gemini")
8
+ MODEL_NAME_TH = os.getenv("modTH")
9
+ MODEL_NAME = os.getenv("mod")
 
10
 
11
+ genai.configure(api_key=GEMINI_API_KEY)
 
12
 
13
+ def transcribe_audio(audio_file):
 
14
  try:
 
 
 
15
  mime_type, _ = mimetypes.guess_type(audio_file)
16
+ if mime_type is None:
17
+ return "Немагчыма вызначыць тып файла. Падтрымліваюцца толькі аўдыяфайлы."
 
 
 
 
18
  with open(audio_file, "rb") as f:
19
  audio_data = f.read()
20
+ prompt_text = (
21
+ """The user wants me to transcribe the audio into subtitles in SRT format, with a maximum of three words per one subtitle.
22
+ I need to listen to the audio and create subtitles with timestamps. Check time format hours:minutes:seconds,milliseconds (00:00:00,000) after creating all. Example SRT format:
23
+ 1
24
+ 00:00:01,670 --> 00:00:02,030
25
+ За мяжою, за мяжою,
26
+ 2
27
+ 00:00:02,270 --> 00:00:03,850
28
+ ні сваё і не чужое.
29
+ 3
30
+ 00:00:04,240 --> 00:00:05,760
31
+ Хоць спявай ты, хоць ты грай,
32
+ 4
33
+ 00:00:05,770 --> 00:00:06,250
34
+ а навокал іншы край.
35
+ """
36
  )
37
+ model = genai.GenerativeModel(MODEL_NAME_TH)
38
+ response = model.generate_content(
39
+ [prompt_text, {"mime_type": mime_type, "data": audio_data}]
40
+ )
41
+ if response.text:
42
+ transcript = response.text.strip()
43
+ else:
44
+ transcript = "Не атрымалася транскрыбаваць аўдыя. Магчыма, памылка з API."
45
+ return transcript
46
  except FileNotFoundError:
 
47
  return "Памылка: Файл не знойдзены."
48
+ except genai.APIError as e:
49
+ return f"Памылка API: {str(e)}"
50
  except Exception as e:
 
51
  return f"Нечаканая памылка: {str(e)}"
52
 
53
+ def fix_subtitles_format(transcript):
54
+ """
55
+ Дадатковы запыт да мадэлі, які выпраўляе фармат часоў у субцітрах.
56
+ """
 
 
 
 
 
 
 
57
  try:
58
+ prompt_fix = (
59
+ f"Не змяняй тэксты, выправі толькі часовы фармат у субцітрах на правільны, вось прыклад 00:00:01,589 \n"
60
+ f" �� адказ напішы толькі субцітры: {transcript}"
 
61
  )
62
+ model = genai.GenerativeModel(MODEL_NAME)
63
+ response_fix = model.generate_content(prompt_fix)
64
+ if response_fix.text:
65
+ fixed_transcript = response_fix.text.strip()
66
+ else:
67
+ fixed_transcript = transcript
68
+ return fixed_transcript
69
  except Exception as e:
 
70
  return transcript
71
 
72
+ def create_srt(transcript, filename="subtitles.srt"):
 
 
 
 
 
73
  try:
74
  with open(filename, "w", encoding="utf-8") as f:
75
  f.write(transcript)
76
  return transcript, filename
77
  except Exception as e:
78
+ return f"Памылка пры запісе SRT-файла: {str(e)}", None
 
 
 
 
 
 
 
 
 
 
 
79
 
80
+ def process_audio(audio):
81
+ transcript = transcribe_audio(audio)
82
+ if transcript.startswith("Памылка"):
83
+ return transcript, None
84
+ # Дадаем другі запыт для выпраўлення фармату часоў у субцітрах
85
  fixed_transcript = fix_subtitles_format(transcript)
86
  text, srt_file = create_srt(fixed_transcript)
87
  return text, srt_file
88
 
89
+ def extract_audio_from_video(video_file):
 
 
 
 
 
90
  try:
91
  audio = AudioSegment.from_file(video_file)
92
  audio_path = "extracted_audio.mp3"
93
  audio.export(audio_path, format="mp3")
94
+ return audio_path, None
95
  except Exception as e:
96
+ return None, f"Памылка пры выдзяленні аўдыі з відэафайла: {str(e)}"
 
 
97
 
98
+ def process_video(video):
99
+ audio_path, error = extract_audio_from_video(video)
 
 
 
 
100
  if error:
101
+ return error, None
102
  return process_audio(audio_path)
103
 
104
+ def process_file(audio, video):
105
+ if audio is not None:
106
+ return process_audio(audio)
107
+ elif video is not None:
108
+ return process_video(video)
109
+ else:
110
+ return "Няма файла для апрацоўкі.", None
111
+
112
+ def update_on_audio_change(audio):
113
+ if audio is not None:
114
+ return gr.update(value=None, interactive=False)
115
+ else:
116
+ return gr.update(interactive=True)
117
+
118
+ def update_on_video_change(video):
119
+ if video is not None:
120
+ return gr.update(value=None, interactive=False)
121
+ else:
122
+ return gr.update(interactive=True)
123
+
124
+ def translate_transcript(transcript, target_language):
125
  try:
126
+ prompt_text = (
127
+ f"перакладзі толькі тэксты субцітраў на {target_language} мову. Астатняя пакінь як ёсць."
128
+ f"Тэкст:\n{transcript}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  )
130
+ model = genai.GenerativeModel(MODEL_NAME)
131
+ response = model.generate_content(prompt_text)
132
+ if response.text:
133
+ translated = response.text.strip()
134
+ else:
135
+ translated = "Не атрымалася перакласці тэкст. Магчыма, памылка з API."
136
  translated_srt_filename = "translated_subtitles.srt"
137
+ with open(translated_srt_filename, "w", encoding="utf-8") as f:
138
+ f.write(translated)
139
+ return translated, translated_srt_filename
140
  except Exception as e:
141
+ return f"Памылка пры перакладзе: {str(e)}", None
142
+
143
+ with gr.Blocks() as demo:
144
+ gr.Markdown("# Транскрыпцыя аўдыя для беларускай мовы")
145
+ gr.Markdown(
146
+ """
147
+ ## Загрузіце аўдыёфайл або відэафайл да 15 хвілін. Калі загружаны аўдыёфайл, відэа неактыўна, і наадварот.
148
+ Субцітры будуць аўтаматычна згенераваны разам з файлам субцітраў.
149
+ [Далучайцеся да беларускаймоўнай суполкі ў ТГ](https://t.me/belarusai)
150
+ **Падтрымаць праект:** [Buy me a coffee](https://buymeacoffee.com/tuteishygpt)
151
+ """
152
+ )
153
+ with gr.Row():
154
+ audio_input = gr.Audio(type="filepath", label="Аўдыёфайл")
155
+ video_input = gr.Video(label="Відэафайл")
156
+ audio_input.change(fn=update_on_audio_change, inputs=audio_input, outputs=video_input)
157
+ video_input.change(fn=update_on_video_change, inputs=video_input, outputs=audio_input)
158
+
159
+ btn = gr.Button("Апрацаваць")
160
+ transcript_output = gr.Textbox(label="Транскрыпцыя", lines=10)
161
+ file_output = gr.File(label="SRT-файл")
162
+ btn.click(fn=process_file, inputs=[audio_input, video_input], outputs=[transcript_output, file_output])
163
+
164
+ gr.Markdown("## Пераклад субцітраў")
165
+ with gr.Row():
166
+ language_dropdown = gr.Dropdown(
167
+ choices=["English", "Руcкая", "Польская", "Літоўская", "Нямецкая"],
168
+ label="Выберы мову перакладу", value="English"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  )
170
+ translate_btn = gr.Button("Пераклад")
171
+ translation_output = gr.Textbox(label="Пераклад", lines=10)
172
+ translation_file_output = gr.File(label="Translated SRT-файл")
173
+ translate_btn.click(
174
+ fn=translate_transcript,
175
+ inputs=[transcript_output, language_dropdown],
176
+ outputs=[translation_output, translation_file_output]
 
 
177
  )
178
+
179
+ demo.launch()