Integrate the Flipbase player (v3)
v3 is a rewrite of the player in TypeScript. The embed API is unchanged from
v2 — the same constructor, the same options, the same events, including the
misspelled scrubbTo that existing integrations listen for. Moving a working v2
embed to v3 is a change of one URL.
3.0.0 is a stable release. But /player/latest/ and /player/v2/ still serve
v2, and will until moving them is a deliberate decision — so nothing changes
for an existing integration until you pin v3 yourself.
How to integrate the Player?
Load from cdn.flipbase.com. That is the CDN itself, so the request goes straight to the nearest edge. app.flipbase.com serves the same file through a reverse proxy on a single instance — existing integrations pointing at it keep working, but it is one more thing between the browser and the file.
<head>
...
<!--
Load the JavaScript Player library in the HTML head section of your page
-->
<script src="https://cdn.flipbase.com/player/v3.0.0/player.min.js"></script>
</head>
<!--
Place the a video element(s) where you want to show the video player.
-->
<div id="video-player-element"></div>
<!-- Initialize the Player and provide your 'player_id' -->
<script>
const player = new FlipbasePlayer({
video_id: '5120293b-583b-4534-90dc-0f44cd51705e',
player_id: '95f4d94b-86c0-4e4a-b23d-484158efd1a4',
selector: 'video-player-element'
})
// Load the Flipbase player(s) manually
player.mount();
// Remove the Flipbase player(s) from the DOM
player.unmount();
</script>
new is optionalFlipbasePlayer is callable both ways, deliberately:
const a = new FlipbasePlayer({ selector, video_id, player_id }); // works
const b = FlipbasePlayer({ selector, video_id, player_id }); // also works
Both forms appear in the v2 documentation, so v3 declares both signatures and returns the same player object either way. Neither is deprecated; an integration written against one does not need changing.
Pin the exact version, as above. From v3 onwards every version path is
immutable — the bytes at /player/v3.0.0/ will never change — and
each release publishes a manifest.json beside the bundle naming the commit it
was built from and a SHA-384 integrity hash per file.
That was not true of v2: its exact-version paths predate the current release
process and do not all contain the same build as /player/v2/.
Opens in a new tab. Runs the published bundle from the CDN — the same bytes you would embed.
What is new in v3
The public API is the same, so this is mostly about what stopped being broken.
- Seeking works. v2 threw
ReferenceErroron every scrub. unmount()thenmount()works. In v2 the second mount produced a player that looked right and did nothing.- Theming works. v2 validated the
themeoption and then ignored it, and built its stylesheet by string concatenation — two of its ten rule blocks were missing a brace and the browser discarded them silently. - Statistics can be turned off, with
collectStatistics: false. There was no opt-out before, which matters where the embedding page has no consent basis for behavioural analytics on candidates. - 24 languages, selected with
locale, with per-string overrides vialabels. - Smaller: 66 kB minified, 24 kB gzipped, against v2's 144 kB — with every language included.
Two features were held back from 3.0.0 so that one build could be published everywhere, and they return as their own minors. See Overlays below for the first of them.
Overlays
A logo and a presenter name, drawn over the video in any of four corners.
Available from 3.1.0-alpha.0.
3.1.0-alpha.0 is published and immutable, and nothing is pinned to it. Use it
to try the overlays; pin 3.0.0 for anything you are shipping.
<script src="https://cdn.flipbase.com/player/v3.1.0-alpha.0/player.min.js"></script>
const player = new FlipbasePlayer({
video_id: '5120293b-583b-4534-90dc-0f44cd51705e',
player_id: '95f4d94b-86c0-4e4a-b23d-484158efd1a4',
selector: 'video-player-element',
logo: {
url: 'https://cdn.example.com/brand/logo.png',
position: 'top right', // or top left, bottom left, bottom right
size: 'medium', // small, medium, large
alt: '' // empty marks it decorative, which is usually right
},
presenter: {
name: 'Anna de Vries',
title: 'Recruiter · Flipbase',
position: 'bottom left',
size: 'medium'
}
});
Both are optional and take the same position and size. For the web component
they flatten into attributes — logo-url, logo-position, presenter-name and
the rest — so the common cases need no script.
Worth knowing:
- Two overlays pinned to the same corner stack rather than overlapping.
- A bottom overlay lifts clear of the control bar while it is on screen.
- The layer is inert, so clicking a logo plays the video like clicking anywhere else on it.
logo.urlmust be anhttp(s)ordata:image/*URL. Anything else is refused with a warning and the logo is dropped — the value usually comes from a configuration UI, and the player runs inside someone else's page.- A logo that fails to load leaves no trace rather than a broken-image icon.
Subtitles are the second held-back feature and arrive the same way, in
3.2.0.
Options
Everything below is in 3.0.0 unless the row says otherwise. The list is taken
from the player's published type surface, so it is the whole of it — an option
not named here is not an option.
| Option | Type | Default | What it does |
|---|---|---|---|
selector | String | — | Id of the element to render into. |
element | HTMLElement | — | The element itself, instead of selector. |
video_id | String | — | The video's UUID. |
player_id | String | — | The player configuration id. |
signature | String | — | Playback signature, for secure mode. |
theme | String | Object | — | A built-in theme name, or an object overriding individual colour tokens. |
locale | String | en | Language of the control labels. 24 languages; regional tags resolve to their base language. |
labels | Object | — | Per-string overrides. Takes precedence over locale. |
collectStatistics | Boolean | true | Registers the view-statistics plugin. Set false where you have no consent basis for behavioural analytics. |
plugins | Array | — | Extra plugins to register at construction. |
apiBaseUrl | String | https://app.flipbase.com | Override the API origin. |
muted | Boolean | false | Start muted, for autoplay policies that require it. |
logo | Object | — | Logo overlay. 3.1.0-alpha.0 — see Overlays. |
presenter | Object | — | Presenter overlay. 3.1.0-alpha.0 — see Overlays. |
Theme tokens, for theme as an object: primaryColor, buttonColor,
secondarySliderColor, playButtonBackground, playButtonHover,
buttonHover, loadingBackground. Each also exists as a --flipbase-* custom
property on the player root, so a host stylesheet can set it instead.
secondaryColor is accepted and published as --flipbase-secondary-color, but
the default stylesheet never reads it — neither did v2's — so setting it changes
nothing on its own.
Values that are not valid CSS colours are ignored with a warning rather than applied.
Events
Subscribe with player.on(name, listener). on returns an unsubscribe
function; player.off(name, listener) also works.
| Event | Listener arguments |
|---|---|
initialized | — |
play | — |
pause | — |
playing | — |
canplay | — |
waiting | — |
ended | — |
error | (error) |
timeupdate | (currentTime, progress) |
progress | (progress) |
loadedmetadata | (duration) |
fullscreenchange | (isFullscreen) |
volumechange | (volume) |
scrubbTo | (seconds) |
scrubbingstarted | (currentTime) |
scrubbingended | (currentTime, delta) |
destroy | — |
scrubbTo, scrubbingstarted and scrubbingended keep v2's spelling on
purpose. They are part of the public contract and will not be renamed in v3.
The error argument is an object with code, a message already translated
into the viewer's locale, and status where there was an HTTP status. code is
one of no-video-id, no-player-id, no-element, not-found, network,
malformed-response, processing-timeout, playback.
Methods
| Method | What it does |
|---|---|
mount() | Render the player into its element. |
unmount() | Remove it from the DOM. mount() afterwards works. |
destroy() | Tear down for good; emits destroy. |
play() | Returns a promise. |
pause() | |
togglePlay() | |
toggleVolume() | Mute/unmute. |
updateVolume(level) | |
enterFullscreen() | |
exitFullscreen() | |
toggleFullscreen() | |
getState() | A read-only snapshot of player state. |
addPlugin(registration) | |
removePlugin(name) | |
on(event, listener) | Returns an unsubscribe function. |
off(event, listener) |
There is also a read-only cid property, the player instance's own id.
Secure mode
Unchanged from v2. Pass the signature property to the constructor; see
the v2 page for how to build the signature string.
Testing against staging
From 3.0.0 the player is built against an environment, so there are two
copies of every release:
| Loads from | Talks to | |
|---|---|---|
| production | cdn.flipbase.com | app.flipbase.com |
| staging | cdn.stg.flipbase.com | app.stg.flipbase.com |
<script src="https://cdn.stg.flipbase.com/player/v3.0.0/player.min.js"></script>
A video recorded through the staging recorder exists only in the staging
database, so the staging player is the one that can play it. Before 3.0.0 the
player had no notion of environment and always queried production.
Browser Support
- Chrome 64+
- Firefox 67+
- Edge 79+
- Safari 12+
- iOS Safari 12+
v3 drops Internet Explorer 11, which v2 supported. If you need IE11, stay on v2.
Migrating from v2
Change the script URL. That is the whole migration for most integrations:
- <script src="https://cdn.flipbase.com/player/v2/player.min.js"></script>
+ <script src="https://cdn.flipbase.com/player/v3.0.0/player.min.js"></script>
Every method, option, event name and flipbase-player-* CSS class is kept. The
things to check are the ones that were broken rather than absent in v2 — if you
worked around the theming or the remount behaviour, those workarounds are now
acting on a player that behaves correctly.