Spaces:
Running
Running
oceansweep
commited on
Commit
•
35c0681
1
Parent(s):
c8eaa51
Update app.py
Browse files
app.py
CHANGED
@@ -17,6 +17,8 @@ import gradio as gr
|
|
17 |
import torch
|
18 |
import yt_dlp
|
19 |
|
|
|
|
|
20 |
os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
|
21 |
#######
|
22 |
# Function Sections
|
@@ -123,6 +125,9 @@ processing_choice = config.get('Processing', 'processing_choice', fallback='cpu'
|
|
123 |
# Log file
|
124 |
# logging.basicConfig(filename='debug-runtime.log', encoding='utf-8', level=logging.DEBUG)
|
125 |
|
|
|
|
|
|
|
126 |
#
|
127 |
#
|
128 |
#######################
|
@@ -318,7 +323,12 @@ def process_path(path):
|
|
318 |
""" Decides whether the path is a URL or a local file and processes accordingly. """
|
319 |
if path.startswith('http'):
|
320 |
logging.debug("file is a URL")
|
321 |
-
|
|
|
|
|
|
|
|
|
|
|
322 |
elif os.path.exists(path):
|
323 |
logging.debug("File is a path")
|
324 |
return process_local_file(path) # For local files, define a function to handle them
|
@@ -327,7 +337,7 @@ def process_path(path):
|
|
327 |
return None
|
328 |
|
329 |
|
330 |
-
#
|
331 |
def process_local_file(file_path):
|
332 |
logging.info(f"Processing local file: {file_path}")
|
333 |
title = normalize_title(os.path.splitext(os.path.basename(file_path))[0])
|
@@ -349,40 +359,40 @@ def process_local_file(file_path):
|
|
349 |
# Video Download/Handling
|
350 |
#
|
351 |
|
352 |
-
def process_url(
|
353 |
-
|
354 |
-
|
355 |
-
api_name = "huggingface"
|
356 |
-
api_key = os.environ.get(HF_TOKEN)
|
357 |
-
print("HUGGINGFACE API KEY CHECK #3: " + api_key)
|
358 |
-
vad_filter = False
|
359 |
-
download_video_flag = False
|
360 |
-
|
361 |
try:
|
362 |
-
results = main(
|
363 |
whisper_model=whisper_model, offset=offset, vad_filter=vad_filter,
|
364 |
-
download_video_flag=
|
365 |
-
|
366 |
if results:
|
367 |
transcription_result = results[0]
|
368 |
json_file_path = transcription_result['audio_file'].replace('.wav', '.segments.json')
|
369 |
-
|
370 |
-
with open(json_file_path, 'r') as file:
|
371 |
-
json_data = json.load(file)
|
372 |
summary_file_path = json_file_path.replace('.segments.json', '_summary.txt')
|
373 |
|
374 |
-
|
375 |
-
|
|
|
376 |
|
377 |
-
|
378 |
-
|
379 |
|
380 |
-
|
381 |
-
|
|
|
382 |
|
|
|
|
|
|
|
|
|
|
|
|
|
383 |
except Exception as e:
|
384 |
-
|
385 |
-
|
|
|
386 |
|
387 |
|
388 |
def create_download_directory(title):
|
@@ -418,8 +428,13 @@ def get_youtube(video_url):
|
|
418 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
419 |
logging.debug("About to extract youtube info")
|
420 |
info_dict = ydl.extract_info(video_url, download=False)
|
421 |
-
logging.debug("Youtube info successfully extracted")
|
422 |
-
|
|
|
|
|
|
|
|
|
|
|
423 |
|
424 |
|
425 |
def get_playlist_videos(playlist_url):
|
@@ -451,7 +466,7 @@ def download_video(video_url, download_path, info_dict, download_video_flag):
|
|
451 |
logging.debug("About to normalize downloaded video title")
|
452 |
title = normalize_title(info_dict['title'])
|
453 |
|
454 |
-
if download_video_flag
|
455 |
file_path = os.path.join(download_path, f"{title}.m4a")
|
456 |
ydl_opts = {
|
457 |
'format': 'bestaudio[ext=m4a]',
|
@@ -568,7 +583,6 @@ def convert_to_wav(video_file_path, offset=0):
|
|
568 |
except Exception as e:
|
569 |
logging.error("Error occurred - ffmpeg doesn't like windows")
|
570 |
raise RuntimeError("ffmpeg failed")
|
571 |
-
exit()
|
572 |
elif os.name == "posix":
|
573 |
os.system(f'ffmpeg -ss 00:00:00 -i "{video_file_path}" -ar 16000 -ac 1 -c:a pcm_s16le "{out_path}"')
|
574 |
else:
|
@@ -1238,131 +1252,114 @@ def process_text(api_key, text_file):
|
|
1238 |
return "Notice:", message
|
1239 |
|
1240 |
|
1241 |
-
def format_file_path(file_path):
|
1242 |
-
# Helper function to check file existence and return an appropriate path or message
|
1243 |
-
return file_path if file_path and os.path.exists(file_path) else None
|
1244 |
|
1245 |
-
def launch_ui(demo_mode=False):
|
1246 |
-
inputs = [
|
1247 |
-
gr.components.Textbox(label="URL", placeholder="Enter the video URL here"),
|
1248 |
-
gr.components.Number(value=2, label="Number of Speakers"),
|
1249 |
-
gr.components.Dropdown(choices=whisper_models, value="small.en", label="Whisper Model"),
|
1250 |
-
gr.components.Textbox(label="Custom Prompt", placeholder="Q: As a professional summarizer, create a concise and comprehensive summary of the provided text.\nA: Here is a detailed, bulleted list of the key points made in the transcribed video and supporting arguments:", lines=3),
|
1251 |
-
gr.components.Number(value=0, label="Offset"),
|
1252 |
-
gr.components.Dropdown(
|
1253 |
-
choices=["huggingface", "openai", "anthropic", "cohere", "groq", "llama", "kobold", "ooba"],
|
1254 |
-
label="API Name"),
|
1255 |
-
gr.components.Textbox(label="API Key", placeholder="Enter your API key here"),
|
1256 |
-
gr.components.Checkbox(label="VAD Filter", value=False),
|
1257 |
-
gr.components.Checkbox(label="Download Video", value=False)
|
1258 |
-
]
|
1259 |
-
|
1260 |
-
outputs = [
|
1261 |
-
gr.components.Textbox(label="Transcription"),
|
1262 |
-
gr.components.Textbox(label="Summary or Status Message"),
|
1263 |
-
gr.components.File(label="Download Transcription as JSON", visible=lambda x: x != "File not available"),
|
1264 |
-
gr.components.File(label="Download Summary as Text", visible=lambda x: x != "File not available"),
|
1265 |
-
gr.components.File(label="Download Video", visible=lambda x: x is not None)
|
1266 |
-
]
|
1267 |
-
|
1268 |
-
def process_url(url, num_speakers, whisper_model, custom_prompt, offset, api_name, api_key, vad_filter,
|
1269 |
-
download_video):
|
1270 |
-
video_file_path = None
|
1271 |
-
try:
|
1272 |
-
results = main(url, api_name=api_name, api_key=api_key, num_speakers=num_speakers,
|
1273 |
-
whisper_model=whisper_model, offset=offset, vad_filter=vad_filter,
|
1274 |
-
download_video_flag=download_video, custom_prompt=custom_prompt)
|
1275 |
-
if results:
|
1276 |
-
transcription_result = results[0]
|
1277 |
-
json_file_path = transcription_result['audio_file'].replace('.wav', '.segments.json')
|
1278 |
-
summary_file_path = json_file_path.replace('.segments.json', '_summary.txt')
|
1279 |
-
|
1280 |
-
json_file_path = format_file_path(json_file_path)
|
1281 |
-
summary_file_path = format_file_path(summary_file_path)
|
1282 |
-
|
1283 |
-
if summary_file_path and os.path.exists(summary_file_path):
|
1284 |
-
return transcription_result[
|
1285 |
-
'transcription'], "Summary available", json_file_path, summary_file_path, video_file_path
|
1286 |
-
else:
|
1287 |
-
return transcription_result[
|
1288 |
-
'transcription'], "Summary not available", json_file_path, None, video_file_path
|
1289 |
-
else:
|
1290 |
-
return "No results found.", "Summary not available", None, None, None
|
1291 |
-
except Exception as e:
|
1292 |
-
return str(e), "Error processing the request.", None, None, None
|
1293 |
|
1294 |
-
iface = gr.Interface(
|
1295 |
-
fn=process_url,
|
1296 |
-
inputs=inputs,
|
1297 |
-
outputs=outputs,
|
1298 |
-
title="Video Transcription and Summarization",
|
1299 |
-
description="Submit a video URL for transcription and summarization. Ensure you input all necessary information including API keys."
|
1300 |
-
)
|
1301 |
|
1302 |
-
|
|
|
|
|
1303 |
|
1304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1305 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1306 |
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
json_file_path = transcription_result['audio_file'].replace('.wav', '.segments.json')
|
1319 |
-
summary_file_path = transcription_result.get('summary', "Summary not available.")
|
1320 |
-
video_file_path = transcription_result.get('video_path', None)
|
1321 |
|
1322 |
-
|
1323 |
-
|
|
|
1324 |
|
1325 |
-
|
1326 |
-
else:
|
1327 |
-
return "No results found.", "No summary available.", None, None, None
|
1328 |
-
except Exception as e:
|
1329 |
-
return str(e), "Error processing the request.", None, None, None, None
|
1330 |
-
|
1331 |
-
inputs = [
|
1332 |
-
gr.components.Textbox(label="URL", placeholder="Enter the video URL here"),
|
1333 |
-
gr.components.Number(value=2, label="Number of Speakers"),
|
1334 |
-
gr.components.Dropdown(choices=whisper_models, value="small.en", label="Whisper Model"),
|
1335 |
-
gr.components.Textbox(label="Custom Prompt",
|
1336 |
-
placeholder="Q: As a professional summarizer, create a concise and comprehensive summary of the provided text.\nA: Here is a detailed, bulleted list of the key points made in the transcribed video and supporting arguments:",
|
1337 |
-
lines=3),
|
1338 |
-
gr.components.Number(value=0, label="Offset"),
|
1339 |
-
gr.components.Dropdown(
|
1340 |
-
choices=["huggingface", "openai", "anthropic", "cohere", "groq", "llama", "kobold", "ooba"],
|
1341 |
-
label="API Name"),
|
1342 |
-
gr.components.Textbox(label="API Key", placeholder="Enter your API key here"),
|
1343 |
-
gr.components.Checkbox(label="VAD Filter", value=False),
|
1344 |
-
gr.components.Checkbox(label="Download Video", value=False)
|
1345 |
-
]
|
1346 |
-
|
1347 |
-
outputs = [
|
1348 |
-
gr.components.Textbox(label="Transcription"),
|
1349 |
-
gr.components.Textbox(label="Summary or Status Message"),
|
1350 |
-
gr.components.File(label="Download Transcription as JSON", visible=lambda x: x != "File not available"),
|
1351 |
-
gr.components.File(label="Download Summary as Text", visible=lambda x: x != "File not available"),
|
1352 |
-
gr.components.File(label="Download Video", visible=lambda x: x is not None)
|
1353 |
-
]
|
1354 |
-
|
1355 |
-
iface = gr.Interface(
|
1356 |
-
fn=process_url,
|
1357 |
-
inputs=inputs,
|
1358 |
-
outputs=outputs,
|
1359 |
-
title="Video Transcription and Summarization",
|
1360 |
-
description="Submit a video URL for transcription and summarization. Ensure you input all necessary information including API keys.",
|
1361 |
-
theme="bethecloud/storj_theme" # Adjust theme as necessary
|
1362 |
-
)
|
1363 |
-
|
1364 |
-
iface.launch(share=False)
|
1365 |
-
"""
|
1366 |
|
1367 |
#
|
1368 |
#
|
@@ -1438,62 +1435,62 @@ def main(input_path, api_name=None, api_key=None, num_speakers=2, whisper_model=
|
|
1438 |
logging.debug(f"MAIN: Summarization being performed by {api_name}")
|
1439 |
json_file_path = audio_file.replace('.wav', '.segments.json')
|
1440 |
if api_name.lower() == 'openai':
|
1441 |
-
|
1442 |
try:
|
1443 |
logging.debug(f"MAIN: trying to summarize with openAI")
|
1444 |
-
summary = summarize_with_openai(
|
1445 |
except requests.exceptions.ConnectionError:
|
1446 |
requests.status_code = "Connection: "
|
1447 |
elif api_name.lower() == "anthropic":
|
1448 |
-
|
1449 |
try:
|
1450 |
logging.debug(f"MAIN: Trying to summarize with anthropic")
|
1451 |
-
summary = summarize_with_claude(
|
1452 |
except requests.exceptions.ConnectionError:
|
1453 |
requests.status_code = "Connection: "
|
1454 |
elif api_name.lower() == "cohere":
|
1455 |
-
|
1456 |
try:
|
1457 |
logging.debug(f"MAIN: Trying to summarize with cohere")
|
1458 |
-
summary = summarize_with_cohere(
|
1459 |
except requests.exceptions.ConnectionError:
|
1460 |
requests.status_code = "Connection: "
|
1461 |
elif api_name.lower() == "groq":
|
1462 |
-
|
1463 |
try:
|
1464 |
logging.debug(f"MAIN: Trying to summarize with Groq")
|
1465 |
-
summary = summarize_with_groq(
|
1466 |
except requests.exceptions.ConnectionError:
|
1467 |
requests.status_code = "Connection: "
|
1468 |
elif api_name.lower() == "llama":
|
1469 |
-
|
1470 |
llama_ip = llama_api_IP
|
1471 |
try:
|
1472 |
logging.debug(f"MAIN: Trying to summarize with Llama.cpp")
|
1473 |
-
summary = summarize_with_llama(llama_ip, json_file_path,
|
1474 |
except requests.exceptions.ConnectionError:
|
1475 |
requests.status_code = "Connection: "
|
1476 |
elif api_name.lower() == "kobold":
|
1477 |
-
|
1478 |
kobold_ip = kobold_api_IP
|
1479 |
try:
|
1480 |
logging.debug(f"MAIN: Trying to summarize with kobold.cpp")
|
1481 |
-
summary = summarize_with_kobold(kobold_ip, json_file_path, custom_prompt)
|
1482 |
except requests.exceptions.ConnectionError:
|
1483 |
requests.status_code = "Connection: "
|
1484 |
elif api_name.lower() == "ooba":
|
1485 |
-
|
1486 |
ooba_ip = ooba_api_IP
|
1487 |
try:
|
1488 |
logging.debug(f"MAIN: Trying to summarize with oobabooga")
|
1489 |
-
summary = summarize_with_oobabooga(ooba_ip, json_file_path, custom_prompt)
|
1490 |
except requests.exceptions.ConnectionError:
|
1491 |
requests.status_code = "Connection: "
|
1492 |
elif api_name.lower() == "huggingface":
|
1493 |
-
|
1494 |
try:
|
1495 |
logging.debug(f"MAIN: Trying to summarize with huggingface")
|
1496 |
-
summarize_with_huggingface(
|
1497 |
except requests.exceptions.ConnectionError:
|
1498 |
requests.status_code = "Connection: "
|
1499 |
|
@@ -1512,10 +1509,10 @@ def main(input_path, api_name=None, api_key=None, num_speakers=2, whisper_model=
|
|
1512 |
except Exception as e:
|
1513 |
logging.error(f"Error processing path: {path}")
|
1514 |
logging.error(str(e))
|
1515 |
-
|
1516 |
-
|
1517 |
|
1518 |
-
|
1519 |
|
1520 |
|
1521 |
if __name__ == "__main__":
|
|
|
17 |
import torch
|
18 |
import yt_dlp
|
19 |
|
20 |
+
log_level = "INFO"
|
21 |
+
logging.basicConfig(level=getattr(logging, log_level), format='%(asctime)s - %(levelname)s - %(message)s')
|
22 |
os.environ["GRADIO_ANALYTICS_ENABLED"] = "False"
|
23 |
#######
|
24 |
# Function Sections
|
|
|
125 |
# Log file
|
126 |
# logging.basicConfig(filename='debug-runtime.log', encoding='utf-8', level=logging.DEBUG)
|
127 |
|
128 |
+
# API Key Shenanigans
|
129 |
+
api_key = "UNSET"
|
130 |
+
|
131 |
#
|
132 |
#
|
133 |
#######################
|
|
|
323 |
""" Decides whether the path is a URL or a local file and processes accordingly. """
|
324 |
if path.startswith('http'):
|
325 |
logging.debug("file is a URL")
|
326 |
+
info_dict = get_youtube(path)
|
327 |
+
if info_dict:
|
328 |
+
return info_dict
|
329 |
+
else:
|
330 |
+
logging.error("Failed to get Video info")
|
331 |
+
return None
|
332 |
elif os.path.exists(path):
|
333 |
logging.debug("File is a path")
|
334 |
return process_local_file(path) # For local files, define a function to handle them
|
|
|
337 |
return None
|
338 |
|
339 |
|
340 |
+
#
|
341 |
def process_local_file(file_path):
|
342 |
logging.info(f"Processing local file: {file_path}")
|
343 |
title = normalize_title(os.path.splitext(os.path.basename(file_path))[0])
|
|
|
359 |
# Video Download/Handling
|
360 |
#
|
361 |
|
362 |
+
def process_url(url, num_speakers, whisper_model, custom_prompt, offset, api_name, api_key, vad_filter,
|
363 |
+
download_video, download_audio, chunk_size):
|
364 |
+
video_file_path = None
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
try:
|
366 |
+
results = main(url, api_name=api_name, api_key=api_key, num_speakers=num_speakers,
|
367 |
whisper_model=whisper_model, offset=offset, vad_filter=vad_filter,
|
368 |
+
download_video_flag=download_video, custom_prompt=custom_prompt)
|
|
|
369 |
if results:
|
370 |
transcription_result = results[0]
|
371 |
json_file_path = transcription_result['audio_file'].replace('.wav', '.segments.json')
|
372 |
+
prettified_json_file_path = transcription_result['audio_file'].replace('.wav', '.segments_pretty.json')
|
|
|
|
|
373 |
summary_file_path = json_file_path.replace('.segments.json', '_summary.txt')
|
374 |
|
375 |
+
json_file_path = format_file_path(json_file_path)
|
376 |
+
prettified_json_file_path = format_file_path(prettified_json_file_path)
|
377 |
+
summary_file_path = format_file_path(summary_file_path)
|
378 |
|
379 |
+
if download_video:
|
380 |
+
video_file_path = transcription_result['video_path'] if 'video_path' in transcription_result else None
|
381 |
|
382 |
+
formatted_transcription = format_transcription(transcription_result)
|
383 |
+
|
384 |
+
summary_text = transcription_result.get('summary', 'Summary not available')
|
385 |
|
386 |
+
if summary_file_path and os.path.exists(summary_file_path):
|
387 |
+
return formatted_transcription, summary_text, prettified_json_file_path, summary_file_path, video_file_path, None
|
388 |
+
else:
|
389 |
+
return formatted_transcription, "Summary not available", prettified_json_file_path, None, video_file_path, None
|
390 |
+
else:
|
391 |
+
return "No results found.", "Summary not available", None, None, None, None
|
392 |
except Exception as e:
|
393 |
+
return str(e), "Error processing the request.", None, None, None, None
|
394 |
+
|
395 |
+
|
396 |
|
397 |
|
398 |
def create_download_directory(title):
|
|
|
428 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
429 |
logging.debug("About to extract youtube info")
|
430 |
info_dict = ydl.extract_info(video_url, download=False)
|
431 |
+
logging.debug(f"Youtube info successfully extracted: {info_dict}")
|
432 |
+
if isinstance(info_dict, dict):
|
433 |
+
return info_dict
|
434 |
+
else:
|
435 |
+
logging.error("Invalid info_dict format")
|
436 |
+
return None
|
437 |
+
|
438 |
|
439 |
|
440 |
def get_playlist_videos(playlist_url):
|
|
|
466 |
logging.debug("About to normalize downloaded video title")
|
467 |
title = normalize_title(info_dict['title'])
|
468 |
|
469 |
+
if not download_video_flag:
|
470 |
file_path = os.path.join(download_path, f"{title}.m4a")
|
471 |
ydl_opts = {
|
472 |
'format': 'bestaudio[ext=m4a]',
|
|
|
583 |
except Exception as e:
|
584 |
logging.error("Error occurred - ffmpeg doesn't like windows")
|
585 |
raise RuntimeError("ffmpeg failed")
|
|
|
586 |
elif os.name == "posix":
|
587 |
os.system(f'ffmpeg -ss 00:00:00 -i "{video_file_path}" -ar 16000 -ac 1 -c:a pcm_s16le "{out_path}"')
|
588 |
else:
|
|
|
1252 |
return "Notice:", message
|
1253 |
|
1254 |
|
|
|
|
|
|
|
1255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1256 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1257 |
|
1258 |
+
def format_file_path(file_path):
|
1259 |
+
# Helper function to check file existence and return an appropriate path or message
|
1260 |
+
return file_path if file_path and os.path.exists(file_path) else None
|
1261 |
|
1262 |
|
1263 |
+
def update_visibility(mode):
|
1264 |
+
if mode == "Advanced":
|
1265 |
+
# Show all inputs below URL
|
1266 |
+
return [gr.update(visible=True)] * 9
|
1267 |
+
else:
|
1268 |
+
# Hide all inputs below URL
|
1269 |
+
return [gr.update(visible=False)] * 9
|
1270 |
|
1271 |
+
# https://www.gradio.app/guides/controlling-layout
|
1272 |
+
def launch_ui(demo_mode=False):
|
1273 |
+
whisper_models = ["small.en", "medium.en", "large"]
|
1274 |
+
|
1275 |
+
with gr.Blocks() as iface:
|
1276 |
+
with gr.Tab("Audio Transcription + Summarization"):
|
1277 |
+
with gr.Row():
|
1278 |
+
# Light/Dark mode toggle switch
|
1279 |
+
theme_toggle = gr.Radio(choices=["Light", "Dark"], value="Light",
|
1280 |
+
label="Light/Dark Mode Toggle (Toggle to change UI color scheme)")
|
1281 |
+
|
1282 |
+
# UI Mode toggle switch
|
1283 |
+
ui_mode_toggle = gr.Radio(choices=["Simple", "Advanced"], value="Simple",
|
1284 |
+
label="UI Mode (Toggle to show all options)")
|
1285 |
+
|
1286 |
+
# URL input is always visible
|
1287 |
+
url_input = gr.Textbox(label="URL (Mandatory)", placeholder="Enter the video URL here")
|
1288 |
+
|
1289 |
+
# Inputs to be shown or hidden
|
1290 |
+
num_speakers_input = gr.Number(value=2, label="Number of Speakers(Optional - Currently has no effect)",
|
1291 |
+
visible=False)
|
1292 |
+
whisper_model_input = gr.Dropdown(choices=whisper_models, value="small.en",
|
1293 |
+
label="Whisper Model(This is the ML model used for transcription.)",
|
1294 |
+
visible=False)
|
1295 |
+
custom_prompt_input = gr.Textbox(
|
1296 |
+
label="Custom Prompt (Customize your summary, or ask a different question)",
|
1297 |
+
placeholder="Q: As a professional summarizer, create a concise and comprehensive summary of the provided text.\nA: Here is a detailed, bulleted list of the key points made in the transcribed video and supporting arguments:",
|
1298 |
+
lines=3, visible=True)
|
1299 |
+
offset_input = gr.Number(value=0, label="Offset (Seconds into the video to start transcribing at)",
|
1300 |
+
visible=False)
|
1301 |
+
api_name_input = gr.Dropdown(
|
1302 |
+
choices=[None,"huggingface", "openai", "anthropic", "cohere", "groq", "llama", "kobold", "ooba"], value=None,
|
1303 |
+
label="API Name (Mandatory Unless you just want a Transcription)", visible=True)
|
1304 |
+
api_key_input = gr.Textbox(label="API Key (Mandatory if API Name is specified)",
|
1305 |
+
placeholder="Enter your API key here", visible=True)
|
1306 |
+
vad_filter_input = gr.Checkbox(label="VAD Filter(Can safely ignore)", value=False, visible=False)
|
1307 |
+
download_video_input = gr.Checkbox(
|
1308 |
+
label="Download Video(Select to allow for file download of selected video)", value=False, visible=False)
|
1309 |
+
download_audio_input = gr.Checkbox(
|
1310 |
+
label="Download Audio(Select to allow for file download of selected Video's Audio)", value=False,
|
1311 |
+
visible=True)
|
1312 |
+
detail_level_input = gr.Slider(minimum=0.0, maximum=1.0, value=0.1, step=0.1, interactive=False,
|
1313 |
+
label="Detail Level (Slide me)", visible=True)
|
1314 |
+
|
1315 |
+
inputs = [num_speakers_input, whisper_model_input, custom_prompt_input, offset_input, api_name_input,
|
1316 |
+
api_key_input, vad_filter_input, download_video_input, download_audio_input, detail_level_input]
|
1317 |
+
|
1318 |
+
# Function to toggle Light/Dark Mode
|
1319 |
+
def toggle_light(mode):
|
1320 |
+
dark = (mode == "Dark")
|
1321 |
+
return {"__theme": "dark" if dark else "light"}
|
1322 |
+
|
1323 |
+
# Set the event listener for the Light/Dark mode toggle switch
|
1324 |
+
theme_toggle.change(fn=toggle_light, inputs=theme_toggle, outputs=None)
|
1325 |
+
|
1326 |
+
# Function to toggle visibility of advanced inputs
|
1327 |
+
def toggle_ui(mode):
|
1328 |
+
visible = (mode == "Advanced")
|
1329 |
+
return [visible] * len(inputs)
|
1330 |
+
|
1331 |
+
# Set the event listener for the UI Mode toggle switch
|
1332 |
+
ui_mode_toggle.change(fn=toggle_ui, inputs=ui_mode_toggle, outputs=inputs)
|
1333 |
+
|
1334 |
+
# Combine URL input and inputs
|
1335 |
+
all_inputs = [url_input] + inputs
|
1336 |
+
|
1337 |
+
outputs = [
|
1338 |
+
gr.Textbox(label="Transcription (Resulting Transcription from your input URL)"),
|
1339 |
+
gr.Textbox(label="Summary or Status Message (Current status of Summary or Summary itself)"),
|
1340 |
+
gr.File(label="Download Transcription as JSON (Download the Transcription as a file)"),
|
1341 |
+
gr.File(label="Download Summary as Text (Download the Summary as a file)"),
|
1342 |
+
gr.File(label="Download Video (Download the Video as a file)"),
|
1343 |
+
gr.File(label="Download Audio (Download the Audio as a file)")
|
1344 |
+
]
|
1345 |
|
1346 |
+
gr.Interface(
|
1347 |
+
fn=process_url,
|
1348 |
+
inputs=all_inputs,
|
1349 |
+
outputs=outputs,
|
1350 |
+
title="Video Transcription and Summarization",
|
1351 |
+
description="Submit a video URL for transcription and summarization. Ensure you input all necessary information including API keys."
|
1352 |
+
)
|
1353 |
|
1354 |
+
with gr.Tab("Transcription & Summarization History"):
|
1355 |
+
image_input = gr.Image(label="Upload Image")
|
1356 |
+
image_output = gr.Image(label="Processed Image")
|
|
|
|
|
|
|
1357 |
|
1358 |
+
with gr.Accordion("Open for More!", open=False):
|
1359 |
+
gr.Markdown("Look at me...")
|
1360 |
+
gr.Slider(minimum=0.0, maximum=1.0, value=0.1, step=0.1, interactive=True, label="Slide me")
|
1361 |
|
1362 |
+
iface.launch(share=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1363 |
|
1364 |
#
|
1365 |
#
|
|
|
1435 |
logging.debug(f"MAIN: Summarization being performed by {api_name}")
|
1436 |
json_file_path = audio_file.replace('.wav', '.segments.json')
|
1437 |
if api_name.lower() == 'openai':
|
1438 |
+
openai_api_key = api_key if api_key else config.get('API', 'openai_api_key', fallback=None)
|
1439 |
try:
|
1440 |
logging.debug(f"MAIN: trying to summarize with openAI")
|
1441 |
+
summary = summarize_with_openai(openai_api_key, json_file_path, openai_model, custom_prompt)
|
1442 |
except requests.exceptions.ConnectionError:
|
1443 |
requests.status_code = "Connection: "
|
1444 |
elif api_name.lower() == "anthropic":
|
1445 |
+
anthropic_api_key = api_key if api_key else config.get('API', 'anthropic_api_key', fallback=None)
|
1446 |
try:
|
1447 |
logging.debug(f"MAIN: Trying to summarize with anthropic")
|
1448 |
+
summary = summarize_with_claude(anthropic_api_key, json_file_path, anthropic_model, custom_prompt)
|
1449 |
except requests.exceptions.ConnectionError:
|
1450 |
requests.status_code = "Connection: "
|
1451 |
elif api_name.lower() == "cohere":
|
1452 |
+
cohere_api_key = api_key if api_key else config.get('API', 'cohere_api_key', fallback=None)
|
1453 |
try:
|
1454 |
logging.debug(f"MAIN: Trying to summarize with cohere")
|
1455 |
+
summary = summarize_with_cohere(cohere_api_key, json_file_path, cohere_model, custom_prompt)
|
1456 |
except requests.exceptions.ConnectionError:
|
1457 |
requests.status_code = "Connection: "
|
1458 |
elif api_name.lower() == "groq":
|
1459 |
+
groq_api_key = api_key if api_key else config.get('API', 'groq_api_key', fallback=None)
|
1460 |
try:
|
1461 |
logging.debug(f"MAIN: Trying to summarize with Groq")
|
1462 |
+
summary = summarize_with_groq(groq_api_key, json_file_path, groq_model, custom_prompt)
|
1463 |
except requests.exceptions.ConnectionError:
|
1464 |
requests.status_code = "Connection: "
|
1465 |
elif api_name.lower() == "llama":
|
1466 |
+
llama_token = api_key if api_key else config.get('API', 'llama_api_key', fallback=None)
|
1467 |
llama_ip = llama_api_IP
|
1468 |
try:
|
1469 |
logging.debug(f"MAIN: Trying to summarize with Llama.cpp")
|
1470 |
+
summary = summarize_with_llama(llama_ip, json_file_path, llama_token, custom_prompt)
|
1471 |
except requests.exceptions.ConnectionError:
|
1472 |
requests.status_code = "Connection: "
|
1473 |
elif api_name.lower() == "kobold":
|
1474 |
+
kobold_token = api_key if api_key else config.get('API', 'kobold_api_key', fallback=None)
|
1475 |
kobold_ip = kobold_api_IP
|
1476 |
try:
|
1477 |
logging.debug(f"MAIN: Trying to summarize with kobold.cpp")
|
1478 |
+
summary = summarize_with_kobold(kobold_ip, json_file_path, kobold_token, custom_prompt)
|
1479 |
except requests.exceptions.ConnectionError:
|
1480 |
requests.status_code = "Connection: "
|
1481 |
elif api_name.lower() == "ooba":
|
1482 |
+
ooba_token = api_key if api_key else config.get('API', 'ooba_api_key', fallback=None)
|
1483 |
ooba_ip = ooba_api_IP
|
1484 |
try:
|
1485 |
logging.debug(f"MAIN: Trying to summarize with oobabooga")
|
1486 |
+
summary = summarize_with_oobabooga(ooba_ip, json_file_path, ooba_token, custom_prompt)
|
1487 |
except requests.exceptions.ConnectionError:
|
1488 |
requests.status_code = "Connection: "
|
1489 |
elif api_name.lower() == "huggingface":
|
1490 |
+
huggingface_api_key = api_key if api_key else config.get('API', 'huggingface_api_key', fallback=None)
|
1491 |
try:
|
1492 |
logging.debug(f"MAIN: Trying to summarize with huggingface")
|
1493 |
+
summarize_with_huggingface(huggingface_api_key, json_file_path, custom_prompt)
|
1494 |
except requests.exceptions.ConnectionError:
|
1495 |
requests.status_code = "Connection: "
|
1496 |
|
|
|
1509 |
except Exception as e:
|
1510 |
logging.error(f"Error processing path: {path}")
|
1511 |
logging.error(str(e))
|
1512 |
+
# end_time = time.monotonic()
|
1513 |
+
# print("Total program execution time: " + timedelta(seconds=end_time - start_time))
|
1514 |
|
1515 |
+
return results
|
1516 |
|
1517 |
|
1518 |
if __name__ == "__main__":
|