Flow Diagrams
Architecture and sequence diagrams for Bakery services. These show principle flows only — edge cases and error handling are omitted for clarity.
System Overview
End-to-end squeezeback flow from configuration through delivery.
sequenceDiagram
participant Operator
participant Bakery as Bakery API
participant DB as PostgreSQL
participant Redis
participant Uflock
participant S3
participant Player
rect rgb(230, 245, 255)
Note over Operator, DB: Phase 1 — Configuration
Operator->>Bakery: Create brand config (squeeze defaults)
Bakery->>DB: Store brand config
Operator->>Bakery: Create event config (overrides)
Bakery->>DB: Store event config
Operator->>Bakery: Add configured ads
Bakery->>DB: Store ad references
end
rect rgb(255, 245, 230)
Note over Operator, Redis: Phase 2 — Orchestration
Operator->>Bakery: Start ad break
Bakery->>DB: Load event + brand config
Bakery->>Redis: Set squeeze state (active)
end
rect rgb(230, 255, 230)
Note over Bakery, S3: Phase 3 — Transcoding
Bakery->>Uflock: Submit squeeze job (content + ad + bg)
Uflock->>Uflock: Compose dual-box frame
Uflock->>S3: Write squeezed .ts segment
end
rect rgb(245, 230, 255)
Note over Player, S3: Phase 4 — Delivery
Player->>Bakery: Request HLS manifest
Bakery->>Redis: Check squeeze state
Bakery->>Player: Modified manifest with CUE tags
Player->>S3: Fetch squeeze segments
Player->>Player: Render dual-box layout
end
AdPilot Flow
CRUD lifecycle for squeeze configuration — brand defaults, event overrides, and ad management.
sequenceDiagram
participant Admin as Admin/Operator
participant B as Bakery
participant DB as PostgreSQL
participant FW as FreeWheel
%% PHASE 1: Configuration Setup
rect rgb(230, 245, 255)
Note over Admin,DB: PHASE 1: Configuration Setup (One-time)
Admin->>B: PUT /api/v1/squeeze-brand-config<br/>{brand_id, sqz_ratios, animations}
B->>DB: Store SqueezeBrandConfig
DB-->>B: OK
B-->>Admin: 200 OK
Admin->>B: PUT /api/v1/squeeze-event-config<br/>{asset_id, source_uri, brand_config_id}
B->>DB: Store SqueezeEventConfig
DB-->>B: OK
B-->>Admin: 200 OK {id: event_id}
end
%% PHASE 2: Pre-Configure Ads (AdPilot CRUD)
rect rgb(255, 245, 230)
Note over Admin,DB: PHASE 2: Pre-Configure Ads (AdPilot CRUD)
Admin->>B: PUT /api/v1/squeeze-configured-ad<br/>{event_id, ad_uri, duration, abid, slau, geo_lang_loc}
B->>DB: Check duplicate (event_id + abid)
DB-->>B: No duplicate
B->>DB: INSERT SqueezeConfiguredAds
DB-->>B: Created (id)
B-->>Admin: 200 OK {id, ad_uri, duration...}
Admin->>B: GET /api/v1/squeeze-configured-ad?event_id=X
B->>DB: Query with filters
DB-->>B: Matching ads[]
B-->>Admin: {results: [...], total_results}
Admin->>B: POST /api/v1/squeeze-configured-ad<br/>{id, ad_duration: 45}
B->>DB: UPDATE SqueezeConfiguredAds
DB-->>B: Updated
B-->>Admin: 200 OK {updated ad}
Admin->>B: DELETE /api/v1/squeeze-configured-ad<br/>{id}
B->>DB: DELETE by id
DB-->>B: Deleted
B-->>Admin: 200 OK
end
%% PHASE 3: Ad Selection During Break
rect rgb(255, 230, 230)
Note over Admin,FW: PHASE 3: Ad Selection During Ad Break
Admin->>B: POST /api/v1/squeeze-ad-break<br/>{event_id, break_duration}
B->>DB: Query SqueezeConfiguredAds<br/>{event_id, abid, geo_lang_loc}
DB-->>B: Pre-configured ads[]
alt Has pre-configured ads (is_curated: true)
Note over B: Use SqueezeConfiguredAds<br/>Match duration, geo targeting
else No pre-configured ads
B->>FW: GET VMAP ad_tag URL
FW-->>B: VAST ads
Note over B: Use Freewheel decisioned ads
end
B-->>Admin: {status: scheduled, segments...}
end
Fastbreak Flow
Server-side ad stitching with Google DAI and FreeWheel ad decisioning.
sequenceDiagram
participant CP as Client Player
participant B as Bakery
participant Redis as Redis Cache
participant MRSS as MRSS DB
participant DAI as Google DAI
participant FW as FreeWheel
participant Origin as Origin CDN
participant AdCDN as Ad CDN
rect rgb(230, 245, 255)
Note over CP,DAI: PHASE 1: Stream Registration
CP->>DAI: POST /stream_registration
DAI-->>CP: {stream_id, media_verification_url}
end
rect rgb(255, 245, 230)
Note over CP,MRSS: PHASE 2: Manifest Request
CP->>B: POST /fastbreak/{protocol}/stream/{stream_id}/asset/{asset_id}
B->>MRSS: Lookup MediaRecord
MRSS-->>B: {ingest_uri, cue_points[], brand_name}
end
rect rgb(255, 240, 245)
Note over B,FW: PHASE 3: Ad Tag Preparation
B->>Origin: GET feature manifest
Origin-->>B: HLS/DASH manifest
Note over B: Build FreeWheel ad_tag URL
end
rect rgb(255, 230, 230)
Note over B,FW: PHASE 4: Ad Decisioning
B->>DAI: POST /adpods {ad_tag, encoding_profiles[]}
DAI->>FW: GET VMAP via ad_tag
FW-->>DAI: VMAP {AdBreak[], VAST ads}
DAI-->>B: AdPodResponse {ad_pods[]}
end
rect rgb(230, 255, 230)
Note over B,Redis: PHASE 5: Manifest Stitching
loop For each ad_pod
B->>AdCDN: GET ad manifest
AdCDN-->>B: Ad manifest
end
B->>Redis: Cache stitched manifest + ad cue data
end
rect rgb(220, 240, 255)
Note over B,CP: PHASE 6: Response & Manifest Fetch
B-->>CP: {cache_url, breaks[]}
CP->>B: GET stitched manifest
B->>Redis: GET cached manifest
B-->>CP: Stitched HLS/DASH manifest
end
rect rgb(245, 230, 255)
Note over CP,AdCDN: PHASE 7: Playback & Beaconing
CP->>Origin: GET content segments
CP->>AdCDN: GET ad segments
CP->>DAI: Tracking (impression, quartiles, complete)
end
FS-Multi (Dual-Box) Flow
Live squeeze segment composition and HLS manifest manipulation.
sequenceDiagram
participant Player
participant Bakery as Bakery (Manifest)
participant Uflock
participant S3
participant Origin as Origin (Live)
rect rgb(245, 230, 255)
Note over Player, Origin: Normal Playback
Player->>Bakery: GET /manifest.m3u8
Bakery->>Origin: Proxy to origin manifest
Origin-->>Bakery: HLS manifest (normal segments)
Bakery-->>Player: Unmodified manifest
Player->>Origin: Fetch .ts segments
end
rect rgb(255, 245, 230)
Note over Player, S3: Squeeze Active (CUE-OUT)
Player->>Bakery: GET /manifest.m3u8
Note right of Bakery: Squeeze state active in Redis
Bakery-->>Player: Modified manifest with CUE-OUT tag
end
rect rgb(230, 255, 230)
Note over Bakery, S3: Segment Composition
Bakery->>Uflock: POST /v3/squeeze (content .ts + ad .mp4 + bg .png)
Note right of Uflock: FFmpeg compose: scale, position, fade
Uflock->>S3: PUT composed segment
Uflock-->>Bakery: S3 output URI
end
rect rgb(245, 230, 255)
Note over Player, S3: Squeeze Delivery
Bakery-->>Player: Manifest with squeeze segment URIs
Player->>S3: Fetch composed .ts segments
Player->>Player: Render dual-box (content + ad)
end
rect rgb(230, 245, 255)
Note over Player, Origin: Return to Normal (CUE-IN)
Player->>Bakery: GET /manifest.m3u8
Bakery-->>Player: Modified manifest with CUE-IN tag
Player->>Origin: Resume normal .ts segments
end
Squeezel (L-Bar) Flow
Planned L-bar squeeze layout — not yet implemented.
sequenceDiagram
participant Player
participant Bakery as Bakery (Manifest)
participant Uflock
participant S3
rect rgb(230, 245, 255)
Note over Player, S3: Planned — L-Bar Squeeze
Player->>Bakery: GET /manifest.m3u8
Note right of Bakery: L-bar squeeze state active
Bakery->>Uflock: POST /v3/squeeze (content + ad, layout=lbar)
Note right of Uflock: Compose L-shaped frame<br/>(content squeezed, ad in L region)
Uflock->>S3: PUT L-bar segment
Uflock-->>Bakery: S3 output URI
Bakery-->>Player: Manifest with L-bar segment URIs
Player->>S3: Fetch L-bar .ts segments
end
Service Interaction Overview
How the squeezeback system components connect.
flowchart LR
subgraph Config
Operator([Operator])
end
subgraph Orchestration
Bakery[Bakery API]
DB[(PostgreSQL)]
Redis[(Redis)]
end
subgraph Transcoding
Uflock[Uflock]
end
subgraph Storage
S3[(S3)]
end
subgraph Delivery
Player([Player])
Origin[Origin CDN]
end
Operator -->|brand/event/ad config| Bakery
Bakery -->|persist config| DB
Bakery -->|squeeze state| Redis
Bakery -->|submit squeeze job| Uflock
Uflock -->|read content .ts| S3
Uflock -->|write composed .ts| S3
Player -->|request manifest| Bakery
Bakery -->|proxy normal segments| Origin
Player -->|fetch segments| S3
Player -->|fetch segments| Origin