AudioBot / app.py
Deepakkori45's picture
Update app.py
c29ce38 verified
raw
history blame
5.8 kB
import streamlit as st
import openai
import os
from pydub import AudioSegment
from pydub.silence import split_on_silence
from dotenv import load_dotenv
from tempfile import NamedTemporaryFile
import math
from docx import Document
# Load environment variables from .env file
load_dotenv()
# Set your OpenAI API key
openai.api_key = os.getenv("OPENAI_API_KEY")
def split_audio_on_silence(audio_file_path, min_silence_len=500, silence_thresh=-40, keep_silence=250):
"""
Split an audio file into chunks using silence detection.
Args:
audio_file_path (str): Path to the audio file.
min_silence_len (int): Minimum length of silence (in ms) required to be used as a split point.
silence_thresh (int): The volume (in dBFS) below which is considered silence.
keep_silence (int): Amount of silence (in ms) to retain at the beginning and end of each chunk.
Returns:
list: List of AudioSegment chunks.
"""
audio = AudioSegment.from_file(audio_file_path)
chunks = split_on_silence(
audio,
min_silence_len=min_silence_len,
silence_thresh=silence_thresh,
keep_silence=keep_silence
)
return chunks
def transcribe(audio_file):
"""
Transcribe an audio file using the OpenAI Whisper model.
Args:
audio_file (str): Path to the audio file.
Returns:
str: Transcribed text.
"""
with open(audio_file, "rb") as audio:
response = openai.audio.transcriptions.create(
model="whisper-1",
file=audio,
response_format="text",
language="en" # Ensures transcription is in English
)
return response
def process_audio_chunks(audio_chunks):
"""
Process and transcribe each audio chunk.
Args:
audio_chunks (list): List of AudioSegment chunks.
Returns:
str: Combined transcription from all chunks.
"""
transcriptions = []
min_length_ms = 100 # Minimum length required by OpenAI API (0.1 seconds)
for i, chunk in enumerate(audio_chunks):
if len(chunk) < min_length_ms:
st.warning(f"Chunk {i} is too short to be processed.")
continue
with NamedTemporaryFile(delete=False, suffix=".wav") as temp_audio_file:
chunk.export(temp_audio_file.name, format="wav")
temp_audio_file_path = temp_audio_file.name
transcription = transcribe(temp_audio_file_path)
if transcription:
transcriptions.append(transcription)
st.write(f"Transcription for chunk {i}: {transcription}")
os.remove(temp_audio_file_path)
return " ".join(transcriptions)
def save_transcription_to_docx(transcription, audio_file_path):
"""
Save the transcription as a .docx file.
Args:
transcription (str): Transcribed text.
audio_file_path (str): Path to the original audio file for naming purposes.
Returns:
str: Path to the saved .docx file.
"""
# Extract the base name of the audio file (without extension)
base_name = os.path.splitext(os.path.basename(audio_file_path))[0]
# Create a new file name by appending "_full_transcription" with .docx extension
output_file_name = f"{base_name}_full_transcription.docx"
# Create a new Document object
doc = Document()
# Add the transcription text to the document
doc.add_paragraph(transcription)
# Save the document in .docx format
doc.save(output_file_name)
return output_file_name
st.title("Audio Transcription with OpenAI's Whisper")
# Allow uploading of audio or video files
uploaded_file = st.file_uploader("Upload an audio or video file", type=["wav", "mp3", "ogg", "m4a", "mp4", "mov"])
if 'transcription' not in st.session_state:
st.session_state.transcription = None
if uploaded_file is not None and st.session_state.transcription is None:
st.audio(uploaded_file)
# Save uploaded file temporarily
file_extension = uploaded_file.name.split(".")[-1]
original_file_name = uploaded_file.name.rsplit('.', 1)[0] # Get original file name without extension
temp_audio_file = f"temp_audio_file.{file_extension}"
with open(temp_audio_file, "wb") as f:
f.write(uploaded_file.getbuffer())
# Split and process audio using silence detection
with st.spinner('Transcribing...'):
audio_chunks = split_audio_on_silence(
temp_audio_file,
min_silence_len=500, # adjust based on your audio characteristics
silence_thresh=-40, # adjust based on the ambient noise level
keep_silence=250 # optional: keeps a bit of silence at the edges
)
transcription = process_audio_chunks(audio_chunks)
if transcription:
st.session_state.transcription = transcription
st.success('Transcription complete!')
# Save transcription to a Word (.docx) file
output_docx_file = save_transcription_to_docx(transcription, uploaded_file.name)
st.session_state.output_docx_file = output_docx_file
# Clean up temporary file
if os.path.exists(temp_audio_file):
os.remove(temp_audio_file)
if st.session_state.transcription:
st.text_area("Transcription", st.session_state.transcription, key="transcription_area_final")
# Download the transcription as a .docx file
with open(st.session_state.output_docx_file, "rb") as docx_file:
st.download_button(
label="Download Transcription (.docx)",
data=docx_file,
file_name=st.session_state.output_docx_file,
mime='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
)