D
DreamLake

Key Design

Video Splitting

Video files are split into HLS segments via AWS Lambda for streaming playback.

Pipeline

Raw video in staging

 ├─ 1. Download from S3: {owner}/{project}/staging/{hash}
 ├─ 2. Probe fps with ffprobe
 ├─ 3. Split with ffmpeg (copy codec, no re-encode)
-c:v copy -an -f hls -hls_time 6
 ├─ 4. Parse segment durations from ffmpeg m3u8
 ├─ 5. Hash each .ts segment (SHA256[:16])
 │     Upload to chunks/{hash}.ts (skip if exists = dedup)
 ├─ 6. Build stream m3u8 with bare hex hashes
 ├─ 6.5. Generate thumbnail + sprite sheet (non-fatal)
 ├─ 7. Upload playlist: videos/{id}/stream/{streamHash}.m3u8
 ├─ 8. Update videos/{id}/meta.json
 └─ 9. Callback PATCH to BSS

ffmpeg Command

ffmpeg -i input.mp4 \
  -c:v copy \                      # no re-encode — fast
  -an \                            # strip audio (separate pipeline)
  -f hls \
  -hls_time 6 \                    # 6-second segments
  -hls_list_size 0 \               # keep all segments
  -hls_segment_type mpegts \
  -hls_flags independent_segments \
  -hls_segment_filename seg_%05d.ts \
  out.m3u8

Key: -c:v copy means no transcoding — the Lambda just repackages frames into TS segments. This is fast and lossless.

Chunk Deduplication

Each TS segment is content-addressed:

hash = SHA256(segment_bytes)[:16]    # 16 hex chars
key  = chunks/{hash}.ts

Before uploading, Lambda checks if the chunk already exists via HeadObject. Duplicate segments (common in re-uploads or similar content) are skipped. Chunks are uploaded with Cache-Control: public, max-age=31536000, immutable.

M3U8 Format

Stream playlists store bare hex hashes — no URLs, no extensions:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:6.000,
a1b2c3d4e5f67890
#EXTINF:4.500,
1234567890abcdef
#EXT-X-ENDLIST

BSS's rewriteM3u8() replaces each hash with a full CDN URL at serving time. This keeps playlists portable across CDN configurations.

Thumbnail & Sprite

Generated alongside HLS segments (non-fatal — skipped on error):

AssetResolutionTimingS3 Path
Thumbnail640px wideSingle frame at ~10% of durationvideos/{id}/thumb.jpg
Sprite160x90 tiles, max 10 columns1 frame every 5 secondsvideos/{id}/sprite.jpg

Meta.json After Splitting

{
  "length": 750,
  "fps": 30.0,
  "durationSec": 25.0,
  "streams": ["abc123def456"],
  "thumbnailUrl": "https://cdn.../thumb.jpg",
  "spriteUrl": "https://cdn.../sprite.jpg",
  "spriteInterval": 5,
  "spriteCols": 5,
  "spriteRows": 1,
  "spriteWidth": 160,
  "spriteHeight": 90,
  "updatedAt": "2026-04-14T..."
}