概要
動画を公開ストレージに上げてそのリンク経由で動画視聴するのではなく、動画をプロジェクト内部に置いて手軽にそれを再生したい時ってあるのかなーと思います。
ローカルの動画を再生するにあたって、若干ハマってしまったので整理します。
環境
$ node -v
v16.13.1
$ npm -v
8.1.2
準備
今回はcreate-react-appでプロジェクトを作り、react-playerというライブラリを採用しました。インストールはyarnを使う場合は以下になります。
※「create-react-app」の@5.0.0のバージョン指定は2022年1月時点でエラー出る対策です。これは時期性のものと考えられるので、適宜変更ください。
※動画をインポートする部分のエッセンスはReact x Typescript x create-react-appの組み合わせであれば、videoタグでも同様と思います。
npx create-react-app@5.0.0 video_play_demo --template typescript
yarn add react-player
実装
ハマった部分は後述します。とりあえず結論だけ見たいという方は以下のサンプルを参照ください。
import ReactPlayer from "react-player"
// src直下にassetsフォルダを作り、そこに動画を置きました。
import VideoGuideLocalPath from './assets/video_guide.mp4'
export const VideoGuide: React.FC = () => {
return (
<ReactPlayer
url={VideoGuideLocalPath}
controls
/>
)
}
// mp4以外であれば、*.mp4の拡張子の部分を変更ください
declare module '*.mp4' {
const src: string;
export default src;
}
ハマったこと
ファイルパスを直接指定すると、何も表示されない
正直、原因はわかってません。。。わかる方コメント等で教えてください。
ただ解決方法としては、ファイルパスをimportする必要がありました。
// URL直接指定のみだと、何も表示されない。この1文は参考にしないで。
<ReactPlayer url={'./assets/video_guide.mp4'} />
importすると、ts2307エラーが発生する
// Cannot find module './assets/video_guide.mp4' or its corresponding type declarations.ts(2307)
import VideoGuideLocalPath from './assets/video_guide.mp4'
create-react-appの以下のissueによると、Typescript側のエラーらしいです(ほんまかいな)。
issueの通り、react-app-env.d.ts
に対してmoduleとしてmp4の拡張子を受け入れるようなコードを書くと解決しました。
/// <reference types="react-scripts" />
// mp4以外であれば、*.mp4の拡張子の部分を変更ください
declare module '*.mp4' {
const src: string;
export default src;
}
controlsオプションを指定しないと動画が再生されない
controlsのオプション指定しないと初期フレームの絵だけ表示されて、動画が再生されませんでした。
メディアボタン(ex.再生ボタン、一時指定ボタン)を表示するオプションを入れないと再生が開始できないので、要注意です。
※YouTubeのURLを直接指定だと、指定せずとも再生ボタンが表示されるので意外とハマりポイントではと思っています。
import ReactPlayer from "react-player"
import VideoGuideLocalPath from './assets/video_guide.mp4'
export const VideoGuide: React.FC = () => {
return (
// メディアボタン(ex.再生ボタン、一時指定ボタン)は表示されない
<ReactPlayer url={VideoGuideLocalPath} />
)
}
所感
ローカルの動画再生くらい、ライブラリ使えば大したことないやと思ってたのですが、意外とハマりどころ多くて、整理したくなりました。俺だったら、私だったらこうするぜとかあればフィードバックお待ちしてますー。