[React] react-player を使ってストリーミング動画ビューア画面をつくる

こんにちは、広野です。

React アプリ内に、ストリーミング用動画ファイルを再生させる動画ビューア画面の作成方法を紹介します。
react-player というモジュールを使用します。

GitHub - cookpete/react-player: A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion
A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion - GitHub...

操作イメージは、YouTube のようなものです。

react-player を採用したきっかけ

MP4 等のオリジナル動画ファイルを YouTube に公開するのではなく、認証を受けたユーザにのみデバイス問わず視聴させたかった、というのが動画ビューア画面を開発したきっかけです。

HTML 5 には動画埋込機能を持つ <video> タグがありますが、デバイス、ブラウザ、ストリーミング動画ファイル形式の組み合わせによっては再生できない制約があります。あらゆるユーザ環境で再生できる動画ビューアとして見つけたのが react-player でした。

アーキテクチャ

オリジナル動画ファイルは AWS Elemental MediaConvert というサービスで HLS 形式のストリーミング動画ファイルに変換し、Amazon S3 バケットに配置、Amazon CloudFront 経由で配信します。

AWS Elemental MediaConvert(動画を処理してオンデマンドコンテンツを準備)| AWS
AWS Elemental MediaConvert はファイルベースの動画処理サービスで、動画プロバイダはコンテンツを放送とマルチスクリーン配信のためにあらゆる規模でコード変換できます。

開発した動画ビューア画面は、Amazon CloudFront 経由でストリーミング動画ファイルにアクセスし、画面上で再生してくれます。

React 内では動画ビューア画面は共通コンポーネントとし、見たい動画のファイル名、タイトル等をリンク元からパラメータとして渡して再生させるという設計になっています。

動画ビューア画面周りのアーキテクチャ図は以下のような感じです。

動画ビューア画面サンプルコード

動画ビューア画面へのリンク

動画ビューア画面に動画のパラメータを渡す役割です。
React-router の <Link> タグで動画ビューア画面 (/videoviewer) へリンクされています。動画単位で <Link> に設定するパラメータが変わります。state={{ }} の部分でパラメータを渡します。今気が付きましたが、これは React-router の Link によるリンク先コンポーネントへのパラメータ渡しテクニックで、めっちゃ便利です。

import React from 'react';
import { Link } from 'react-router-dom';

//コードはだいぶ簡略化しています。

const SubmenuVideo = () => {
  return (
    <Link
      to="/videoviewer"
      state={{
        "videoid": "Step 3",
        "title": "ワンポイントアドバイス",
        "duration": "4:22",
        "videofile": "advice"
      }}
      className="button"
    >
      Step 3
      <br />
      ワンポイントアドバイス
      <br />
      4:22
    </Link>
  );
};

export default SubmenuVideo;

動画ビューア画面

react-player を埋め込むコードは基本公式ドキュメント通りです。

GitHub - cookpete/react-player: A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion
A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion - GitHub...

ここでは、レスポンシブデザイン用のオプション設定にしています。画面サイズがスマホ、PC 問わずユーザの画面サイズに合わせて最適なビューアサイズになってくれます。あらかじめ、以下の CSS を用意しておく必要があります。

  • CSS
.player-wrapper {
  position: relative;
  padding-top: 56.25% /* Player ratio: 100 / (1280 / 720) */
}
.react-player {
  position: absolute;
  top: 0;
  left: 0;
}
  • VideoViewer.js
    コードはだいぶ簡略化しています。主に画面デザインに関するコードを割愛しています。

<Link> から渡された、動画に関するパラメータを受け取ります。React-router の useLocation を使用します。
受け取ったパラメータを、react-player のオプションや、タイトル表示用の見出しに埋め込んでいます。

import React from 'react';
import { useLocation } from 'react-router-dom';
import ReactPlayer from 'react-player';

const VideoViewer = () => {
  //パラメータ(ビデオメタデータ)を受け取る
  const location = useLocation();
  const videoid = location.state.videoid;
  const title = location.state.title;
  const duration = location.state.duration;
  const videofile = location.state.videofile;
  const imgUrl = process.env.REACT_APP_IMG_URL; //環境変数から動画保存先URLの途中までを取得

  //ビデオ再生ログ取得関数
  const putVideoPlayLog = () => {
    //内容は省略
  };

  //動画ビューア画面を表示
  return(
    <React.Fragment>
      <h3>{videoid} {title} ({duration})</h3>
      <div className="player-wrapper">
        <ReactPlayer
          url={imgUrl + "/" + videofile + ".m3u8"}
          className="react-player"
          controls={true}
          width="100%"
          height="100%"
          playing={false}
          onStart={() => putVideoPlayLog()}
        />
      </div>
    </React.Fragment>
  );
};

export default VideoViewer;

react-player は、動画の操作に対してコールバック関数を呼び出すことができます。

例えば上記サンプルコードにあるように、onStart= という prop を指定することで、ユーザが「再生」をしたときに任意の関数 putVideoPlayLog を実行しています。この関数は、名前の通り再生ログを送信する関数です。具体的なコードは割愛していますが、再生数カウントや再生ユーザ情報を収集するために Amazon Kinesis Data Firehose にログデータを送っています。

他にも react-player に用意された prop を記述することで、いろいろなアクションをかけることができそうです。

まとめ

いかがでしたでしょうか?

react-player を使うときのコードの書き方を中心に紹介しようと思いましたが、書いてみると React-router や動画ファイルの保存先アーキテクチャにも触れることになってしまいました。

本記事が皆様のお役に立てれば幸いです。

タイトルとURLをコピーしました