Update app.py
Browse files
app.py
CHANGED
|
@@ -18,16 +18,16 @@ from groq import Groq
|
|
| 18 |
|
| 19 |
client = Groq(api_key=os.getenv("GROQ_API_KEY"))
|
| 20 |
|
| 21 |
-
TRANSCRIPTION_MODEL = "
|
| 22 |
REWRITE_MODEL = "openai/gpt-oss-120b"
|
| 23 |
CHUNK_SIZE = 600 # 10 min in seconds for audio splitting
|
|
|
|
| 24 |
|
| 25 |
# ============================================================================
|
| 26 |
# UTILITY FUNCTIONS
|
| 27 |
# ============================================================================
|
| 28 |
|
| 29 |
def get_video_duration(video_path):
|
| 30 |
-
"""Get video duration using ffprobe"""
|
| 31 |
try:
|
| 32 |
result = subprocess.run(
|
| 33 |
["ffprobe", "-v", "error", "-show_entries",
|
|
@@ -43,20 +43,17 @@ def get_video_duration(video_path):
|
|
| 43 |
raise RuntimeError(f"Failed to get video duration: {str(e)}")
|
| 44 |
|
| 45 |
def extract_audio_chunks(video_path, chunk_size=CHUNK_SIZE):
|
| 46 |
-
"""Extract audio from video and split into chunks"""
|
| 47 |
try:
|
| 48 |
duration = get_video_duration(video_path)
|
| 49 |
num_chunks = math.ceil(duration / chunk_size)
|
| 50 |
audio_chunks = []
|
| 51 |
|
| 52 |
-
# extract full audio first
|
| 53 |
temp_audio_full = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False)
|
| 54 |
audio_full_path = temp_audio_full.name
|
| 55 |
temp_audio_full.close()
|
| 56 |
|
| 57 |
os.system(f"ffmpeg -y -i \"{video_path}\" -q:a 0 -map a \"{audio_full_path}\"")
|
| 58 |
|
| 59 |
-
# split audio into chunks
|
| 60 |
for i in range(num_chunks):
|
| 61 |
start = i * chunk_size
|
| 62 |
end = min((i + 1) * chunk_size, duration)
|
|
@@ -66,7 +63,6 @@ def extract_audio_chunks(video_path, chunk_size=CHUNK_SIZE):
|
|
| 66 |
os.system(f"ffmpeg -y -i \"{audio_full_path}\" -ss {start} -to {end} -c copy \"{chunk_path}\"")
|
| 67 |
audio_chunks.append(chunk_path)
|
| 68 |
|
| 69 |
-
# remove full audio file
|
| 70 |
if os.path.exists(audio_full_path):
|
| 71 |
os.unlink(audio_full_path)
|
| 72 |
|
|
@@ -102,17 +98,16 @@ def transcribe_audio_chunks(audio_chunks, language="English"):
|
|
| 102 |
# GRAMMAR & PUNCTUATION CORRECTION (CHUNKED)
|
| 103 |
# ============================================================================
|
| 104 |
|
| 105 |
-
def rewrite_transcript_chunked(text, language="English",
|
| 106 |
"""
|
| 107 |
-
Rewrite transcript in smaller chunks to avoid token limits
|
| 108 |
-
chunk_size is approx number of words per request (adjust as needed)
|
| 109 |
"""
|
| 110 |
try:
|
| 111 |
words = text.split()
|
| 112 |
rewritten_chunks = []
|
| 113 |
|
| 114 |
-
for i in range(0, len(words),
|
| 115 |
-
chunk_text = " ".join(words[i:i+
|
| 116 |
prompt = f"Correct grammar, punctuation, and make it readable. Language: {language}\n\n{chunk_text}"
|
| 117 |
response = client.chat.completions.create(
|
| 118 |
model=REWRITE_MODEL,
|
|
@@ -121,7 +116,6 @@ def rewrite_transcript_chunked(text, language="English", chunk_size=4000):
|
|
| 121 |
)
|
| 122 |
rewritten_chunks.append(response.choices[0].message.content)
|
| 123 |
|
| 124 |
-
# Join all rewritten chunks
|
| 125 |
rewritten_text = "\n\n".join(rewritten_chunks)
|
| 126 |
return rewritten_text
|
| 127 |
except Exception as e:
|
|
|
|
| 18 |
|
| 19 |
client = Groq(api_key=os.getenv("GROQ_API_KEY"))
|
| 20 |
|
| 21 |
+
TRANSCRIPTION_MODEL = "whisper-large-v3" # transcription model
|
| 22 |
REWRITE_MODEL = "openai/gpt-oss-120b"
|
| 23 |
CHUNK_SIZE = 600 # 10 min in seconds for audio splitting
|
| 24 |
+
REWRITE_CHUNK_WORDS = 4000 # number of words per GPT rewrite chunk
|
| 25 |
|
| 26 |
# ============================================================================
|
| 27 |
# UTILITY FUNCTIONS
|
| 28 |
# ============================================================================
|
| 29 |
|
| 30 |
def get_video_duration(video_path):
|
|
|
|
| 31 |
try:
|
| 32 |
result = subprocess.run(
|
| 33 |
["ffprobe", "-v", "error", "-show_entries",
|
|
|
|
| 43 |
raise RuntimeError(f"Failed to get video duration: {str(e)}")
|
| 44 |
|
| 45 |
def extract_audio_chunks(video_path, chunk_size=CHUNK_SIZE):
|
|
|
|
| 46 |
try:
|
| 47 |
duration = get_video_duration(video_path)
|
| 48 |
num_chunks = math.ceil(duration / chunk_size)
|
| 49 |
audio_chunks = []
|
| 50 |
|
|
|
|
| 51 |
temp_audio_full = tempfile.NamedTemporaryFile(suffix=".mp3", delete=False)
|
| 52 |
audio_full_path = temp_audio_full.name
|
| 53 |
temp_audio_full.close()
|
| 54 |
|
| 55 |
os.system(f"ffmpeg -y -i \"{video_path}\" -q:a 0 -map a \"{audio_full_path}\"")
|
| 56 |
|
|
|
|
| 57 |
for i in range(num_chunks):
|
| 58 |
start = i * chunk_size
|
| 59 |
end = min((i + 1) * chunk_size, duration)
|
|
|
|
| 63 |
os.system(f"ffmpeg -y -i \"{audio_full_path}\" -ss {start} -to {end} -c copy \"{chunk_path}\"")
|
| 64 |
audio_chunks.append(chunk_path)
|
| 65 |
|
|
|
|
| 66 |
if os.path.exists(audio_full_path):
|
| 67 |
os.unlink(audio_full_path)
|
| 68 |
|
|
|
|
| 98 |
# GRAMMAR & PUNCTUATION CORRECTION (CHUNKED)
|
| 99 |
# ============================================================================
|
| 100 |
|
| 101 |
+
def rewrite_transcript_chunked(text, language="English", chunk_words=REWRITE_CHUNK_WORDS):
|
| 102 |
"""
|
| 103 |
+
Rewrite transcript in smaller word-based chunks to avoid token limits
|
|
|
|
| 104 |
"""
|
| 105 |
try:
|
| 106 |
words = text.split()
|
| 107 |
rewritten_chunks = []
|
| 108 |
|
| 109 |
+
for i in range(0, len(words), chunk_words):
|
| 110 |
+
chunk_text = " ".join(words[i:i+chunk_words])
|
| 111 |
prompt = f"Correct grammar, punctuation, and make it readable. Language: {language}\n\n{chunk_text}"
|
| 112 |
response = client.chat.completions.create(
|
| 113 |
model=REWRITE_MODEL,
|
|
|
|
| 116 |
)
|
| 117 |
rewritten_chunks.append(response.choices[0].message.content)
|
| 118 |
|
|
|
|
| 119 |
rewritten_text = "\n\n".join(rewritten_chunks)
|
| 120 |
return rewritten_text
|
| 121 |
except Exception as e:
|