StreamKit SDK API Reference

Every config option, method, event, and integration surface — documented straight from the SDK source, so what you read here is what actually ships.

Current version 3.22.0

Install

StreamKit SDK ships as a single UMD bundle plus a stylesheet. Drop both into your page — no build step, no package manager required.

<link rel="stylesheet" href="dist/skplayer.min.css">
<script src="dist/skplayer.min.js"></script>

hls.js and dash.js are not bundled — they're fetched from a CDN on demand, only when the source you give StreamKit SDK actually needs that engine (.m3u8 → hls.js, .mpd → dash.js). Native MP4/native HLS (Safari) needs neither.

Tip: call SKPlayer.preload("hls") (or "dash") — or pass preload: "hls" in config — to start fetching the engine script before playback is requested, shaving the head-start off first play.

Quick Start

Video

<div id="player"></div>

<script>
  new SKPlayer({
    containerId: "player",
    mediaType:   "video",
    src:         "https://example.com/stream.m3u8",
    backupsrc:   "https://backup-cdn.example.com/stream.m3u8",
    autoplay:    1,
    muted:       1,
    poster:      "https://example.com/poster.jpg",
  });
</script>

Audio

new SKPlayer({
  containerId: "player",
  mediaType:   "audio",
  src:         "https://example.com/stream.mp3",
});

containerId must point to an element already in the DOM — the constructor throws if it isn't found. See Audio Mode for what's different when mediaType: "audio".

Config Options

Everything below is a top-level key on the object passed to new SKPlayer({...}). Defaults shown are what applies when the key is omitted entirely.

KeyTypeDefaultDescription
containerIdstringrequiredid of an existing DOM element the player mounts into
mediaType"video" | "audio"—anything other than exactly "video" creates an <audio> element — see Audio Mode
srcstring—media URL. Engine is auto-selected by extension (.m3u8→HLS, .mpd→DASH, else native) unless streamType is set
backupsrcstring—fallback URL swapped in automatically on a fatal stream error. One retry only
streamType"hls" | "dash"—forces engine selection, bypassing URL-extension sniffing
hlsUrl / dashUrlstringjsDelivr CDN URLoverride the CDN URL StreamKit SDK fetches hls.js / dash.js from
autoplay0/1/bool0attempts autoplay with sound first, falls back to muted-autoplay automatically if the browser blocks it
muted0/1/bool0starts the player muted
posterstring—poster image, video mode only
controlsbool | objecttruefalse = headless mode (no built-in UI at all). Object form: { ui, tapToUnmute, contextMenu, fullscreen, volume }, each independently toggleable
preload"hls" | "dash"—starts fetching that engine's script immediately, ahead of playback
drmobject—see Multi-DRM
adsobject—see IMA Ads
lbandobject—see L-Band. Presence of the key at all (even {}) turns it on
cmcdbool | object—see CMCD
analyticsobject—see GA4 Analytics
licenseKeystring—see License Protection
playlistarray—see Playlist
autoplayNextbooltrue when a playlist is setauto-advance to the next track on ended
loopboolfalseplaylist wraps to the first track after the last (or last track on prevTrack() from the first)

Query-String Overrides

Useful for demos and support links — appending these to the page's own URL overrides matching config keys at runtime, taking priority over whatever the embedding code passed in.

ParamOverrides
?autoplay=1autoplay
?muted=1muted
?controls=0controls
?ui=, ?tapToUnmute=, ?contextMenu=, ?fullscreen=, ?volume=the matching controls.* sub-flag
?lband=1turns L-Band on
?lband_tag=, ?lband_thickness=, ?lband_refresh=, ?lband_duration=, ?lband_pause=the matching lband.* field
?ga4=analytics.ga4MeasurementId
?ga4debug=1analytics.debug
?preload=hls|dashsame as the preload config key, evaluated at script-parse time

Instance Methods

Called on the object returned by new SKPlayer(...).

MethodDescription
play()starts/resumes playback
pause()pauses playback
seek(seconds)seeks to an absolute time
isLive()returns true if the current stream has no fixed duration
setSource(config)swaps to a new source at runtime — pauses, tears down the old stream engine, and reloads with the given config (same shape as the constructor's)
destroy()full teardown — stream/ads/L-Band/listeners, empties the container
on(event, callback)subscribes to internal lifecycle events: "ready", "play", "pause", "buffering", "ended", "error", "fatal", "sourcechange"
goToTrack(index)playlist only — jumps to a track by index and plays it
nextTrack() / prevTrack()playlist only — advance/go back one track (wraps if loop: true)
getPlaylistIndex()playlist only — current 0-based index
getPlaylist()playlist only — the playlist array, or []
Not a public method: there's no setVolume(), mute(), or toggleFullscreen() on the instance today — those are only reachable through the built-in control-bar UI, or directly via player.core.media.el.volume / .muted and player.core.container.requestFullscreen().

Quality control (via player.core.stream)

Not exposed on the top-level instance — reach through player.core.stream:

getAvailableQualities()list of available bitrate/quality levels
setQuality(value)manually select a quality level
setAutoQuality()return to ABR (automatic) quality selection
getCurrentQuality() / getCurrentQualityLabel() / getCurrentQualityBadge()current selection, for building custom quality UI

L-Band (via player.core.lband)

show() / hide()manually toggle the squeeze-back ad layout
refresh()force-refresh both GPT ad slots
isVisible()current visibility state
cycleRemaining()returns { displayDuration, pauseDuration } for the current auto-show/hide cycle

Static Methods

SKPlayer.versioncurrent SDK version string
SKPlayer.preload(type)preloads "hls" or "dash" engine script ahead of any instance being created
SKPlayer.pauseAll()pauses every SKPlayer instance currently on the page
SKPlayer.destroyAll()destroys every SKPlayer instance currently on the page

Events

Custom DOM events, dispatched on the media element unless noted otherwise. Listen with document.getElementById("player").querySelector("video").addEventListener(...), or use the container-level ones directly on your containerId element.

EventTargetFires when
avplayer-fatal-errormedia elementhls.js/dash.js retries exhausted, or a DRM/FairPlay setup failure — triggers automatic backupsrc failover if configured
avplayer-retry-requestedmedia elementuser clicks "Retry" after a CDN script load failure with no backupsrc set
avplayer-license-invalidmedia elementthe license server explicitly returns "not licensed" (never on a network error — that fails open)
avplayer-errorbubbles from the player containerany handled error — network/media/stream/config/fatal/license — carrying the full error object
avplayer-livemedia elementthe stream is detected as live (no fixed duration)
avplayer-levels-readymedia elementquality/bitrate levels have been parsed and are available
avplayer-quality-changedmedia elementa manual or automatic ABR quality switch completed
avplayer-playlist-changedcontainer{ index, item, total } — fired by goToTrack() / nextTrack() / prevTrack() / auto-advance

Multi-DRM

One drm config block covers Widevine, PlayReady, FairPlay, and ClearKey.

KeyFields
widevinelicenseUrl, headers, serverCertificateUrl
playreadylicenseUrl, headers
fairplaylicenseUrl, certificateUrl, headers — native EME path, Safari/iOS
clearkeykeys: { "<kidHex>": "<keyHex>" } — DASH only, no license server needed

Widevine · DASH

drm: {
  widevine: { licenseUrl: "https://your-license-server.com/widevine" }
}

Multi-DRM (Widevine + PlayReady) · DASH

drm: {
  widevine:  { licenseUrl: "https://.../AcquireLicense", headers: { "X-AxDRM-Message": token } },
  playready: { licenseUrl: "https://.../AcquireLicense", headers: { "X-AxDRM-Message": token } },
}

ClearKey · DASH

drm: {
  clearkey: { keys: { "4060a865887842679cbf91ae5bae1e72": "fc35340837310cc0fb53de97e22a69e0" } }
}

Widevine · HLS (via hls.js EME)

drm: {
  widevine: { licenseUrl: "https://your-license-server.com/widevine" }
}

Try any of these live on the Live Demo's DRM tab.

IMA Ads — Pre/Mid/Post-roll

Google IMA SDK integration. An empty ads: {} does nothing — at least one of preroll/midroll/postroll must be set.

// Preroll only
ads: { preroll: "https://pubads.g.doubleclick.net/gampad/ads?..." }

// Postroll only
ads: { postroll: "https://pubads.g.doubleclick.net/gampad/ads?..." }

// Midroll — multiple cue points, one shared tag
ads: { midroll: { times: [30, 90, 180], tag: "..." } }

// Midroll — per-cue tags
ads: { midrolls: [ { time: 30, tag: "..." }, { time: 90, tag: "..." } ] }

// All three together
ads: {
  preroll:  "...",
  midroll:  { times: [30, 90, 180], tag: "..." },
  postroll: "...",
}

Midrolls are VOD-only — they're automatically cancelled if the stream turns out to be live. A 8-second internal timeout guards every ad request; if the ad manager never responds, content plays through uninterrupted rather than hanging.

L-Band Display Ads

A squeeze-back display-ad format (Google Ad Manager/GPT) — the video shrinks into a corner and opens two ad slots, left vertical + bottom horizontal.

KeyDefaultDescription
adUnit"/6355419/Travel"GPT ad unit path used for both slots unless overridden per-side
leftAdUnit / bottomAdUnitfalls back to adUnitper-slot ad unit override
thickness100bar thickness in px (width of the left bar, height of the bottom bar)
refresh60seconds between automatic ad refreshes, once visible
autoShowtrueshow automatically once both slots render
displayDuration0seconds visible before auto-collapsing (0 = stays forever)
pauseDuration0seconds hidden before re-showing with fresh ads (0 = no cycle)
lband: {
  adUnit:    "/1234567/YourNetwork/Video",
  thickness: 100,
  refresh:   60,
}

GPT requests each slot at its computed exact size plus common IAB fallback sizes (300×250, 728×90, 160×600, etc.), since real ad inventory is bought at standard sizes. See it live on the Live Demo's L-Band tab.

CMCD

Common Media Client Data (CTA-5004) — attaches session/QoS data to every manifest and segment request so your CDN can make smarter delivery decisions.

// auto-generated session ID
cmcd: true

// or customize fields
cmcd: { sessionId: "my-session-id", contentId: "my-content-id" }

Delivered as hls.js's native cmcd option for HLS, dash.js's streaming.cmcd for DASH, and appended as a CMCD= query parameter for native/Safari HLS playback where no per-request hook exists.

GA4 Analytics

Push standard playback events straight into your own GA4 property. Zero overhead when not configured — no measurement ID, no tracking calls at all.

analytics: {
  ga4MeasurementId: "G-XXXXXXXXXX",
  debug: false  // true = tag every hit for GA4 DebugView
}

Reuses the host page's existing gtag if present, otherwise lazy-loads one. Events tracked automatically: init, play, video_start, resume, pause, seek, buffering_start/buffering_end, video_complete, error, fullscreen_enter/fullscreen_exit, volume_change, mute/unmute, plus ad-lifecycle events (ad_request, ad_loaded, ad_start, ad_complete, ad_skip, ad_failed). Each hit carries an anonymous per-device ID (localStorage-persisted), a per-viewing session ID, domain, browser/OS, and screen size — no PII.

License Protection

Domain-locked license keys, checked server-side against the embedding domain.

licenseKey: "avp_your_key_here"
Currently inert: the config key is accepted and the check runs fire-and-forget alongside normal startup, but server-side enforcement is off while the license backend is being finalized. Setting licenseKey today has no effect on playback — this will change with no action needed on your part once enforcement goes live, and it always fails open (a network hiccup never blocks playback) even once it does.

When active: fails open on any network error/timeout, always bypasses localhost, and only stops playback on an explicit "not licensed" response from the server — shown as a clear, non-recoverable message rather than a generic error.

Playlist

An array of per-track configs — each item takes the same keys as a single-source player config.

player = new SKPlayer({
  containerId: "player",
  mediaType:   "video",
  autoplay: 1, muted: 1,
  playlist: [
    { title: "Track 1", src: "https://.../a.m3u8", mediaType: "video" },
    { title: "Track 2", src: "https://.../b.mpd",  mediaType: "video" },
  ],
  autoplayNext: true,
  loop: false,
});

player.nextTrack();
player.goToTrack(1);

Extra fields like title pass through harmlessly — StreamKit SDK only reads src/mediaType/autoplay/muted/etc. from each item; anything else is yours to use for your own UI (track titles, thumbnails).

Audio Mode

mediaType: "audio" reuses the entire control bar, seek bar, volume, and settings UI — same engine, same reliability, just no video canvas.

  • • The control bar never auto-hides (video mode hides it after 3s of inactivity)
  • • No touch-to-reveal-controls mobile behavior — the bar is always visible
  • • No right-click context menu (video-only feature)
  • • All streaming engines, DRM, ads, CMCD, and analytics work identically to video mode

Ready to power your streaming platform?

Start a 30-day free trial with full feature access — no credit card required.

Start Free Trial Get a License Key