razhan commited on
Commit
0392a4f
·
verified ·
1 Parent(s): dbe2587

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +228 -80
app.py CHANGED
@@ -1,20 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
 
3
  import gradio as gr
4
  import yt_dlp as youtube_dl
5
-
6
  from transformers import pipeline
7
- from huggingface_hub import model_info
8
- import re
9
  import tempfile
10
  import os
11
 
12
  MODEL_NAME = "razhan/whisper-small-ckb"
13
  BATCH_SIZE = 1
14
  FILE_LIMIT_MB = 10
15
- YT_LENGTH_LIMIT_S = 60 * 10
16
 
17
  device = 0 if torch.cuda.is_available() else "cpu"
 
18
  pipe = pipeline(
19
  task="automatic-speech-recognition",
20
  model=MODEL_NAME,
@@ -22,71 +187,27 @@ pipe = pipeline(
22
  device=device,
23
  )
24
 
25
- pipe.model.config.forced_decoder_ids = pipe.tokenizer.get_decoder_prompt_ids(task="transcribe")
26
 
27
- def transcribe(microphone, file_upload):
28
- warn_output = ""
29
- if (microphone is not None) and (file_upload is not None):
30
- warn_output = (
31
- "WARNING: You've uploaded an audio file and used the microphone. "
32
- "The recorded file from the microphone will be used and the uploaded audio will be discarded.\n"
33
- )
34
 
35
- elif (microphone is None) and (file_upload is None):
36
- return "ERROR: You have to either use the microphone or upload an audio file"
37
-
38
- file = microphone if microphone is not None else file_upload
39
-
40
- text = pipe(file)["text"]
41
-
42
- return warn_output + text
43
 
44
 
45
  def _return_yt_html_embed(yt_url):
46
- if 'youtu.be' in yt_url:
47
- video_id = yt_url.split('/')[-1].split('?')[0]
48
- else:
49
- video_id = yt_url.split("?v=")[-1].split('&')[0]
50
-
51
  HTML_str = (
52
- f'<center><iframe width="560" height="315" src="https://www.youtube.com/embed/{video_id}" '
53
- 'frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" '
54
- 'allowfullscreen></iframe></center>'
55
  )
56
  return HTML_str
57
 
58
-
59
-
60
-
61
-
62
- def yt_transcribe(yt_url, task="transcribe", max_filesize=75.0, progress=gr.Progress()):
63
- html_embed_str = _return_yt_html_embed(yt_url)
64
-
65
- with tempfile.TemporaryDirectory() as tmpdirname:
66
- filepath = os.path.join(tmpdirname, "video.mp4")
67
- download_yt_audio(yt_url, filepath)
68
- with open(filepath, "rb") as f:
69
- inputs = f.read()
70
-
71
- inputs = ffmpeg_read(inputs, pipe.feature_extractor.sampling_rate)
72
- inputs = {"array": inputs, "sampling_rate": pipe.feature_extractor.sampling_rate}
73
-
74
-
75
-
76
- start_time = time.time()
77
- outputs = pipe(inputs, chunk_length_s=30, batch_size=BATCH_SIZE, generate_kwargs={"task": task, "language": "persian"}, return_timestamps=False)
78
- exec_time = time.time() - start_time
79
- logging.info(print(f"transcribe: {exec_time} sec."))
80
-
81
- return html_embed_str, txt, exec_time
82
-
83
-
84
- def download_yt_audio(yt_url, filename, progress=gr.Progress()):
85
- if '&list' in yt_url:
86
- yt_url = yt_url.split('&list')[0]
87
-
88
  info_loader = youtube_dl.YoutubeDL()
89
-
90
  try:
91
  info = info_loader.extract_info(yt_url, download=False)
92
  except youtube_dl.utils.DownloadError as err:
@@ -107,27 +228,60 @@ def download_yt_audio(yt_url, filename, progress=gr.Progress()):
107
  file_length_hms = time.strftime("%HH:%MM:%SS", time.gmtime(file_length_s))
108
  raise gr.Error(f"Maximum YouTube length is {yt_length_limit_hms}, got {file_length_hms} YouTube video.")
109
 
110
- # ydl_opts = {"outtmpl": filename, "format": "worstvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best"}
111
- ydl_opts = {"outtmpl": filename, "format": "bestaudio/best"}
112
 
113
  with youtube_dl.YoutubeDL(ydl_opts) as ydl:
114
  try:
115
  ydl.download([yt_url])
116
  except youtube_dl.utils.ExtractorError as err:
117
  raise gr.Error(str(err))
118
- progress(1, desc="Video downloaded from YouTube!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
 
 
 
121
  mf_transcribe = gr.Interface(
122
  fn=transcribe,
123
  inputs=[
124
  gr.Audio(sources="microphone", type="filepath"),
125
- gr.Audio(sources="upload", type="filepath"),
126
  ],
127
  outputs="text",
128
  title="Whisper Central Kurdish‌ (Sorani) Demo: Transcribe Audio",
129
  description=(
130
- "Transcribe long-form microphone or audio inputs with the click of a button! Demo uses the the fine-tuned"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  f" checkpoint [{MODEL_NAME}](https://huggingface.co/{MODEL_NAME}) and 🤗 Transformers to transcribe audio files"
132
  " of arbitrary length."
133
  ),
@@ -136,27 +290,21 @@ mf_transcribe = gr.Interface(
136
 
137
  yt_transcribe = gr.Interface(
138
  fn=yt_transcribe,
139
- inputs=[gr.Textbox(lines=1, placeholder="Paste the URL to a YouTube video here", label="YouTube URL")],
140
- outputs=["html",
141
- gr.Textbox(
142
- label="Output",
143
- rtl=True,
144
- show_copy_button=True,
145
- ),
146
- gr.Text(label="Transcription Time")
147
- ],
148
  title="Whisper Central Kurdish‌ (Sorani) Demo: Transcribe YouTube",
149
  description=(
150
- "Transcribe long-form YouTube videos with the click of a button! Demo uses the the fine-tuned checkpoint:"
151
- f" [{MODEL_NAME}](https://huggingface.co/{MODEL_NAME}) and 🤗 Transformers to transcribe audio files of"
152
  " arbitrary length."
153
  ),
154
  allow_flagging="never",
155
  )
156
 
 
 
157
 
158
- demo = gr.TabbedInterface([mf_transcribe, yt_transcribe], ["Transcribe Audio", "Transcribe YouTube"])
159
-
160
- if __name__ == "__main__":
161
- demo.launch()
162
-
 
1
+ # import torch
2
+
3
+ # import gradio as gr
4
+ # import yt_dlp as youtube_dl
5
+
6
+ # from transformers import pipeline
7
+ # from huggingface_hub import model_info
8
+ # import re
9
+ # import tempfile
10
+ # import os
11
+
12
+ # MODEL_NAME = "razhan/whisper-small-ckb"
13
+ # BATCH_SIZE = 1
14
+ # FILE_LIMIT_MB = 10
15
+ # YT_LENGTH_LIMIT_S = 60 * 10
16
+
17
+ # device = 0 if torch.cuda.is_available() else "cpu"
18
+ # pipe = pipeline(
19
+ # task="automatic-speech-recognition",
20
+ # model=MODEL_NAME,
21
+ # chunk_length_s=30,
22
+ # device=device,
23
+ # )
24
+
25
+ # pipe.model.config.forced_decoder_ids = pipe.tokenizer.get_decoder_prompt_ids(task="transcribe")
26
+
27
+ # def transcribe(microphone, file_upload):
28
+ # warn_output = ""
29
+ # if (microphone is not None) and (file_upload is not None):
30
+ # warn_output = (
31
+ # "WARNING: You've uploaded an audio file and used the microphone. "
32
+ # "The recorded file from the microphone will be used and the uploaded audio will be discarded.\n"
33
+ # )
34
+
35
+ # elif (microphone is None) and (file_upload is None):
36
+ # return "ERROR: You have to either use the microphone or upload an audio file"
37
+
38
+ # file = microphone if microphone is not None else file_upload
39
+
40
+ # text = pipe(file)["text"]
41
+
42
+ # return warn_output + text
43
+
44
+
45
+ # def _return_yt_html_embed(yt_url):
46
+ # if 'youtu.be' in yt_url:
47
+ # video_id = yt_url.split('/')[-1].split('?')[0]
48
+ # else:
49
+ # video_id = yt_url.split("?v=")[-1].split('&')[0]
50
+
51
+ # HTML_str = (
52
+ # f'<center><iframe width="560" height="315" src="https://www.youtube.com/embed/{video_id}" '
53
+ # 'frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" '
54
+ # 'allowfullscreen></iframe></center>'
55
+ # )
56
+ # return HTML_str
57
+
58
+
59
+
60
+
61
+
62
+ # def yt_transcribe(yt_url, task="transcribe", max_filesize=75.0, progress=gr.Progress()):
63
+ # html_embed_str = _return_yt_html_embed(yt_url)
64
+
65
+ # with tempfile.TemporaryDirectory() as tmpdirname:
66
+ # filepath = os.path.join(tmpdirname, "video.mp4")
67
+ # download_yt_audio(yt_url, filepath)
68
+ # with open(filepath, "rb") as f:
69
+ # inputs = f.read()
70
+
71
+ # inputs = ffmpeg_read(inputs, pipe.feature_extractor.sampling_rate)
72
+ # inputs = {"array": inputs, "sampling_rate": pipe.feature_extractor.sampling_rate}
73
+
74
+
75
+
76
+ # start_time = time.time()
77
+ # outputs = pipe(inputs, chunk_length_s=30, batch_size=BATCH_SIZE, generate_kwargs={"task": task, "language": "persian"}, return_timestamps=False)
78
+ # exec_time = time.time() - start_time
79
+ # logging.info(print(f"transcribe: {exec_time} sec."))
80
+
81
+ # return html_embed_str, txt, exec_time
82
+
83
+
84
+ # def download_yt_audio(yt_url, filename, progress=gr.Progress()):
85
+ # if '&list' in yt_url:
86
+ # yt_url = yt_url.split('&list')[0]
87
+
88
+ # info_loader = youtube_dl.YoutubeDL()
89
+
90
+ # try:
91
+ # info = info_loader.extract_info(yt_url, download=False)
92
+ # except youtube_dl.utils.DownloadError as err:
93
+ # raise gr.Error(str(err))
94
+
95
+ # file_length = info["duration_string"]
96
+ # file_h_m_s = file_length.split(":")
97
+ # file_h_m_s = [int(sub_length) for sub_length in file_h_m_s]
98
+
99
+ # if len(file_h_m_s) == 1:
100
+ # file_h_m_s.insert(0, 0)
101
+ # if len(file_h_m_s) == 2:
102
+ # file_h_m_s.insert(0, 0)
103
+ # file_length_s = file_h_m_s[0] * 3600 + file_h_m_s[1] * 60 + file_h_m_s[2]
104
+
105
+ # if file_length_s > YT_LENGTH_LIMIT_S:
106
+ # yt_length_limit_hms = time.strftime("%HH:%MM:%SS", time.gmtime(YT_LENGTH_LIMIT_S))
107
+ # file_length_hms = time.strftime("%HH:%MM:%SS", time.gmtime(file_length_s))
108
+ # raise gr.Error(f"Maximum YouTube length is {yt_length_limit_hms}, got {file_length_hms} YouTube video.")
109
+
110
+ # # ydl_opts = {"outtmpl": filename, "format": "worstvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best"}
111
+ # ydl_opts = {"outtmpl": filename, "format": "bestaudio/best"}
112
+
113
+ # with youtube_dl.YoutubeDL(ydl_opts) as ydl:
114
+ # try:
115
+ # ydl.download([yt_url])
116
+ # except youtube_dl.utils.ExtractorError as err:
117
+ # raise gr.Error(str(err))
118
+ # progress(1, desc="Video downloaded from YouTube!")
119
+
120
+
121
+ # mf_transcribe = gr.Interface(
122
+ # fn=transcribe,
123
+ # inputs=[
124
+ # gr.Audio(sources="microphone", type="filepath"),
125
+ # gr.Audio(sources="upload", type="filepath"),
126
+ # ],
127
+ # outputs="text",
128
+ # title="Whisper Central Kurdish‌ (Sorani) Demo: Transcribe Audio",
129
+ # description=(
130
+ # "Transcribe long-form microphone or audio inputs with the click of a button! Demo uses the the fine-tuned"
131
+ # f" checkpoint [{MODEL_NAME}](https://huggingface.co/{MODEL_NAME}) and 🤗 Transformers to transcribe audio files"
132
+ # " of arbitrary length."
133
+ # ),
134
+ # allow_flagging="never",
135
+ # )
136
+
137
+ # yt_transcribe = gr.Interface(
138
+ # fn=yt_transcribe,
139
+ # inputs=[gr.Textbox(lines=1, placeholder="Paste the URL to a YouTube video here", label="YouTube URL")],
140
+ # outputs=["html",
141
+ # gr.Textbox(
142
+ # label="Output",
143
+ # rtl=True,
144
+ # show_copy_button=True,
145
+ # ),
146
+ # gr.Text(label="Transcription Time")
147
+ # ],
148
+ # title="Whisper Central Kurdish‌ (Sorani) Demo: Transcribe YouTube",
149
+ # description=(
150
+ # "Transcribe long-form YouTube videos with the click of a button! Demo uses the the fine-tuned checkpoint:"
151
+ # f" [{MODEL_NAME}](https://huggingface.co/{MODEL_NAME}) and 🤗 Transformers to transcribe audio files of"
152
+ # " arbitrary length."
153
+ # ),
154
+ # allow_flagging="never",
155
+ # )
156
+
157
+
158
+ # demo = gr.TabbedInterface([mf_transcribe, yt_transcribe], ["Transcribe Audio", "Transcribe YouTube"])
159
+
160
+ # if __name__ == "__main__":
161
+ # demo.launch()
162
+
163
+
164
+
165
+ import spaces
166
  import torch
167
 
168
  import gradio as gr
169
  import yt_dlp as youtube_dl
 
170
  from transformers import pipeline
171
+ from transformers.pipelines.audio_utils import ffmpeg_read
172
+
173
  import tempfile
174
  import os
175
 
176
  MODEL_NAME = "razhan/whisper-small-ckb"
177
  BATCH_SIZE = 1
178
  FILE_LIMIT_MB = 10
179
+ YT_LENGTH_LIMIT_S = 60 * 10 # limit to 1 hour YouTube files
180
 
181
  device = 0 if torch.cuda.is_available() else "cpu"
182
+
183
  pipe = pipeline(
184
  task="automatic-speech-recognition",
185
  model=MODEL_NAME,
 
187
  device=device,
188
  )
189
 
 
190
 
191
+ @spaces.GPU
192
+ def transcribe(inputs, task):
193
+ if inputs is None:
194
+ raise gr.Error("No audio file submitted! Please upload or record an audio file before submitting your request.")
 
 
 
195
 
196
+ text = pipe(inputs, batch_size=BATCH_SIZE, generate_kwargs={"task": task}, return_timestamps=True)["text"]
197
+ return text
 
 
 
 
 
 
198
 
199
 
200
  def _return_yt_html_embed(yt_url):
201
+ video_id = yt_url.split("?v=")[-1]
 
 
 
 
202
  HTML_str = (
203
+ f'<center> <iframe width="500" height="320" src="https://www.youtube.com/embed/{video_id}"> </iframe>'
204
+ " </center>"
 
205
  )
206
  return HTML_str
207
 
208
+ def download_yt_audio(yt_url, filename):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  info_loader = youtube_dl.YoutubeDL()
210
+
211
  try:
212
  info = info_loader.extract_info(yt_url, download=False)
213
  except youtube_dl.utils.DownloadError as err:
 
228
  file_length_hms = time.strftime("%HH:%MM:%SS", time.gmtime(file_length_s))
229
  raise gr.Error(f"Maximum YouTube length is {yt_length_limit_hms}, got {file_length_hms} YouTube video.")
230
 
231
+ ydl_opts = {"outtmpl": filename, "format": "worstvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best"}
 
232
 
233
  with youtube_dl.YoutubeDL(ydl_opts) as ydl:
234
  try:
235
  ydl.download([yt_url])
236
  except youtube_dl.utils.ExtractorError as err:
237
  raise gr.Error(str(err))
238
+
239
+ @spaces.GPU
240
+ def yt_transcribe(yt_url, task, max_filesize=75.0):
241
+ html_embed_str = _return_yt_html_embed(yt_url)
242
+
243
+ with tempfile.TemporaryDirectory() as tmpdirname:
244
+ filepath = os.path.join(tmpdirname, "video.mp4")
245
+ download_yt_audio(yt_url, filepath)
246
+ with open(filepath, "rb") as f:
247
+ inputs = f.read()
248
+
249
+ inputs = ffmpeg_read(inputs, pipe.feature_extractor.sampling_rate)
250
+ inputs = {"array": inputs, "sampling_rate": pipe.feature_extractor.sampling_rate}
251
+
252
+ text = pipe(inputs, batch_size=BATCH_SIZE, generate_kwargs={"task": task}, return_timestamps=True)["text"]
253
+
254
+ return html_embed_str, text
255
 
256
 
257
+ demo = gr.Blocks(theme=gr.themes.Ocean())
258
+
259
  mf_transcribe = gr.Interface(
260
  fn=transcribe,
261
  inputs=[
262
  gr.Audio(sources="microphone", type="filepath"),
263
+ gr.Radio(["transcribe", "translate"], label="Task", value="transcribe"),
264
  ],
265
  outputs="text",
266
  title="Whisper Central Kurdish‌ (Sorani) Demo: Transcribe Audio",
267
  description=(
268
+ "Transcribe long-form microphone or audio inputs with the click of a button! Demo uses the"
269
+ f" checkpoint [{MODEL_NAME}](https://huggingface.co/{MODEL_NAME}) and 🤗 Transformers to transcribe audio files"
270
+ " of arbitrary length."
271
+ ),
272
+ allow_flagging="never",
273
+ )
274
+
275
+ file_transcribe = gr.Interface(
276
+ fn=transcribe,
277
+ inputs=[
278
+ gr.Audio(sources="upload", type="filepath", label="Audio file"),
279
+ gr.Radio(["transcribe", "translate"], label="Task", value="transcribe"),
280
+ ],
281
+ outputs="text",
282
+ title="Whisper Central Kurdish‌ (Sorani) Demo: Transcribe Audio",
283
+ description=(
284
+ "Transcribe long-form microphone or audio inputs with the click of a button! Demo uses the"
285
  f" checkpoint [{MODEL_NAME}](https://huggingface.co/{MODEL_NAME}) and 🤗 Transformers to transcribe audio files"
286
  " of arbitrary length."
287
  ),
 
290
 
291
  yt_transcribe = gr.Interface(
292
  fn=yt_transcribe,
293
+ inputs=[
294
+ gr.Textbox(lines=1, placeholder="Paste the URL to a YouTube video here", label="YouTube URL"),
295
+ gr.Radio(["transcribe", "translate"], label="Task", value="transcribe")
296
+ ],
297
+ outputs=["html", "text"],
 
 
 
 
298
  title="Whisper Central Kurdish‌ (Sorani) Demo: Transcribe YouTube",
299
  description=(
300
+ "Transcribe long-form YouTube videos with the click of a button! Demo uses the checkpoint"
301
+ f" [{MODEL_NAME}](https://huggingface.co/{MODEL_NAME}) and 🤗 Transformers to transcribe video files of"
302
  " arbitrary length."
303
  ),
304
  allow_flagging="never",
305
  )
306
 
307
+ with demo:
308
+ gr.TabbedInterface([mf_transcribe, file_transcribe, yt_transcribe], ["Microphone", "Audio file", "YouTube"])
309
 
310
+ demo.queue().launch(ssr_mode=False)