こんにちは。てぃろです。
今回はReactとTypeScriptでvideo.jsを使い動画を見ることができるWebクライアントを作りました。
これをつくったのは、恒例のNRIハッカソンに参加したのをきっかけにしています。
最終成果物の内容はまた別の記事で書くとして、ここではそのために使用する動画配信用のクライアントWebアプリケーションの原型として作ったものを公開します。
この記事を書こうと思った理由がもう一つあります。ざっと調べたところですが、React + TypeScript + video.jsで関数コンポーネントで書いてあるいい例がなかったからです。
おしいものでは、React + TypeScript + video.jsで書いてあるものでクラスで書かれていたのがありました。今回はそれを参考にして関数の形で書き直しました。
ソースコードはコチラです。Create React Appで作っているのでクローンしてもらったらそのまま動くと思います。
主に書いたソースは以下の2つです。
動画再生コンポーネントの本体
まずこちらがvideo.jsを使ったプレイヤーのコンポーネントの本体です。props
でオプションを渡すことによってその挙動を変えられるように工夫してあります。
import React, { useState, useEffect } from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';
function Player (props : videojs.PlayerOptions) {
const [player, setPlayer] = useState<videojs.Player>();
const videoNodeId: string = 'videojs-player';
useEffect(() => {
setPlayer(videojs(videoNodeId, props).ready(function() {
console.log('Player is Ready', this)
}));
}, [props]);
useEffect(() => {
return function cleanup () {
if (player) {
player.dispose();
}
};
});
return (
<div className="c-player">
<div className="c-player__screen" data-vjs-player="true">
<video
id={videoNodeId}
className="video-js"
/>
</div>
</div>
);
}
export default React.memo(Player);
動画再生コンポーネントの利用
次にこのコンポーネントを使っている部分です。こちらでは単純にvideoJsOptions
でオプションを渡すようにしているだけです。videoJsOptions
では様々なオプションを指定できるのでソースを参照するなどして設定してみるといいでしょう。とりあえずサンプルの動画で音が出るとびっくりするのでミュートにしてあります。
import React from 'react';
import './App.css';
import videojs from 'video.js';
import Player from './components/Player'
const videoJsOptions: videojs.PlayerOptions = {
controls: true,
muted: true,
sources: [{
src: 'http://vjs.zencdn.net/v/oceans.mp4',
type: 'video/mp4'
}]
};
function App() {
return (
<div className="App">
<header className="App-header">
<Player {...videoJsOptions}/>
</header>
</div>
);
}
export default App;
最後に
今回は簡単なReactのサンプルを紹介しました。
こうした小さいものでも公開するとなると、恥ずかしくないようにいろいろ細かいことも整理しようとするのでいい勉強になるものです。
実は本番はAmazon IVSでライブストリーミングをできるようにするのが目的なのです。次はこれをベースにしてIVSを使用できるようにカスタマイズしていくつもりです。
また作ることができたら、コツなど含めて紹介しようと思います。