Testcomic / backend /subtitles /subs_real.py
3v324v23's picture
Update Comic123 with local comic folder files
83e35a7
"""
Real Subtitle Extraction from Video Audio
Extracts actual audio and uses speech recognition to generate real subtitles
"""
import os
import subprocess
import srt
import whisper
from datetime import timedelta
import tempfile
def extract_audio_from_video(video_path):
"""Extract audio from video using ffmpeg"""
try:
# Create temporary audio file
audio_path = "temp_audio.wav"
# Extract audio using ffmpeg
cmd = [
'ffmpeg', '-i', video_path,
'-vn', # No video
'-acodec', 'pcm_s16le', # PCM audio codec
'-ar', '16000', # 16kHz sample rate
'-ac', '1', # Mono audio
'-y', # Overwrite output
audio_path
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print(f"βœ… Audio extracted: {audio_path}")
return audio_path
else:
print(f"❌ Audio extraction failed: {result.stderr}")
return None
except Exception as e:
print(f"❌ Audio extraction error: {e}")
return None
def transcribe_audio_with_whisper(audio_path):
"""Transcribe audio using OpenAI Whisper"""
try:
print("🎀 Loading Whisper model...")
# Load Whisper model (base model for speed)
model = whisper.load_model("base")
print("🎀 Transcribing audio...")
# Transcribe audio
result = model.transcribe(
audio_path,
language="en", # English
word_timestamps=True, # Get word-level timestamps
verbose=True
)
print("βœ… Transcription completed")
return result
except Exception as e:
print(f"❌ Transcription error: {e}")
return None
def create_subtitles_from_transcription(transcription_result):
"""Create SRT subtitles from Whisper transcription"""
try:
subtitles = []
# Get segments from transcription
segments = transcription_result.get('segments', [])
if not segments:
print("⚠️ No segments found in transcription")
return []
print(f"πŸ“ Creating subtitles from {len(segments)} segments...")
for i, segment in enumerate(segments, 1):
# Get timing information
start_time = segment.get('start', 0)
end_time = segment.get('end', 0)
text = segment.get('text', '').strip()
if text: # Only create subtitle if there's text
# Create SRT subtitle
subtitle = srt.Subtitle(
index=i,
start=timedelta(seconds=start_time),
end=timedelta(seconds=end_time),
content=text
)
subtitles.append(subtitle)
print(f"βœ… Created {len(subtitles)} subtitles")
return subtitles
except Exception as e:
print(f"❌ Subtitle creation error: {e}")
return []
def get_real_subtitles(video_path):
"""Extract real subtitles from video audio"""
print("🎬 Extracting real subtitles from video...")
# Step 1: Extract audio from video
audio_path = extract_audio_from_video(video_path)
if not audio_path:
print("❌ Failed to extract audio, using fallback")
return create_fallback_subtitles()
# Step 2: Transcribe audio with Whisper
transcription = transcribe_audio_with_whisper(audio_path)
if not transcription:
print("❌ Failed to transcribe audio, using fallback")
return create_fallback_subtitles()
# Step 3: Create subtitles from transcription
subtitles = create_subtitles_from_transcription(transcription)
if not subtitles:
print("❌ Failed to create subtitles, using fallback")
return create_fallback_subtitles()
# Step 4: Save subtitles to file
try:
with open('test1.srt', 'w', encoding='utf-8') as f:
f.write(srt.compose(subtitles))
print(f"βœ… Real subtitles saved: test1.srt ({len(subtitles)} segments)")
# Clean up temporary audio file
if os.path.exists(audio_path):
os.remove(audio_path)
return True
except Exception as e:
print(f"❌ Failed to save subtitles: {e}")
return False
def create_fallback_subtitles():
"""Create fallback subtitles if real extraction fails"""
print("πŸ“ Creating fallback subtitles...")
# Create basic subtitles with longer segments
fallback_subtitles = [
srt.Subtitle(index=1, start=timedelta(seconds=0), end=timedelta(seconds=5), content="[Dialogue from video]"),
srt.Subtitle(index=2, start=timedelta(seconds=5), end=timedelta(seconds=10), content="[Conversation continues]"),
srt.Subtitle(index=3, start=timedelta(seconds=10), end=timedelta(seconds=15), content="[Story development]"),
srt.Subtitle(index=4, start=timedelta(seconds=15), end=timedelta(seconds=20), content="[Scene transition]"),
srt.Subtitle(index=5, start=timedelta(seconds=20), end=timedelta(seconds=25), content="[Action sequence]"),
srt.Subtitle(index=6, start=timedelta(seconds=25), end=timedelta(seconds=30), content="[Character interaction]"),
srt.Subtitle(index=7, start=timedelta(seconds=30), end=timedelta(seconds=35), content="[Plot development]"),
srt.Subtitle(index=8, start=timedelta(seconds=35), end=timedelta(seconds=40), content="[Story climax]"),
srt.Subtitle(index=9, start=timedelta(seconds=40), end=timedelta(seconds=45), content="[Resolution]"),
srt.Subtitle(index=10, start=timedelta(seconds=45), end=timedelta(seconds=50), content="[Conclusion]"),
srt.Subtitle(index=11, start=timedelta(seconds=50), end=timedelta(seconds=55), content="[Final scene]"),
srt.Subtitle(index=12, start=timedelta(seconds=55), end=timedelta(seconds=60), content="[End credits]"),
srt.Subtitle(index=13, start=timedelta(seconds=60), end=timedelta(seconds=65), content="[Additional content]"),
srt.Subtitle(index=14, start=timedelta(seconds=65), end=timedelta(seconds=70), content="[Extended scene]"),
srt.Subtitle(index=15, start=timedelta(seconds=70), end=timedelta(seconds=75), content="[Behind scenes]"),
srt.Subtitle(index=16, start=timedelta(seconds=75), end=timedelta(seconds=80), content="[Epilogue]"),
]
# Save fallback subtitles
with open('test1.srt', 'w', encoding='utf-8') as f:
f.write(srt.compose(fallback_subtitles))
print("βœ… Fallback subtitles created")
return True
if __name__ == '__main__':
get_real_subtitles('video/IronMan.mp4')