BustPlay
JA

BustPlay — クイックスタート

空のページから広告付きプレーヤーまで 5 分。以下はすべて現在のビルド (リポジトリのルートで npm run build)で動く実際の API であり、計画ではありません。

1. script タグでプレーヤー(1 分)

<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 または要素そのもの
    sources: 'https://cdn.example/video.mp4',  // 文字列または [{src, type}]
    muted: true,                               // ブラウザの自動再生ポリシーに対応済み
  });
  BustPlayUI.createUI(player, { title: '動画タイトル' });
</script>

ファイルは packages/*/dist/ から取得します(npm 公開まで)。UMD グローバル: BustPlay (core)、BustPlayUI、BustPlayHls、BustPlayAds、 BustPlayAnalytics。

2. バンドラーで同じことを(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: '動画タイトル',
  chapters: [{ t: 0, name: 'プロローグ' }, { t: 96, name: '第二章' }],
  skin: 'studio',            // studio | minimal | vertical
  accent: '#5B8CFF',         // 変数ひとつでホワイトラベル
});

インポートは SSR セーフ:createPlayer まで window に触れません。

3. HLS

import { attachHls, bindQualityMenu } from '@bustplay/hls';

const player = createPlayer({ container: 'player', sources: [] }); // ソースはアダプターが管理
const ui = createUI(player, { title: 'ライブ' });
const hls = await attachHls(player, 'https://cdn.example/stream.m3u8');
bindQualityMenu(hls, ui.menu); // 品質レベルは自動でメニューに表示

Safari はネイティブで再生。他のブラウザは hls.js を遅延読み込み: options.lib → ページ上のグローバル Hls → import('hls.js')。

4. 広告

import { createAdScheduler, breaksFromVmap } from '@bustplay/ads';

const scheduler = createAdScheduler(player, {
  ui,                                    // 「広告 1 / 2」カウンター、シーク禁止
  breaks: [
    { offset: 'pre',              tags: [TAG_A, TAG_B] }, // A が埋まらなければ B を試す
    { offset: { percent: 0.5 },   tags: [TAG_MID], pod: 2 },
    { offset: 'post',             tags: [TAG_POST] },
  ],
  consent: { gdpr: '1', gdprConsent: TCF_STRING },  // → マクロ {gdpr}/{gdpr_consent}
});

// コンテンツがちらつかないクリーンなプリロール:
await scheduler.runPreRoll();
void player.play();

// または VMAP からまるごと:
createAdScheduler(player, { ui, breaks: breaksFromVmap(vmapXml) });

5. 分析

import { createAnalytics } from '@bustplay/analytics';

createAnalytics(player, {
  endpoint: 'https://stats.example.com/v1/events',
  video: 'video-42',       // 自社の動画 id。PII ではない
  sampleRate: 1,           // 収集するセッションの割合
});

イベント(TTFF 付き view_start、四分位、リバッファ、エラー、QoE 付き session_end) はバッチで送信され、タブを閉じても sendBeacon で届きます。受信側は services/stats(README はそちら)。

6. React と Web Component

import { BustPlayer } from '@bustplay/react';
import '@bustplay/ui/ui.css';

<BustPlayer sources="https://cdn.example/video.mp4" title="動画"
  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="動画" muted></bust-play>

sources/src を変えるとプレーヤーが再生成されます。見た目(title、skin)は 生成時に適用。<bust-play> は Shadow DOM を使わないため、ページに ui.css が必要です。

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) });          // hls.js の EME
await attachDash(player, src, { protectionData: toDashProtectionData(drm) });
const off = enableFairPlay(player.media, drm.fairplay);                  // Safari ネイティブ HLS

Widevine/PlayReady は hls.js/dash.js が処理。ネイティブ経路の FairPlay は当方の EME 層が担当します(SPC/CKC は生バイト。サーバー差異は licenseBody / licenseResponse フックで)。実際の動作確認にはライセンスサーバーが必要です。

次のステップ