---
title: "MediaOps"
slug: mediaops
category: business
term_status: niche
evidence_status: partially_verified
summary: "MediaOps is the operation of time-critical media pipelines: getting audio and video from source to screen through ingest, quality control, encoding, packaging and delivery, on time, within rights and at acceptable quality and cost."
audience: [Broadcast and media operations engineers, Video platform engineers, Live event producers, DAM and media managers, Beginners]
last_verified: 2026-10-23
key_takeaways:
  - "MediaOps is a niche label used in broadcast and media technology, most visibly as the name of Skyline Communications' DataMiner MediaOps product. The work behind it, media operations, is an everyday job family at broadcasters and streamers."
  - "Its centre of gravity is the media supply chain: contribution, ingest, QC, encoding, packaging, origin, CDN and player. A live event cannot be re-run, so the deadline governs every decision."
  - "Most quality rules are public specifications you can test automatically: RFC 8216 and Apple's authoring spec for HLS, DASH-IF guidelines for DASH, EBU R 128 for loudness, and WCAG and WebVTT for captions."
  - "A second pipeline protects only what it duplicates. AWS documents that a redundant MediaLive channel cannot be set up without two upstream sources and brings no advantage unless the downstream system can switch, so check the whole path before you call it redundant."
  - "Measure the viewer, not the server. Track video start failures, exits before video start, startup time percentiles and rebuffering ratio, split by CDN, device and title."
  - "Rights, captions and loudness are release gates, not cleanup items: a perfect stream that breaks a licence window or a loudness rule is still a failed delivery."
related: [contentops, adops, webops, edgeops, observabilityops, incidentops, legalops, releaseops]
---

## What MediaOps is

### MediaOps in 30 seconds

**MediaOps** (media operations) is the work of getting audio and video from a source to a screen reliably, on time, within the
rights you hold, and at acceptable quality and cost. The source might be a stadium camera, a studio's file or an archive tape. In
between sit **ingest**, **quality control (QC)**, **encoding**, **packaging**, an **origin**, one or more **content delivery
networks (CDNs)** and the **player**, supported by **asset management**, **metadata** and **rights** (licence windows,
territories and platforms).

**In one line: MediaOps runs the media supply chain like a production system with a deadline. For live events, the deadline is
the start time, and nothing can be re-run.**

It is for video platform and broadcast engineers, live producers, DAM managers, and beginners curious how a stream reaches a
phone. The emphasis is **time-critical pipelines, live-event reliability and video quality**.

### At a glance

| Item | Summary |
|---|---|
| Term status | **Niche.** Used in broadcast and media technology, most visibly as a product name (Skyline's DataMiner MediaOps); "media operations" is a common job family. No standard or certification defines it (see [origins](#origins-and-evolution-of-the-label)). |
| Goals | Media on time, playable wherever licensed, within delivery specs, at a known cost per viewer hour. |
| In scope | Contribution and ingest; QC; ladders and codecs; packaging (HLS, DASH, CMAF); origin and CDN delivery of video; live and VOD; assets, metadata and rights; playout and scheduling; QoE monitoring. |
| Out of scope | Text and structured content → [ContentOps](../contentops/); ad insertion and trafficking → [AdOps](../adops/); general CDN, TLS and web performance → [WebOps](../webops/); edge infrastructure → [EdgeOps](../edgeops/); contract law → [LegalOps](../legalops/). |
| Prerequisites | HTTP and CDN basics ([WebOps](../webops/)); helpful: incident management ([IncidentOps](../incidentops/)). |
| Key outputs | Delivery specs; ladders; event run sheets; redundancy maps; QoE dashboards; rights-checked publication. |

### The problem it solves

Video is unforgiving in three ways that ordinary web content is not.

1. **It is heavy and bursty.** RFC 9317 notes that "in the worst case, the bitrate demands can be multiplied by the number of
   simultaneous users": for 10,000 viewers of 1080p video below one node, "approximately 80 Gbps might be necessary". Caching
   and multicast replication can reduce that.[^rfc9317]
2. **It is deadline-bound.** A live match that starts with no picture cannot be repaired afterwards. In November 2024 Netflix
   reported 65 million live concurrent streams for the Paul–Tyson fight, and viewers complained of buffering.[^netflix-fight] The
   sources give no root cause; the case shows only that live demand can exceed preparation.
3. **It answers to many specifications at once:** HLS and DASH rules, captions, loudness, mastering formats and licence windows
   by territory.

| Operating reality | Without MediaOps | With MediaOps |
|---|---|---|
| Live event | Built the week before; failover untested | Run sheet, tested failover, named decision owner |
| File delivery | Visual spot checks; failures found by the platform | Automated QC against the written delivery spec |
| Encoding | One fixed ladder for every title | Ladders per content type and codec, checked with quality metrics |
| Rights | Spreadsheet checked by hand | Availability windows drive publish and takedown |
| Monitoring | Server health only | Viewer QoE by CDN, device and title |

### What MediaOps is not: naming and boundaries

- **Not one product.** Skyline's documentation says DataMiner MediaOps "seamlessly blends information and communication
  technology (ICT) with media technology and workflows".[^skyline-docs] The practice is wider than any tool.
- **Not paid-media operations.** In advertising, "media operations" can mean trafficking paid media: a Dublin agency's "Media
  Operations Specialist" posting (removed in March 2026) asked the holder to "Manage the end-to-end ad trafficking process in
  Google Campaign Manager (DCM)".[^paid-media-job] That work belongs to [AdOps](../adops/) and [MarketingOps](../marketingops/).
- **Not content operations.** Text and structured content is [ContentOps](../contentops/). MediaOps starts when audio-visual
  essence (the actual video and audio data) enters the chain.
- **Not generic web delivery.** CDNs, TLS and Core Web Vitals belong to [WebOps](../webops/); MediaOps covers segments, ladders,
  manifests and player QoE.

::: note Editorial distinction
The split from ContentOps (text and structured content) and AdOps (ad insertion, trafficking, paid media) is this Atlas's
**editorial distinction**. No standard defines it.
:::

## Where MediaOps comes from and where it sits

### Origins and evolution of the label

No founding paper or manifesto exists; the evidence is scattered and mostly commercial.

| Date | Evidence | What it shows |
|---|---|---|
| Ongoing | An NBCUniversal "Media Operations" posting (7 October 2026) covers ingest, transcoding, QC and distribution, and "time-sensitive media requirements for live events, sports, digital streaming, broadcast".[^nbcu] | The job family, spaced name |
| Ongoing | The IETF's "Media OPerationS (mops)" working group is active;[^mops] it published RFC 9317 (2022).[^rfc9317] | A network concern |
| August 2023 | TVBEurope reported a TMT Insights media operations division named MediaOps that can "bridge the critical gap between an organisation's traditional engineering and digital content operations groups".[^tmt] | The compact label at a services firm |
| 2025 | Skyline's DataMiner MediaOps.PLAN is "a full suite designed for booking teams, MCR teams, TX room operators, engineers, and IT staff".[^skyline-plan] | The most visible use: a product |

**Status judgement: niche.** More than one company in one industry uses the label, so it is not `vendor-specific`; it has no
shared definition, literature or certification, so it is not `established`. The practice and its specifications are mature.

### Glossary and mental model

| Term | Meaning |
|---|---|
| **Essence** | The actual video, audio and caption data, as opposed to metadata |
| **Contribution** | Getting a live feed from venue to facility (fibre, satellite, internet) |
| **Mezzanine** | The high-quality master all deliverables are made from |
| **Bitrate ladder (ABR ladder)** | The renditions (resolution plus bitrate) the player chooses from |
| **GOP / keyframe interval** | Distance between independently decodable frames (IDR) |
| **Segment** | A few seconds of media fetched as one HTTP object |
| **Manifest / playlist** | HLS `.m3u8` or DASH MPD listing renditions and segments |
| **CMAF** | Common Media Application Format: fragmented MP4 usable by HLS and DASH |
| **Origin** | The server the CDN fetches segments from |
| **QoE** | Quality of experience: startup, stalls, picture quality as the viewer sees them |
| **Availability window** | When, where and on which platforms a title may be shown |
| **MCR** | Master control room: where channels and live feeds are monitored and switched |
| **DAM / MAM** | Digital asset management (any media) / media asset management (broadcast video) |
| **SRT** | Secure Reliable Transport: UDP-based live contribution over the internet |
| **PTP** | Precision Time Protocol: the shared clock of an ST 2110 facility |
| **IMF** | Interoperable Master Format (SMPTE ST 2067): one master package, many versions |
| **DRM / CENC** | Digital rights management / Common Encryption: one encrypted file, several DRM systems |
| **CMCD** | Common Media Client Data (CTA-5004): player data sent to the CDN with each request |
| **SCTE-35** | In-stream splice signals marking ad breaks and programme boundaries |
| **LUFS / LU** | Loudness level relative to full scale / a loudness difference (1 LU = 1 dB) |
| **True peak (dBTP)** | Peak of the reconstructed waveform; can exceed sample peaks |
| **VMAF** | Netflix's full-reference quality metric: the encode is scored against its source |

**Mental model: a relay race against a clock.** Each stage hands a baton (feed, file, segment) to the next; quality can only fall
downstream, and delays add up. MediaOps decides where to put checks, spare runners and timekeepers.

### How MediaOps relates to other Ops

::: figure Where MediaOps sits among its neighbours
```mermaid
flowchart TB
  C["ContentOps: text, structured content, editorial workflow"]
  L["LegalOps: contracts behind rights"]
  M["MediaOps: media supply chain, live and VOD video"]
  A["AdOps: ad insertion, trafficking"]
  W["WebOps: CDN, TLS, web performance"]
  O["ObservabilityOps: telemetry platform"]
  I["IncidentOps: incident roles and comms"]
  C -->|"scripts, artwork, copy"| M
  L -->|"licence terms become windows"| M
  M -->|"ad markers, inventory"| A
  M -->|"segments to deliver"| W
  O -->|"metrics and logs"| M
  M -->|"event incidents"| I
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class M core
  class C,L,A,W,O,I neutral
```
Text equivalent: MediaOps sits in the middle. ContentOps sends it scripts, artwork and copy; LegalOps sends licence terms that
become windows. MediaOps sends ad markers and inventory to AdOps, segments to WebOps and event incidents to IncidentOps, and
receives metrics and logs from ObservabilityOps.
:::

| Neighbour | Shared ground | MediaOps focus | Choose the neighbour when |
|---|---|---|---|
| [ContentOps](../contentops/) | Publishing workflows, metadata | Audio-visual essence and its delivery | The work is text or structured content |
| [AdOps](../adops/) | Live streams with ad breaks | Clean delivery of the programme and its markers | You are selling, trafficking or inserting ads |
| [WebOps](../webops/) | CDNs, caching, TLS | Video-specific delivery: segments, manifests, ladders | The asset is a web page or API |
| [ObservabilityOps](../observabilityops/) | Telemetry | Which media and QoE signals matter | You build the telemetry platform |
| [IncidentOps](../incidentops/) | Live incidents | Media failure modes, event readiness | You define roles, paging and comms |
| [ReleaseOps](../releaseops/) | Change control | Change freezes around events | You manage software releases |
| [LegalOps](../legalops/) | Rights | Enforcing windows in the pipeline | You negotiate or manage contracts |

## Principles and operating model

### Charter and principles

::: note This is the Atlas's proposal
No official MediaOps charter exists; these principles are this Atlas's synthesis of the sources cited here.
:::

**Mission:** every licensed viewer gets the programme at the promised time and quality, and nobody else gets it.

1. **The clock is a requirement.** Live readiness is measured in hours before the event.
2. **Write the spec, then test against it.** Codec, loudness and caption rules are machine-checkable.
3. **Quality never improves downstream.** Check early; keep the mezzanine.
4. **Redundancy is a property of the whole path** (see [live redundancy](#live-redundancy-what-a-second-pipeline-really-protects)).
5. **Measure the viewer.** Server health leads; viewer QoE is the outcome.
6. **Rights and accessibility gate publication.** No captions, wrong loudness or an expired window: it does not ship.
7. **Know the cost per viewer hour.** Encoding, storage and egress scale differently.

**Non-goals:** writing content, selling ads, running the web estate.

### Building blocks: the media supply chain

| Block | Job | Typical artefacts |
|---|---|---|
| Acquisition and contribution | Bring feeds or files in | Circuits, SRT, satellite, file transfer |
| Ingest and QC | Register, check, normalise | QC reports, checksums, technical metadata |
| Asset management (DAM/MAM) | Store, find and version assets | Asset IDs, proxies, metadata records |
| Rights and scheduling | Decide what may run where and when; book resources | Availability windows, schedules, bookings |
| Encoding | Make renditions per ladder | Ladder definitions, encoder profiles |
| Packaging and protection | Segment, write manifests, encrypt | HLS/DASH/CMAF output, DRM keys |
| Origin and CDN | Serve segments at scale | Origin shield, CDN configs, steering |
| Player and QoE | Play, adapt, report | Player config, QoE beacons, CMCD |
| Archive | Keep masters for reuse | Mezzanine, IMF packages |

### Roles, ownership and RACI

Typical roles (titles vary): **media ops specialist or MCR operator** (ingest, QC, monitoring); **video platform engineer**
(encoders to player); **event producer** (run sheet, go/no-go); **DAM manager**; **rights and scheduling coordinator**; **QoE
analyst**. R = responsible, A = accountable, C = consulted, I = informed.

| Activity | Media ops | Platform eng. | Event producer | Rights/scheduling | DAM manager |
|---|---|---|---|---|---|
| Delivery spec and QC policy | R | C | I | C | A |
| Encoding ladder and profiles | C | A/R | I | I | C |
| Live event run sheet and go/no-go | R | C | A | C | I |
| Failover rehearsal | R | A/R | C | I | I |
| Availability windows and takedown | R | C | I | A | C |
| QoE dashboards and alert thresholds | R | A | C | I | I |
| Archive and mezzanine retention | R | C | I | C | A |

### Lifecycle: from title or event to archive

A **VOD title** goes: receive → ingest and QC → register with rights → encode and package → publish at window open → monitor →
take down at window close → archive. A **live event** follows the figure.

::: figure Live event lifecycle from booking to review
```mermaid
flowchart TB
  B["Book: circuits, encoders, crew, CDN capacity"] --> CF["Configure: profiles, manifests, ad markers"]
  CF --> T["Test: end-to-end on real devices"]
  T --> R["Rehearse: pull the primary, watch failover"]
  R --> F["Freeze: change freeze, go/no-go"]
  F --> RUN["Run: monitor QoE, decide fast"]
  RUN --> W["Wrap: archive recording, release resources"]
  W --> RV["Review: incidents, metrics, actions"]
  RV -.->|"actions feed the next booking"| B
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  class B,CF,T,RUN,W,RV core
  class R,F decision
```
Text equivalent: eight steps, top to bottom: book circuits, encoders, crew and CDN capacity; configure profiles, manifests and
ad markers; test end to end on real devices; rehearse by pulling the primary; freeze changes and make the go/no-go call; run
while monitoring QoE; wrap up and archive; review. Rehearse and freeze are decision points. A dashed arrow takes review actions
back to the next booking.
:::

### Operating model and governance

- **Delivery specs as policy.** Each outlet's spec is data in version control, run by QC ([reference
  implementation](#reference-implementation)).
- **Event classes** (tier 1: national final; tier 3: internal webcast) set redundancy, rehearsal and staffing.
- **Change freeze** from rehearsal to the end of a tier-1 event ([ReleaseOps](../releaseops/)).
- **Cadence.** Daily: failed deliveries, window changes. Weekly: QoE by CDN and device, cost per viewer hour. After tier-1
  events: a blameless review ([IncidentOps](../incidentops/)).
- **Escalation.** During a live event, one named person may switch sources, CDNs or ladders.

## Architecture and workflow

### Reference architecture

A logical architecture for most streaming services and the IP side of a broadcaster; real deployments merge or split boxes.

::: figure Logical architecture of a media supply chain
```mermaid
flowchart TB
  SRC["Sources: live feeds, delivered files, archive"] --> ING["Ingest and QC"]
  ING --> DAM["DAM or MAM: assets, metadata, proxies"]
  RTS["Rights and scheduling: windows, bookings"] --> DAM
  DAM --> ENC["Encode: ABR ladder renditions"]
  ENC --> PKG["Package and protect: HLS, DASH, CMAF, DRM"]
  RTS -->|"publish only inside the window"| PKG
  PKG --> ORG["Origin with shield cache"]
  ORG --> CDN["One or more CDNs, steered"]
  CDN --> PLY["Players on devices"]
  PLY -.->|"QoE beacons, CMCD"| MON["Monitoring and QoE analytics"]
  ENC -.->|"encoder and stream alarms"| MON
  MON -.->|"alerts, run sheet decisions"| OPS["Media ops and MCR"]
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class ING,ENC,PKG,ORG,CDN core
  class RTS decision
  class SRC,DAM,PLY,MON,OPS neutral
```
Text equivalent: sources pass ingest and QC into a DAM or MAM. Rights and scheduling feed the DAM and gate the packager to the
availability window. Media is encoded into ladder renditions, packaged and protected, served by an origin with a shield cache to
one or more steered CDNs, and played on devices. Dashed arrows: players (QoE beacons, CMCD) and encoders (alarms) feed
monitoring, which alerts media ops and the MCR.
:::

**Main trade-offs:** automatic QC rejection versus operator review; just-in-time packaging (less storage) versus pre-packaging
(less request-time compute); one CDN (simple) versus several (resilient, more to operate).

**Standards that shape the boxes.** HLS is RFC 8216, an Informational RFC from August 2017.[^rfc8216] Its successor draft
(protocol version 13) adds Low-Latency HLS and Content Steering. It is an Independent Submission, "not endorsed by the IETF",
with the RFC Editor since 2026-05-15.[^hlsbis] DASH is ISO/IEC 23009-1. DASH-IF announced the fifth edition as ISO/IEC 23009-1:2022;[^dashif-5th] the sixth edition
(ISO/IEC 23009-1:2026, July 2026) "cancels and replaces" it, adding Content Steering and CMCD reporting among other
changes.[^iso-dash6] Check which edition your packager and players implement. DASH-IF's IOP v5 constrains DASH to media
"formatted according to the MPEG CMAF Specification (ISO/IEC 23000-19)".[^dashif-iop] In facilities, SMPTE ST 2110 "specifies
the carriage, synchronization, and description of separate elementary essence streams over IP", timed by PTP.[^st2110]

### Live redundancy: what a second pipeline really protects

- **Contribution.** SMPTE ST 2022-7 rebuilds one stream from "multiple redundant streams of RTP packets" by switching "at the
  RTP datagram level".[^st2022-7] It protects against losing a path, not a broken signal carried on both.
- **Encoding.** On AWS Elemental MediaLive, a *standard* channel has two pipelines that "deliver identical content to two
  destinations"; a *single-pipeline* channel has one.[^medialive-class] AWS separates two conditions. Without standard-class
  inputs and two source streams from upstream, "you can't set up as a standard channel". Without a downstream system that can
  take two identical outputs and switch, "there is no advantage to setting up as a standard channel"; MediaPackage input
  redundancy is one such downstream.[^medialive-red]
- **Ingest to origin.** In DASH-IF Live Media Ingest v1.2, "a first ingest source can be seamlessly replaced by a redundant
  second ingest source" if both share a timeline anchor and "will produce segments with identical durations".[^dashif-ingest]
- **Delivery.** Content Steering in the HLS draft groups redundant variant streams into "Pathways" chosen from a steering
  manifest: one way to move viewers between CDNs.[^hlsbis]

::: figure Dual-path live chain and the points that stay single
```mermaid
flowchart TB
  V["Venue production output"] --> PA["Path A: fibre"]
  V --> PB["Path B: internet with SRT"]
  PA --> EA["Encoder pipeline A"]
  PB --> EB["Encoder pipeline B"]
  EA --> PK["Packager or origin with input redundancy"]
  EB --> PK
  PK --> ST["Steering: choose CDN pathway"]
  ST --> C1["CDN 1"]
  ST --> C2["CDN 2"]
  C1 --> P["Players"]
  C2 --> P
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  class PA,PB,EA,EB,C1,C2 core
  class V,PK,ST risk
```
Text equivalent: the venue output splits onto path A (fibre) and path B (internet with SRT), each feeding its own encoder
pipeline. Both feed a packager or origin with input redundancy; a steering service chooses CDN 1 or CDN 2 to serve players. Three
boxes are marked as risks because they stay single: the venue output, the packager or origin, and the steering service.
:::

Teams often duplicate the expensive middle and leave the ends single. Record for each box: duplicated, tested manual fallback,
or accepted risk.

### Linear channels and playout

A linear channel turns a schedule into a continuous stream. Playout automation plays programmes, promotions, graphics and ad
breaks in order; the MCR watches the output and steps in when a file is missing, a live programme overruns or a break fails.
Most playout risks are data: an item with no playable file, a programme outside its window, an overrun that shifts every later
item. In streaming, a channel can be assembled from manifests: AWS Elemental MediaTailor channel assembly is "a manifest-only
service that allows you to create linear streaming channels using your existing video on demand (VOD) content mixed with live
content".[^mediatailor] Either way, check tomorrow's schedule against files, captions and rights today.

### End-to-end workflow: a VOD title from delivery to playback

**Trigger:** a supplier delivers a programme file and metadata. **Actors:** media ops, the QC system, DAM, rights, platform.
**Output:** a title playable on every licensed outlet, from the moment the window opens.

::: figure VOD delivery workflow with its exception path
```mermaid
flowchart TB
  D["File and metadata delivered"] --> Q{"Checksum and spec QC pass?"}
  Q -->|"no"| RJ["Reject with QC report to supplier"]
  RJ --> RD["Redelivery"]
  RD --> Q
  Q -->|"yes"| REG["Register in DAM, link rights record"]
  REG --> EP["Encode and package all renditions"]
  EP --> PC{"Automated playback and manifest check pass?"}
  PC -->|"no"| FX["Retry once, then escalate to platform engineer"]
  FX --> EP
  PC -->|"yes"| WN{"Availability window open?"}
  WN -->|"not yet"| HOLD["Hold, scheduled publish"]
  HOLD --> WN
  WN -->|"yes"| PUB["Publish, monitor QoE"]
  PUB --> TD["Automatic takedown at window end"]
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  class D,REG,EP,PUB,TD core
  class RJ,FX risk
  class Q,PC,WN decision
```
Text equivalent: a delivered file goes through checksum and spec QC; a failure is rejected with a report and the redelivery
re-enters QC. A pass is registered in the DAM with its rights record, encoded, packaged and checked by an automated playback
and manifest test (failures retry once, then escalate). The title is held until its window opens, then published, monitored
and taken down automatically at window end.
:::

**"Delivered" means:** QC passed; manifests pass checks ([Lab 1](#lab-1-beginner-check-an-hls-ladder-against-the-spec));
captions and loudness in spec; rights linked; one test play per platform family.

## Practices, standards and tools

### Core practices and playbooks

| Practice | Goal | Trigger | Owner | Output | Verification |
|---|---|---|---|---|---|
| Spec-driven QC | Reject bad files early | Each delivery | Media ops | QC report | False-reject review |
| Ladder design | Fit renditions to content | New content type or codec | Platform eng. | Ladder file | Quality and bitrate checks |
| Event readiness | No kick-off surprises | Each event | Event producer | Run sheet | Failover drill passed |
| Window enforcement | On-time publish and takedown | Rights change | Rights coordinator | Schedules | Daily audit |
| Loudness and captions | Compliant, accessible output | Each programme | Media ops | Measurements, tracks | Spec checks, spot review |
| QoE review | Find device or CDN problems | Weekly; after events | QoE analyst | Ranked issues | KPI trend |

**Playbook: designing a ladder.** Apple's authoring specification gives an example 16:9 H.264 ladder from 416×234 at 145 kbit/s
to 1920×1080 at 7,800 kbit/s, with 6-second target durations and an IDR keyframe every two seconds.[^apple-hls] Start there:

1. Encode representative titles (sport, animation, dark drama) at each candidate rung.
2. Measure quality against the source with a full-reference metric such as VMAF.[^vmaf]
3. Remove rungs that add bits without visible gain; add rungs where neighbours are far apart.
4. Check measured bitrates against the manifest: for VOD, Apple requires the peak within 10% of `BANDWIDTH` and the average
   within 10% of `AVERAGE-BANDWIDTH`.[^apple-hls]
5. Record the decision and its test set.

**Acceptance:** quality rises with bitrate on every rung of the test set, and declared bandwidths match measured values.

### Codecs and containers

Choose a codec by device support first, cost second and licensing third. Apple's rules, as an example (as of October
2026):[^apple-hls]

| Codec | Apple HLS rules | Typical role |
|---|---|---|
| H.264/AVC | "some video content SHOULD be encoded with H.264"; fMP4 or MPEG-TS | The ladder every device can play |
| HEVC/H.265 | fMP4 only; HDR "MUST be HDR10, HLG, or Dolby Vision" | HDR and 4K tiers; a second ladder for capable devices |
| AV1 | fMP4 only; level at most 6.2 | A further ladder for capable devices; AOMedia calls it "an open video codec"[^av1] |

**Device check.** For the devices that carry most viewing, check codec, profile and level against each platform's rules
(Apple's tvOS amendment caps H.264 at High Profile, Level 5.1). Declare `CODECS`, which every variant "SHOULD include" under
RFC 8216, so players skip variants they cannot decode.[^rfc8216]

**Cost trade-off (illustrative).** A second codec adds a second ladder's encoding and storage but saves egress only on the
viewing it serves. With the [cost example](#cost-capacity-and-sustainability) below (egress 10,800 a month), moving 40% of
viewing to a codec needing 20% fewer bits at equal quality saves 10,800 × 0.4 × 0.2 = 864 a month. That favours popular titles
and large live audiences, where egress dominates, over a rarely watched long tail.

**Containers.** MPEG-TS is the older segment format; fMP4 and CMAF let one set of segments serve HLS and DASH.[^dashif-iop]

**Licensing.** Access Advance's Video Distribution Patent Pool says it "covers essential patents for all four major video codecs
currently used by video distribution providers" (HEVC, VVC, VP9, AV1), priced by "the size of the licensee's streaming
business".[^vdp] "Open" does not settle the question; take legal advice ([LegalOps](../legalops/)).

### Methods, standards and frameworks

| Area | Document | Type | What to take from it |
|---|---|---|---|
| HLS | RFC 8216 (2017)[^rfc8216]; successor draft -22 (May 2026; RFC Editor queue, October 2026)[^hlsbis] | Informational RFC; Independent Submission draft | Playlist rules; low latency and steering (draft) |
| HLS on Apple devices | HLS Authoring Specification (revised 2025-06-26)[^apple-hls] | Platform requirements | Codecs, ladders, keyframes, captions |
| DASH and CMAF | ISO/IEC 23009-1:2026[^iso-dash6]; DASH-IF IOP v5 (parts dated 2021–2025)[^dashif-iop] | Standard; industry guidelines | DASH with CMAF; ads, DRM, text parts |
| Ad signalling | SCTE-35, mapped into HLS `EXT-X-DATERANGE` by RFC 8216[^rfc8216] | Industry standard; RFC mapping | Carry break markers cleanly for [AdOps](../adops/) |
| Live ingest | DASH-IF Live Media Ingest v1.2[^dashif-ingest] | Industry specification | HTTP POST ingest, redundant sources, failover |
| IP production | SMPTE ST 2110 suite[^st2110]; ST 2022-7:2019[^st2022-7] | Standards | Essence over IP with PTP timing; seamless path protection |
| TS monitoring | ETSI TR 101 290 V1.4.1 (2020)[^tr101290] | Measurement guidelines | Priority-1 checks |
| Loudness | EBU R 128 v5 (November 2023)[^r128] | Recommendation (binding via law or contract) | Target, tolerance, true peak |
| Mastering | SMPTE ST 2067 (IMF)[^imf] | Standard | One master package, many versions |
| Metadata and IDs | EBUCore and EBUCorePlus[^ebucore]; EIDR[^eidr]; EMA Avails[^movielabs-md] | Specifications and registries | Metadata, identifiers, availability |
| Player data | CTA-5004 CMCD[^cta-wave]; CTA-2066 QoE terms[^cta2066] | Standards (CTA) | Player-to-CDN data; shared QoE vocabulary |
| Accessibility | WCAG 2.2 SC 1.2.4[^wcag-live]; WebVTT[^webvtt] | W3C | Live captions at level AA; caption format |
| Operations | RFC 9317[^rfc9317] | Informational RFC | Latency classes, ABR pitfalls, capacity |

Two frameworks give the bigger picture without adding rules. **MovieLabs' 2030 Vision** paper (2019) "lays out 10 Principles for
a more efficient media pipeline using cloud infrastructure, zero trust security and software-defined workflows".[^movielabs-2030]
**IETF MOPS** gathers network-level operational knowledge.[^mops]

### Tooling landscape

Choose by job first; brand names are verified examples, not recommendations.

| Job | Representative options (checked 2026-10-23) | Selection criteria | Watch-outs |
|---|---|---|---|
| Encode, transcode, measure | FFmpeg (open source): HLS muxer, `loudnorm`, `ebur128`, `libvmaf`[^ff-formats][^ff-filters] | Codec support, scriptability | Defaults are not your spec ([Lab 2](#lab-2-intermediate-encode-a-ladder-and-check-loudness)) |
| Live encoding (managed) | AWS Elemental MediaLive (standard or single-pipeline channels)[^medialive-class] | Redundancy model, inputs, region | Redundancy preconditions; per-pipeline charges |
| Packaging and DRM | Shaka Packager ("DASH and HLS packaging and encryption", BSD-3-Clause)[^shaka] | Formats, DRM systems, live support | Key management is a separate system |
| Players | hls.js (HLS in browsers through MSE, Apache 2.0)[^hlsjs]; dash.js (CMCD v1)[^dashjs-cmcd] | Platforms, telemetry hooks | Test on real devices |
| Quality metrics | VMAF (BSD+Patent licence)[^vmaf] | Correlation with viewers for your content | A score is not a viewer study |
| Orchestration and scheduling | e.g. DataMiner MediaOps (inventory, plan and reserve "supported by default")[^skyline-docs] | Integration with rights and devices | Verify vendor claims in a pilot |
| Contribution transport | SRT, "a user-level protocol over User Datagram Protocol" (expired individual IETF draft)[^srt]; satellite; managed fibre | Loss, latency, cost | Not an IETF standard |
| QoE analytics | Commercial analytics or self-built beacons with CMCD | Metric definitions, sampling | Different vendors define KPIs differently |

**Lock-in** sits in encoder profiles, DRM integration, analytics definitions and scheduling data, not in the open formats. Keep
ladders, QC rules and event templates as files you own.

### Automation and AI

Automate where rules are explicit: QC against a spec, manifest checks, window-driven publish and takedown, event setup from
templates. Keep a human decision for irreversible live actions: switching the primary source, dropping a rung, going to a slate.

AI applies to draft captions, content-aware encoding and anomaly detection on QoE series. Captions need human review for names
and required accuracy; detectors need event-start spikes labelled, or they page at every kick-off. We found no published
evidence that a specific AI tool improves live-event reliability.

## MediaOps in practice

### Reference implementation

**Assumptions:** a mid-sized streamer with a VOD catalogue and about 20 live events a month; HLS and DASH; a primary and a
standby CDN. Files live in version control; uncited values are illustrative.

**1. A delivery specification as data.** QC tools and people read the same file.

_Example status: syntax-checked, not executed. Illustrative house spec._

```yaml
# delivery-spec/outlet-ott-hd.yaml  (one file per outlet)
spec_id: ott-hd
version: 2026.10.1
owner: dam-manager@example.com
mezzanine:
  container: [mxf, mov]
  video:
    min_resolution: 1920x1080
    frame_rates: [25, 29.97, 50, 59.94]
    scan: progressive
  audio:
    layout: [stereo, "5.1"]
    loudness:                          # EBU R 128 v5 (2023)
      target_lufs: -23.0
      tolerance_lu: 1.0                # only where -23.0 is not practical, e.g. live
      qc_measurement_tolerance_lu: 0.2
      max_true_peak_dbtp: -1.0
captions:
  required_languages: [en]
  formats: [webvtt, imsc1]  # Apple 5.2: IMSC1 only in fMP4; tvOS: WebVTT only
metadata:
  required: [eidr_id, title, episode_number, rating, rights_record_id]
qc:
  on_fail: reject_with_report
  auto_checks: [checksum, container, codec, duration, black_frames,
                freeze_frames, silence, loudness, true_peak, captions_present]
```

**2. An encoding ladder with the rules that make it switchable.**

_Example status: syntax-checked, not executed. Rungs from Apple's example ladder (§1.25); peaks an illustrative 110%._

```yaml
# ladders/h264-16x9-v3.yaml
codec: h264
segment_seconds: 6          # Apple spec 7.5: target durations SHOULD be 6 s
keyframe_seconds: 2         # Apple spec 1.13: IDR every two seconds
scene_cut_keyframes: false  # keep keyframes aligned across rungs
rungs:
  - {name: 234p,  width: 416,  height: 234,  avg_kbps: 145,  peak_kbps: 160}
  - {name: 360p,  width: 640,  height: 360,  avg_kbps: 365,  peak_kbps: 400}
  - {name: 432p,  width: 768,  height: 432,  avg_kbps: 1100, peak_kbps: 1210}
  - {name: 540p,  width: 960,  height: 540,  avg_kbps: 2000, peak_kbps: 2200}
  - {name: 720p,  width: 1280, height: 720,  avg_kbps: 3000, peak_kbps: 3300}
  - {name: 1080p, width: 1920, height: 1080, avg_kbps: 6000, peak_kbps: 6600}
acceptance:
  vod_peak_within_pct_of_BANDWIDTH: 10      # Apple spec 1.27
  vod_avg_within_pct_of_AVERAGE_BANDWIDTH: 10  # Apple spec 1.26
```

**3. An event class policy.** It decides how much redundancy and rehearsal each event buys.

_Example status: syntax-checked, not executed. Illustrative policy, not an industry standard._

```yaml
# events/classes.yaml
tier1:   # e.g. national final, paid pay-per-view
  contribution_paths: 2           # diverse routes, ST 2022-7 where supported
  encoder_pipelines: 2            # e.g. MediaLive STANDARD class
  origin: redundant_inputs
  cdns: 2                         # steering or manual switch tested
  rehearsal: full_failover_drill  # pull each primary once
  change_freeze_hours_before: 48
  staffing: [event_producer, mcr_operator, platform_engineer, cdn_contact]
tier2:
  contribution_paths: 2
  encoder_pipelines: 2
  origin: single                  # accepted risk: both encoders meet here
  cdns: 1
  rehearsal: signal_check
  change_freeze_hours_before: 24
  staffing: [mcr_operator, platform_engineer_on_call]
tier3:
  contribution_paths: 1
  encoder_pipelines: 1
  origin: single
  cdns: 1
  rehearsal: none
  change_freeze_hours_before: 0
  staffing: [mcr_operator]
```

**4. A one-page event run sheet** is in the [templates](#templates).

### Hands-on labs

Labs 1 and 3 need only Python 3 and were **executed** (Linux, 2026-10-23). Lab 2 needs FFmpeg, which was not installed on the
authoring machine: **syntax-checked only, not executed**. All labs work in a temporary directory.

#### Lab 1 (beginner): check an HLS ladder against the spec

**Objective:** catch three common playlist defects: a missing `BANDWIDTH`, a segment longer than the target duration, and a VOD
playlist without an end marker.

**Prerequisites:** Python 3.8 or later; no network. **Cost and risk:** none.

**Steps**

1. Create a working directory: `cd "$(mktemp -d)"`, then `mkdir -p vod/720p`.
2. Save this as `vod/master.m3u8`. The 1080p variant deliberately lacks `BANDWIDTH`:

```text
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=1210000,AVERAGE-BANDWIDTH=1100000,RESOLUTION=768x432,CODECS="avc1.64001e,mp4a.40.2"
432p/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3300000,AVERAGE-BANDWIDTH=3000000,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
720p/index.m3u8
#EXT-X-STREAM-INF:AVERAGE-BANDWIDTH=6000000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
1080p/index.m3u8
```

3. Save this as `vod/720p/index.m3u8`. Segment 2 is 7.507 s, as when an encoder cuts on a late keyframe:

```text
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:6.006,
seg0.ts
#EXTINF:6.006,
seg1.ts
#EXTINF:7.507,
seg2.ts
#EXTINF:4.004,
seg3.ts
```

4. Save the checker as `hls_check.py`. It encodes three RFC 8216 rules: every `EXT-X-STREAM-INF` "MUST include the BANDWIDTH
   attribute" and be followed by a URI; each `EXTINF` duration, "when rounded to the nearest integer, MUST be less than or equal to
   the target duration"; and a finished VOD playlist ends with `EXT-X-ENDLIST`.[^rfc8216] It also flags a target duration other
   than Apple's 6 s.[^apple-hls]

_Example status: executed with Python 3 on 2026-10-23 (re-run after the rounding fix); the output below is real._

```python
"""Check an HLS multivariant playlist and one media playlist against
a few RFC 8216 rules and Apple authoring-spec targets. Stdlib only."""
import math
import re
import sys
from pathlib import Path

ATTR = re.compile(r'([A-Z0-9-]+)=("[^"]*"|[^,]*)')


def attrs(line):
    return {k: v.strip('"') for k, v in ATTR.findall(line.split(":", 1)[1])}


def check_multivariant(path):
    problems, variants = [], []
    lines = [l.strip() for l in Path(path).read_text().splitlines() if l.strip()]
    if not lines or lines[0] != "#EXTM3U":
        problems.append("first line is not #EXTM3U")
    for i, line in enumerate(lines):
        if line.startswith("#EXT-X-STREAM-INF:"):
            a = attrs(line)
            uri = lines[i + 1] if i + 1 < len(lines) else ""
            if not uri or uri.startswith("#"):
                problems.append(f"line {i + 1}: STREAM-INF not followed by a URI")
            if "BANDWIDTH" not in a:
                problems.append(f"{uri}: BANDWIDTH missing (required)")
            variants.append((int(a.get("BANDWIDTH", 0)), a.get("RESOLUTION", "?"), uri))
    peaks = [v[0] for v in variants if v[0]]
    if peaks != sorted(peaks):
        problems.append("ladder is not listed in ascending BANDWIDTH order (style)")
    return variants, problems


def check_media(path, vod=True):
    problems = []
    text = Path(path).read_text()
    m = re.search(r"#EXT-X-TARGETDURATION:(\d+)", text)
    if not m:
        return ["TARGETDURATION missing"]
    target = int(m.group(1))
    durs = [float(d) for d in re.findall(r"#EXTINF:([\d.]+)", text)]
    for n, d in enumerate(durs):
        r = math.floor(d + 0.5)  # halves round up; Python's round(6.5) is 6
        if r > target:
            problems.append(f"segment {n}: EXTINF {d} rounds to {r} > target {target}")
    if vod and "#EXT-X-ENDLIST" not in text:
        problems.append("VOD playlist has no #EXT-X-ENDLIST")
    if target != 6:
        problems.append(f"target duration {target}s (Apple spec: SHOULD be 6)")
    return problems


if __name__ == "__main__":
    master, media = sys.argv[1], sys.argv[2]
    variants, p1 = check_multivariant(master)
    for bw, res, uri in variants:
        print(f"variant {res:>9} peak={bw:>8} {uri}")
    p2 = check_media(media)
    for p in p1 + p2:
        print("PROBLEM:", p)
    print("RESULT:", "FAIL" if p1 + p2 else "PASS")
    sys.exit(1 if p1 + p2 else 0)
```

5. Run `python3 hls_check.py vod/master.m3u8 vod/720p/index.m3u8`.

**Expected output** (exit code 1):

```text
variant   768x432 peak= 1210000 432p/index.m3u8
variant  1280x720 peak= 3300000 720p/index.m3u8
variant 1920x1080 peak=       0 1080p/index.m3u8
PROBLEM: 1080p/index.m3u8: BANDWIDTH missing (required)
PROBLEM: segment 2: EXTINF 7.507 rounds to 8 > target 6
PROBLEM: VOD playlist has no #EXT-X-ENDLIST
RESULT: FAIL
```

6. Fix the files: add `BANDWIDTH=6600000,` to the 1080p line; change segment 2 to `#EXTINF:6.006,` (in real life, by forcing
   keyframes every 2 s so that the packager can cut at 6 s); and append `#EXT-X-ENDLIST`. Optionally change the last segment
   to `#EXTINF:5.505,`: the 4.004 s value was already valid, but the cut moves 1.501 s of media from segment 2 into segment 3,
   so the total duration stays the same.

**Validation:** rerun the checker: the 1080p variant shows `peak= 6600000`, then `RESULT: PASS`, exit code 0.

**Troubleshooting:** `IndexError` means a tag line has no colon; `FileNotFoundError` means a wrong working directory. RFC 8216
does not say how to round a half: the checker rounds 6.5 up to 7 (we ran that case: it fails against a target of 6), where
Python's `round()` gives 6. The checker skips codecs, encryption, I-frame and live playlists; use a full validator in production.

**Teardown:** `cd ..` and remove the directory that `mktemp -d` created, by its exact path.

#### Lab 2 (intermediate): encode a ladder and check loudness

**Objective:** produce a three-rung HLS ladder with aligned keyframes and normalised loudness, then verify keyframes, loudness
and quality.

**Prerequisites:** FFmpeg with libx264; `libvmaf` for step 5 (`--enable-libvmaf` at build time);[^ff-filters] about 1 GB of disk.
**Cost and risk:** local CPU only; synthetic test pattern, so quality scores will not represent real content.

**Two FFmpeg defaults to set explicitly.** The `loudnorm` filter defaults to an integrated target of -24.0 LUFS, which misses
EBU R 128's -23.0 LUFS, and to a true peak of -2.0 dBTP, which is stricter than R 128's -1 dBTP production ceiling; R 128 adds
that permitted maximum true-peak levels "may be lower for different distribution systems and data reduction rates". The HLS
muxer's `hls_time` defaults to 2 seconds, and a segment "will be cut on the next key frame after this time has passed".[^ff-filters][^ff-formats][^r128]

_Example status: syntax-checked with `bash -n`, **not executed** (no FFmpeg on the authoring machine). Options follow the FFmpeg
documentation checked on 2026-10-23._

```bash
#!/usr/bin/env bash
set -euo pipefail
work="$(mktemp -d)"; cd "$work"; echo "working in $work"

# 1. A 60-second synthetic source: moving test pattern plus a 1 kHz tone.
ffmpeg -hide_banner -y \
  -f lavfi -i testsrc2=size=1920x1080:rate=25:duration=60 \
  -f lavfi -i sine=frequency=1000:sample_rate=48000:duration=60 \
  -c:v libx264 -crf 12 -preset veryfast -pix_fmt yuv420p \
  -c:a pcm_s24le source.mov

# 2. Measure loudness and true peak before normalising.
ffmpeg -hide_banner -nostats -i source.mov -map 0:a \
  -af ebur128=peak=true -f null - 2>&1 | tail -n 14

# 3. Three rungs, keyframe every 2 s (50 frames at 25 fps), no scene-cut keyframes,
#    loudness normalised to -23 LUFS / -1 dBTP, 6-second VOD segments.
FC="[0:v]split=3[s0][s1][s2];[s0]scale=-2:1080[v0];[s1]scale=-2:720[v1];"
FC+="[s2]scale=-2:432[v2];[0:a]loudnorm=I=-23:TP=-1:LRA=7,aresample=48000,"
FC+="asplit=3[a0][a1][a2]"
ffmpeg -hide_banner -y -i source.mov -filter_complex "$FC" \
  -map "[v0]" -map "[v1]" -map "[v2]" -map "[a0]" -map "[a1]" -map "[a2]" \
  -c:v libx264 -preset veryfast -profile:v high \
  -g 50 -keyint_min 50 -sc_threshold 0 \
  -b:v:0 6000k -maxrate:v:0 6600k -bufsize:v:0 12000k \
  -b:v:1 3000k -maxrate:v:1 3300k -bufsize:v:1 6000k \
  -b:v:2 1100k -maxrate:v:2 1210k -bufsize:v:2 2200k \
  -c:a aac -b:a 128k -ac 2 \
  -f hls -hls_time 6 -hls_playlist_type vod \
  -hls_flags independent_segments -hls_segment_type mpegts \
  -master_pl_name master.m3u8 \
  -hls_segment_filename "out_%v/seg%03d.ts" \
  -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" "out_%v/index.m3u8"

# 4. Keyframes: in a 6 s segment at 25 fps expect K at 0, 2, 4 s offsets.
ffprobe -v error -select_streams v:0 -show_entries packet=pts_time,flags \
  -of csv=p=0 out_1/seg001.ts | grep ',K' | head -n 5

# 5. Quality of the 720p rung against the source (needs libvmaf).
#    First input = distorted, second = reference, as the filter documents.
#    Different containers: reset timestamps on both, as FFmpeg's example does.
VM="[0:v]settb=AVTB,setpts=PTS-STARTPTS,scale=1920:1080:flags=bicubic[d];"
VM+="[1:v]settb=AVTB,setpts=PTS-STARTPTS[r];"
VM+="[d][r]libvmaf=log_path=vmaf.json:log_fmt=json"
ffmpeg -hide_banner -i out_1/index.m3u8 -i source.mov -lavfi "$VM" -f null -
```

**Expected output (not observed):** step 2 prints `I:`, `LRA:` and true peak; step 3 writes `master.m3u8` and `out_0`–`out_2`;
step 4 shows keyframes 2 s apart; step 5 writes `vmaf.json`.

**Validation:** run the Lab 1 checker on `master.m3u8` and `out_1/index.m3u8`. Measure the audio **after** the AAC encode, since
lossy encoding can raise peaks: `ffmpeg -i out_1/index.m3u8 -map 0:a -af ebur128=peak=true -f null -`. Confirm integrated
loudness within ±1 LU of -23 and true peak at or below your outlet's ceiling; if it is over, lower `TP` and re-encode.

**Troubleshooting:** "Unknown encoder 'libx264'" or "No such filter: 'libvmaf'" means a build without that library; segments
over 6 s mean the keyframe options missed a rung. For files, prefer `loudnorm`'s two-pass mode with `measured_*` values.[^ff-filters]

**Teardown:** remove the directory printed as `working in …`, by its exact path.

#### Lab 3 (advanced): compute QoE KPIs per CDN

**Objective:** turn player sessions into the [KPIs](#metrics-and-kpis) and see a CDN split expose what averages hide.

**Prerequisites:** Python 3.8 or later. **Cost and risk:** none; synthetic data.

1. In a `mktemp -d` directory, save `sessions.json`. Times are seconds; `stalls` are `[start, duration]`; `seek_stalls` are seek
   waits; `kbps_time` is `[bitrate, seconds played]`.

```json
[
 {"sid": "s1", "cdn": "cdn-a", "play_req": 0.0, "first_frame": 1.4,
  "end": 1801.4, "stalls": [[600.0, 2.0]], "seek_stalls": 0.0,
  "kbps_time": [[3000, 1798.0]], "error": null},
 {"sid": "s2", "cdn": "cdn-a", "play_req": 0.0, "first_frame": 2.1,
  "end": 903.6, "stalls": [], "seek_stalls": 1.5,
  "kbps_time": [[6000, 600.0], [3000, 300.0]], "error": null},
 {"sid": "s3", "cdn": "cdn-a", "play_req": 0.0, "first_frame": null,
  "end": 9.0, "stalls": [], "seek_stalls": 0.0,
  "kbps_time": [], "error": null},
 {"sid": "s4", "cdn": "cdn-b", "play_req": 0.0, "first_frame": 1.2,
  "end": 1201.2, "stalls": [[100.0, 6.0], [400.0, 9.0], [800.0, 15.0]],
  "seek_stalls": 0.0, "kbps_time": [[1100, 1170.0]], "error": null},
 {"sid": "s5", "cdn": "cdn-b", "play_req": 0.0, "first_frame": 6.8,
  "end": 606.8, "stalls": [[300.0, 4.0]], "seek_stalls": 0.0,
  "kbps_time": [[3000, 596.0]], "error": null},
 {"sid": "s6", "cdn": "cdn-b", "play_req": 0.0, "first_frame": null,
  "end": 4.0, "stalls": [], "seek_stalls": 0.0,
  "kbps_time": [], "error": "MANIFEST_403"}
]
```

2. Save the calculator as `qoe_kpis.py`:

_Example status: executed with Python 3 on 2026-10-23; output below is the real output._

```python
"""Compute streaming QoE KPIs per CDN from simplified session records.
Times are seconds. Stdlib only."""
import json
import math
import sys
from collections import defaultdict


def percentile(values, p):
    if not values:
        return None
    s = sorted(values)
    k = max(0, math.ceil(p / 100 * len(s)) - 1)  # nearest-rank method
    return s[k]


def kpis(sessions):
    attempts = len(sessions)
    started = [s for s in sessions if s["first_frame"] is not None]
    vsf = [s for s in sessions if s["first_frame"] is None and s["error"]]
    ebvs = [s for s in sessions if s["first_frame"] is None and not s["error"]]
    startup = [s["first_frame"] - s["play_req"] for s in started]
    stall = sum(d for s in started for _, d in s["stalls"])  # seek stalls excluded
    played = sum(t for s in started for _, t in s["kbps_time"])
    bits = sum(k * t for s in started for k, t in s["kbps_time"])
    return {
        "attempts": attempts,
        "vsf_pct": round(100 * len(vsf) / attempts, 1),
        "ebvs_pct": round(100 * len(ebvs) / attempts, 1),
        "startup_p50_s": percentile(startup, 50),
        "startup_p95_s": percentile(startup, 95),
        "rebuffer_ratio_pct": round(100 * stall / (stall + played), 2),
        "avg_kbps": round(bits / played) if played else None,
    }


if __name__ == "__main__":
    data = json.load(open(sys.argv[1]))
    groups = defaultdict(list)
    for s in data:
        groups[s["cdn"]].append(s)
    groups["ALL"] = data
    for name, rows in groups.items():
        k = kpis(rows)
        print(f"{name:6} n={k['attempts']} vsf={k['vsf_pct']}% ebvs={k['ebvs_pct']}% "
              f"start_p50={k['startup_p50_s']}s p95={k['startup_p95_s']}s "
              f"rebuf={k['rebuffer_ratio_pct']}% kbps={k['avg_kbps']}")
```

3. Run `python3 qoe_kpis.py sessions.json`.

**Expected output:**

```text
cdn-a  n=3 vsf=0.0% ebvs=33.3% start_p50=1.4s p95=2.1s rebuf=0.07% kbps=3667
cdn-b  n=3 vsf=33.3% ebvs=0.0% start_p50=1.2s p95=6.8s rebuf=1.89% kbps=1741
ALL    n=6 vsf=16.7% ebvs=16.7% start_p50=1.4s p95=6.8s rebuf=0.8% kbps=2905
```

**Validation:** by hand, cdn-b stalls 6 + 9 + 15 + 4 = 34 s against 1,170 + 596 = 1,766 s played: 34 ÷ 1,800 = 1.89%. The
overall 0.8% hides a CDN at roughly 25 times its peer (cdn-a: 2 ÷ 2,700 = 0.074%).

**Troubleshooting:** `KeyError` means a missing field; `ZeroDivisionError` means no session in a group started. This lab
excludes seek waits from stalls; vendors differ.

**Teardown:** remove the `mktemp -d` directory by its exact path.

### Use cases and scenarios

| Scenario | Context | Method | Trade-offs | Success measure |
|---|---|---|---|---|
| National live sports event | Spikes in minutes; no re-run | Tier-1 class, rehearsal, freeze | Idle duplicates cost money | VSF, rebuffering on target at peak |
| VOD catalogue re-encode | New codec or ladder | Test set, quality gates, staged rollout | Compute now, egress later | Same quality, fewer bits |
| Broadcast scheduling and MCR | Many events, circuits, crews | Scheduling tied to rights and devices | Lock-in, integration | No clashes; setup time |
| Rights-window enforcement | Licences differ by territory | Avails drive publish and takedown | Rights data quality | Zero titles outside windows |

**Sourced examples.** *Live scale:* see the Netflix fight in [the problem it solves](#the-problem-it-solves). *Scheduling
(vendor-reported):* DAZN selected DataMiner to "streamline DAZN's broadcast scheduling and business planning", fed from its
MediaGenix WHATS'ON rights platform;[^dazn] neither this nor Skyline's release[^skyline-plan] publishes outcome data.

::: example Illustrative scenario: the window that closed on a Sunday
A streamer licenses a series until 23:59 on Sunday 30 June, for one country. Takedown is a manual Monday task, so the titles
stay up ten hours too long. The fix is data, not diligence: machine-readable avails (MovieLabs: "Formal definition of business
rules associated with content availability"[^movielabs-md]), a scheduled takedown, and a daily audit.
:::

## Measure, secure and pay

### Metrics and KPIs

CTA-2066 standardises "media player events, properties, quality of experience (QoE) metrics";[^cta2066] its text was not opened
for this page, so these formulas are **this page's working definitions**.

| KPI | Definition / formula | Data source | Pitfall | Review |
|---|---|---|---|---|
| Video start failure (VSF) | errored before first frame ÷ attempts | Player beacons | Retries hide failures | Live: per minute |
| Exits before video start (EBVS) | abandoned without error before first frame ÷ attempts | Player beacons | Mixes impatience and slowness | Daily |
| Startup time | first frame − play request; report p50 and p95 | Player beacons | Averages hide the slow tail | Daily |
| Rebuffering ratio | stall time ÷ (stall time + play time), excluding startup and seeks | Player beacons | One long stall in a small sample | Live: per minute |
| Average bitrate | Σ(bitrate × seconds) ÷ Σ seconds | Player beacons, CMCD | High bitrate is not high quality | Weekly |
| Delivery right first time | deliveries passing QC first time ÷ deliveries | QC system | Lenient QC inflates it | Weekly |
| On-time publication | titles live at window open ÷ titles due | DAM and rights | Ignores takedown | Daily |
| Window breaches | titles live outside their window | Rights audit | Investigate each | Daily |
| Cost per viewer hour | (encode + storage + packaging + egress) ÷ viewer hours | Bills, analytics | Shared-cost allocation | Monthly |

**Worked example (illustrative tier-1 objective):** VSF at most 1% and rebuffering ratio at most 0.5%, with 2,000,000 start
attempts and 1,000,000 viewer hours.

- VSF budget = 1% × 2,000,000 = 20,000 failed starts; 14,000 failures use 70% of it.
- Rebuffering: watch time is 3.6e9 s; solving s ÷ (s + 3.6e9) = 0.005 gives a stall budget of about 18.09 million s. If players
  report 12 million s of stalls, the ratio is 12e6 ÷ 3.612e9 = 0.33%, within the objective.

Agree in advance what happens at 50% and 100% of each budget (drop the top rung, switch CDN). Leading indicators: encoder
alarms, origin errors, cache misses; lagging: QoE and complaints. **Vanity traps:** peak concurrency says nothing about quality;
a higher average bitrate can mean bigger files with no visible gain.

### Quality, security, rights and compliance

- **Loudness.** EBU R 128 (v5, 2023) recommends -23.0 LUFS, ±1.0 LU where that is not practical (for example live), ±0.2 LU
  for QC measurement error, and true peak not above -1 dBTP in production.[^r128] In the United States, FCC rules under the
  CALM Act "restrict the volume of television commercials" by incorporating ATSC A/85.[^calm] Check jurisdiction and contracts.
- **Captions.** WCAG 2.2 SC 1.2.4 (level AA): "Captions are provided for all live audio content in synchronized
  media".[^wcag-live] WebVTT is a W3C Candidate Recommendation Draft (May 2026).[^webvtt] Apple supports CEA-608 and CEA-708 closed
  captions carried in the video segments, declared with an `EXT-X-MEDIA` tag carrying `LANGUAGE`, and WebVTT or IMSC1 subtitles
  (IMSC1 only in fMP4; tvOS accepts WebVTT only).[^apple-hls] Legal duties vary by country and service.
- **Stream integrity.** ETSI TR 101 290's first priority for transport streams, "necessary for de-codability", includes
  `TS_sync_loss`, `PAT_error` and `Continuity_count_error`.[^tr101290]
- **Content protection.** Encrypt once with Common Encryption and serve several DRM systems: Shaka Packager supports Widevine,
  PlayReady, FairPlay and Marlin, with the `cenc`, `cbc1`, `cens` or `cbcs` schemes.[^shaka-docs] DASH-IF IOP v5 Part 6 allows
  `cenc` or `cbcs` for DASH and calls them "two mutually exclusive protection schemes": a DRM client that supports only one
  cannot decrypt the other.[^dashif-iop6] Apple's spec says protection "SHOULD follow" FairPlay Streaming.[^apple-hls] Risks: every session needs a licence, so
  a licence-server fault looks like a VSF spike at kick-off; a scheme mismatch fails on some devices only. Keep key management
  apart from packaging, and protect ingest endpoints (HTTP POST or PUT) like any write API.[^dashif-ingest]
- **Rights.** A window breach is a contract breach. Use machine-readable avails and stable identifiers (EIDR: "a universal
  identifier system for movies, television, sports, and other audiovisual content"[^eidr]).
- **Privacy.** QoE beacons and CMCD carry session identifiers ([PrivacyOps](../privacyops/)).

### Cost, capacity and sustainability

**Encoding** scales with catalogue × ladder, **storage** with renditions × retention, **egress** with audience × bitrate × hours.

**Capacity sizing, worked.** RFC 9317's worst case: 10,000 viewers at about 8 Mbit/s "might" need "approximately 80 Gbps";
caching and replication can cut the need at peering and ingest points to as little as one copy per feed.[^rfc9317] The CDN edge
still serves every viewer: 500,000 concurrent viewers at an average of 4 Mbit/s need about 2 Tbit/s there. Confirm that with
your CDNs weeks ahead.

**Cost per viewer hour, illustrative.** 2,000,000 viewer hours a month at an average of 3 Mbit/s is 2,000,000 × 3,600 s ×
3 Mbit/s ÷ 8 = 2,700,000 GB (2.7 PB). At an assumed 0.004 per GB, egress costs 10,800; with an assumed 2,400 for encoding and
storage, the total is 13,200, or 0.0066 per viewer hour (placeholder prices). A 10% lower average bitrate at equal quality saves
about 1,080 a month.

**Sustainability:** fewer bits at equal quality and colder archive tiers cut energy too ([GreenOps](../greenops/)).

### Assurance of the operating model

- **QC:** sample passed deliveries monthly; track defects QC missed.
- **Redundancy:** every tier-1 event has a rehearsal record; a map without a drill is untested.
- **Windows:** a daily audit; any breach opens an incident.
- **Metrics:** one definitions file, re-checked when the analytics vendor or player changes.

## When things go wrong

### Common failures and troubleshooting

| Symptom | Likely cause | Diagnosis | Remediation and prevention |
|---|---|---|---|
| Black or frozen picture at kick-off | Wrong source routed; contribution down | Monitors per path; encoder input alarms | Switch to the backup path; pre-event check of both paths |
| Players stall on one rung only | That rung's segments late or its peak above `BANDWIDTH` | Compare segment timestamps across rungs; measure peaks | Fix the encoder profile; check declared bandwidth in QC |
| Rebuffering spike on one CDN | CDN capacity or routing; origin overload on cache misses | QoE by CDN and region; origin errors | Shift traffic; raise shield capacity |
| Live playlist stops advancing | Packager stalled; ingest dropped | Poll the playlist for 2 × target duration ([runbook](#runbook-rebuffering-spikes-on-one-cdn-during-a-live-event)) | Fail over the ingest source; alert on a stale media sequence |
| Delivery rejected by a platform | Spec drift (codec level, loudness, captions) | Compare the QC report with the spec version | Run the outlet's spec in your own QC before sending |
| Title visible after its licence ended | Manual takedown; wrong time zone | Rights audit; publish log | Scheduled takedown from rights data; daily audit |
| TS errors at the receiver | Continuity or sync problems in transport | TR 101 290 priority-1 indicators[^tr101290] | Fix the transport path; monitor priority-1 continuously |

### Runbook: rebuffering spikes on one CDN during a live event

**Trigger:** rebuffering ratio at 2% for three minutes, against a 0.5% objective.

1. **Declare (minute 0).** Producer decides, platform engineer investigates, MCR watches ([IncidentOps](../incidentops/)).
2. **Locate (minutes 0–3).** Split QoE by CDN, region, device and rung. All CDNs: step 3. One CDN: step 4.
3. **Check the live edge.** If no new segment appears, the problem is upstream of the CDNs. RFC 8216 lets a server publish the
   next playlist up to 1.5 target durations after the previous one, and tells clients to retry an unchanged playlist after half
   a target duration,[^rfc8216] so a single check one target duration later can call a healthy origin stale. The script polls
   every half target duration and reports STALE only after two target durations plus the CDN's playlist TTL. It counts
   segments too, so EVENT playlists work.

_Example status: executed on 2026-10-23 against a local test server with simulated playlists (advancing at 1.45 target
durations, stale, no media-sequence tag, no target duration, ended, unreachable): each gave the expected result. Not run
against a production stream._

```bash
#!/usr/bin/env bash
# Is the live playlist advancing? RFC 8216 lets a new version appear up to
# 1.5 x target duration (TD) after the last one, so poll every TD/2 and call
# it STALE only after 2 x TD plus the CDN's playlist cache TTL.
set -euo pipefail
url="${1:-https://origin.example.com/live/event1/720p/index.m3u8}"
ttl="${2:-0}"   # playlist cache TTL at this CDN, in seconds (0 at the origin)

get() { curl -fsS --max-time 5 "$url"; }
tag() { printf '%s\n' "$1" | sed -n "/^#EXT-X-$2:/{s/^[^:]*:\([0-9]*\).*/\1/p;q;}"; }
newest() {      # media sequence number of the newest segment
  local s n
  s="$(tag "$1" MEDIA-SEQUENCE)"
  n="$(printf '%s\n' "$1" | grep -c '^#EXTINF' || true)"
  echo $(( ${s:-0} + n - 1 ))   # no MEDIA-SEQUENCE tag: RFC 8216 says 0
}

pl="$(get)" || { echo "ERROR: cannot fetch $url"; exit 2; }
td="$(tag "$pl" TARGETDURATION)"
if [ -z "$td" ]; then echo "ERROR: no TARGETDURATION (multivariant?)"; exit 2; fi
case "$pl" in *'#EXT-X-ENDLIST'*) echo "ENDED: EXT-X-ENDLIST present"; exit 0;; esac

first="$(newest "$pl")"; waited=0
step=$(( td / 2 > 0 ? td / 2 : 1 )); limit=$(( 2 * td + ttl ))
while [ "$waited" -lt "$limit" ]; do
  sleep "$step"; waited=$(( waited + step ))
  pl="$(get)" || { echo "ERROR: fetch failed after ${waited}s"; exit 2; }
  now="$(newest "$pl")"
  if [ "$now" -gt "$first" ]; then
    echo "OK: newest segment $first -> $now after ${waited}s (TD ${td}s)"; exit 0
  fi
done
echo "STALE: no new segment in ${waited}s (2 x TD ${td}s + TTL ${ttl}s)"; exit 1
```

   Run it against the origin and each CDN hostname. If only one CDN serves an old playlist, it caches playlists too long; live
   clients "MUST periodically reload", so stale playlists starve them.[^rfc8216]
4. **Mitigate first (minutes 3–8).** Move traffic off a bad CDN (steering, DNS or load-balancer weights), for example 50% then
   100%. Leave the encoders alone unless they are the cause.
5. **Degrade deliberately** if capacity is the issue: removing the top rung cuts demand at once.
6. **Verify (minutes 8–15):** rebuffering falls below the objective and VSF does not rise.
7. **Communicate** at a fixed interval; **afterwards**, run a blameless review (per-CDN playlist cache rules, capacity
   reservations, a stale-sequence alert).

::: caution Do not fix forward in the middle of the live window
A new encoder profile or player hot-fix adds an untested change to a failing system. Use rehearsed levers.
:::

### Anti-patterns and myths

- **"Two encoders, so we are redundant."** Not if both share a source or one origin.
- **"QC is a person watching the file."** Eyes miss loudness, caption timing and container faults.
- **"One ladder fits all content."** Cartoons and sport need different bits.
- **"Higher bitrate means better quality."** Past a point you pay for invisible bits.
- **"The CDN handles live scale."** Only within reserved capacity and an origin that survives cache misses.
- **"Rights are Legal's problem."** Legal writes the contract; MediaOps enforces the window.
- **Myth: "MediaOps is a certified discipline."** We found no certification, standard or governing body for the label.

## Deciding and adopting

### When to use and when not to use

**Use it when** media is the product (broadcasters, streamers, rights holders), live failures are public, outlets impose
specs, or windows differ by territory.

**Do not use it when** video is occasional and not time-critical (a training library, marketing clips): a managed platform plus
[WebOps](../webops/) is enough, though captions, music rights and egress stay yours. **Exit:** if events become rare, fold the
role into platform operations; keep the specs and templates.

### Decision framework

::: figure Deciding how much MediaOps you need
```mermaid
flowchart TB
  Q1{"Is video central to revenue or reputation?"}
  Q1 -->|"no"| N1["Managed video platform plus WebOps; no dedicated team"]
  Q1 -->|"yes"| Q2{"Do you run live events with a public start time?"}
  Q2 -->|"no"| V["VOD focus: spec-driven QC, ladders, rights automation"]
  Q2 -->|"yes"| Q3{"Can a failure cost a contract, a refund or a regulator query?"}
  Q3 -->|"no"| L1["Tier 2: dual encoders, one CDN; tier 3: single path"]
  Q3 -->|"yes"| L2["Tier 1 practice: full path redundancy, rehearsals, MCR, QoE SLOs"]
  V --> B{"Build, buy managed services, or outsource operations?"}
  L1 --> B
  L2 --> B
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class Q1,Q2,Q3,B decision
  class V,L1,L2 core
  class N1 neutral
```
Text equivalent: if video is not central to revenue or reputation, use a managed platform with WebOps. Without live events,
focus on VOD QC, ladders and rights automation. With live events, ask whether a failure can cost a contract, refund or
regulator query: if not, tier 2 (dual encoders, one CDN) or tier 3 (single path); if so, tier-1 practice (full path redundancy,
rehearsals, MCR, QoE objectives). All paths end at build, buy managed services, or outsource.
:::

**Build, buy or outsource: a weighted comparison.** Example weights for a mid-sized streamer with frequent live sport.

| Criterion (weight) | Build on open source | Managed cloud media services | Outsourced media operations |
|---|---|---|---|
| Control over quality and latency (25%) | 5 | 4 | 3 |
| Time to first event (20%) | 2 | 4 | 5 |
| Staff and on-call burden (20%) | 1 | 3 | 5 |
| Unit cost at high volume (20%) | 4 | 3 | 2 |
| Exit cost and lock-in (15%) | 5 | 3 | 2 |
| **Weighted score (of 5)** | **3.40** | **3.45** | **3.45** |

Scores: 5 = best. The near-tie is honest: the choice turns on which risk you would rather own.

### Maturity model

::: note This is the Atlas's model
No official MediaOps maturity model exists. These levels are this Atlas's proposal.
:::

| Level | Observable behaviour | Evidence | Next step |
|---|---|---|---|
| 1. Ad hoc | Deliveries checked by eye; events set up by whoever is free | Rejections; kick-off surprises | Write delivery specs |
| 2. Repeatable | Written specs; event checklists; one ladder | Checklists in use | Automate QC against the specs |
| 3. Defined | Automated QC; event classes; rehearsed failover for tier 1 | Rehearsal records; QC reports | Measure QoE by CDN and device |
| 4. Measured | QoE objectives per event; cost per viewer hour; window audits | Dashboards with budgets; zero breaches | Per-content ladders; multi-CDN steering |
| 5. Optimising | Ladder, codec and CDN choices driven by quality and cost data | Quality per bit improves; fewer incidents | Re-test as codecs and devices change |

**Exit criteria:** 2→3 when QC runs every outlet's spec; 3→4 when every tier-1 event has a written objective and review;
4→5 when ladder and CDN changes cite measured quality and cost.

### Adoption roadmap: 30/60/90 days

| Window | Actions | Owner | Milestone |
|---|---|---|---|
| Days 1–30 | Inventory outlet specs; classify events; list single points per tier-1 event; agree KPI definitions | Media ops lead | Top three outlet specs; redundancy map |
| Days 31–60 | Automate QC for one outlet; scheduled takedown; QoE by CDN and device; first failover rehearsal | Platform eng. and rights | Window audit at zero; rehearsal record |
| Days 61–90 | Ladder review on a test set; QoE objectives for tier-1 events; first post-event review; cost per viewer hour | Media ops and finance | Objective and review per tier-1 event |

**Quick wins:** stale-playlist alert, scheduled takedown, loudness at ingest. **Dependencies:** player telemetry, CDN logs, rights data.

## Toolkit

### Checklists

**Delivery preflight (per file)**

- [ ] Checksum, container, codec, resolution and frame rate match the spec version
- [ ] Loudness and true peak in spec; captions per language, timing spot-checked
- [ ] Identifier and rights record present; QC report stored with the asset

**Tier-1 live event readiness (T-48 h to T-0)**

- [ ] Both contribution paths tested end to end on real devices
- [ ] Each primary (path, encoder, origin input, CDN) pulled once in rehearsal
- [ ] Change freeze in force; CDN capacity confirmed in writing for the peak
- [ ] Objective, thresholds and levers in the run sheet; DRM licence service and CDN contacts named

**Weekly review**

- [ ] QoE by CDN, device and title; worst three investigated; right-first-time; window audit

### Templates

**Event run sheet (one page)**

```text
EVENT RUN SHEET                         Class: tier 1 / 2 / 3
Event: ____________________  Start (UTC): ________  End: ________
Decision owner: ____________  MCR: __________  Platform: _________
Rights: territories ________  platforms ________  window ________
Paths: contribution A ______  B ______   encoders A ______ B _____
Origin inputs: ______  CDNs: 1 ______ 2 ______  steering: _______
Objective: VSF <= ___%   rebuffering ratio <= ___%   (per minute)
Levers (pre-agreed, in order):
  1. Switch contribution path        owner ______
  2. Shift CDN traffic 50% -> 100%   owner ______
  3. Remove top rung for all         owner ______
  4. Slate and audio-only fallback   owner ______
Rehearsal done (date, result): _________________________________
Status updates every ___ min to: ______________________________
Post-event review booked: ____________
```

**Delivery QC failure report**

```text
QC FAILURE REPORT        Asset ID: ________   Spec: ______ v______
Supplier: __________     Received: __________ (UTC)
Check            Expected              Measured          Result
Loudness         -23.0 LUFS +/- tol    ________          PASS/FAIL
True peak        <= -1.0 dBTP          ________          PASS/FAIL
Captions         en (WebVTT/IMSC1)     ________          PASS/FAIL
Duration         ________              ________          PASS/FAIL
Action required: redeliver by __________ / accept with waiver by ___
```

**Ladder change decision record**

```text
DECISION: Ladder h264-16x9 v3 -> v4         Date: __________
Context: devices, content mix, codec support
Test set: titles and content types used
Evidence: quality metric per rung, bitrate, startup and stall impact
Decision and rollback: staged by device family; revert to v3 if
  rebuffering ratio rises above ___% for ___ days
Owner: __________   Review date: __________
```

### Deep comparisons

| Choice | Option A | Option B | Choose A when | Choose B when |
|---|---|---|---|---|
| Live latency | Standard HLS/DASH (10 s to a few minutes) | Low-latency HLS/DASH (under 10 s) | Stability and scale matter most | Betting, interactivity or spoilers make delay costly |
| Transport into the cloud | Managed fibre or satellite | SRT over the internet | Highest assurance, budget available | Cost and flexibility, with tested loss behaviour |
| Mastering | Separate files per version | IMF package ("multiple content versions" of one work)[^imf] | Few versions | Many territories and edits |

Latency classes are from RFC 9317, which also names "ultra-low-latency (less than 1 second)".[^rfc9317]

### FAQ

**Is MediaOps the same as "media operations"?** Largely: the spaced form is the job family, the compact form a niche label.

**Does it include advertising?** Only carrying ad markers cleanly (SCTE-35 splice signals, which RFC 8216 maps into
`EXT-X-DATERANGE` tags[^rfc8216]); selling and inserting ads is [AdOps](../adops/).

**Do I need SMPTE ST 2110?** Only for IP production facilities, not to stream finished feeds.

**Why do segments come out longer than I set?** Encoders cut only on keyframes. FFmpeg's HLS muxer cuts on the next keyframe after
`hls_time`.[^ff-formats] Fix the keyframe interval (for example every 2 s) and disable scene-cut keyframes.

**Is VMAF the truth about quality?** It is a documented, Emmy-winning metric from Netflix,[^vmaf] but still a model: validate it
on your content and look at the worst frames.


## Going further

### Advanced topics and emerging direction

- **Client data to the CDN.** CTA-5004 (CMCD) is at revision B (April 2026), beside CTA-5006, Common Media Server Data
  (November 2022).[^cta-wave] dash.js supports CMCD version 1 fully; version 2 fields "are gradually being added".[^dashjs-cmcd]
- **Content steering** is in the HLS draft and the sixth DASH edition; the HLS draft's partial segments "provide a parallel
  channel for distributing media at the live edge".[^hlsbis][^iso-dash6]
- **Metadata.** The EBU says EBUCorePlus "can fully replace" EBUCore and CCDM.[^ebucore]

### Learning path

| Stage | What to do | Output |
|---|---|---|
| 1 day | RFC 9317 overview; Lab 1; Apple's authoring spec | Annotated playlist |
| 1 week | Lab 2 on your own clip; EBU R 128 | Tested three-rung ladder |
| 30 days | Lab 3 on real data; one outlet spec; one failover rehearsal | Dashboard and spec file |
| Specialise | Contribution (ST 2022-7, SRT), ST 2110, IMF, codecs, DRM, rights data | Design note |
| Portfolio | Run sheet, post-event review, ladder decision record | Evidence of judgement |

## Wrap-up

### Executive recap and cheat sheet

- **What:** the media supply chain run against a clock, with quality and rights as gates.
- **Decide:** event classes, redundancy per class, codecs by device and cost, build versus buy.
- **Practise:** spec-driven QC, aligned ladders, rehearsed failover, window-driven publishing.
- **Measure:** VSF, EBVS, startup p95, rebuffering by CDN and device, window breaches, cost per viewer hour.
- **Watch out for:** single ends on "redundant" chains, tool defaults, untested failover, manual takedowns.

### A judgement call: low latency for the final, or stability?

**Situation (illustrative).** Live latency is about 25 seconds, and social media spoils goals. Marketing wants "under 5
seconds" for the national cup final. The low-latency setup has run on two small events; the final should draw several times
the largest audience so far.

**Option A: low latency for the final.** A visible win. Costs: partial segments multiply requests per viewer, smaller buffers
stall more when throughput dips (RFC 9317 notes how fast Wi-Fi throughput can swing[^rfc9317]), and scale is untested.
**Option B: standard latency for the final**, low latency proven on mid-size events first.

**Assumptions to state:** peak audience; CDN-confirmed low-latency capacity at that peak; the cost of a stall-heavy final
against the cost of spoilers.

**Reasoning.** A's benefit is visible and its risk is not, but a tier-1 event is the worst place for a first run at scale. **A
defensible choice is B plus a plan:** low latency for tier 1 once it meets written objectives on three mid-size events. If the
contract mandates it, A only with a load test at the expected peak and a rehearsed fallback.

### Learning objectives and mastery check

After this page you should be able to:

1. Explain the media supply chain and where quality, time and rights can be lost.
2. Check an HLS playlist against its core rules; design a keyframe-aligned ladder and choose codecs.
3. Map a live chain's single points and choose redundancy by event class.
4. Define and compute QoE KPIs, and set an event objective with a budget.
5. Decide when a dedicated MediaOps practice is not worth it.

::: answer Q1. Your standard-class live channel has two encoder pipelines, yet a fault at the venue took the stream down. Why?
Both pipelines took the same venue output: redundancy protects only what it duplicates. AWS requires two upstream source
streams for a standard channel,[^medialive-red] but two streams from one venue output share its faults. Protect the source end
or record it as an accepted risk.
:::

::: answer Q2. A 720p media playlist declares TARGETDURATION 6, and one segment has EXTINF 6.6. Is that valid? And 6.4?
6.6 rounds to 7 > 6, which breaks RFC 8216; 6.4 rounds to 6: allowed. Fix keyframe placement, not the playlist.
:::

::: answer Q3. Overall rebuffering is 0.8%, under your 1% objective. Why might you still act?
Averages hide segments: in Lab 3 one CDN sits at 1.89% beside another at 0.07%. Split by CDN, region and device.
:::

::: answer Q4. You normalised a programme with FFmpeg's loudnorm defaults. Will it meet an EBU R 128 delivery spec?
Not for loudness: the -24.0 LUFS default misses R 128's -23.0 target. The -2.0 dBTP default is stricter than R 128's -1 dBTP
ceiling, which R 128 says may be lower for data-reduced delivery. Set I=-23, take TP from the outlet's spec, and measure after
the final encode.[^ff-filters][^r128]
:::

::: answer Q5. A small company streams four internal town halls a year. Should it build a MediaOps team?
No: a managed platform, a checklist and captions suffice ([decision framework](#decision-framework)).
:::

::: answer Q6. Marketing wants 2-second latency for every event. What do you ask?
Which use case needs it, at what audience and stall rate. In RFC 9317's terms, under 1 s usually needs other protocols; under
10 s is reachable with low-latency HLS or DASH, at the cost of more requests and less buffer.[^rfc9317]
:::

### Conclusion

MediaOps is a modest label for demanding work: move heavy, time-bound media through a chain of hand-offs without losing quality,
time or rights. The discipline is a set of habits, not a trademark: test against a written spec, measure before choosing ladders,
map single points before claiming redundancy, rehearse, and judge by what viewers saw. Teams with these habits rarely need
heroics on the night; teams without them rely on luck, and a live event exposes that in public.

## Sources and further reading

All sources were opened on 2026-10-23; the evidence ledger records support and gaps.

[^skyline-docs]: [MediaOps](https://docs.dataminer.services/solutions/standard_solutions/MediaOps/MediaOps.html) — DataMiner Docs, Skyline Communications, undated (© 2026). Checked 2026-10-23.
[^skyline-plan]: [Skyline Communications showcases the evolution of DataMiner MediaOps.PLAN at IBC 2025](https://satellitemarkets.com/products-and-services/skyline-communications-showcases-evolution-dataminer-mediaopsplan-ibc-2025) — Skyline press release, Satellite Markets, 2025-09-11. Checked 2026-10-23.
[^dazn]: [DAZN selects dataminer.MediaOps](https://www.advanced-television.com/2025/03/20/dazn-selects-dataminer-mediaops/) — Advanced Television (press release), 2025-03-20. Checked 2026-10-23.
[^tmt]: [TMT Insights announces media operations division, makes key appointments](https://www.tvbeurope.com/?p=114046) — TVBEurope, 2023-08-22. Checked 2026-10-23.
[^nbcu]: [Media Operations Specialist (NBCUniversal)](https://www.entertainmentcareers.net/nbcuniversal/media-operations-specialist/job/533695/) — job posting, EntertainmentCareers.net, 2026-10-07. Checked 2026-10-23.
[^mops]: [Media OPerationS (mops) working group](https://datatracker.ietf.org/wg/mops/about/) — IETF Datatracker, state Active. Checked 2026-10-23.
[^rfc9317]: [RFC 9317: Operational Considerations for Streaming Media](https://www.rfc-editor.org/rfc/rfc9317) — IETF, October 2022. Checked 2026-10-23.
[^rfc8216]: [RFC 8216: HTTP Live Streaming](https://www.rfc-editor.org/rfc/rfc8216) — IETF, August 2017. Checked 2026-10-23.
[^hlsbis]: [HTTP Live Streaming 2nd Edition (draft-pantos-hls-rfc8216bis-22)](https://datatracker.ietf.org/doc/draft-pantos-hls-rfc8216bis/) — Independent Submission, 2026-05-01; sent to the RFC Editor 2026-05-15; printed expiry 2026-11-02. Checked 2026-10-23.
[^apple-hls]: [HLS Authoring Specification for Apple Devices](https://developer.apple.com/documentation/http-live-streaming/hls-authoring-specification-for-apple-devices) — Apple, latest revision 2025-06-26. Checked 2026-10-23.
[^dashif-iop]: [DASH-IF Interoperability Points v5](https://dashif.org/guidelines/iop-v5/) — DASH Industry Forum, parts dated 2021–2025. Checked 2026-10-23.
[^dashif-5th]: [MPEG-DASH 5th edition published](https://dashif.org/news/5th-edition/) — DASH Industry Forum news, undated. Checked 2026-10-23.
[^iso-dash6]: [ISO/IEC 23009-1:2026 preview](https://www.technickenormy.cz/publicdoc/iec_previews/4278791.pdf) — ISO/IEC, 2026-07 (preview copy; iso.org returned 403). Checked 2026-10-23.
[^dashif-iop6]: [DASH-IF IOP v5.1.0 Part 6: Content protection and security](https://github.com/user-attachments/files/24056674/DASH-IF-IOPv5.1.0-Part6.pdf) — DASH Industry Forum, 2025-12-09. Checked 2026-10-23.
[^dashif-ingest]: [DASH-IF Live Media Ingest Protocol, v1.2](https://dashif.org/Ingest/) — DASH Industry Forum, page dated 2026-09-01. Checked 2026-10-23.
[^st2110]: [SMPTE ST 2110](https://www.smpte.org/standards/st2110) — SMPTE, overview page. Checked 2026-10-23.
[^st2022-7]: [SMPTE ST 2022-7:2019 Seamless Protection Switching of RTP Datagrams](https://pub.smpte.org/pub/st2022-7/st2022-7-2019.pdf) — SMPTE, approved 2018-12-26. Checked 2026-10-23.
[^medialive-class]: [Channel class](https://docs.aws.amazon.com/medialive/latest/ug/channel-class.html) — AWS Elemental MediaLive User Guide. Checked 2026-10-23.
[^medialive-red]: [Deciding whether to implement pipeline redundancy](https://docs.aws.amazon.com/medialive/latest/ug/pipeline-redundancy-guidelines.html) — AWS Elemental MediaLive User Guide. Checked 2026-10-23.
[^tr101290]: [ETSI TR 101 290 V1.4.1: Measurement guidelines for DVB systems](https://www.etsi.org/deliver/etsi_tr/101200_101299/101290/01.04.01_60/tr_101290v010401p.pdf) — ETSI, 2020-06. Checked 2026-10-23.
[^r128]: [EBU R 128: Loudness normalisation and permitted maximum level of audio signals](https://tech.ebu.ch/docs/r/r128.pdf) — EBU, version 5.0, November 2023. Checked 2026-10-23.
[^calm]: [Federal Register 79 FR 51107: CALM Act, incorporation of ATSC A/85:2013](https://www.govinfo.gov/content/pkg/FR-2014-08-27/pdf/2014-20251.pdf) — FCC, 2014-08-27. Checked 2026-10-23.
[^imf]: [SMPTE ST 2067 (Interoperable Master Format)](https://www.smpte.org/standards/st2067) — SMPTE, overview page. Checked 2026-10-23.
[^ebucore]: [Metadata specifications (EBUCore, EBUCorePlus)](https://tech.ebu.ch/MetadataEbuCore) — EBU, undated. Checked 2026-10-23.
[^eidr]: [EIDR](https://www.eidr.org/) — EIDR Association. Checked 2026-10-23.
[^movielabs-md]: [MovieLabs Digital Distribution Framework specifications](http://movielabs.com/md/) — MovieLabs. Checked 2026-10-23.
[^movielabs-2030]: [Production technology and the 2030 Vision](https://movielabs.com/production-technology/) — MovieLabs (paper 2019). Checked 2026-10-23.
[^cta-wave]: [WAVE specifications](https://www.cta.tech/wave-project/specifications/) — CTA. Checked 2026-10-23.
[^cta2066]: [CTA-2066: Streaming Quality of Experience Events, Properties and Metrics](https://www.cta.tech/standards/cta-2066/) — CTA, March 2020 (description page). Checked 2026-10-23.
[^dashjs-cmcd]: [Common Media Client Data](https://dashif.org/dash.js/pages/usage/cmcd.html) — dash.js docs, DASH Industry Forum. Checked 2026-10-23.
[^wcag-live]: [Understanding SC 1.2.4: Captions (Live)](https://www.w3.org/WAI/WCAG22/Understanding/captions-live.html) — W3C WAI, WCAG 2.2. Checked 2026-10-23.
[^webvtt]: [WebVTT: The Web Video Text Tracks Format](https://www.w3.org/TR/webvtt1/) — W3C Candidate Recommendation Draft, 2026-05-20. Checked 2026-10-23.
[^ff-formats]: [FFmpeg Formats Documentation (hls muxer)](https://ffmpeg.org/ffmpeg-formats.html) — FFmpeg project. Checked 2026-10-23.
[^ff-filters]: [FFmpeg Filters Documentation (loudnorm, ebur128, libvmaf)](https://ffmpeg.org/ffmpeg-filters.html) — FFmpeg project. Checked 2026-10-23.
[^vmaf]: [Netflix/vmaf](https://github.com/Netflix/vmaf) — Netflix, GitHub (libvmaf v3.0.0, 2023-12-07). Checked 2026-10-23.
[^shaka-docs]: [Shaka Packager documentation](https://shaka-project.github.io/shaka-packager/html/documentation.html) — Shaka Project. Checked 2026-10-23.
[^shaka]: [shaka-project/shaka-packager](https://github.com/shaka-project/shaka-packager) — Shaka Project, GitHub. Checked 2026-10-23.
[^hlsjs]: [video-dev/hls.js](https://github.com/video-dev/hls.js) — video-dev, GitHub. Checked 2026-10-23.
[^srt]: [The SRT Protocol (draft-sharabayko-srt-01)](https://datatracker.ietf.org/doc/draft-sharabayko-srt/) — individual Internet-Draft, 2021-09-07 (expired). Checked 2026-10-23.
[^av1]: [AV1 specification](https://aomedia.org/specifications/av1/) — Alliance for Open Media (v1.0.0-errata1). Checked 2026-10-23.
[^vdp]: [Video Distribution Patent Pool](https://accessadvance.com/licensing-programs/vdp-pool/) — Access Advance (self-description). Checked 2026-10-23.
[^mediatailor]: [Using AWS Elemental MediaTailor to create linear assembled streams](https://docs.aws.amazon.com/mediatailor/latest/ug/channel-assembly.html) — AWS Elemental MediaTailor User Guide. Checked 2026-10-23.
[^paid-media-job]: [Media Operations Specialist (Connelly Partners Integrated Europe)](https://builtindublin.ie/job/media-operations-specialist/8060762) — job posting, Built In Dublin, removed 2026-03-19. Checked 2026-10-23.
[^netflix-fight]: [Mike Tyson, Jake Paul fight was the most streamed sporting event ever, Netflix says](https://www.nbcnews.com/business/business-news/mike-tyson-jake-paul-fight-was-streamed-sporting-event-ever-netflix-rcna180876) — Jake Piazza, CNBC via NBC News, 2024-11-19. Checked 2026-10-23.

**Further reading**

- [IETF MOPS documents](https://datatracker.ietf.org/wg/mops/documents/), including RFC 9706 (TreeDN, live streaming to mass audiences).
- [Interoperable Master Format explainer](https://www.imfug.com/explainer/imf-explainer-en) — IMF User Group.

**Changelog**

- 2026-10-23 — First version: term status confirmed as niche; research, labs (Labs 1 and 3 executed; Lab 2 syntax-checked only),
  diagrams and validation.
- 2026-10-23 — Round-1 revision: verbatim MovieLabs quote; DASH editions corrected; stale-playlist script fixed to RFC 8216
  timing and tested locally; codecs, DRM, SCTE-35 and linear playout added; several precision and lab fixes.
- 2026-10-23, post-score polish: HLS draft status corrected (Independent Submission with the RFC Editor); two repetitions cut.
