はじめに
Webサイトに動画を埋め込むとき、まずは HTML5 の <video> タグを使いますよね。ところが実際にプロダクトへ組み込もうとすると、すぐに壁にぶつかります。「ブラウザごとにコントロールUIの見た目がバラバラ」「HLSでのストリーミング配信がChromeで再生できない」「再生速度の変更や画質切り替えのUIがない」……。
こうした悩みを一手に引き受けてくれるのが、今回紹介する Video.js です。15年以上にわたってWeb動画プレイヤーの定番であり続け、GitHubスターは約4万、CDN経由では月間数十億ものユーザーに動画を届けている、まさに「事実上の標準」と呼べるライブラリです。
Video.jsとは
Video.jsは、HTML5の <video> タグをラップして、どのブラウザでも統一されたUIと機能を提供するオープンソースの動画プレイヤーライブラリです。単なる見た目の統一にとどまらず、HLSやDASHといったストリーミング形式の再生、字幕、プラグインによる拡張まで、動画再生に必要なものが一通り揃っています。
主な特徴
- 主要フォーマットを網羅 - MP4などの通常のファイルに加え、HLS・DASHといったアダプティブストリーミング形式を標準サポート。ライブ配信にも対応します
- どこでも同じ体験 - デスクトップ、モバイル、タブレット、スマートTVまで、統一されたUIと操作感を提供します
- プラグインエコシステム - 数百のプラグインが公開されており、広告挿入、アナリティクス、サムネイルプレビューなどを後付けできます
- アクセシビリティ重視 - キーボード操作(スペースで再生/停止、
fで全画面、mでミュートなど)やスクリーンリーダー対応が組み込まれています - CSSで自由にスキン変更 - コンポーネントベースの設計で、UIの見た目も構成も細かくカスタマイズできます
執筆時点の安定版は v8.23.9 です。また、次世代版のv10がベータとして開発中で、公式Reactパッケージ(@videojs/react)やモダンなUIデザインを引っさげた大幅刷新が進んでいます。本記事では安定版のv8をベースに解説します。
インストール
CDNで手軽に始める
まずは1番手軽なCDN読み込みです。HTMLに2行追加するだけで使えます。
<link href="https://vjs.zencdn.net/8.23.9/video-js.min.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/8.23.9/video.min.js"></script>
npmでプロジェクトに組み込む
ビルド環境がある場合はnpmでインストールします。
# npm
npm install video.js
# yarn
yarn add video.js
# pnpm
pnpm add video.js
基本的な使い方
最小構成はとてもシンプルです。video-js クラスを付けた <video> タグを置き、data-setup 属性を指定するだけで自動的にプレイヤー化されます。
<!DOCTYPE html>
<html>
<head>
<link href="https://vjs.zencdn.net/8.23.9/video-js.min.css" rel="stylesheet" />
</head>
<body>
<video
id="my-player"
class="video-js"
controls
preload="auto"
width="640"
height="360"
poster="poster.jpg"
data-setup="{}"
>
<source src="sample.mp4" type="video/mp4" />
<p class="vjs-no-js">
動画を再生するにはJavaScriptを有効にしてください。
</p>
</video>
<script src="https://vjs.zencdn.net/8.23.9/video.min.js"></script>
</body>
</html>
JavaScriptから初期化・制御したい場合は videojs() 関数を使います。
import videojs from 'video.js';
import 'video.js/dist/video-js.css';
const player = videojs('my-player', {
controls: true,
autoplay: false,
fluid: true, // コンテナ幅に合わせてレスポンシブに
playbackRates: [0.5, 1, 1.5, 2], // 再生速度の選択肢
});
player.ready(() => {
videojs.log('プレイヤーの準備が完了しました');
});
// イベントの購読
player.on('play', () => console.log('再生開始'));
player.on('ended', () => console.log('再生終了'));
playbackRates を1行足すだけで再生速度切り替えUIが付く手軽さは、素の <video> タグでは味わえない体験です。
実践的なユースケース
HLSストリーミングを再生する
Video.jsの真価が発揮されるのがストリーミング再生です。HLS(HTTP Live Streaming)はSafari以外のブラウザではネイティブ再生できませんが、Video.jsは内蔵の再生エンジン(http-streaming)によって、追加設定なしで全ブラウザでのHLS再生を実現します。
const player = videojs('my-player', { fluid: true });
// .m3u8 のプレイリストを指定するだけ
player.src({
src: 'https://example.com/stream/playlist.m3u8',
type: 'application/x-mpegURL',
});
視聴者の回線速度に応じて画質を自動で切り替えるアダプティブビットレート再生も、これだけで動きます。VODサービスやライブ配信サイトの土台として十分な機能です。
字幕を追加する
WebVTT形式の字幕ファイルを <track> タグで指定すれば、字幕切り替えメニューが自動で表示されます。
<video id="my-player" class="video-js" controls data-setup="{}">
<source src="sample.mp4" type="video/mp4" />
<track
kind="captions"
src="captions-ja.vtt"
srclang="ja"
label="日本語"
default
/>
<track kind="captions" src="captions-en.vtt" srclang="en" label="English" />
</video>
Reactと組み合わせる
Reactで使う場合は、コンポーネントのライフサイクルに合わせてプレイヤーを生成・破棄するのがポイントです。公式ドキュメント推奨のパターンを紹介します。
import { useEffect, useRef } from 'react';
import videojs from 'video.js';
import type Player from 'video.js/dist/types/player';
import 'video.js/dist/video-js.css';
type VideoPlayerProps = {
options: typeof videojs.options;
onReady?: (player: Player) => void;
};
export function VideoPlayer({ options, onReady }: VideoPlayerProps) {
const videoRef = useRef<HTMLDivElement>(null);
const playerRef = useRef<Player | null>(null);
useEffect(() => {
if (!playerRef.current && videoRef.current) {
// React管理下のDOMを汚さないよう、video要素を動的に生成
const videoElement = document.createElement('video-js');
videoElement.classList.add('vjs-big-play-centered');
videoRef.current.appendChild(videoElement);
playerRef.current = videojs(videoElement, options, function () {
onReady?.(this);
});
}
}, [options, onReady]);
// アンマウント時にプレイヤーを破棄
useEffect(() => {
return () => {
if (playerRef.current && !playerRef.current.isDisposed()) {
playerRef.current.dispose();
playerRef.current = null;
}
};
}, []);
return <div data-vjs-player ref={videoRef} />;
}
使う側はこうなります。
<VideoPlayer
options={{
controls: true,
fluid: true,
sources: [{ src: '/videos/intro.mp4', type: 'video/mp4' }],
}}
onReady={(player) => {
player.on('ended', () => console.log('視聴完了'));
}}
/>
なお、開発中のv10では公式Reactパッケージ @videojs/react が提供され、こうしたラッパーを自作せずに宣言的に書けるようになる予定です。今後が楽しみなところです。
プラグインで機能を拡張する
Video.jsのプラグインは videojs.registerPlugin() で登録し、初期化オプションで有効化します。自作も簡単です。
import videojs from 'video.js';
// 視聴時間を記録するシンプルなプラグイン
const Plugin = videojs.getPlugin('plugin');
class WatchTimeTracker extends Plugin {
constructor(player, options) {
super(player, options);
let watchedSeconds = 0;
let lastTime = 0;
player.on('timeupdate', () => {
const current = player.currentTime();
// シークではなく連続再生のときだけ加算
if (current - lastTime > 0 && current - lastTime < 1) {
watchedSeconds += current - lastTime;
}
lastTime = current;
});
player.on('ended', () => {
videojs.log(`実視聴時間: ${Math.round(watchedSeconds)}秒`);
});
}
}
videojs.registerPlugin('watchTimeTracker', WatchTimeTracker);
// 有効化
const player = videojs('my-player', {
plugins: {
watchTimeTracker: {},
},
});
コミュニティ製プラグインも豊富で、広告挿入の videojs-contrib-ads、シークバーのサムネイルプレビュー、YouTubeソース対応の videojs-youtube など、「欲しい」と思った機能はたいてい見つかります。
まとめ
Video.jsについて、基本から実践的な使い方まで紹介しました。
- HTML5の
<video>タグをラップし、全ブラウザで統一されたUIと操作感を提供する定番ライブラリです - HLS・DASHのストリーミング再生が追加ライブラリなしで動き、VODやライブ配信の土台になります
- 字幕、再生速度切り替え、キーボード操作などの実用機能が標準装備されています
- プラグインとコンポーネントベース設計により、細かなカスタマイズや機能拡張が可能です
「とりあえず動画を埋め込む」だけなら <video> タグで十分ですが、プロダクトとして動画体験を作り込むなら、Video.jsは今なお最有力の選択肢です。15年の実績が積み上げた安定感は伊達ではありません。まずはCDN版をHTMLに2行追加して、その完成度を体感してみてください。
