[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...

操作イメージは、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...

ここでは、レスポンシブデザイン用のオプション設定にしています。画面サイズがスマホ、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 や動画ファイルの保存先アーキテクチャにも触れることになってしまいました。

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

著者について
広野 祐司

AWS サーバーレスアーキテクチャを駆使して社内クラウド人材育成アプリとコンテンツづくりに勤しんでいます。React で SPA を書き始めたら快適すぎて、他の言語には戻れなくなりました。サーバーレス & React 仲間を増やしたいです。AWSは好きですが、それよりもAWSすげー!って気持ちの方が強いです。
取得資格:AWS 認定は12資格、ITサービスマネージャ、ITIL v3 Expert 等
2020 - 2023 Japan AWS Top Engineer 受賞
2022 - 2023 Japan AWS Ambassador 受賞
2023 当社初代フルスタックエンジニア認定
好きなAWSサービス:AWS Amplify / AWS AppSync / Amazon Cognito / AWS Step Functions / AWS CloudFormation

広野 祐司をフォローする
クラウドに強いによるエンジニアブログです。
SCSKは専門性と豊富な実績を活かしたクラウドサービス USiZE(ユーサイズ)を提供しています。
USiZEサービスサイトでは、お客様のDX推進をワンストップで支援するサービスの詳細や導入事例を紹介しています。
アプリケーション開発ソリューション
シェアする
タイトルとURLをコピーしました