Introduction
Narration is the heartbeat of trailers, injecting excitement and intrigue into every frame. With VideoDB, adding narration becomes a seamless, creative process.
In this tutorial, we will:
Analyze a movie trailer to understand its scenes. Generate a dramatic script using VideoDB’s text generation. Synthesize a deep, trailer-style voiceover using VideoDB’s voice generation. Edit the narration into specific time slots to match the video’s pacing. Overlay a movie poster at the end. All using a single SDK.
Here’s an example of weaving a thrilling storyline from a reel of unrelated, but valuable cinematic shots:
Setup
📦 Installing VideoDB
🔑 API Keys
You only need your VideoDB API Key.
Get your API key from . (Free for first 50 uploads, No credit card required).Get your API key from . ( Free for first 50 uploads, No credit card required ) 🎉
import videodb
import os
from getpass import getpass
# Prompt user for API key securely
api_key = getpass("Please enter your VideoDB API Key: ")
os.environ["VIDEO_DB_API_KEY"] = api_key
🌐 Step 1: Connect to VideoDB
Establish a connection to your VideoDB project.
from videodb import connect
# Connect to VideoDB
conn = connect()
coll = conn.get_collection()
🎬 Step 2: Upload the Trailer
We’ll upload a sample movie trailer (Chase) to VideoDB. This creates the base video asset we will edit.
video = coll.upload(url='https://www.youtube.com/watch?v=WQmGwmc-XUY')
🔍 Step 3: Analyze Scenes
We need to understand the visual pacing of the trailer to write a good script. index_scenes() will generate descriptions and timestamps for every shot.
video_scenes_id = video.index_scenes()
Let's view the description of first scene from the video
video_scenes = video.get_scene_index(video_scenes_id)
import json
print(json.dumps(video_scenes[0], indent=2))
Output:
{
"description": "The scene is engulfed in a vast, tumultuous blaze, with vibrant yellow and fiery orange flames swirling and dancing across the entire frame. The intense heat radiating from the inferno creates a mesmerizing, dynamic spectacle, casting a reddish-brown glow that fills the atmosphere. Darker, smoky elements are intermittently visible through the brilliant light, suggesting objects being consumed within the heart of this powerful, destructive force. The fire is alive, constantly shifting and reaching, conveying both destructive power and captivating motion.",
"end": 1.043,
"metadata": {},
"scene_metadata": {},
"start": 0.0
}
🔊 Step 4: Generate Narration Script
We’ll use VideoDB’s generate_text to write a dramatic script. We feed the scene descriptions into the prompt to ensure the narration matches the visual action.
# Construct prompt with scene context
scene_context = "\n".join([f"- {scene['description']}" for scene in video_scenes])
prompt = f"""
Craft a dynamic, dramatic narration script for a movie trailer based on these visual descriptions:
{scene_context}
Requirements:
- Style: Intense, gritty, like a blockbuster action movie trailer.
- Output: ROnly provide the script for direct voice generation, no stage directions or narration.
"""
script_response = coll.generate_text(
prompt=prompt,
model_name="pro"
)
print("--- Generated Script ---")
print(script_response)
You can refine the narration script prompt to ensure synchronization with timestamps in the scene index, optimizing the storytelling experience.
🎙️ Step 5: Generate Voiceover Audio
Now we synthesize the audio.
# Generate speech directly as an Audio Asset
audio = coll.generate_voice(
text=voiceover_script['output'],
voice_name="Brian"
)
print(f"Generated Audio ID: {audio.id}")
🎥 Step 6: Edit the Timeline
Now we combine the video and audio.
from videodb.editor import Timeline, Track, Clip, VideoAsset, AudioAsset
timeline = Timeline(conn)
# --- 1. Main Video Track ---
main_track = Track()
video_asset = VideoAsset(id=video.id, volume=0.5)
video_clip = Clip(asset=video_asset, duration=float(video.length))
main_track.add_clip(0, video_clip)
timeline.add_track(main_track)
# --- 2. Narration Track---
audio_track = Track()
audio_asset1 = AudioAsset(id=audio.id, start=0, volume=2.0)
audio_clip1 = Clip(asset=audio_asset1, duration=float(audio.length))
audio_track.add_clip(4, audio_clip1)
timeline.add_track(audio_track)
🪄 Step 8: Review and Share
Preview the trailer with the integrated narration to ensure it aligns with your vision. Once satisfied, share the trailer with others to experience the enhanced storytelling.
from videodb import play_stream
stream_url = timeline.generate_stream()
play_stream(stream_url)
🎬 Bonus - Add Movie Poster
Let’s add a “Coming Soon” style movie poster at the very end of the trailer. We’ll upload an image URL and overlay it on the video.
from videodb import MediaType
# Upload movie poster
poster_url = "https://img.freepik.com/free-photo/darkly-atmospheric-retail-environment-rendering_23-2151153755.jpg"
image = coll.upload(url=poster_url, media_type=MediaType.image)
from videodb.editor import ImageAsset
# Create an overlay track for the poster
image_track = Track()
# Show poster at the 10 seconds of the trailer
image_asset = ImageAsset(id=image.id)
image_clip = Clip(
asset=image_asset,
duration=10.0,
fit="contain"
)
image_track.add_clip(float(video.length) - 10, image_clip)
timeline.add_track(image_track)
stream_url = timeline.generate_stream()
play_stream(stream_url)
🎉 Conclusion
You’ve successfully built a sophisticated video editing workflow:
Analysis: Automated scene understanding.