compress / app1.py
Asad235's picture
Rename app.py to app1.py
0fe9751 verified
Raw
History Blame Contribute Delete
5.55 kB
import os
import uuid
import subprocess
import whisper
from flask import Flask, request, send_file, render_template_string
from werkzeug.utils import secure_filename
app = Flask(__name__)
# Configuration
UPLOAD_FOLDER = 'uploads'
OUTPUT_FOLDER = 'outputs'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
# Load Whisper model (small for speed, or 'base', 'medium')
print("πŸ”„ Loading Whisper model...")
model = whisper.load_model("small") # small is good balance of speed/accuracy
print("βœ… Model loaded!")
# HTML Template
HTML = '''
<!DOCTYPE html>
<html>
<head>
<title>Word-by-Word Subtitle Generator</title>
<style>
body { font-family: Arial; max-width: 600px; margin: 50px auto; padding: 20px; }
input, button { padding: 10px; margin: 10px 0; width: 100%; }
button { background: #007bff; color: white; border: none; cursor: pointer; }
button:hover { background: #0056b3; }
.status { margin: 20px 0; padding: 10px; border-radius: 5px; }
.success { background: #d4edda; color: #155724; }
.error { background: #f8d7da; color: #721c24; }
</style>
</head>
<body>
<h1>🎬 Word-by-Word Subtitle Generator</h1>
<p>Upload video, get word-by-word subtitles burned in!</p>
<form action="/process" method="post" enctype="multipart/form-data">
<input type="file" name="video" accept="video/*" required>
<button type="submit">🎬 Generate Subtitles</button>
</form>
<div id="status" class="status" style="display:none"></div>
</body>
</html>
'''
def extract_audio(video_path, audio_path):
"""Extract audio from video using FFmpeg"""
subprocess.run([
'ffmpeg', '-i', video_path, '-ac', '1', '-ar', '16000',
audio_path, '-y'
], capture_output=True, check=True)
def get_word_timestamps(audio_path):
"""Get word-by-word timestamps using Whisper"""
result = model.transcribe(audio_path, word_timestamps=True)
words = []
for segment in result['segments']:
for word in segment.get('words', []):
words.append({
'word': word['word'].strip(),
'start': word['start'],
'end': word['end']
})
return words
def format_time(seconds):
"""Convert seconds to SRT time format (HH:MM:SS,mmm)"""
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = seconds % 60
millis = int((secs % 1) * 1000)
return f"{hours:02d}:{minutes:02d}:{int(secs):02d},{millis:03d}"
def generate_srt(words, output_path):
"""Generate SRT file with word-by-word timing"""
with open(output_path, 'w', encoding='utf-8') as f:
for i, word in enumerate(words, 1):
start = format_time(word['start'])
end = format_time(word['end'])
f.write(f"{i}\n{start} --> {end}\n{word['word']}\n\n")
return output_path
def add_subtitles(video_path, srt_path, output_path):
"""Burn subtitles into video using FFmpeg"""
subprocess.run([
'ffmpeg', '-i', video_path,
'-vf', f"subtitles={srt_path}:force_style='FontSize=24,OutlineColour=&H00000000,BorderStyle=1'",
'-c:a', 'copy',
'-preset', 'fast',
output_path, '-y'
], capture_output=True, check=True)
return output_path
@app.route('/')
def home():
return render_template_string(HTML)
@app.route('/process', methods=['POST'])
def process_video():
"""Main processing endpoint"""
if 'video' not in request.files:
return "No video file", 400
file = request.files['video']
if file.filename == '':
return "No file selected", 400
# Generate unique IDs
video_id = uuid.uuid4().hex[:8]
filename = secure_filename(file.filename)
# File paths
input_path = os.path.join(UPLOAD_FOLDER, f"{video_id}_{filename}")
audio_path = os.path.join(UPLOAD_FOLDER, f"{video_id}.wav")
srt_path = os.path.join(OUTPUT_FOLDER, f"{video_id}.srt")
output_path = os.path.join(OUTPUT_FOLDER, f"{video_id}_subtitled.mp4")
try:
# Step 1: Save video
file.save(input_path)
print(f"πŸ“ Video saved: {input_path}")
# Step 2: Extract audio
print("🎡 Extracting audio...")
extract_audio(input_path, audio_path)
# Step 3: Get word timestamps
print("πŸŽ™οΈ Transcribing with Whisper...")
words = get_word_timestamps(audio_path)
print(f"βœ… Found {len(words)} words")
# Step 4: Generate SRT
print("πŸ“ Generating subtitles...")
generate_srt(words, srt_path)
# Step 5: Burn subtitles into video
print("πŸ”₯ Adding subtitles to video...")
add_subtitles(input_path, srt_path, output_path)
print(f"βœ… Done! Output: {output_path}")
# Send file for download
return send_file(
output_path,
as_attachment=True,
download_name="subtitled_video.mp4"
)
except Exception as e:
print(f"❌ Error: {e}")
return f"Error: {str(e)}", 500
finally:
# Cleanup
for f in [input_path, audio_path, srt_path]:
if os.path.exists(f):
try:
os.remove(f)
except:
pass
@app.route('/health')
def health():
return {"status": "ok"}
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=False)