import gradio as gr import torch from transformers import WhisperProcessor, WhisperForConditionalGeneration import requests from bs4 import BeautifulSoup import tempfile import os import soundfile as sf from spellchecker import SpellChecker from pydub import AudioSegment # Check if CUDA is available and set the device device = "cuda" if torch.cuda.is_available() else "cpu" print(f"Using device: {device}") # Load the Whisper model and processor model_name = "openai/whisper-small" processor = WhisperProcessor.from_pretrained(model_name) model = WhisperForConditionalGeneration.from_pretrained(model_name).to(device) spell = SpellChecker() def download_audio_from_url(url): try: if "share" in url: print("Processing shareable link...") response = requests.get(url) soup = BeautifulSoup(response.content, 'html.parser') video_tag = soup.find('video') if video_tag and 'src' in video_tag.attrs: video_url = video_tag['src'] print(f"Extracted video URL: {video_url}") else: raise ValueError("Direct video URL not found in the shareable link.") else: video_url = url print(f"Downloading video from URL: {video_url}") response = requests.get(video_url) audio_bytes = response.content print(f"Successfully downloaded {len(audio_bytes)} bytes of data") return audio_bytes except Exception as e: print(f"Error in download_audio_from_url: {str(e)}") raise def correct_spelling(text): words = text.split() corrected_words = [spell.correction(word) or word for word in words] return ' '.join(corrected_words) def format_transcript(transcript): sentences = transcript.split('.') formatted_transcript = [] current_speaker = None for sentence in sentences: if ':' in sentence: speaker, content = sentence.split(':', 1) if speaker != current_speaker: formatted_transcript.append(f"\n\n{speaker.strip()}:{content.strip()}.") current_speaker = speaker else: formatted_transcript.append(f"{content.strip()}.") else: formatted_transcript.append(sentence.strip() + '.') return ' '.join(formatted_transcript) def transcribe_audio(audio_file): try: # Load and preprocess the audio audio_input, sample_rate = sf.read(audio_file) input_features = processor(audio_input, sampling_rate=sample_rate, return_tensors="pt").input_features.to(device) # Generate token ids predicted_ids = model.generate(input_features) # Decode token ids to text transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True) return transcription[0] except Exception as e: print(f"Error in transcribe_audio: {str(e)}") raise def transcribe_video(url): try: print(f"Attempting to download audio from URL: {url}") audio_bytes = download_audio_from_url(url) print(f"Successfully downloaded {len(audio_bytes)} bytes of audio data") # Convert audio bytes to AudioSegment audio = AudioSegment.from_file(io.BytesIO(audio_bytes)) # Save as WAV file with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_audio: audio.export(temp_audio.name, format="wav") temp_audio_path = temp_audio.name print("Starting audio transcription...") transcript = transcribe_audio(temp_audio_path) print("Transcription completed successfully") # Clean up the temporary file os.unlink(temp_audio_path) # Apply spelling correction and formatting transcript = correct_spelling(transcript) transcript = format_transcript(transcript) return transcript except Exception as e: error_message = f"An error occurred: {str(e)}" print(error_message) return error_message def download_transcript(transcript): with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as temp_file: temp_file.write(transcript) temp_file_path = temp_file.name return temp_file_path # Create the Gradio interface with gr.Blocks(title="Video Transcription") as demo: gr.Markdown("# Video Transcription") video_url = gr.Textbox(label="Video URL") transcribe_button = gr.Button("Transcribe") transcript_output = gr.Textbox(label="Transcript", lines=20) download_button = gr.Button("Download Transcript") download_link = gr.File(label="Download Transcript") transcribe_button.click(fn=transcribe_video, inputs=video_url, outputs=transcript_output) download_button.click(fn=download_transcript, inputs=transcript_output, outputs=download_link) demo.launch()