はじめに
こんにちは!! EventHubのWebエンジニアの須田です!
今回、React で新しい動画プレイヤーを実装するための技術調査をしたので、その内容についてと、 React で動画プレイヤーを作成するなら react-player が簡単に実装できて、おすすめなのでご紹介していきます🐱
React 動画ライブラリ比較結果
2024年9月時点で、React の動画プレイヤー・ライブラリで調べて出てきたものを比較してみました👀
候補は「React 動画ライブラリ」で調べてでてきた次の 5 つです 🙏
- react-player
- mux-player-react
- react-video-js-player
- video-react
- video.js
結論:react-player がよさそう
判断基準は、次のとおりです👀✨
- 要件を満たす機能を備えていること。
- React 対応のライブラリであること。
- 正式リリースがされており、安定版であること。
- 定期的にメンテナンスがされていること。
- npm trends や GitHub Star などを参照して、使用率や人気がある状態であることが望ましい。
調べた感じ「React ✖️ 動画ライブラリ」の選択肢が、あまりない状況に見えました👀
react-player とは?
react-player は、React アプリケーションで動画や音声などのメディアを再生するためのオープンソースの React コンポーネントです。
YouTube、Vimeo、Mux、Twitch、SoundCloud、Facebook など、さまざまなプラットフォームからのコンテンツをサポートしています。
また、シンプルな API と豊富なプロパティを提供しており、メディアプレーヤーのカスタマイズや制御が簡単です 💪🥺🔥
npm や GitHub は、次のとおりです 👀✨
npm: react-player
GitHub: react-player
公式 Doc がない代わりに、GitHub の README.md にて設定できる Option に関する説明が細かく掲載されています👀✨
React Player デモ環境
react-player のデモで、いろいろな動画タイプや、パラメーターを試すことができます 🙏
ちなみに、react-player
のメンテナンスは、Mux チームが引き継ぐらしいです 🙌
(Mux は、アメリカの同名のソフトウェア会社が運営する、API ベースの動画配信サービスです)
参照:https://www.npmjs.com/package/react-player#-the-future-of-reactplayer
react-player で動画プレイヤーを作成する
それでは、実際に react-player で動画プレイヤーを作成していきます。
react-player をインストール
npm install react-player yarn add react-player
シンプルな Video Player を実装してみる
試しに、シンプルな Video Player を実装してみると、 これぐらいのCode量で、簡単な Video Playerが実装できます👀✨
import ReactPlayer from "react-player"; interface SimpleVideoPlayerProps { videoUrl: string; isLoop?: boolean; isAutoPlay?: boolean; isControls?: boolean; } export const SimpleVideoPlayer = ({ videoUrl, isLoop, isAutoPlay, isControls, }: SimpleVideoPlayerProps) => { return ( <ReactPlayer url={videoUrl} width={"100%"} height={"100%"} playing={isLoop} // 自動再生 loop={isAutoPlay} // ループ再生 controls={isControls} // 動画の操作が可能かどうか /> ); };
React Player の Option について
react-player の README には、渡せる Props や Callback 系などの設定値の一覧がまとまっているので、これを見れば何ができるのかは、把握できます🙆♂️
また、Youtube, Vimeo, Mux などの各動画配信サービスの設定プロパティにも対応しているのも、Goodなポイントです🙌
Props
主な Props は、次のとおりです👀✨
Prop | Description | Default |
---|---|---|
url |
再生するビデオまたは曲のURL。array または MediaStream オブジェクトを指定可能。 |
|
playing |
true または false を設定してメディアの再生や一時停止を行う。 |
false |
loop |
true または false を設定してメディアをループ再生する。 |
false |
controls |
ネイティブプレーヤーコントロールを表示するかどうかを設定。Vimeoビデオの場合、コントロールを非表示にするにはビデオ所有者が有効にする必要がある。 | false |
light |
true に設定するとビデオのサムネイルのみが表示され、クリックでフルプレーヤーが読み込まれる。プレビュー画像をオーバーライドするには画像URLを渡す。 |
false |
volume |
プレーヤーの音量を 0 から 1 まで設定。null の場合、全プレーヤーでデフォルトの音量が使用される。 |
null |
muted |
プレーヤーをミュートにする。volume が設定されている場合のみ機能。 |
false |
playbackRate |
プレーヤーの再生速度を設定。YouTube、Wistia、およびファイルパスでのみサポートされている。 | 1 |
width |
プレーヤーの幅を設定。 | 640px |
height |
プレーヤーの高さを設定。 | 360px |
style |
ルート要素に inline styles を追加。 |
{} |
progressInterval |
onProgress コールバックの間隔をミリ秒単位で設定。 |
1000 |
playsinline |
対応している場合に playsinline 属性を適用。 |
false |
pip |
true または false を設定してピクチャー・イン・ピクチャーモードを有効化または無効化する。ファイルURLで再生している場合のみ、特定のブラウザでサポートされている。 |
false |
stopOnUnmount |
pip を使用している場合、stopOnUnmount={false} を使用してReactPlayerがアンマウントされてもピクチャー・イン・ピクチャーモードで再生を続けるようにする。 |
true |
fallback |
遅延読み込みを使用している場合に使用するフォールバック要素またはコンポーネント。 | null |
wrapper |
コンテナ要素として使用する要素またはコンポーネント。 | div |
playIcon |
ライトモードで再生アイコンとして使用する要素またはコンポーネント。 | |
previewTabIndex |
ライトモードで使用するタブインデックスを設定。 | 0 |
config |
各プレーヤーの設定を上書きするオプションを指定。config prop を参照。 |
参照・引用: https://github.com/CookPete/react-player?tab=readme-ov-file#props
Callback Props
主な Callback Props は、次のとおりです👀✨
Prop | Description |
---|---|
onReady |
メディアがロードされ再生の準備が完了した際に呼び出される。playing が true に設定されている場合、メディアは即座に再生される。 |
onStart |
メディアの再生が開始されたときに呼び出される。 |
onPlay |
メディアが再生または一時停止後やバッファリング後に再開されたときに呼び出される。 |
onProgress |
played と loaded の進捗状況を割合で提供するコールバック。秒単位で playedSeconds と loadedSeconds も提供される。例: { played: 0.12, playedSeconds: 11.3, loaded: 0.34, loadedSeconds: 16.7 } |
onDuration |
メディアの長さ(秒単位)を含むコールバック。 |
onPause |
メディアが一時停止されたときに呼び出される。 |
onBuffer |
メディアがバッファリングを開始したときに呼び出される。 |
onBufferEnd |
メディアのバッファリングが完了したときに呼び出される。ファイル、YouTube、Facebookで動作する。 |
onSeek |
seconds パラメータでメディアがシークされたときに呼び出される。 |
onPlaybackRateChange |
プレーヤーの再生速度が変更されたときに呼び出される。YouTube、Vimeo、Wistia、およびファイルパスでサポートされている。 |
onPlaybackQualityChange |
プレーヤーの再生品質が変更されたときに呼び出される。YouTubeでのみサポートされている(有効にした場合)。 |
onEnded |
メディアの再生が終了したときに呼び出される。loop が true に設定されている場合は発火しない。 |
onError |
メディアの再生中にエラーが発生したときに呼び出される。 |
onClickPreview |
ユーザーが light モードのプレビューをクリックしたときに呼び出される。 |
onEnablePIP |
ピクチャー・イン・ピクチャーモードが有効になったときに呼び出される。 |
参照・引用: https://github.com/CookPete/react-player?tab=readme-ov-file#callback-props
Youtube Video Player を実装する
続いて、Callback Props を活用した Youtube Video Player を実装してみます。
Callback Props の挙動を確認するために、再生中かどうかを確認するようなFlag判定を持たせています。
また、onProgress
に関しては、動画の再生状況のデータの内容を確認できるようにlog出力を仕込んでみます。
実際に実装した画面は、次のような感じです👀✨
import { Fragment, useState } from "react"; import ReactPlayer from "react-player"; import type { OnProgressProps } from "react-player/base"; interface YoutubeVideoPlayerProps { videoKey: string; // youtube video key autoPlay?: boolean; // 自動再生フラグ originUrl?: string; // ルートURL } // TODO: 実際に実装する際は Logic は Custom Hook に切り出す export const YoutubeVideoPlayer = ({ videoKey, autoPlay, originUrl, }: YoutubeVideoPlayerProps) => { // 再生中フラグ const [isPlaying, setIsPlaying] = useState(false); const handlePlayOn = () => { setIsPlaying(true); }; const handlePlayOff = () => { setIsPlaying(false); }; // 再生中に定期実行されるコールバック const handleProgress = (progress: OnProgressProps) => { console.log("onProgress Called", progress); const { played, // 動画の再生済み部分を全体の割合で示した値 (0〜1) playedSeconds, // 動画の再生済み時間を秒単位で示した値 (秒) loaded, // 動画の読み込み(バッファリング)済み部分を全体の割合で示した値 (0〜1) loadedSeconds, // 動画の読み込み済み時間を秒単位で示した値 (秒) } = progress; // 再生済みのパーセンテージを表示 console.log(`再生位置(%): ${(played * 100).toFixed(2)}%`); // 再生済みの時間を表示 console.log(`再生位置(秒): ${playedSeconds.toFixed(2)}秒`); // 読み込み済みのパーセンテージを表示 console.log(`読み込み済み(%): ${(loaded * 100).toFixed(2)}%`); // 読み込み済みの時間を表示 console.log(`読み込み時間(秒): ${loadedSeconds.toFixed(2)}秒`); }; return ( <Fragment> <ReactPlayer url={`https://www.youtube.com/watch?v=${videoKey}`} width={"100%"} height={"100%"} playing={autoPlay} // 自動再生 loop={false} // ループ再生 controls={true} // 動画の操作が可能かどうか onStart={handlePlayOn} // 再生開始時 Callback Func onPlay={handlePlayOn} // 再開する時 Callback Func onPause={handlePlayOff} // 一時停止時 Callback Func onEnded={handlePlayOff} // 再生が終了した時 Callback Func progressInterval={1000} // onProgressの実行間隔(秒) Default: 1000(1秒) onProgress={handleProgress} // 再生中に定期実行される Callback Func // 各プレーヤーごとの独自設定 config={{ /** * YouTubeのプレーヤーのパラメータ設定 Docs * https://developers.google.com/youtube/player_parameters?playerVersion=HTML5&hl=ja */ youtube: { playerVars: { autoplay: autoPlay ? 1 : 0, // 自動再生 playsinline: 1, // iOS 上の HTML5 プレーヤーで動画をインライン再生する origin: originUrl, // ルートURL指定 rel: 0, // パラメータの値が 0 に設定されている場合、関連動画は表示されません。 }, }, }} /> <p className="flex items-center justify-center mt-5 text-lg"> 再生中: {isPlaying ? "Yes" : "No"} </p> </Fragment> ); };
さいごに
今回は、React で新しい動画プレイヤーを実装するための技術調査として、react-playerを使って動画プレイヤーを試しに実装してみました。
react-player は、動画プレイヤーを簡単に実装できオプションも豊富なので、おすすめです。
もし、これをみてEventHubに興味をお持ちいただけたら、ぜひ以下のリンクから詳細をご覧ください!