archivartaunik commited on
Commit
1cfce90
·
verified ·
1 Parent(s): d8ce896

Rename app (11).py to app.py

Browse files
Files changed (2) hide show
  1. app (11).py +0 -179
  2. app.py +292 -0
app (11).py DELETED
@@ -1,179 +0,0 @@
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()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from argparse import Namespace
3
+ import os
4
+ import shutil
5
+ import sys
6
+ import yt_dlp # Дададзены імпарт для працы з YouTube
7
+
8
+ from sub_tools.media.converter import hls_to_media, media_to_signature, video_to_audio
9
+ from sub_tools.media.segmenter import segment_audio
10
+ from sub_tools.subtitles.combiner import combine_subtitles
11
+ from sub_tools.system.directory import change_directory
12
+ from sub_tools.system.console import header, success, error
13
+ from sub_tools.transcribe import transcribe
14
+
15
+ GEMINI_API_KEY = os.getenv("gemini")
16
+
17
+ genai.configure(api_key=GEMINI_API_KEY)
18
+
19
+ def main_logic(args: Namespace) -> tuple:
20
+ """
21
+ Асноўная логіка прыкладання: ад загрузкі відэа/аўдыё да зліцця субтытраў.
22
+ Пасля зліцця субтытраў вяртае (тэкст субтытраў, шлях да SRT‑файла для спампоўкі).
23
+ """
24
+ output_str = ""
25
+ subtitles_text = ""
26
+ srt_file_path = None
27
+
28
+ try:
29
+ change_directory(args.output_path)
30
+ step = 1
31
+
32
+ if "video" in args.tasks:
33
+ if not args.hls_url:
34
+ output_str += f"{step}. Download Video: No video file uploaded\n"
35
+ raise Exception("No video file uploaded")
36
+ header(f"{step}. Download Video")
37
+ output_str += f"{step}. Download Video: Started\n"
38
+ hls_to_media(args.hls_url, args.video_file, False, args.overwrite)
39
+ success("Done!")
40
+ output_str += "Done!\n"
41
+ step += 1
42
+
43
+ if "audio" in args.tasks:
44
+ header(f"{step}. Video to Audio")
45
+ output_str += f"{step}. Video to Audio: Started\n"
46
+ video_to_audio(args.video_file, args.audio_file, args.overwrite)
47
+ success("Done!")
48
+ output_str += "Done!\n"
49
+ step += 1
50
+
51
+ if "signature" in args.tasks:
52
+ header(f"{step}. Audio to Signature")
53
+ output_str += f"{step}. Audio to Signature: Started\n"
54
+ media_to_signature(args.audio_file, args.signature_file, args.overwrite)
55
+ success("Done!")
56
+ output_str += "Done!\n"
57
+ step += 1
58
+
59
+ if "segment" in args.tasks:
60
+ header(f"{step}. Segment Audio")
61
+ output_str += f"{step}. Segment Audio: Started\n"
62
+ segment_audio(args.audio_file, args.audio_segment_prefix, args.audio_segment_format, args.audio_segment_length, args.overwrite)
63
+ success("Done!")
64
+ output_str += "Done!\n"
65
+ step += 1
66
+
67
+ if "transcribe" in args.tasks:
68
+ if not (args.gemini_api_key and args.gemini_api_key.strip()):
69
+ output_str += f"{step}. Transcribe Audio: No Gemini API Key provided\n"
70
+ raise Exception("No Gemini API Key provided")
71
+ header(f"{step}. Transcribe Audio")
72
+ output_str += f"{step}. Transcribe Audio: Started\n"
73
+ transcribe(args)
74
+ success("Done!")
75
+ output_str += "Done!\n"
76
+ step += 1
77
+
78
+ if "combine" in args.tasks:
79
+ header(f"{step}. Combine Subtitles")
80
+ output_str += f"{step}. Combine Subtitles: Started\n"
81
+ combine_subtitles(args.languages, args.audio_segment_prefix, args.audio_segment_format)
82
+ success("Done!")
83
+ output_str += "Done!\n"
84
+ if args.languages:
85
+ language = args.languages[0]
86
+ srt_file_path = os.path.join(os.getcwd(), f"{language}.srt")
87
+ try:
88
+ with open(srt_file_path, "r", encoding="utf-8") as f:
89
+ subtitles_text = f.read()
90
+ except Exception as e:
91
+ subtitles_text = f"Error reading subtitles file: {str(e)}"
92
+ else:
93
+ subtitles_text = "No language specified"
94
+ step += 1
95
+
96
+ return (subtitles_text, srt_file_path)
97
+
98
+ except Exception as e:
99
+ error_msg = f"Error: {str(e)}"
100
+ error(error_msg)
101
+ return (error_msg, None)
102
+
103
+
104
+ def run_subtools(
105
+ tasks,
106
+ hls_url,
107
+ video_file,
108
+ audio_file,
109
+ signature_file,
110
+ output_path,
111
+ languages,
112
+ overwrite,
113
+ retry,
114
+ gemini_api_key,
115
+ debug,
116
+ audio_segment_prefix,
117
+ audio_segment_format,
118
+ audio_segment_length
119
+ ):
120
+ """
121
+ Падрыхтоўка каталога вываду і запуск асноўнай логікі.
122
+ """
123
+ if os.path.exists(output_path):
124
+ shutil.rmtree(output_path)
125
+ os.makedirs(output_path, exist_ok=True)
126
+
127
+ if isinstance(languages, str):
128
+ languages = [lang.strip() for lang in languages.split(",") if lang.strip()]
129
+
130
+ args = Namespace(
131
+ tasks=tasks,
132
+ hls_url=hls_url,
133
+ video_file=video_file,
134
+ audio_file=audio_file,
135
+ signature_file=signature_file,
136
+ output_path=output_path,
137
+ languages=languages,
138
+ overwrite=overwrite,
139
+ retry=retry,
140
+ gemini_api_key=gemini_api_key,
141
+ debug=debug,
142
+ audio_segment_prefix=audio_segment_prefix,
143
+ audio_segment_format=audio_segment_format,
144
+ audio_segment_length=audio_segment_length,
145
+ )
146
+
147
+ return main_logic(args)
148
+
149
+
150
+ def transcribe_youtube(youtube_url: str) -> tuple:
151
+ """
152
+ Спампоўвае аўдыё з відэа YouTube праз yt_dlp і вяртае паведамленне і шлях да часовага аўдыёфайла.
153
+ Выкарыстоўвае chromewebstore.google.com_cookies.txt, калі ён ёсць.
154
+ """
155
+ if not youtube_url:
156
+ return "Не ўведзена спасылка", None
157
+
158
+ temp_audio_file = "temp_youtube_audio.wav" # Пераканайцеся, што пашырэнне адпавядае audioformat
159
+ try:
160
+ ydl_opts = {
161
+ 'format': 'bestaudio/best',
162
+ 'outtmpl': temp_audio_file,
163
+ 'quiet': True,
164
+ 'extractaudio': True,
165
+ 'audioformat': 'wav',
166
+ 'audioquality': 0 # Якасць 0 = лепшая
167
+ }
168
+
169
+ # Вызначаем шлях да файла cookie
170
+ default_cookies_file = "chromewebstore.google.com_cookies.txt"
171
+ if os.path.exists(default_cookies_file):
172
+ ydl_opts['cookiefile'] = default_cookies_file
173
+ print(f"Выкарыстоўваецца файл cookie па змаўчанні: {default_cookies_file}")
174
+ else:
175
+ ydl_opts['cookiesfrombrowser'] = 'chrome'
176
+ print("Файл cookie па змаўчанні не знойдзены. Паспрабуйце атрымаць cookies з браўзера аўтаматычна.")
177
+
178
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
179
+ ydl.download([youtube_url])
180
+ return ("Спампоўка YouTube аўдыё завершана", temp_audio_file)
181
+ except Exception as e:
182
+ err_msg = f"Памылка пры апрацоўцы YouTube (yt_dlp): {e}. Калі ласка, пераканайцеся, што спасылка сапраўдная, і праверце, ці даступныя відэа."
183
+ print(err_msg)
184
+ return (err_msg, None)
185
+
186
+
187
+ def process_uploaded_file(audio, video):
188
+ """
189
+ Выбірае, які файл загружаны, і фармуе параметры для апрацоўкі.
190
+ Калі загружаны аўдыёфайл – запускае апрацоўку для аўдыё,
191
+ калі відэафайл – запускае поўны ланцуг апрацоўкі.
192
+ """
193
+ # Калі загружаны толькі аўдыёфайл:
194
+ if audio is not None and video is None:
195
+ tasks = ["signature", "segment", "transcribe", "combine"]
196
+ video_file = "" # відэа не выкарыстоўваецца
197
+ audio_file = audio
198
+ hls_url = "" # не патрабуецца
199
+ # Калі загружаны толькі відэафайл:
200
+ elif video is not None and audio is None:
201
+ tasks = ["video", "audio", "signature", "segment", "transcribe", "combine"]
202
+ video_file = video
203
+ audio_file = "audio.mp3" # прызначаем імя для аўдыёфайла
204
+ hls_url = "dummy" # задаём няпустое значэнне для праверкі
205
+ else:
206
+ return "Error: Загрузіце толькі АЎДЫЁ або ВІДЭАфайл, а не абодва.", None
207
+
208
+ return run_subtools(
209
+ tasks=tasks,
210
+ hls_url=hls_url,
211
+ video_file=video_file,
212
+ audio_file=audio_file,
213
+ signature_file="message.shazamsignature",
214
+ output_path="output",
215
+ languages="be",
216
+ overwrite=False,
217
+ retry=50,
218
+ gemini_api_key="AIzaSyCwvZ_s4TvxoMaegbpQOOW1nzjZ6IbqGbg",
219
+ debug=False,
220
+ audio_segment_prefix="audio_segment",
221
+ audio_segment_format="mp3",
222
+ audio_segment_length=300000
223
+ )
224
+
225
+
226
+ def process_youtube_url(youtube_url):
227
+ """
228
+ Апрацоўвае YouTube спасылку: спампоўвае аўдыё і запускае ланцуг апрацоўкі для стварэння субтытраў.
229
+ """
230
+ download_msg, audio_file = transcribe_youtube(youtube_url)
231
+ if not audio_file:
232
+ return download_msg, None
233
+
234
+ # Выкарыстоўваем апрацоўку толькі для аўдыё (аналагічна выпадку, калі загружаны аўдыёфайл)
235
+ tasks = ["signature", "segment", "transcribe", "combine"]
236
+ return run_subtools(
237
+ tasks=tasks,
238
+ hls_url="",
239
+ video_file="",
240
+ audio_file=audio_file,
241
+ signature_file="message.shazamsignature",
242
+ output_path="output_youtube", # выкарыстоўваем асобны вывад для YouTube
243
+ languages="be",
244
+ overwrite=False,
245
+ retry=50,
246
+ gemini_api_key="AIzaSyCwvZ_s4TvxoMaegbpQOOW1nzjZ6IbqGbg",
247
+ debug=False,
248
+ audio_segment_prefix="audio_segment",
249
+ audio_segment_format="mp3",
250
+ audio_segment_length=300000
251
+ )
252
+
253
+
254
+ # --------------------- Gradio UI ---------------------
255
+ with gr.Blocks() as demo:
256
+ with gr.Tabs():
257
+ with gr.Tab("Файл"):
258
+ with gr.Row():
259
+ audio_input = gr.Audio(type="filepath", label="Аўдыёфайл")
260
+ video_input = gr.Video(label="Відэафайл")
261
+
262
+ # Пры змене аднаго з палёў дэактывуецца процілеглае
263
+ audio_input.change(fn=update_on_audio_change, inputs=audio_input, outputs=video_input)
264
+ video_input.change(fn=update_on_video_change, inputs=video_input, outputs=audio_input)
265
+ submit_btn_file = gr.Button("Submit")
266
+ output_text_file = gr.Textbox(label="Тэкст субтытраў")
267
+ output_file_file = gr.File(label="Спампаваць SRT файл")
268
+
269
+ submit_btn_file.click(fn=process_uploaded_file, inputs=[audio_input, video_input], outputs=[output_text_file, output_file_file])
270
+
271
+ with gr.Tab("YouTube"):
272
+ youtube_url_input = gr.Textbox(label="YouTube URL", placeholder="Устаўце спасылку на відэа YouTube")
273
+ submit_btn_youtube = gr.Button("Submit")
274
+ output_text_youtube = gr.Textbox(label="Тэкст субтытраў")
275
+ output_file_youtube = gr.File(label="Спампаваць SRT файл")
276
+
277
+ submit_btn_youtube.click(fn=process_youtube_url, inputs=youtube_url_input, outputs=[output_text_youtube, output_file_youtube])
278
+
279
+
280
+ def update_on_audio_change(audio):
281
+ if audio is not None:
282
+ return gr.update(interactive=False)
283
+ return gr.update(interactive=True)
284
+
285
+
286
+ def update_on_video_change(video):
287
+ if video is not None:
288
+ return gr.update(interactive=False)
289
+ return gr.update(interactive=True)
290
+
291
+
292
+ demo.launch()