Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| from transformers import pipeline | |
| import torch | |
| import moviepy.editor as mp | |
| import os | |
| from googleapiclient.discovery import build | |
| from google.oauth2 import credentials | |
| from google_auth_oauthlib.flow import InstalledAppFlow | |
| from google.auth.transport.requests import Request | |
| from googleapiclient.http import MediaIoBaseDownload | |
| from googleapiclient.errors import HttpError | |
| import uuid | |
| # Device setup | |
| device = "cpu" # Using CPU to avoid CUDA memory issues | |
| print(f"Using device: {device}") | |
| # Preload models | |
| try: | |
| transcriber = pipeline("automatic-speech-recognition", model="openai/whisper-large-v2", device=device) | |
| summarizer = pipeline("summarization", model="facebook/bart-large-cnn", device=device) | |
| except Exception as e: | |
| print(f"Error loading models: {e}. Make sure you have internet connectivity and sufficient resources.") | |
| transcriber = None | |
| summarizer = None | |
| # Google Drive API setup | |
| SCOPES = ['https://www.googleapis.com/auth/drive.readonly'] | |
| CLIENT_SECRET_FILE = 'client_secrets.json' # Relative path | |
| APPLICATION_NAME = 'MyMeetNotes' | |
| def get_credentials(): | |
| if not os.path.exists(CLIENT_SECRET_FILE): | |
| raise FileNotFoundError( | |
| "The 'client_secrets.json' file is missing. Please ensure it’s in the same directory as the script. See: " | |
| "https://developers.google.com/drive/api/v3/quickstart/python" | |
| ) | |
| creds = None | |
| if os.path.exists('token.json'): | |
| creds = credentials.Credentials.from_authorized_user_file('token.json', SCOPES) | |
| if not creds or not creds.valid: | |
| if creds and creds.expired and creds.refresh_token: | |
| creds.refresh(Request()) | |
| else: | |
| flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES) | |
| creds = flow.run_local_server(port=0) | |
| with open('token.json', 'w') as token: | |
| token.write(creds.to_json()) | |
| return creds | |
| def list_google_meet_recordings(): | |
| try: | |
| creds = get_credentials() | |
| service = build('drive', 'v3', credentials=creds) | |
| results = service.files().list( | |
| pageSize=10, fields="nextPageToken, files(id, name, mimeType)", | |
| q="name contains 'Meeting recording' and mimeType contains 'video/'").execute() | |
| items = results.get('files', []) | |
| if not items: | |
| return ["No Google Meet recordings found."] | |
| return [f"{item['name']} (ID: {item['id']})" for item in items] | |
| except HttpError as error: | |
| return [f"An error occurred: {error}"] | |
| except Exception as e: | |
| return [f"An unexpected error occurred: {e}"] | |
| def download_google_meet_recording(file_id): | |
| try: | |
| creds = get_credentials() | |
| service = build('drive', 'v3', credentials=creds) | |
| file_name = f"temp_recording_{file_id}_{uuid.uuid4()}.mp4" # removed os.path.join(os.getcwd(), ...) for simplicity in local usage | |
| print(f"Downloading file ID: {file_id} to {file_name}") | |
| request = service.files().get_media(fileId=file_id) | |
| with open(file_name, 'wb') as fh: | |
| downloader = MediaIoBaseDownload(fh, request) | |
| done = False | |
| while not done: | |
| status, done = downloader.next_chunk() | |
| print(f"Download progress: {int(status.progress() * 100)}%") | |
| if os.path.exists(file_name): | |
| print(f"Download complete. File saved as: {file_name}") | |
| return file_name | |
| else: | |
| return f"Error: File '{file_name}' not found after download." | |
| except HttpError as error: | |
| return f"HTTP error during download: {error}" | |
| except Exception as e: | |
| return f"Unexpected error during download: {e}" | |
| def generate_meeting_notes(file_id): | |
| if transcriber is None or summarizer is None: | |
| return "Error: Models failed to load. Check your internet connection and resources." | |
| try: | |
| download_result = download_google_meet_recording(file_id) | |
| if isinstance(download_result, str) and "Error" in download_result: | |
| return download_result | |
| file_name = download_result | |
| if not os.path.exists(file_name): | |
| return f"Error: Downloaded file '{file_name}' not found." | |
| print(f"Extracting audio from {file_name}") | |
| video = mp.VideoFileClip(file_name) | |
| audio_file = f"temp_audio_{uuid.uuid4()}.wav" | |
| video.audio.write_audiofile(audio_file) | |
| print("Audio extraction complete.") | |
| print("Starting transcription...") | |
| transcription = transcriber(audio_file)["text"] | |
| print("Transcription complete.") | |
| print("Starting summarization...") | |
| summary = summarizer(transcription, max_length=1024, min_length=100, do_sample=False) | |
| meeting_notes = summary[0]["summary_text"] | |
| print("Summarization complete.") | |
| return meeting_notes | |
| except Exception as e: | |
| return f"Error in processing: {str(e)}" | |
| finally: | |
| try: | |
| if 'video' in locals() and video: # Check if video exists | |
| video.close() | |
| if 'audio_file' in locals() and os.path.exists(audio_file): | |
| os.remove(audio_file) | |
| if 'file_name' in locals() and os.path.exists(file_name): # Check if file_name exists | |
| os.remove(file_name) | |
| except Exception as cleanup_error: | |
| print(f"Cleanup error: {cleanup_error}") | |
| def launch_gradio(): | |
| with gr.Blocks() as iface: | |
| gr.Markdown("# Automatic Meeting Notes Generator from Google Meet") | |
| with gr.Row(): | |
| with gr.Column(): | |
| file_id_input = gr.Textbox(label="Google Meet Recording File ID", placeholder="Enter the Google Drive File ID") | |
| generate_button = gr.Button("Generate Notes") | |
| recording_list_button = gr.Button("List Recordings") | |
| with gr.Column(): | |
| output_text = gr.Textbox(label="Meeting Notes") | |
| recording_list = gr.Textbox(label="Available Recordings") | |
| generate_button.click(fn=generate_meeting_notes, inputs=file_id_input, outputs=output_text) | |
| recording_list_button.click(fn=list_google_meet_recordings, inputs=None, outputs=recording_list) | |
| iface.launch(debug=True) | |
| if __name__ == "__main__": | |
| launch_gradio() |