Documentation Index Fetch the complete documentation index at: https://docs.videodb.io/llms.txt
Use this file to discover all available pages before exploring further.
Deliver video content to end users through embedded players, shareable links, and social media integrations.
Quick Example
import videodb
conn = videodb.connect()
coll = conn.get_collection()
video = coll.get_video( "m-xxx" )
# Get streaming URL
stream_url = video.generate_stream()
# Get thumbnail
thumbnail_url = video.generate_thumbnail()
# Get download link
download_url = video.download( name = "sample video" )
Embed Player
Basic HTML Embed
< video
id = "player"
controls
width = "100%"
poster = "{thumbnail_url}"
>
< source
src = "{stream_url}"
type = "application/x-mpegURL"
>
</ video >
< script src = "https://cdn.jsdelivr.net/npm/hls.js@latest" ></ script >
< script >
const video = document . getElementById ( 'player' );
const src = video . querySelector ( 'source' ). src ;
if ( Hls . isSupported ()) {
const hls = new Hls ();
hls . loadSource ( src );
hls . attachMedia ( video );
}
</ script >
React Component
import Hls from 'hls.js' ;
import { useRef , useEffect } from 'react' ;
function VideoPlayer ({ streamUrl , thumbnailUrl , title }) {
const videoRef = useRef ( null );
useEffect (() => {
const video = videoRef . current ;
if ( ! video ) return ;
if ( Hls . isSupported ()) {
const hls = new Hls ();
hls . loadSource ( streamUrl );
hls . attachMedia ( video );
return () => hls . destroy ();
} else if ( video . canPlayType ( 'application/vnd.apple.mpegurl' )) {
// Safari native HLS
video . src = streamUrl ;
}
}, [ streamUrl ]);
return (
< video
ref = { videoRef }
controls
poster = { thumbnailUrl }
title = { title }
style = { { width: '100%' } }
/>
);
}
Vue Component
< template >
< video
ref = "videoPlayer"
controls
: poster = " thumbnailUrl "
style = " width : 100 % "
/ >
</ template >
< script setup >
import Hls from 'hls.js' ;
import { ref , onMounted , onUnmounted } from 'vue' ;
const props = defineProps ([ 'streamUrl' , 'thumbnailUrl' ]);
const videoPlayer = ref ( null );
let hls = null ;
onMounted (() => {
if ( Hls . isSupported ()) {
hls = new Hls ();
hls . loadSource ( props . streamUrl );
hls . attachMedia ( videoPlayer . value );
}
});
onUnmounted (() => {
if ( hls ) hls . destroy ();
});
</ script >
Embed Code Generation
get_embed_code()
Generate an HTML iframe embed string directly from SDK objects. Available on Video, Shot, SearchResult, Timeline, RTStream, RTStreamShot, RTStreamExportResult, and Editor Timeline.
embed_html = obj.get_embed_code(
width = "100%" , # iframe width
height = 405 , # iframe height in pixels
title = "VideoDB Player" , # iframe title attribute
allow_fullscreen = True , # allow fullscreen
auto_generate = True # auto-call generate_stream() if player_url missing
)
Returns an HTML <iframe> string. Raises ValueError if player_url is not available and cannot be auto-generated.
Video Embed
video = coll.get_video( "m-xxx" )
# Auto-generates stream URL if needed
embed_html = video.get_embed_code()
print (embed_html)
# <iframe src="https://console.videodb.io/player?url=..." width="100%" height="405" ...></iframe>
# Custom dimensions
embed_html = video.get_embed_code( width = "640px" , height = 360 , title = "My Video" )
Search Result Embed
results = video.search( "product demo" )
# Embed the compiled search results
embed_html = results.get_embed_code( height = 480 )
RTStream Note
RTStream does not support auto_generate. You must call generate_stream(start, end) explicitly before calling get_embed_code():
rt_stream.generate_stream( start = 0 , end = 120 )
embed_html = rt_stream.get_embed_code( auto_generate = False )
build_iframe_embed_code() Utility
A standalone helper when you already have a player URL:
from videodb import build_iframe_embed_code
embed_html = build_iframe_embed_code(player_url, width = "100%" , height = 405 )
Thumbnail Generation
Get Video Thumbnail
# Default thumbnail (first frame)
thumbnail_url = video.generate_thumbnail()
# Thumbnail at specific time
thumbnail_url = video.generate_thumbnail( time = 30.5 )
Multiple Thumbnails for Preview
def generate_preview_thumbnails ( video , count = 5 ):
"""Generate evenly spaced thumbnails across video"""
duration = video.duration
interval = duration / (count + 1 )
thumbnails = []
for i in range ( 1 , count + 1 ):
time = interval * i
url = video.generate_thumbnail( time = time)
thumbnails.append({
"time" : time,
"url" : url
})
return thumbnails
previews = generate_preview_thumbnails(video, count = 5 )
Share Links
VideoDB Console Player
Generate shareable links using the console player:
import urllib.parse
stream_url = video.generate_stream()
encoded_url = urllib.parse.quote(stream_url, safe = '' )
share_link = f "https://console.videodb.io/player?url= { encoded_url } "
Share Specific Clips
# Share a specific segment
clip_url = video.generate_stream([( 120 , 180 )])
share_clip = f "https://console.videodb.io/player?url= { urllib.parse.quote(clip_url) } "
<!-- Video metadata for social sharing -->
< meta property = "og:type" content = "video.other" />
< meta property = "og:title" content = "{video_title}" />
< meta property = "og:description" content = "{video_description}" />
< meta property = "og:image" content = "{thumbnail_url}" />
< meta property = "og:video" content = "{stream_url}" />
< meta property = "og:video:type" content = "application/x-mpegURL" />
< meta property = "og:video:width" content = "1920" />
< meta property = "og:video:height" content = "1080" />
< meta name = "twitter:card" content = "player" />
< meta name = "twitter:title" content = "{video_title}" />
< meta name = "twitter:description" content = "{video_description}" />
< meta name = "twitter:image" content = "{thumbnail_url}" />
< meta name = "twitter:player" content = "{embed_url}" />
< meta name = "twitter:player:width" content = "1280" />
< meta name = "twitter:player:height" content = "720" />
def generate_social_metadata ( video , title , description ):
"""Generate metadata for social sharing"""
stream_url = video.generate_stream()
thumbnail_url = video.generate_thumbnail()
return {
"title" : title,
"description" : description,
"thumbnail" : thumbnail_url,
"video_url" : stream_url,
"og" : {
"type" : "video.other" ,
"title" : title,
"description" : description,
"image" : thumbnail_url,
"video" : stream_url
},
"twitter" : {
"card" : "player" ,
"title" : title,
"description" : description,
"image" : thumbnail_url
}
}
CDN Delivery
Stream URL Structure
VideoDB serves content through a global CDN:
https://stream.videodb.io/v3/published/manifests/{manifest-id}.m3u8
Endpoint Purpose stream.videodb.ioHLS streaming cdn.videodb.ioDirect file downloads
URL Caching Strategy
import time
from functools import lru_cache
class VideoURLCache :
def __init__ ( self , ttl = 23 * 3600 ): # 23 hours
self .cache = {}
self .ttl = ttl
def get_stream_url ( self , video , timestamps = None ):
key = f " { video.id } : { timestamps } "
if key in self .cache:
url, expires = self .cache[key]
if time.time() < expires:
return url
# Generate new URL
if timestamps:
url = video.generate_stream(timestamps)
else :
url = video.generate_stream()
self .cache[key] = (url, time.time() + self .ttl)
return url
# Usage
url_cache = VideoURLCache()
stream_url = url_cache.get_stream_url(video)
Player Features
Autoplay with Mute
< video
id = "player"
autoplay
muted
playsinline
poster = "{thumbnail_url}"
>
< source src = "{stream_url}" type = "application/x-mpegURL" >
</ video >
Loop Playback
< video id = "player" loop controls >
< source src = "{stream_url}" type = "application/x-mpegURL" >
</ video >
Custom Controls
function CustomPlayer ({ streamUrl }) {
const videoRef = useRef ( null );
const [ playing , setPlaying ] = useState ( false );
const [ progress , setProgress ] = useState ( 0 );
const togglePlay = () => {
if ( playing ) {
videoRef . current . pause ();
} else {
videoRef . current . play ();
}
setPlaying ( ! playing );
};
return (
< div className = "player-container" >
< video
ref = { videoRef }
onTimeUpdate = { ( e ) => {
const pct = ( e . target . currentTime / e . target . duration ) * 100 ;
setProgress ( pct );
} }
/>
< div className = "controls" >
< button onClick = { togglePlay } >
{ playing ? 'Pause' : 'Play' }
</ button >
< div className = "progress-bar" style = { { width: ` ${ progress } %` } } />
</ div >
</ div >
);
}
Responsive Embed
Aspect Ratio Container
.video-container {
position : relative ;
width : 100 % ;
padding-bottom : 56.25 % ; /* 16:9 aspect ratio */
}
.video-container video {
position : absolute ;
top : 0 ;
left : 0 ;
width : 100 % ;
height : 100 % ;
}
< div class = "video-container" >
< video controls >
< source src = "{stream_url}" type = "application/x-mpegURL" >
</ video >
</ div >
Multiple Aspect Ratios
.video-16-9 { padding-bottom : 56.25 % ; }
.video-4-3 { padding-bottom : 75 % ; }
.video-1-1 { padding-bottom : 100 % ; }
.video-9-16 { padding-bottom : 177.78 % ; }
Best Practices
Practice Reason Cache stream URLs Avoid regenerating on every request Use thumbnails Improve perceived load time Preload metadata preload="metadata" for faster startsLazy load off-screen Defer loading until visible Handle errors Show fallback on stream failure
Error Handling
function VideoPlayer ({ streamUrl , fallbackUrl }) {
const [ error , setError ] = useState ( false );
if ( error && fallbackUrl ) {
return < img src = { fallbackUrl } alt = "Video unavailable" /> ;
}
return (
< video
controls
onError = { () => setError ( true ) }
>
< source src = { streamUrl } type = "application/x-mpegURL" />
</ video >
);
}
Next Steps
Streams and Exports Generate clips and export video
Timeline Architecture Compose video programmatically