Multi-DRM
Bring your DRM vendor’s license URLs and OGPlayer handles the rest — key
exchange, renewals, error mapping to the stable 4000-series codes, and the
DrmKeysLoaded analytics event on success.
| Platform | Systems |
|---|---|
| Android | Widevine (default), PlayReady, ClearKey |
| iOS | FairPlay |
| Web | Widevine, PlayReady and FairPlay — the SDK engages whichever the browser supports; DASH items use Widevine and PlayReady |
OGMediaItem.Builder("https://example.com/protected.mpd") .setDrm( DrmConfig.Builder("https://drm.example.com/widevine") .addHeader("x-custom", "value") .build(), ) .build()var item = OGMediaItem(urlString: "https://example.com/protected.m3u8")!item.drm = FairPlayConfig( certificateURLString: "https://drm.example.com/fairplay.cer", licenseServerURLString: "https://drm.example.com/fairplay")player.load({ url: "https://example.com/protected.m3u8", drm: { widevine: { licenseUrl: "https://drm.example.com/widevine" }, playready: { licenseUrl: "https://drm.example.com/playready" }, fairplay: { licenseUrl: "https://drm.example.com/fairplay", certificateUrl: "https://drm.example.com/fairplay.cer" }, },});<OGPlayerView style={{ flex: 1 }} source={{ url: Platform.OS === "android" ? "https://example.com/protected.mpd" : "https://example.com/protected.m3u8", drm: { widevine: { licenseUrl: "https://drm.example.com/widevine", headers: { "x-custom": "value" } }, playready: { licenseUrl: "https://drm.example.com/playready" }, fairplay: { licenseUrl: "https://drm.example.com/fairplay", certificateUrl: "https://drm.example.com/fairplay.cer" }, }, }}/>OGPlayerView( source: OGMediaItem( url: Platform.isAndroid ? 'https://example.com/protected.mpd' : 'https://example.com/protected.m3u8', drm: const DrmConfig( widevine: WidevineConfig( licenseUrl: 'https://drm.example.com/widevine', headers: {'x-custom': 'value'}, ), playready: PlayReadyConfig(licenseUrl: 'https://drm.example.com/playready'), fairplay: FairPlayConfig( licenseUrl: 'https://drm.example.com/fairplay', certificateUrl: 'https://drm.example.com/fairplay.cer', ), ), ),)Failures are never mysterious: every DRM problem maps to a stable code — 4000 license failed, 4001+status HTTP, 4002 token fetch, 4003 provisioning, 4004 session expired, 4005 unsupported — see error codes. Android additionally retries silently (max 2 attempts / 60 s) before surfacing anything.
For expiring tokens, use a token provider instead of static headers.
DASH on the web
Section titled “DASH on the web”DASH items on the web take the very same DrmConfig: Widevine and PlayReady
license URLs, per-scheme headers, the tokenProvider called on every
license request (renewals included), onDrmSessionRenewed, the
DrmKeysLoaded event and the 4000–4005 error codes all behave as they do for
HLS. Configure both schemes and the browser’s or TV set’s CDM picks the one it
has:
player.load({ url: "https://example.com/protected.mpd", // or mimeType: "application/dash+xml" drm: { widevine: { licenseUrl: "https://drm.example.com/widevine" }, playready: { licenseUrl: "https://drm.example.com/playready" }, tokenProvider: async ({ renewal }) => ({ "X-DRM-Token": await freshToken() }), },});Safari has no DASH path — serve it the HLS rendition with fairplay (CMAF
lets one packaging feed both). Pages that load the SDK with a <script> tag,
and packaged Tizen and webOS apps, add the DASH engine file
ogplayer.dash.global.js next to the bundle; with the npm package it loads on
its own (see the web and
smart TV quick
starts).