BustPlay — démarrage rapide
Cinq minutes d’une page vide à un lecteur avec publicité. Tout ce qui suit est l’API réelle des builds actuels (npm run build à la racine du dépôt), pas des projets.
1. Lecteur par balise script (une minute)
<link rel="stylesheet" href="bustplay/ui.css">
<div id="player"></div>
<script src="bustplay/core.umd.cjs"></script>
<script src="bustplay/ui.umd.cjs"></script>
<script>
const player = BustPlay.createPlayer({
container: 'player', // id ou l’élément lui-même
sources: 'https://cdn.example/video.mp4', // chaîne ou [{src, type}]
muted: true, // politiques d’autoplay des navigateurs gérées
});
BustPlayUI.createUI(player, { title: 'Titre de la vidéo' });
</script>
Les fichiers viennent de packages/*/dist/ (jusqu’à la publication npm). Globales UMD : BustPlay (core), BustPlayUI, BustPlayHls, BustPlayAds, BustPlayAnalytics.
2. La même chose avec un bundler (ESM)
import { createPlayer } from '@bustplay/core';
import { createUI } from '@bustplay/ui';
import '@bustplay/ui/ui.css';
const player = createPlayer({ container: 'player', sources: 'https://cdn.example/video.mp4' });
const ui = createUI(player, {
title: 'Titre de la vidéo',
chapters: [{ t: 0, name: 'Prologue' }, { t: 96, name: 'Chapitre deux' }],
skin: 'studio', // studio | minimal | vertical
accent: '#5B8CFF', // marque blanche avec une seule variable
});
L’import est compatible SSR : window n’est pas touché avant createPlayer.
3. HLS
import { attachHls, bindQualityMenu } from '@bustplay/hls';
const player = createPlayer({ container: 'player', sources: [] }); // l’adaptateur pilote la source
const ui = createUI(player, { title: 'Direct' });
const hls = await attachHls(player, 'https://cdn.example/stream.m3u8');
bindQualityMenu(hls, ui.menu); // les niveaux de qualité apparaissent d’eux-mêmes dans le menu
Safari lit nativement ; les autres navigateurs chargent hls.js paresseusement : options.lib → la globale Hls de la page → import('hls.js').
4. Publicité
import { createAdScheduler, breaksFromVmap } from '@bustplay/ads';
const scheduler = createAdScheduler(player, {
ui, // compteur « Publicité 1 sur 2 », recherche bloquée
breaks: [
{ offset: 'pre', tags: [TAG_A, TAG_B] }, // A n’a pas rempli — on essaie B
{ offset: { percent: 0.5 }, tags: [TAG_MID], pod: 2 },
{ offset: 'post', tags: [TAG_POST] },
],
consent: { gdpr: '1', gdprConsent: TCF_STRING }, // → macros {gdpr}/{gdpr_consent}
});
// Pre-roll propre sans flash du contenu :
await scheduler.runPreRoll();
void player.play();
// Ou entièrement depuis VMAP :
createAdScheduler(player, { ui, breaks: breaksFromVmap(vmapXml) });
5. Analytique
import { createAnalytics } from '@bustplay/analytics';
createAnalytics(player, {
endpoint: 'https://stats.example.com/v1/events',
video: 'video-42', // votre id de vidéo, pas de PII
sampleRate: 1, // part des sessions collectées
});
Les événements (view_start avec TTFF, quartiles, rebuffer, erreurs, session_end avec QoE) partent par lots ; la fermeture de l’onglet est survécue via sendBeacon. Le côté réception est services/stats (README sur place).
6. React et Web Component
import { BustPlayer } from '@bustplay/react';
import '@bustplay/ui/ui.css';
<BustPlayer sources="https://cdn.example/video.mp4" title="Vidéo"
onReady={({ player, ui }) => console.log(player.getState())} />
<script src="bustplay/element.umd.cjs"></script>
<script>BustPlayElement.define()</script>
<bust-play src="https://cdn.example/video.mp4" title="Vidéo" muted></bust-play>
Changer sources/src recrée le lecteur ; la cosmétique (title, skin) est appliquée à la création. <bust-play> n’a pas de Shadow DOM : il lui faut ui.css inclus dans la page.
7. DRM
import { toHlsDrmConfig, toDashProtectionData, enableFairPlay } from '@bustplay/drm';
const drm = {
widevine: { licenseUrl: 'https://lic.example/wv', headers: { 'X-Auth': token } },
playready: { licenseUrl: 'https://lic.example/pr' },
fairplay: { licenseUrl: 'https://lic.example/fps', certificateUrl: 'https://lic.example/cert' },
};
await attachHls(player, src, { config: toHlsDrmConfig(drm) }); // EME de hls.js
await attachDash(player, src, { protectionData: toDashProtectionData(drm) });
const off = enableFairPlay(player.media, drm.fairplay); // HLS natif de Safari
Widevine/PlayReady sont gérés par hls.js/dash.js ; FairPlay sur le chemin natif est piloté par notre couche EME (SPC/CKC en octets bruts ; variantes serveur via les hooks licenseBody/licenseResponse). Un essai réel nécessite un serveur de licences.
Et ensuite
- Démo en direct :
apps/demo/index.html(aprèsnpm run build). - Système de design de l’interface :
UI_DESIGN.md. - Feuille de route et état honnête :
README.md§6.