Airi

Player

A professional player you embed in one line, wired to your storage and your DRM. It is free: you pay the delivery and licences playback already consumes, not the player.

What it is #

A player is a named configuration — colors, controls, restrictions — stored in your account. You embed it on any website by id, next to whichever video should play. One player serves your whole catalogue: the embed picks the content, the player brings everything else.

Underneath it is Shaka Player, the open-source player Google maintains: adaptive HLS and DASH, progressive mp4, DRM. We add the persistent configuration, URL signing, the connection to your DRM, and the one-line embed.

Why it is free

A player costs nothing by existing. What costs money is already billed by its own service: the GB the CDN serves and the DRM licences your account issues. Charging for the player on top would be charging twice, and giving it away makes everything else worth more.

Prefer to assemble the player yourself, with your own Shaka or Video.js? The manual integration guide is still there — the player is optional by design.

Embedding it #

Two ways. The recommended one is the loader: it builds the iframe with the right permissions (autoplay, encrypted-media, fullscreen), which get forgotten when written by hand.

With the loader (recommended)
<div data-airi-player="PLAYER_ID" data-file="FILE_ID"></div>
<script async src="https://airi.live/player.js"></script>
Direct iframe
<iframe
  src="https://airi.live/embed/PLAYER_ID?file=FILE_ID"
  style="aspect-ratio:16/9;width:100%;border:0"
  allow="autoplay; encrypted-media; fullscreen; picture-in-picture"
  allowfullscreen></iframe>

FILE_ID is the id (or your customId) of a file in your storage: a plain mp4 or an HLS/DASH package. For an external source use data-src="https://…" instead of data-file. In a SPA that renders the div after load, call AiriPlayer.scan().

AttributeWhat it does
data-airi-playerThe player id. Required.
data-fileA file from your storage (id or customId).
data-srcAn external https URL (mp4, m3u8 or mpd), unsigned.
data-aspectContainer aspect ratio (16:9 by default).
data-*Any parameter from the next table, as an attribute.

URL parameters #

Each embed can adjust the player without touching its saved configuration. Precedence is URL > configuration > defaults, and it only reaches presentation and playback — delivery (expiries, countries, speed) and allowed origins cannot be touched from a URL, by construction.

ParameterWhat it does
autoplay=1Starts by itself, muted (browser policy).
muted=1Starts silent.
loop=1Repeats.
t=90Starts at second 90.
rate=1.5Initial speed.
maxh=720Quality ceiling in lines.
lang=enControls language (es, en, auto).
captions=esCaptions in that language, visible from the start.
audio=enPreferred audio track.
poster=https://…Waiting image.
accent=22ccaaAccent color, hex without #.
bigplay=0No big play button.
controls=0No controls — for background videos.

The configuration #

The dashboard covers the common ground with a live preview. The full surface — exact button order, menu speeds, each bar's color — lives in the API's config object, grouped in four blocks:

BlockWhat it holds
themeAccent and bar colors, aspect ratio, poster, linked logo with position and opacity.
playbackAutoplay, mute, loop, start position, rate, quality ceiling, audio and caption languages.
uiWhich buttons appear and in what order, overflow menu, speeds, seek bar, big play button, keyboard shortcuts, mobile gestures, language, title.
deliverySigned URL lifetime, allowed or blocked countries, speed cap. Enforced at the CDN edge.

Everything is optional: {} is a fully working player with Shaka's defaults. The exact schema, every field documented, is in the OpenAPI reference under PlayerConfig.

Through the API #

Players are managed with the player:read and player:write scopes. The id creation returns is the one that goes into the embed.

Create a player
curl -X POST https://kms.airi.live/v1/players \
  -H "Authorization: Bearer $TOKEN" \
  -H 'content-type: application/json' \
  -d '{
    "name": "My player",
    "config": {
      "theme": { "accentColor": "#22ccaa" },
      "playback": { "muted": true }
    },
    "allowedOrigins": ["https://mysite.com"]
  }'
Management
# List
curl "https://kms.airi.live/v1/players" -H "Authorization: Bearer $TOKEN"

# Update (config = full replacement; allowedOrigins: null removes it)
curl -X PATCH "https://kms.airi.live/v1/players/$ID" \
  -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{ "config": { "ui": { "locale": "en" } } }'

# Delete — every embed with this id stops working immediately
curl -X DELETE "https://kms.airi.live/v1/players/$ID" -H "Authorization: Bearer $TOKEN"

The embed calls a public resolution endpoint — GET /v1/players/{id}/resolve — that returns the configuration and, when content is named, its signed URL and licence endpoints. You can call it yourself to build your own player on top of our resolution: it needs no token.

Restricting to your domains #

A public embed works on any website — the YouTube model, and for most content the right one. If your player should only work on your sites, give it a list of origins:

example
curl -X PATCH "https://kms.airi.live/v1/players/$ID" \
  -H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{ "allowedOrigins": ["https://mysite.com", "https://www.mysite.com"] }'

The real wall is not a check of ours: the embed document answers with Content-Security-Policy: frame-ancestors, and it is the viewer's browser that refuses to render the iframe outside your list. The resolution also answers 403 when the origin does not match, as fast failure.

What it protects and what it does not

It protects against casual embedding on other people's sites — the real case. It is not DRM: whoever can watch can always screen-record, and signed URLs expire per delivery.urlTtlSeconds. For content that needs real protection, encrypt it at encode time: the player plays it just as easily.

Automatic DRM #

If a package came out of your encoding encrypted, the embed knows without any configuration: resolution detects the job's key and hands over your own DRM's licence endpoints. The embedding site sees no keys and no licence URLs — just the usual div and script.

DRM playback issues licences, and each licence bills at the usual rate ($0.009). Same cost with our player or with yours.

Limits of this version #

  • No Chromecast. The Cast button arrives with our own receiver; we would rather show no button than a failing one.
  • FairPlay pending — see the Safari note above.
  • External data-src carries no DRM: a foreign URL cannot resolve our licences.
  • Plain mp4s play progressively: no adaptive ladder, no quality menu. Encode them for ABR — exactly what encoding exists for.
  • No playback analytics yet: delivery data is in your daily billing.