bluenevus commited on
Commit
ce4312e
·
verified ·
1 Parent(s): 25726df

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -46
app.py CHANGED
@@ -3,6 +3,7 @@ import os
3
  import tempfile
4
  import threading
5
  import base64
 
6
  from urllib.parse import urlparse
7
 
8
  import dash
@@ -16,11 +17,19 @@ from pydub import AudioSegment
16
  import google.generativeai as genai
17
  from moviepy.editor import VideoFileClip
18
 
 
 
 
 
19
  # Initialize the Dash app
20
  app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
21
 
22
  # Retrieve the Google API key from Hugging Face Spaces
23
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
 
 
 
 
24
  genai.configure(api_key=GOOGLE_API_KEY)
25
 
26
  # Initialize Gemini model
@@ -31,68 +40,95 @@ def is_valid_url(url):
31
  result = urlparse(url)
32
  return all([result.scheme, result.netloc])
33
  except ValueError:
 
34
  return False
35
 
36
  def download_media(url):
37
- if "youtube.com" in url or "youtu.be" in url:
38
- yt = YouTube(url)
39
- stream = yt.streams.filter(progressive=True, file_extension='mp4').first()
40
- with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file:
41
- stream.download(output_path=os.path.dirname(temp_file.name), filename=temp_file.name)
42
- return temp_file.name
43
- else:
44
- response = requests.get(url)
45
- content_type = response.headers.get('content-type', '')
46
- if 'video' in content_type:
47
- suffix = '.mp4'
48
- elif 'audio' in content_type:
49
- suffix = '.mp3'
50
  else:
51
- suffix = ''
52
- with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
53
- temp_file.write(response.content)
54
- return temp_file.name
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  def extract_audio(file_path):
57
- video = VideoFileClip(file_path)
58
- audio = video.audio
59
- audio_file = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
60
- audio.write_audiofile(audio_file.name)
61
- video.close()
62
- audio.close()
63
- return audio_file.name
 
 
 
 
 
 
64
 
65
  def transcribe_audio(file_path):
66
- with open(file_path, "rb") as audio_file:
67
- audio_data = audio_file.read()
68
-
69
- response = model.generate_content(audio_data)
70
- return response.text
 
 
 
 
 
 
71
 
72
  def process_media(contents, filename, url):
73
- if contents:
74
- content_type, content_string = contents.split(',')
75
- decoded = base64.b64decode(content_string)
76
- suffix = os.path.splitext(filename)[1]
77
- with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
78
- temp_file.write(decoded)
79
- temp_file_path = temp_file.name
80
- elif url:
81
- temp_file_path = download_media(url)
82
- else:
83
- raise ValueError("No input provided")
84
-
85
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  if temp_file_path.lower().endswith(('.mp4', '.avi', '.mov', '.flv', '.wmv')):
 
87
  audio_file_path = extract_audio(temp_file_path)
88
  transcript = transcribe_audio(audio_file_path)
89
  os.unlink(audio_file_path)
90
  else:
 
91
  transcript = transcribe_audio(temp_file_path)
92
- finally:
93
- os.unlink(temp_file_path)
94
 
95
- return transcript
 
 
 
 
96
 
97
  app.layout = dbc.Container([
98
  html.H1("Audio/Video Transcription App", className="text-center my-4"),
@@ -142,6 +178,7 @@ def update_transcription(n_clicks, contents, filename, url):
142
  try:
143
  return process_media(contents, filename, url)
144
  except Exception as e:
 
145
  return f"An error occurred: {str(e)}"
146
 
147
  thread = threading.Thread(target=transcribe)
@@ -149,11 +186,13 @@ def update_transcription(n_clicks, contents, filename, url):
149
  thread.join(timeout=600) # 10 minutes timeout
150
 
151
  if thread.is_alive():
 
152
  return "Transcription timed out after 10 minutes", {'display': 'none'}
153
 
154
  transcript = getattr(thread, 'result', "Transcription failed")
155
 
156
  if transcript and not transcript.startswith("An error occurred"):
 
157
  return dbc.Card([
158
  dbc.CardBody([
159
  html.H5("Transcription Result"),
@@ -161,6 +200,7 @@ def update_transcription(n_clicks, contents, filename, url):
161
  ])
162
  ]), {'display': 'block'}
163
  else:
 
164
  return transcript, {'display': 'none'}
165
 
166
  @app.callback(
@@ -177,6 +217,6 @@ def download_transcript(n_clicks, transcription_output):
177
  return dict(content=transcript, filename="transcript.txt")
178
 
179
  if __name__ == '__main__':
180
- print("Starting the Dash application...")
181
  app.run(debug=True, host='0.0.0.0', port=7860)
182
- print("Dash application has finished running.")
 
3
  import tempfile
4
  import threading
5
  import base64
6
+ import logging
7
  from urllib.parse import urlparse
8
 
9
  import dash
 
17
  import google.generativeai as genai
18
  from moviepy.editor import VideoFileClip
19
 
20
+ # Set up logging
21
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
22
+ logger = logging.getLogger(__name__)
23
+
24
  # Initialize the Dash app
25
  app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
26
 
27
  # Retrieve the Google API key from Hugging Face Spaces
28
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
29
+ if not GOOGLE_API_KEY:
30
+ logger.error("GOOGLE_API_KEY not found in environment variables")
31
+ raise ValueError("GOOGLE_API_KEY not set")
32
+
33
  genai.configure(api_key=GOOGLE_API_KEY)
34
 
35
  # Initialize Gemini model
 
40
  result = urlparse(url)
41
  return all([result.scheme, result.netloc])
42
  except ValueError:
43
+ logger.error(f"Invalid URL: {url}")
44
  return False
45
 
46
  def download_media(url):
47
+ logger.info(f"Attempting to download media from URL: {url}")
48
+ try:
49
+ if "youtube.com" in url or "youtu.be" in url:
50
+ yt = YouTube(url)
51
+ stream = yt.streams.filter(progressive=True, file_extension='mp4').first()
52
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_file:
53
+ stream.download(output_path=os.path.dirname(temp_file.name), filename=temp_file.name)
54
+ logger.info(f"YouTube video downloaded: {temp_file.name}")
55
+ return temp_file.name
 
 
 
 
56
  else:
57
+ response = requests.get(url)
58
+ content_type = response.headers.get('content-type', '')
59
+ if 'video' in content_type:
60
+ suffix = '.mp4'
61
+ elif 'audio' in content_type:
62
+ suffix = '.mp3'
63
+ else:
64
+ suffix = ''
65
+ with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
66
+ temp_file.write(response.content)
67
+ logger.info(f"Media downloaded: {temp_file.name}")
68
+ return temp_file.name
69
+ except Exception as e:
70
+ logger.error(f"Error downloading media: {str(e)}")
71
+ raise
72
 
73
  def extract_audio(file_path):
74
+ logger.info(f"Extracting audio from video: {file_path}")
75
+ try:
76
+ video = VideoFileClip(file_path)
77
+ audio = video.audio
78
+ audio_file = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
79
+ audio.write_audiofile(audio_file.name)
80
+ video.close()
81
+ audio.close()
82
+ logger.info(f"Audio extracted: {audio_file.name}")
83
+ return audio_file.name
84
+ except Exception as e:
85
+ logger.error(f"Error extracting audio: {str(e)}")
86
+ raise
87
 
88
  def transcribe_audio(file_path):
89
+ logger.info(f"Transcribing audio: {file_path}")
90
+ try:
91
+ with open(file_path, "rb") as audio_file:
92
+ audio_data = audio_file.read()
93
+
94
+ response = model.generate_content(audio_data)
95
+ logger.info("Transcription completed successfully")
96
+ return response.text
97
+ except Exception as e:
98
+ logger.error(f"Error during transcription: {str(e)}")
99
+ raise
100
 
101
  def process_media(contents, filename, url):
102
+ logger.info("Starting media processing")
 
 
 
 
 
 
 
 
 
 
 
103
  try:
104
+ if contents:
105
+ content_type, content_string = contents.split(',')
106
+ decoded = base64.b64decode(content_string)
107
+ suffix = os.path.splitext(filename)[1]
108
+ with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp_file:
109
+ temp_file.write(decoded)
110
+ temp_file_path = temp_file.name
111
+ logger.info(f"File uploaded: {temp_file_path}")
112
+ elif url:
113
+ temp_file_path = download_media(url)
114
+ else:
115
+ logger.error("No input provided")
116
+ raise ValueError("No input provided")
117
+
118
  if temp_file_path.lower().endswith(('.mp4', '.avi', '.mov', '.flv', '.wmv')):
119
+ logger.info("Video file detected, extracting audio")
120
  audio_file_path = extract_audio(temp_file_path)
121
  transcript = transcribe_audio(audio_file_path)
122
  os.unlink(audio_file_path)
123
  else:
124
+ logger.info("Audio file detected, transcribing directly")
125
  transcript = transcribe_audio(temp_file_path)
 
 
126
 
127
+ os.unlink(temp_file_path)
128
+ return transcript
129
+ except Exception as e:
130
+ logger.error(f"Error in process_media: {str(e)}")
131
+ raise
132
 
133
  app.layout = dbc.Container([
134
  html.H1("Audio/Video Transcription App", className="text-center my-4"),
 
178
  try:
179
  return process_media(contents, filename, url)
180
  except Exception as e:
181
+ logger.error(f"Transcription failed: {str(e)}")
182
  return f"An error occurred: {str(e)}"
183
 
184
  thread = threading.Thread(target=transcribe)
 
186
  thread.join(timeout=600) # 10 minutes timeout
187
 
188
  if thread.is_alive():
189
+ logger.warning("Transcription timed out after 10 minutes")
190
  return "Transcription timed out after 10 minutes", {'display': 'none'}
191
 
192
  transcript = getattr(thread, 'result', "Transcription failed")
193
 
194
  if transcript and not transcript.startswith("An error occurred"):
195
+ logger.info("Transcription successful")
196
  return dbc.Card([
197
  dbc.CardBody([
198
  html.H5("Transcription Result"),
 
200
  ])
201
  ]), {'display': 'block'}
202
  else:
203
+ logger.error(f"Transcription failed: {transcript}")
204
  return transcript, {'display': 'none'}
205
 
206
  @app.callback(
 
217
  return dict(content=transcript, filename="transcript.txt")
218
 
219
  if __name__ == '__main__':
220
+ logger.info("Starting the Dash application...")
221
  app.run(debug=True, host='0.0.0.0', port=7860)
222
+ logger.info("Dash application has finished running.")