import gradio as gr from moviepy import VideoFileClip, TextClip, CompositeVideoClip from PIL import Image, ImageDraw, ImageFont import whisper from keybert import KeyBERT import numpy as np import warnings import os # Suppress Whisper FP16 CPU warning warnings.filterwarnings("ignore", category=UserWarning, module="whisper") # Load models whisper_model = whisper.load_model("base") kw_model = KeyBERT() # Optional: Hindi-compatible system font (must be pre-installed or accessible by name) SYSTEM_FONT_NAME = "Noto-Sans-Devanagari" # This should be installed on the OS def process_video(video_path, caption="Your Caption"): # === 1. Load Video === clip = VideoFileClip(video_path) # === 2. Extract Frame at 5s for Thumbnail === frame = clip.get_frame(5) image = Image.fromarray(np.uint8(frame)) draw = ImageDraw.Draw(image) # Use PIL to draw caption on thumbnail try: pil_font = ImageFont.truetype("/usr/share/fonts/truetype/noto/NotoSansDevanagari-Regular.ttf", size=40) except: pil_font = ImageFont.load_default() draw.text((50, image.height - 100), caption, fill="white", font=pil_font) thumbnail_path = "thumbnail.jpg" image.save(thumbnail_path) # === 3. Transcribe Audio in Hindi === result = whisper_model.transcribe(video_path, language="hi") text = result["text"] # === 4. Extract SEO Keywords === keywords = kw_model.extract_keywords(text, keyphrase_ngram_range=(1, 2), stop_words='english') keywords_list = [kw[0] for kw in keywords] # === 5. Burn Caption onto Video === try: text_clip = TextClip( caption, fontsize=50, color='white', font=SYSTEM_FONT_NAME, # Use font name (not file path) method='caption', size=(clip.w, None) ) except Exception as e: print("Font fallback used due to error:", e) text_clip = TextClip(caption, color ="black") text_clip = text_clip.set_position(("center", "bottom")).set_duration(clip.duration) final_video = CompositeVideoClip([clip, text_clip]) output_path = "output_with_caption.mp4" final_video.write_videofile(output_path, codec="libx264", audio_codec="aac", verbose=False, logger=None) return thumbnail_path, ", ".join(keywords_list), output_path # === Gradio Interface === with gr.Blocks() as demo: gr.Markdown("# 📹 Video Caption & SEO Tool (Hindi Supported)") with gr.Row(): video_input = gr.File(label="📁 Upload Video", type="filepath") caption_input = gr.Textbox(label="📝 Caption for Thumbnail & Video", value="यह शानदार वीडियो है!") generate_button = gr.Button("🚀 Generate") with gr.Row(): thumbnail_output = gr.Image(label="🖼️ Generated Thumbnail") keywords_output = gr.Textbox(label="🔑 Extracted SEO Keywords") video_output = gr.File(label="⬇️ Download Final Video") generate_button.click( fn=process_video, inputs=[video_input, caption_input], outputs=[thumbnail_output, keywords_output, video_output] ) demo.launch(share=True)