muhtasham commited on
Commit
daf7f7b
·
1 Parent(s): 2362603
Files changed (2) hide show
  1. app.py +87 -39
  2. requirements.txt +1 -0
app.py CHANGED
@@ -1,19 +1,31 @@
1
  import spaces
2
  import torch
3
-
4
  import gradio as gr
5
  import yt_dlp as youtube_dl
6
  from transformers import pipeline
7
  from transformers.pipelines.audio_utils import ffmpeg_read
8
-
9
  import tempfile
10
  import os
 
 
 
11
 
12
- MODEL_NAME = "openai/whisper-large-v3-turbo"
13
  BATCH_SIZE = 8
14
  FILE_LIMIT_MB = 1000
15
  YT_LENGTH_LIMIT_S = 3600 # limit to 1 hour YouTube files
16
 
 
 
 
 
 
 
 
 
 
 
 
17
  device = 0 if torch.cuda.is_available() else "cpu"
18
 
19
  pipe = pipeline(
@@ -23,54 +35,91 @@ pipe = pipeline(
23
  device=device,
24
  )
25
 
26
-
27
  @spaces.GPU
28
  def transcribe(inputs, task):
29
  if inputs is None:
30
  raise gr.Error("No audio file submitted! Please upload or record an audio file before submitting your request.")
31
 
32
- text = pipe(inputs, batch_size=BATCH_SIZE, generate_kwargs={"task": task}, return_timestamps=True)["text"]
33
  return text
34
 
35
-
36
  def _return_yt_html_embed(yt_url):
37
- video_id = yt_url.split("?v=")[-1]
38
- HTML_str = (
39
- f'<center> <iframe width="500" height="320" src="https://www.youtube.com/embed/{video_id}"> </iframe>'
40
- " </center>"
41
- )
42
- return HTML_str
 
 
 
 
43
 
44
  def download_yt_audio(yt_url, filename):
45
- info_loader = youtube_dl.YoutubeDL()
46
 
47
- try:
48
- info = info_loader.extract_info(yt_url, download=False)
49
- except youtube_dl.utils.DownloadError as err:
50
- raise gr.Error(str(err))
51
-
52
- file_length = info["duration_string"]
53
- file_h_m_s = file_length.split(":")
54
- file_h_m_s = [int(sub_length) for sub_length in file_h_m_s]
55
-
56
- if len(file_h_m_s) == 1:
57
- file_h_m_s.insert(0, 0)
58
- if len(file_h_m_s) == 2:
59
- file_h_m_s.insert(0, 0)
60
- file_length_s = file_h_m_s[0] * 3600 + file_h_m_s[1] * 60 + file_h_m_s[2]
61
-
62
- if file_length_s > YT_LENGTH_LIMIT_S:
63
- yt_length_limit_hms = time.strftime("%HH:%MM:%SS", time.gmtime(YT_LENGTH_LIMIT_S))
64
- file_length_hms = time.strftime("%HH:%MM:%SS", time.gmtime(file_length_s))
65
- raise gr.Error(f"Maximum YouTube length is {yt_length_limit_hms}, got {file_length_hms} YouTube video.")
66
 
67
- ydl_opts = {"outtmpl": filename, "format": "worstvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best"}
68
-
69
- with youtube_dl.YoutubeDL(ydl_opts) as ydl:
70
- try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  ydl.download([yt_url])
72
- except youtube_dl.utils.ExtractorError as err:
73
- raise gr.Error(str(err))
 
 
 
 
 
 
 
 
 
74
 
75
  @spaces.GPU
76
  def yt_transcribe(yt_url, task, max_filesize=75.0):
@@ -89,7 +138,6 @@ def yt_transcribe(yt_url, task, max_filesize=75.0):
89
 
90
  return html_embed_str, text
91
 
92
-
93
  demo = gr.Blocks(theme=gr.themes.Ocean())
94
 
95
  mf_transcribe = gr.Interface(
 
1
  import spaces
2
  import torch
 
3
  import gradio as gr
4
  import yt_dlp as youtube_dl
5
  from transformers import pipeline
6
  from transformers.pipelines.audio_utils import ffmpeg_read
 
7
  import tempfile
8
  import os
9
+ import time
10
+ import subprocess
11
+ from loguru import logger
12
 
13
+ MODEL_NAME = "muhtasham/whisper-tg"
14
  BATCH_SIZE = 8
15
  FILE_LIMIT_MB = 1000
16
  YT_LENGTH_LIMIT_S = 3600 # limit to 1 hour YouTube files
17
 
18
+ # Check if ffmpeg is installed
19
+ def check_ffmpeg():
20
+ try:
21
+ subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
22
+ except (subprocess.CalledProcessError, FileNotFoundError):
23
+ logger.error("ffmpeg is not installed. Please install ffmpeg to use this application.")
24
+ raise gr.Error("ffmpeg is not installed. Please install ffmpeg to use this application.")
25
+
26
+ # Initialize ffmpeg check
27
+ check_ffmpeg()
28
+
29
  device = 0 if torch.cuda.is_available() else "cpu"
30
 
31
  pipe = pipeline(
 
35
  device=device,
36
  )
37
 
 
38
  @spaces.GPU
39
  def transcribe(inputs, task):
40
  if inputs is None:
41
  raise gr.Error("No audio file submitted! Please upload or record an audio file before submitting your request.")
42
 
43
+ text = pipe(inputs, batch_size=BATCH_SIZE, generate_kwargs={"task": task}, return_timestamps=True)
44
  return text
45
 
 
46
  def _return_yt_html_embed(yt_url):
47
+ try:
48
+ video_id = yt_url.split("?v=")[-1]
49
+ HTML_str = (
50
+ f'<center> <iframe width="500" height="320" src="https://www.youtube.com/embed/{video_id}"> </iframe>'
51
+ " </center>"
52
+ )
53
+ return HTML_str
54
+ except Exception as e:
55
+ logger.error(f"Error creating embed HTML: {str(e)}")
56
+ raise gr.Error("Invalid YouTube URL format")
57
 
58
  def download_yt_audio(yt_url, filename):
59
+ logger.info(f"Starting download for URL: {yt_url}")
60
 
61
+ # Configure yt-dlp options
62
+ ydl_opts = {
63
+ "format": "bestaudio/best",
64
+ "postprocessors": [{
65
+ "key": "FFmpegExtractAudio",
66
+ "preferredcodec": "mp3",
67
+ "preferredquality": "192",
68
+ }],
69
+ "outtmpl": filename,
70
+ "quiet": True,
71
+ "no_warnings": True,
72
+ "extract_flat": False,
73
+ "force_generic_extractor": False,
74
+ "nocheckcertificate": True,
75
+ "ignoreerrors": False,
76
+ "logtostderr": False,
77
+ "verbose": False,
78
+ }
 
79
 
80
+ try:
81
+ # First, get video info without downloading
82
+ with youtube_dl.YoutubeDL({"quiet": True}) as ydl:
83
+ logger.info("Extracting video information...")
84
+ info = ydl.extract_info(yt_url, download=False)
85
+
86
+ # Check video duration
87
+ file_length = info.get("duration_string", "0:00:00")
88
+ file_h_m_s = file_length.split(":")
89
+ file_h_m_s = [int(sub_length) for sub_length in file_h_m_s]
90
+
91
+ if len(file_h_m_s) == 1:
92
+ file_h_m_s.insert(0, 0)
93
+ if len(file_h_m_s) == 2:
94
+ file_h_m_s.insert(0, 0)
95
+ file_length_s = file_h_m_s[0] * 3600 + file_h_m_s[1] * 60 + file_h_m_s[2]
96
+
97
+ if file_length_s > YT_LENGTH_LIMIT_S:
98
+ yt_length_limit_hms = time.strftime("%HH:%MM:%SS", time.gmtime(YT_LENGTH_LIMIT_S))
99
+ file_length_hms = time.strftime("%HH:%MM:%SS", time.gmtime(file_length_s))
100
+ raise gr.Error(f"Maximum YouTube length is {yt_length_limit_hms}, got {file_length_hms} YouTube video.")
101
+
102
+ # Check if video is age-restricted or private
103
+ if info.get("age_limit") or info.get("is_private"):
104
+ raise gr.Error("This video is age-restricted or private and cannot be processed.")
105
+
106
+ logger.info("Video information extracted successfully")
107
+
108
+ # Now download the audio
109
+ logger.info("Starting audio download...")
110
+ with youtube_dl.YoutubeDL(ydl_opts) as ydl:
111
  ydl.download([yt_url])
112
+ logger.info("Audio download completed successfully")
113
+
114
+ except youtube_dl.utils.DownloadError as err:
115
+ logger.error(f"Download error: {str(err)}")
116
+ raise gr.Error(f"Failed to download video: {str(err)}")
117
+ except youtube_dl.utils.ExtractorError as err:
118
+ logger.error(f"Extraction error: {str(err)}")
119
+ raise gr.Error(f"Failed to extract video information: {str(err)}")
120
+ except Exception as e:
121
+ logger.error(f"Unexpected error: {str(e)}")
122
+ raise gr.Error(f"An unexpected error occurred: {str(e)}")
123
 
124
  @spaces.GPU
125
  def yt_transcribe(yt_url, task, max_filesize=75.0):
 
138
 
139
  return html_embed_str, text
140
 
 
141
  demo = gr.Blocks(theme=gr.themes.Ocean())
142
 
143
  mf_transcribe = gr.Interface(
requirements.txt CHANGED
@@ -1,2 +1,3 @@
1
  transformers
2
  yt-dlp
 
 
1
  transformers
2
  yt-dlp
3
+ loguru