Introduction to Video Streaming on Google Cloud Platform
Building a scalable, reliable video streaming platform requires careful orchestration of ingestion, processing, storage, and delivery components. Google Cloud Platform (GCP) offers a comprehensive suite of managed services that handle every stage of the video pipeline—from live ingest and transcoding to global edge caching and playback analytics. This tutorial walks you through designing a complete video streaming solution on GCP, covering both Video on Demand (VOD) and live streaming architectures with practical code examples you can deploy today.
What is Video Streaming on GCP?
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Video streaming on GCP refers to the use of Google Cloud's managed media services to ingest, process, store, and deliver video content at scale. Rather than building custom media processing infrastructure from scratch, developers leverage purpose-built APIs and services that handle the heavy lifting of video transcoding, packaging, encryption, and global distribution. The platform supports two primary streaming paradigms:
- Video on Demand (VOD): Pre-recorded content that is transcoded into multiple bitrates and stored for on-demand playback
- Live Streaming: Real-time broadcast content ingested, transcoded, and distributed to viewers with minimal latency
The core GCP services that form a video streaming architecture include Cloud Storage for durable media storage, the Transcoder API for format conversion and adaptive bitrate packaging, Cloud CDN or Media CDN for edge caching, and the Live Stream API for real-time ingest and transcoding of live feeds. Together, these services eliminate the need to manage fleets of encoding servers or complex content delivery networks.
Why GCP for Video Streaming Matters
Choosing GCP for video streaming infrastructure offers several compelling advantages that directly impact both developer productivity and end-user experience:
- Fully managed transcoding: The Transcoder API and Live Stream API eliminate the need to provision, scale, or maintain encoding infrastructure. Jobs are submitted as API calls and Google handles the rest, scaling to thousands of concurrent jobs automatically
- Global edge delivery: Cloud CDN and Media CDN leverage Google's worldwide network presence across more than 1,300 edge locations, ensuring low-latency delivery to viewers anywhere
- Pay-as-you-go pricing: You pay only for the minutes of video processed and the bytes delivered, with no upfront hardware costs or over-provisioning
- Seamless integration: All services interoperate natively with Cloud Storage, Cloud Functions, Pub/Sub, and BigQuery, enabling rich event-driven workflows and analytics pipelines
- Security at scale: Built-in support for signed URL authentication, DRM encryption (Widevine, FairPlay, PlayReady), and Cloud Armor DDoS protection safeguard your content
Core GCP Services for Video Streaming
Before diving into implementation, let's map out the key services and their roles in a streaming architecture:
- Cloud Storage: Serves as the durable origin store for master media files, transcoded outputs, HLS/MPD manifests, and segments. Offers multi-region buckets for geo-redundancy and Object Lifecycle Management for cost optimization
- Transcoder API: A fully managed service that converts source media files into adaptive bitrate streaming formats (HLS, DASH). Supports batch transcoding with job templates for predefined output presets
- Live Stream API: Ingests live RTMP or SRT feeds and transcodes them in real time into multiple bitrate HLS or DASH outputs, writing segments and manifests directly to Cloud Storage
- Cloud CDN / Media CDN: Edge caching layers that serve video segments and manifests from Google's global points of presence. Media CDN offers advanced origin shielding, header-based routing, and cache invalidation APIs
- Cloud Functions / Cloud Run: Lightweight compute for event-driven workflows such as triggering transcoding on new file uploads, generating thumbnails, or updating databases
- Pub/Sub: Asynchronous messaging bus that decouples services—for example, notifying a transcoding orchestrator when a new video lands in a storage bucket
- Secret Manager: Securely stores API keys, signing secrets for token-based CDN authentication, and DRM encryption keys
- BigQuery & Cloud Logging: Enable playback analytics, quality-of-experience monitoring, and operational observability across the streaming pipeline
Architecture Overview: Video on Demand (VOD)
The classic VOD workflow on GCP follows a linear ingestion-to-delivery pipeline. A source video file lands in an input Cloud Storage bucket, which triggers a transcoding job via the Transcoder API. The transcoded adaptive bitrate outputs (multiple renditions plus HLS/DASH manifests) are written to an output bucket. Cloud CDN or Media CDN is configured with the output bucket as its origin, caching segments at the edge for efficient delivery to end-user devices.
A typical VOD architecture diagram flows as follows:
- Ingestion: Source video uploaded to
gs://my-vod-input-bucket(via direct upload, presigned URLs, or transfer appliances) - Event trigger: A Cloud Storage object finalize event is pushed to Pub/Sub, which invokes a Cloud Function orchestrator
- Transcoding: The orchestrator calls the Transcoder API with a job template specifying output renditions (e.g., 1080p, 720p, 480p, 360p) and packaging format (HLS with fragmented MP4 segments)
- Output: Transcoded segments and manifests are written to
gs://my-vod-output-bucket, organized by video ID - Delivery: Cloud CDN is configured with the output bucket as the origin, serving HLS playlists and segments via HTTPS to video players across the globe
Architecture Overview: Live Streaming
Live streaming introduces a real-time dimension. A broadcaster pushes a live RTMP or SRT feed to the Live Stream API input endpoint. The API transcodes the incoming stream into multiple adaptive bitrate renditions and continuously writes HLS segments and updating manifests to a Cloud Storage bucket. Viewers consume the live stream via Cloud CDN, which caches segments for the few seconds they remain relevant before the next segment arrives.
- Ingest: Broadcaster sends RTMP/SRT stream to
INPUT_ENDPOINT_URLprovided by the Live Stream API channel - Real-time transcoding: Live Stream API converts the feed into 1080p, 720p, 480p, and 360p renditions, packaging as HLS with short segment durations (typically 2–4 seconds)
- Manifest updates: The master playlist and media playlists are continuously updated as new segments are written to the output Cloud Storage bucket
- Edge delivery: Cloud CDN serves the manifests and segments to viewers, with appropriate cache TTLs (usually a few seconds) to balance latency and cache efficiency
- Recording (optional): The live stream can be recorded to Cloud Storage for later VOD playback, with the recording triggered by channel configuration
How to Build a VOD Streaming Pipeline
Let's walk through building a complete VOD pipeline step by step. We'll use gcloud commands and Python code examples that you can adapt directly.
Step 1: Create Cloud Storage Buckets
Create separate buckets for input (source files) and output (transcoded content). Using separate buckets simplifies permissions and lifecycle management.
# Create the input bucket (standard storage, regional for cost optimization)
gcloud storage buckets create gs://my-vod-input-bucket \
--location=us-central1 \
--storage-class=STANDARD
# Create the output bucket (standard storage, multi-region for global delivery)
gcloud storage buckets create gs://my-vod-output-bucket \
--location=us \
--storage-class=STANDARD
# Enable uniform bucket-level access for security
gcloud storage buckets update gs://my-vod-input-bucket --uniform-bucket-level-access
gcloud storage buckets update gs://my-vod-output-bucket --uniform-bucket-level-access
Step 2: Define a Transcoder Job Template
Job templates encapsulate your encoding settings so you can reuse them across jobs without specifying every detail each time. The following template creates an HLS adaptive bitrate ladder with four renditions.
# Create a job template for HLS adaptive bitrate output
gcloud transcoder templates create vod-hls-ladder \
--json='{
"templateId": "vod-hls-ladder",
"jobConfig": {
"inputList": [{"key": "input0"}],
"outputList": [
{
"key": "output0",
"uri": "gs://my-vod-output-bucket/${videoId}/master.m3u8",
"editList": [
{
"key": "edit0",
"inputs": ["input0"],
"processing": {
"videoStreams": [
{
"key": "video-1080p",
"resolution": {"x": 1920, "y": 1080},
"bitrateBps": 5500000,
"frameRate": 30,
"codec": "h264",
"profile": "high",
"preset": "veryfast"
},
{
"key": "video-720p",
"resolution": {"x": 1280, "y": 720},
"bitrateBps": 3000000,
"frameRate": 30,
"codec": "h264",
"profile": "high",
"preset": "veryfast"
},
{
"key": "video-480p",
"resolution": {"x": 854, "y": 480},
"bitrateBps": 1200000,
"frameRate": 30,
"codec": "h264",
"profile": "main",
"preset": "veryfast"
},
{
"key": "video-360p",
"resolution": {"x": 640, "y": 360},
"bitrateBps": 600000,
"frameRate": 30,
"codec": "h264",
"profile": "main",
"preset": "veryfast"
}
],
"audioStreams": [
{
"key": "audio-aac",
"codec": "aac",
"bitrateBps": 128000,
"channels": 2,
"sampleRateHertz": 48000
}
],
"manifests": [
{
"fileName": "master.m3u8",
"type": "hls",
"muxStreams": [
{"key": "mux-1080p", "videoKeys": ["video-1080p"], "audioKeys": ["audio-aac"]},
{"key": "mux-720p", "videoKeys": ["video-720p"], "audioKeys": ["audio-aac"]},
{"key": "mux-480p", "videoKeys": ["video-480p"], "audioKeys": ["audio-aac"]},
{"key": "mux-360p", "videoKeys": ["video-360p"], "audioKeys": ["audio-aac"]}
],
"segmentSettings": {
"segmentDuration": "4s",
"individualSegments": true
}
}
]
}
}
]
}
]
}
}' --location=us-central1
Step 3: Create a Cloud Function Orchestrator
When a new video lands in the input bucket, we want to automatically trigger transcoding. This Python Cloud Function listens for Cloud Storage events and submits a job to the Transcoder API.
# requirements.txt for the Cloud Function
# google-cloud-transcoder==1.0.0
# google-cloud-storage==2.10.0
# main.py - Cloud Function triggered by Cloud Storage object finalize events
import os
import uuid
from google.cloud import transcoder_v1
from google.cloud import storage
def trigger_transcoding(event, context):
"""
Triggered by a Cloud Storage object finalize event.
event: Contains bucket name, file name, and other metadata.
context: Contains event metadata like event ID and timestamp.
"""
bucket_name = event['bucket']
file_name = event['name']
# Extract video ID from filename (remove extension)
video_id = os.path.splitext(file_name)[0]
# Initialize the Transcoder API client
client = transcoder_v1.TranscoderServiceClient()
project_id = os.environ.get('GCP_PROJECT', 'my-project-id')
location = 'us-central1'
parent = f'projects/{project_id}/locations/{location}'
# Build the job configuration using our template
job_config = {
'template_id': 'vod-hls-ladder',
'input_uri': f'gs://{bucket_name}/{file_name}',
'output_uri': f'gs://my-vod-output-bucket/{video_id}/'
}
# Submit the transcoding job
job = client.create_transcoder_job(
parent=parent,
transcoder_job={
'input_uri': job_config['input_uri'],
'output_uri': job_config['output_uri'],
'template_id': job_config['template_id']
}
)
print(f"Transcoding job created: {job.name}")
print(f"Video ID: {video_id}")
print(f"Job state: {job.state}")
return f"Job {job.name} submitted successfully", 200
# Deploy the Cloud Function
# gcloud functions deploy trigger-transcoding \
# --runtime=python310 \
# --trigger-event=google.storage.object.finalize \
# --trigger-resource=my-vod-input-bucket \
# --entry-point=trigger_transcoding \
# --region=us-central1 \
# --memory=512MB \
# --timeout=300s
Step 4: Configure Cloud CDN for VOD Delivery
With transcoded content in the output bucket, configure Cloud CDN to serve it globally. You'll need a load balancer and a backend bucket pointing to your output storage bucket.
# Step 1: Create a backend bucket pointing to the output storage bucket
gcloud compute backend-buckets create vod-backend-bucket \
--gcs-bucket=my-vod-output-bucket \
--enable-cdn \
--cache-mode=CACHE_ALL_STATIC \
--default-ttl=86400 \
--max-ttl=2592000 \
--description="Backend bucket for VOD HLS segments and manifests"
# Step 2: Create a URL map to route requests to the backend bucket
gcloud compute url-maps create vod-url-map \
--default-backend-bucket=vod-backend-bucket \
--description="URL map for VOD CDN delivery"
# Step 3: Create a global external HTTP(S) load balancer
gcloud compute target-http-proxies create vod-http-proxy \
--url-map=vod-url-map
# Step 4: Reserve a global static IP and create a forwarding rule
gcloud compute addresses create vod-cdn-ip --global
gcloud compute forwarding-rules create vod-http-rule \
--address=vod-cdn-ip \
--target-http-proxy=vod-http-proxy \
--ports=80 \
--global
# After DNS propagation, viewers access content at:
# http://[CDN_IP]/[video_id]/master.m3u8
How to Build a Live Streaming Pipeline
Live streaming uses the Live Stream API, which handles ingest and real-time transcoding. Here's how to set up a live channel and start broadcasting.
Step 1: Create a Live Stream Input Endpoint
The input endpoint receives the broadcaster's RTMP or SRT stream. You create it once and it persists for the lifetime of your channel.
# Create an input endpoint for RTMP ingest
gcloud live-stream inputs create my-live-input \
--location=us-central1 \
--type=RTMP
# Retrieve the input endpoint URI (this is where you'll push your stream)
gcloud live-stream inputs describe my-live-input \
--location=us-central1 \
--format="get(uri)"
# Example output:
# rtmp://1.2.3.4:1935/my-live-input/stream-key-abc123
# Broadcasters push to this URI using OBS, FFmpeg, or similar tools
Step 2: Create a Live Stream Channel
The channel defines the transcoding settings, output destination, and any recording configuration. It links an input endpoint to output renditions.
# Create a live channel configuration file: live_channel.json
cat > live_channel.json << 'EOF'
{
"inputAttachments": [
{
"key": "main-input",
"input": "projects/my-project-id/locations/us-central1/inputs/my-live-input"
}
],
"output": {
"uri": "gs://my-live-output-bucket/live-stream-001/"
},
"elementaryStreams": [
{
"key": "video-1080p",
"videoStream": {
"h264": {
"profile": "high",
"bitrateBps": 5000000,
"widthPixels": 1920,
"heightPixels": 1080,
"frameRate": 30
}
}
},
{
"key": "video-720p",
"videoStream": {
"h264": {
"profile": "high",
"bitrateBps": 2800000,
"widthPixels": 1280,
"heightPixels": 720,
"frameRate": 30
}
}
},
{
"key": "video-480p",
"videoStream": {
"h264": {
"profile": "main",
"bitrateBps": 1100000,
"widthPixels": 854,
"heightPixels": 480,
"frameRate": 30
}
}
},
{
"key": "audio-aac",
"audioStream": {
"codec": "aac",
"bitrateBps": 128000,
"channelCount": 2,
"sampleRateHertz": 48000
}
}
],
"muxStreams": [
{
"key": "mux-1080p",
"elementaryStreams": ["video-1080p", "audio-aac"],
"segmentSettings": {
"segmentDuration": "2s"
}
},
{
"key": "mux-720p",
"elementaryStreams": ["video-720p", "audio-aac"],
"segmentSettings": {
"segmentDuration": "2s"
}
},
{
"key": "mux-480p",
"elementaryStreams": ["video-480p", "audio-aac"],
"segmentSettings": {
"segmentDuration": "2s"
}
}
],
"manifests": [
{
"fileName": "main.m3u8",
"type": "HLS",
"muxStreams": ["mux-1080p", "mux-720p", "mux-480p"],
"maxSegmentCount": 5
}
]
}
EOF
# Create the live channel
gcloud live-stream channels create my-live-channel \
--location=us-central1 \
--config-file=live_channel.json
# Note the channel ID returned for starting/stopping the channel
Step 3: Start the Live Channel
Once the channel is created, you start it to begin accepting the ingest stream and producing output. The channel remains running until explicitly stopped.
# Start the live channel
gcloud live-stream channels start my-live-channel \
--location=us-central1
# The channel is now accepting input on the RTMP endpoint
# Output segments and manifests will appear in gs://my-live-output-bucket/live-stream-001/
# To stop the channel when the broadcast ends:
gcloud live-stream channels stop my-live-channel \
--location=us-central1
Step 4: Serve the Live Stream via Cloud CDN
Live streams require different CDN caching behavior than VOD. Manifests should be cached for only a few seconds so viewers always get the latest segments, while segments can be cached longer since they are immutable once written.
# Create a backend bucket with live-appropriate cache settings
gcloud compute backend-buckets create live-backend-bucket \
--gcs-bucket=my-live-output-bucket \
--enable-cdn \
--cache-mode=USE_ORIGIN_HEADERS \
--default-ttl=2 \
--max-ttl=5 \
--description="Backend bucket for live HLS streaming with short cache TTLs"
# Create URL map and load balancer as shown in the VOD section
# The viewer plays the live stream at:
# http://[CDN_IP]/live-stream-001/main.m3u8
Advanced Transcoding with the Transcoder API
Beyond basic adaptive bitrate ladders, the Transcoder API supports sophisticated workflows including thumbnail generation, DRM encryption, and multi-input editing. Here are practical examples for each.
Generating Thumbnails (Sprite Sheets)
Thumbnail sprite sheets enable video players to show preview images when users hover over the timeline. The Transcoder API can generate these automatically as part of a transcoding job.
# Add thumbnail generation to a transcoding job configuration
# Include this in the editList processing section
"spriteSheets": [
{
"filePrefix": "gs://my-vod-output-bucket/${videoId}/thumbnails/sprite",
"spriteWidthPixels": 160,
"spriteHeightPixels": 90,
"columnCount": 10,
"rowCount": 10,
"interval": "5s",
"quality": 80
}
]
# This generates sprite sheet images like:
# sprite-000000000.jpg, sprite-000000001.jpg, etc.
# Each containing 10x10=100 thumbnails at 5-second intervals
DRM Encryption with Widevine and FairPlay
For premium content, you can encrypt your HLS streams using the Transcoder API's built-in DRM support. This requires integration with a DRM license server.
# DRM encryption configuration for HLS with Widevine
# Add to the manifest settings in your transcoding job
"drm": {
"widevine": {
"contentId": "my-unique-content-id-001",
"pssh": "AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ...",
"keyProvider": {
"type": "widevine",
"widevine": {
"keyId": "1234567890abcdef1234567890abcdef",
"key": "abcdef1234567890abcdef1234567890"
}
}
}
}
# For FairPlay (used by Apple devices), add:
"fairplay": {
"keyProvider": {
"type": "fairplay",
"fairplay": {
"keyId": "11223344556677889900aabbccddeeff",
"iv": "00112233445566778899aabbccddeeff",
"key": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
}
}
Securing Your Video Streams
Protecting your content requires multiple layers of security, from access control at the CDN level to encryption at the segment level. GCP provides robust tools for both.
Signed URL Authentication with Cloud CDN
Signed URLs restrict access to your CDN content so that only authorized viewers with valid, time-limited tokens can retrieve manifests and segments.
# Python code to generate a signed URL for Cloud CDN
import hashlib
import hmac
import base64
import time
from urllib.parse import quote
def generate_signed_url(base_url, secret_key, expiration_seconds=3600):
"""
Generate a signed URL for Cloud CDN content access.
Args:
base_url: The CDN URL path (e.g., '/my-video/master.m3u8')
secret_key: Shared secret configured in the backend bucket
expiration_seconds: How long the URL remains valid
Returns:
Full signed URL string
"""
# Current timestamp in seconds since epoch
current_time = int(time.time())
expiration_time = current_time + expiration_seconds
# Build the signature components
# Format: URL|EXPIRATION|KEY_NAME
signature_input = f"{base_url}|{expiration_time}|my-key-name"
# Create HMAC-SHA1 signature using the secret key
# Note: Cloud CDN expects the key decoded from base64url
decoded_key = base64.urlsafe_b64decode(secret_key)
signature = hmac.new(
decoded_key,
signature_input.encode('utf-8'),
hashlib.sha1
).digest()
# Base64url-encode the signature (without padding)
encoded_signature = base64.urlsafe_b64encode(signature).rstrip(b'=').decode('utf-8')
# Construct the full signed URL
signed_url = (
f"https://cdn.example.com{base_url}"
f"?Expires={expiration_time}"
f"&KeyName=my-key-name"
f"&Signature={encoded_signature}"
)
return signed_url
# Example usage
secret = "your-base64url-encoded-secret-key-from-backend-bucket-config"
url = generate_signed_url("/videos/abc123/master.m3u8", secret, 3600)
print(url)
# Output: https://cdn.example.com/videos/abc123/master.m3u8?Expires=1712345678&KeyName=my-key-name&Signature=abc123def456...
Setting Up the Signed URL Secret in Cloud CDN
# Configure the signed URL secret on the backend bucket
# First, generate a strong secret and base64url-encode it
head -c 32 /dev/urandom | base64 -w 0 | tr '+/' '-_' | tr -d '='
# Example output: kQj9nX8vL2mP5rT6wYzA3bC4dE1fG7hI...
# Apply the secret to the backend bucket
gcloud compute backend-buckets update vod-backend-bucket \
--add-signed-url-key \
--key-name=my-key-name \
--key-value=kQj9nX8vL2mP5rT6wYzA3bC4dE1fG7hI... \
--caches-duration=3600
# Now only requests with valid signed URLs will be served
# Unauthorized requests receive HTTP 403 Forbidden
Monitoring and Analytics
A production video streaming platform requires observability into every stage of the pipeline. GCP integrates logging and metrics across services, enabling you to build dashboards and alerts for operational health.
Cloud Logging for Transcoder and Live Stream API
# View transcoding job logs
gcloud logging read 'resource.type="transcoder.googleapis.com/Job"' \
--limit=20 \
--format="json"
# View live stream channel events
gcloud logging read 'resource.type="livestream.googleapis.com/Channel"' \
--limit=20 \
--format="json"
# Common log query for failed transcoding jobs in the last 24 hours
gcloud logging read 'resource.type="transcoder.googleapis.com/Job" AND severity>=ERROR' \
--freshness=1d \
--limit=50
Playback Analytics with BigQuery
For deeper insights into viewer behavior, instrument your video player to emit playback events (play, pause, seek, buffering, quality switches) to a Cloud Run endpoint that writes to BigQuery. Here's a sample schema and ingestion function:
# BigQuery table schema for playback events
# Create the dataset and table
bq mk --dataset my-project:video_analytics
bq mk --table my-project:video_analytics.playback_events \
event_id:STRING, \
video_id:STRING, \
session_id:STRING, \
user_id:STRING, \
event_type:STRING, \
timestamp:TIMESTAMP, \
playhead_position:FLOAT, \
bitrate:FLOAT, \
buffering_duration:FLOAT, \
player_resolution:STRING, \
cdn_node:STRING, \
client_ip:STRING, \
user_agent:STRING
# Example Cloud Run service (Python) to ingest playback events
# main.py
import os
import json
from flask import Flask, request
from google.cloud import bigquery
from datetime import datetime
app = Flask(__name__)
client = bigquery.Client()
table_id = os.environ['BQ_TABLE_ID'] # my-project:video_analytics.playback_events
@app.route('/ingest', methods=['POST'])
def ingest_event():
"""Receive playback analytics events from video players."""
event_data = request.get_json()
# Add server-side metadata
event_data['timestamp'] = datetime.utcnow().isoformat()
event_data['client_ip'] = request.remote_addr
event_data['user_agent'] = request.headers.get('User-Agent', 'unknown')
# Insert into BigQuery (streaming insert for near-real-time analytics)
errors = client.insert_rows_json(table_id, [event_data])
if errors:
return json.dumps({'status': 'error', 'errors': errors}), 500
return json.dumps({'status': 'ok'}), 200
# Deploy as Cloud Run service
# gcloud run deploy playback-analytics-ingest \
# --source=. \
# --region=us-central1 \
# --allow-unauthenticated \
# --set-env-vars=BQ_TABLE_ID=my-project:video_analytics.playback_events
Cost Optimization Strategies
Video streaming can generate significant cloud costs if not managed carefully. Here are concrete strategies to keep your infrastructure efficient:
- Use Storage Classes intelligently: Keep recently ingested source files in Standard storage, then transition to Nearline or Coldline after transcoding using Object Lifecycle Management policies. Transcoded outputs that are actively served via CDN should remain in Standard storage
- Right-size your transcoding ladder: Each additional rendition adds storage and transcoding cost. For most content, four renditions (1080p, 720p, 480p, 360p) provide excellent coverage without excessive overhead. Avoid creating renditions that your audience doesn't actually consume
- Leverage CDN cache hit ratios: A well-configured CDN can achieve 95%+ cache hit ratios for VOD content, dramatically reducing origin storage egress costs. Monitor your cache hit ratio in Cloud Monitoring and adjust TTLs if needed
- Use committed use discounts: If you have predictable transcoding volumes (e.g., a fixed number of hours per month), contact Google Cloud sales for committed use discounts on the Transcoder API and Live Stream API
- Clean up obsolete segments: For live streams, old HLS segments accumulate in your output bucket. Configure Object Lifecycle Management to delete segments older than your DVR window (e.g., delete objects older than 7 days for a 7-day DVR capability)
Best Practices for Production Deployments
Drawing from real-world deployments, these best practices will help you build a robust, secure, and performant video streaming platform on GCP:
- Organize storage by video ID: Structure your output bucket as
gs://bucket/{video_id}/master.m3u8with segments in subdirectories likegs://bucket/{video_id}/1080p/segment_000.ts. This makes CDN routing predictable and simplifies signed URL generation - Implement robust error handling: Transcoder jobs can fail due to corrupted source files or transient API issues. Build retry logic with exponential backoff in your orchestrator function, and set up Cloud Monitoring alerts for job failure rates exceeding a threshold