MrSimple01's picture
moviepy_fix
2cbd666 verified
raw
history blame
5.52 kB
import os
import uuid
import time
import json
import requests
import soundfile as sf
import gradio as gr
from moviepy import VideoFileClip
ELEVENLABS_API_KEY = os.environ.get('ELEVENLABS_API_KEY', '')
def extract_audio(video_path, output_format="mp3"):
if not video_path:
return None, "No video provided"
output_path = f"extracted_audio_{uuid.uuid4().hex[:8]}.{output_format}"
try:
video = VideoFileClip(video_path)
video.audio.write_audiofile(output_path, logger=None)
video.close()
return output_path, f"Audio extracted successfully"
except Exception as e:
return None, f"Error extracting audio: {str(e)}"
def transcribe_with_scribe(audio_path, api_key, model_id="scribe_v1"):
start_time = time.time()
if not api_key:
return {"error": "Please provide an API key"}
url = "https://api.elevenlabs.io/v1/speech-to-text"
headers = {
"xi-api-key": api_key
}
try:
with open(audio_path, "rb") as f:
files = {
"file": f,
"model_id": (None, model_id)
}
response = requests.post(url, headers=headers, files=files)
response.raise_for_status()
result = response.json()
except requests.exceptions.RequestException as e:
return {"error": f"API request failed: {str(e)}"}
except json.JSONDecodeError:
return {"error": "Failed to parse API response"}
end_time = time.time()
processing_time = end_time - start_time
file_size = os.path.getsize(audio_path) / (1024 * 1024)
try:
audio_data, sample_rate = sf.read(audio_path)
audio_duration = len(audio_data) / sample_rate
except:
try:
import librosa
audio_duration = librosa.get_duration(filename=audio_path)
except:
audio_duration = 0
text = result.get('text', '')
return {
"service": "Scribe",
"text": text,
"processing_time": processing_time,
"file_size_mb": file_size,
"audio_duration": audio_duration,
"real_time_factor": processing_time / audio_duration if audio_duration > 0 else None,
"processing_speed": audio_duration / processing_time if audio_duration > 0 else None,
"raw_response": result
}
def save_transcription(transcription):
if "error" in transcription:
return None, transcription["error"]
transcript_filename = f"transcription_{uuid.uuid4().hex[:8]}.txt"
try:
with open(transcript_filename, "w", encoding="utf-8") as f:
f.write(transcription.get('text', 'No text found'))
return transcript_filename, "Transcription saved as text file"
except Exception as e:
return None, f"Error saving transcription: {str(e)}"
def process_video_file(video_input, output_format, api_key, model_id):
audio_output, audio_status = extract_audio(video_input, output_format)
if not audio_output:
return None, audio_status, None, audio_status
transcription = transcribe_with_scribe(audio_output, api_key, model_id)
transcript_file, transcript_status = save_transcription(transcription)
try:
os.remove(audio_output)
except Exception:
pass
return audio_output, audio_status, transcript_file, transcript_status
def create_interface():
with gr.Blocks(title="Video to Audio to Transcription") as app:
gr.Markdown("# Video => Audio => Transcription")
with gr.Row():
api_key = gr.Textbox(
placeholder="Enter your ElevenLabs API key",
label="ElevenLabs API Key",
type="password",
value=ELEVENLABS_API_KEY
)
model_id = gr.Dropdown(
choices=["scribe_v1"],
value="scribe_v1",
label="Transcription Model"
)
with gr.Tabs():
with gr.TabItem("Upload Video"):
with gr.Row():
with gr.Column():
video_input = gr.Video(label="Upload Video")
format_choice_file = gr.Radio(
["mp3"],
value="mp3",
label="Output Format"
)
extract_button_file = gr.Button("Extract Audio & Transcribe")
with gr.Column():
audio_output_file = gr.Audio(label="Extracted Audio", type="filepath")
status_output_file = gr.Textbox(label="Audio Extraction Status")
transcript_file_output = gr.File(label="Transcription Text File")
transcript_status_output = gr.Textbox(label="Transcription Status")
extract_button_file.click(
fn=process_video_file,
inputs=[video_input, format_choice_file, api_key, model_id],
outputs=[
audio_output_file,
status_output_file,
transcript_file_output,
transcript_status_output
]
)
return app
def main():
app = create_interface()
app.launch()
if __name__ == "__main__":
main()