- 投稿日:2021-03-05T20:51:47+09:00
コンポネートの表示の仕方「reactメモ」
・コンポネートとは、reactの画面に表示される「部品」のことである。
・JSXのアタイの中でタグとして記述。
・<コンポネート名 /> の形。
⚠︎コンポネート名は大文字スタートreact_app<body> <h1>React</h1> <div id="root">wait.......</div> <script type="text/babel"> let dom = document.querySelector('#root'); const msg = { fontSize: "20px", fontWeight:"bold", padding: "10px", color:"white", backgroundColor:"darkblue", }; // ここから関数コンポーネート function Welcome(props){ return <p style={msg}>Hello React!!</p>; } // 表示するコンポーネート let el = ( <div> <Welcome/> </div> ); ReactDOM.render(el, dom); </script> </body>・計算するコンポネート
let dom = document.querySelector('#root'); const msg = { fontSize: "20px", padding: "10px", border:"double 5px magenta" }; const msg2 ={ fontSize: "16px", fontWeight: "bold", padding: "10px", backgroundColor:"cyan" }; // ここから関数コンポーネート function Calc(props){ let total = 0; for(let i =1;i <= props.number;i++){ total += i; } return <p style={msg}>1から, {props.number}までの 合計は、「{total}」です。</p>; }; // 表示するコンポーネート let el = ( <div> <Calc number="100" /> <Calc number="200" /> <Calc number="300" /> </div> ); ReactDOM.render(el, dom);
- 投稿日:2021-03-05T12:55:58+09:00
Next.js+TailwindCSS製 個人Blog構築の流れ -第1回-
※本記事は、私が作成した こちらのブログ ①〜④の内容をまとめて上げたものです。
語弊を恐れずなるべく平易に書こうとしておりますので、細かなニュアンスの違い等はご容赦頂ければと思います。誤植や記述内容の間違い等ございましたら遠慮なくコメント頂ければ幸いです。|開発動機
Reactの基礎的な学習を終え、何か1つサンプル的なアプリを作りたいなと考えておりまして...
ふと、「情報発信するための自身のBlog」を持っていないなと思い、せっかくなら WordPress ではなく、自作の Blog を作ってみようと思い立ち開発に至りました。
ただ、サクッと作ってしまいたいという気持ちもあったので、ReactのフレームワークであるNext.js
を採用することにしました!
また、CSSが超絶苦手な私はTailwindCSS
さんのお力を借りる事にいたしました^^;【技術スタック】
・ Next.js v10.0.7 ・ React v17.0.1 ・ TailwindCSS v2.0.3記事につきましては
Markdown
ファイルで作成したものを読み込み、レンダリングするようにしました。
読み込み・変換 用のライブラリとして以下のものを活用しました。・ raw-loader v4.0.2 ・ gray-matter v4.0.2 ・ react-markdown v5.0.3 ・ react-syntax-highlighter v15.4.3・
raw-loader
はファイルを文字列としてインポートできるwebpackのローダーです。
・gray-matter
は文字列またはファイルからFrontMatterを読み取り解析するものです。今回はMarkdownファイルの冒頭に以下のように書き込んでおくとJSONデータとして吐き出せるようにしました。--- title: 'ここにブログのタイトルを書きます' author: 'ここには作者名を書きます' date: '20XX年XX月XX日' excerpt: 'ここに記事の概要を書き込んでおくとトップページで表示できます' ---・
react-markdown
はローダーで読み取ったMarkdownファイルのテキストデータをHTMLに変換するためのライブラリです。
・react-syntax-highlighter
はコードブロックのシンタックスハイライトを付けてくれるライブラリです。以上がこのブログで使っているライブラリです。
【デプロイどうしようか】
今回構築したブログはDBを持たず、
/posts
ディレクトリにMarkdownファイルを設置してビルドするだけで完了という構成にしています。
つまり、静的なサイトを生成している(SSG)という感じです。
サーバー自体はレンタルサーバーなどでもよかったのですが、せっかくなら色んな事にチャレンジしたいと思い、Netlify
のようなホスティングサービスを利用し、加え、GitHubとの連携をしてPUSH時に自動ビルドが走るようにしてみようと考えました!なんちゃってCI/CD環境の構築を目指してみたわけです^^;|環境構築
それでは、早速
Next.js
のインストールから行なっていきたいと思います。
とその前に、Next.js アプリを作成するためにはNode.js
をインストールしておく必要があります。公式ドキュメントによりますと、Node.js 10.13 以上のバージョンがインストールされていることが条件となります。この記事を進められる前に、Node.js のインストール作業をお願い致します。アプリ作成
では、早速アプリの作成をしていきましょう!
ターミナルを開いて、アプリを作成したいディレクトリに移動してください。移動先で以下のコマンドを入力してください。npx create-next-app [project-name]
[project-name]
の部分はご自身でお好きな名前を付けてください![]は不要です。
以下のような文言が出ていれば完了です!Success! Created sample at /保存先/[project-name] Inside that directory, you can run several commands: yarn dev Starts the development server. yarn build Builds the app for production. yarn start Runs the built app in production mode. We suggest that you begin by typing: cd [project-name] yarn dev一度
Next.js
のTOP画面を拝んでおきましょう!cd [project-name] // アプリのディレクトリに移動して npm run dev // または yarn dev でもいいですすると、コンパイルが始まって、しばらく経つと
compiled successfully
という文字が表示されると思いますので、ブラウザからhttp://localhost:3000
にアクセスすると以下のようなTOPページが確認できるかと思います!
やりましたね! ^^v
次にTailwindCSS
のセットアップに移りましょう!
ターミナルにて以下のコマンドを入力
(※以下のコマンドはプロジェクトディレクトリ内で入力してください)
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest次にコンフィグファイルを作成していきます。
以下のコマンドを入力するとtailwind.config.js
とpostcss.config.js
が自動的に生成されます。npx tailwindcss init -p生成された
tailwind.config.js
ファイルを編集していきましょう。生成時はpurge
の値が空っぽになっているかと思いますので、以下のように追記します。tailwind.config.jsmodule.exports = { purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'], darkMode: false, // or 'media' or 'class' theme: { extend: {}, }, variants: { extend: {}, }, plugins: [], }続いて
CSS
ファイルにTailwindCSSの設定を読み込むように変更します。
/styles
ディレクトリ内にあるglobals.css
を開き、中身を全て消去し、以下の3行に書き換えてください。globals.css@tailwind base; @tailwind components; @tailwind utilities;以上で TailwindCSS の設定は完了です! ちなみに、このCSSファイルは
pages/_app.js
の中でインポートしています。
もし、他のCSSファイルを作成した時は、適宜読み込みを行なってください!
ということで、一応確認のためと Next.js の動きの確認のためにHello World!!
を表示させてみましょう!
pages/index.js
ファイルを開いてください。以下のようになっているかと思います。index.jsimport Head from 'next/head' import styles from '../styles/Home.module.css' export default function Home() { return ( <div className={styles.container}> <Head> ... 中略 ... </footer> </div> ) }このファイルのインポート部分の削除と
Home()
ファンクションの return の中の<Head>
タグから</footer>
を全て消去し、以下のように書き換えてください。index.jsexport default function Home() { return ( <div className="text-red-400"> Hello World! </div> ) }変更後、ターミナルで
npm run dev
を実行してください。※コマンドを実行する場所はアプリのあるディレクトリ内でです。
実行後にhttp://localhost:3000
にアクセスすると...
赤字
で Hello World!! が表示されましたね ^^v
React で class を付与させるには class="hoge" と書くのではなく、className="hoge"
と書く必要があります。
今回の divタグ内のtext-red-400
は TailwindCSS のクラスで、文字色を赤の400にするというものです。色見本については TailwindCSS公式ドキュメント で確認してみてください!また、他のどのようなクラスがあるのかも見てみてください〜続いて、簡単にルーティングについても確認しておきたいと思います。
npm run dev
は止めずに、そのままで進めていきましょう!止めた方は、再度実行しておいてください!
それでは、まずpages
ディレクトリ内にabout.js
ファイルを作成してください。そして、以下のように書き加えてください。about.jsconst About = () => { return ( <div className="text-center mt-10"> about </div> ) } export default About変更を保存後、
http://localhost:3000/about
にアクセスすると about という文字列が表示されているかと思います。
Next.js は /pages ディレクトリに js のエクスポートファイルを設置すると、ビルド時にファイル名をURLとしてルーティングに組み込んでくれます^^(便利!)|Component分割とレイアウトの作成
コンポーネントの分割の思想については、様々な考え方がございますので、この記事内では深く言及することは避けます。
かなりフランクに捉えて頂いて、分割するにはどうすればいいかという部分のみ掴んでいただければ幸いです。では、早速コーディングをしていきましょう!と、その前に今回使うことのない、不要なファイル達を削除しておきたいと思います。
削除後に残るディレクトリやファイルは以下のようになりますので、それ以外のファイルは削除してしまいましょう!
一応具体的に削除するファイルやディレクトリを挙げておくと、public/vercel.svg
、styles/Home.module.css
とapi
ディレクトリは中のhello.js
ごと削除してしまってください。.next/ node_modules/ pages/ _app.js about.js index.js public/ favicon.ico styles/ global.css .gitignore package-lock.json package.json postcss.config.js README.md tailwind.config.js yarn.lockそれでは、ここからファイルやディレクトリを作成していきます!
●簡易ファイルローディングの体験
コンポーネント分割の前に、JSONファイルを読み込んで画面にデータを表示するということをしてみましょう。
tailwind.config.js と同じ階層にsiteconfig.json
ファイルを作成し、以下のような記述をします。siteconfig.json{ "title": "ブログのタイトルを記述", "description": "ブログの概要をここに記述" }記述を終えたら次に
index.js
ファイルを編集していきます。
先ほど作成した siteconfig.json のデータをインポートしていきます。以下のように中身を書き換えてしまってください。index.jsconst Index = ({ title, description }) => { return ( <div className="text-center mt-10"> site_title: {title} <br /> description: {description} </div> ) } export default Index export async function getStaticProps() { const configData = await import(`../siteconfig.json`) return { props: { title: configData.default.title, description: configData.default.description, }, } }
上の画像ような形でJSONファイル内に書かれた内容を表示することができたでしょうか?
今回記述した内容の中でgetStaticProps()
について簡単に
解説しておきます。
getStaticProps()はNext.jsが用意しているファンクションで、そのファンクション内で返却したデータをビルド時にページコンポーネントに引き渡す役割を担ってくれています。今回のソースコード内でのことをザックリと捉えると、props というものの中にtitle
とdescription
という変数で siteconfig.json のデータを取得・格納し、Indexページのコンポーネント内に引き渡すということを行なっています。それを経て画面に表示されているということなんですね^^
getStaticProps()
について、詳しくはNext公式データフェッチの部分をご参照いただければと思います。●レイアウトの作成
それでは、今度こそレイアウトのコンポーネントを作成していきましょう!
まず、components
ディレクトリをpagesと同階層に作成してください。その中に、Header.js
、Footer.js
、Layout.js
、PostList.js
の4ファイルを空の状態でいいので作成してください。
そのあと、Layout.js
を以下のように編集していってください。Layout.jsimport Head from 'next/head' import Link from 'next/link' export default function Layout({ children, pageTitle, ...props }) { return ( <> <Head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>{pageTitle}</title> </Head> <section className="text-center mt-10"> <header className="bg-blue-300 h-10"> <nav> <Link href="/"> <a className="pr-10">My Blog</a> </Link> <Link href="/about"> <a>About</a> </Link> </nav> </header> <div className="bg-yellow-300 h-20">{children}</div> </section> <footer className="bg-green-300 text-center h-10">Footerのテキスト</footer> </> ) }
<Head>
コンポーネントまず、
next/head
から読み込んでいる<Head>
コンポーネント内ですが、<meta>
情報や<title>
などを書き込むことができます。
あらかじめサイト全体で読み込ませておきたい情報は、ここに置いておきましょう!
<Link>
コンポーネント続いて、
next/link
から読み込んでいる<Link>
コンポーネント内ですが、シンプルに捉えると、飛ばしたい先のリンクを作成することができます。
{children}
パーツ最後に
{children}
の部分ですが、各ページでのコンテンツを表示する場所です。
詳しくは後ほど書くindex.js
で確認していただければと思いますが、各pagesのファイルの中でLayoutコンポーネントで挟んであげれば、
{children}
の部分にコンテンツを表示することができます。
では、pages/index.js
で先ほどのLayout
コンポーネントを読み込み、コンテンツを表示させてみましょう!以下のように変更してください。index.jsimport Layout from '../components/Layout' const Index = ({ title, description }) => { return ( <Layout pageTitle={title}> <div>ここがLayoutコンポーネントのChildren部分です</div> <div>{description}</div> </Layout> ) } export default Index export async function getStaticProps() { const configData = await import(`../siteconfig.json`) return { props: { title: configData.default.title, description: configData.default.description, }, } }編集を保存したあと、
http://localhost:3000
にアクセスすると以下のような画面が表示されていれば成功です!
|Component分割
先ほども少し触れたのですが、コンポーネントの分割に関しては、様々な思想がございますので、この記事内では深くは触れません。
分割ってこうやってやるんだな〜ぐらいの捉え方をして頂けるとありがたいです。
それでは、前回作成したLayout
コンポーネントの分割を行なっていきましょう!前回の時点での components ディレクトリの中は以下のような状態かと思います。components/ - Footer.js // 空ファイル - Header.js // 空ファイル - Layout.js - PostList.js // 空ファイルまた、
Layout.js
ファイル内の Layoutファンクションが返却している部分は以下のようになっているかと思います。Layout.js// Layoutファンクション return()内 <Head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>{pageTitle}</title> </Head> <section className="text-center mt-10"> <header className="bg-blue-300 h-10"> <nav> <Link href="/"> <a className="pr-10">My Blog</a> </Link> <Link href="/about"> <a>About</a> </Link> </nav> </header> <div className="bg-yellow-300 h-20">{children}</div> </section> <footer className="bg-green-300 text-center h-10">Footerのテキスト</footer>この部分を
Header.js
とFooter.js
に分割していきたいと思います。
まずは Header から分けていきましょう!先ほどのコードの<header>
タグの始まりから終わりまでを切り取りし、Header.jsファイルを以下のように書き加えます。Header.jsimport Link from 'next/link' export default function Header() { return ( <header className="bg-blue-300 h-10"> <nav> <Link href="/"> <a className="pr-10">My Blog</a> </Link> <Link href="/about"> <a>About</a> </Link> </nav> </header> ) }その次に
Layout.js
ファイル内で、今ほど作った Header コンポーネントを読み込んでいきましょう!Layout.jsimport Head from 'next/head' import Header from '../components/Header' // ←追記 export default function Layout({ children, pageTitle }) { return ( <> <Head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>{pageTitle}</title> </Head> <section className="text-center"> <Header /> {/* ←変更箇所 */} <div className="bg-yellow-300 h-20">{children}</div> </section> <footer className="bg-green-300 text-center h-10">Footerのテキスト</footer> </> ) }一度画面を確認してみてください!前回と同様に以下のような画面が表示されましたか?
確認ができましたら、Footerも同様に分割してみてください!やり方は同じなので、一度ご自身でチャレンジしてみてくださいね ^^bでは、私の方もやっていきます!
Footer.js
ファイルを以下のように書き加えます。Footer.jsexport default function Footer() { return ( <footer className="bg-green-300 text-center h-10"> Footerのテキスト </footer> ) }Header の時と同様に
Layout.js
で読み込みます。Layout.jsimport Head from 'next/head' import Header from '../components/Header' import Footer from '../components/Footer' // ←追記 export default function Layout({ children, pageTitle }) { return ( <> <Head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>{pageTitle}</title> </Head> <section className="text-center"> <Header /> <div className="bg-yellow-300 h-20">{children}</div> </section> <Footer /> {/* ←変更箇所 */} </> ) }再度画面を確認し、同じ状態を保てていれば成功です!
以上のような感じでコンポーネントの分割を行なっていくことができます!
なぜ分割を行うの?という疑問が浮かんだ方もいらっしゃると思いますので、この作ったものを他のページで再利用する中で少しでも良さを実感してみようと思います!
ということで、"about" としか表示のされないアバウトページにレイアウトを反映させてみましょう!about.js
を以下のように編集してみてください!about.jsimport Layout from '../components/Layout' const About = () => { return ( <Layout pageTitle="ここはアバウトページだよ"> <div>Aboutページのコンテンツをここに書いていく!</div> </Layout> ) } export default Aboutこれだけの変更で以下の画像のようにレイアウトの反映ができました!
ん?何か違和感が...
そうなんです!タイトルも変わっているんです!
実はレイアウトコンポーネントで挟む時に<Layout pageTitle="ここはアバウトページだよ">
という感じでレイアウトコンポーネントにpageTitle
を引き渡しています。レイアウトコンポーネント側にはこのpageTitleの受付口を用意していましたので、「はいはい〜タイトルの変更ね!」という感じで書き換えてくれているわけですね!このように、コンポーネントを分割し、共通パーツとして作成しておくと、複数ページ、複数箇所での使い回しができるので便利だし、コーディングの量が減るので良いよね!という感じだと思っていただければ ^^v
●動的ルート
それでは続いて動的ルーティングについて確認しましょう!
今までの状態で作られているルーティングは/
と/about
の2ページ分です。
必要に応じてpages
ディレクトリにページを追加していけば良いのはご理解いただけたかと思います。
ただ、ブログ記事などのように、画面のデザインはほぼ変わらず、コンテンツの部分のみ変わっていくようなページに関しては、記事作成ごとに、js ファイルを生成するのはどうも手間な気がしますよね...
そこで、Dynamic Routes
(動的ルート)の出番です。/post/3
や/post/156
、/post/nextjs
のような記事のIDや記事のタイトルといった固有の情報を含んだURLにアクセスされた場合に、記事のデータを取得し表示できるようにしてあげると、毎回毎回記事を書くたびにjsファイル(ページコンポーネント)を生成しなくても済むようになりますね!^^v
ということで、簡易的に動的ルートを体験してみましょう!
pages
ディレクトリ内にpost
ディレクトリを作成し、その中に[post].js
ファイルを作成してください。pages/ post/ // ←作成 - [post].js // ←作成 - _app.js - about.js - index.jsその次に、
[post].js
の中身を以下のようにしてください。[post].jsimport { useRouter } from 'next/router' const Post = () => { const router = useRouter() const { post } = router.query return ( <p className="m-10"> Post: {post} </p> ) } export default Postファイルを保存し
http://localhost:3000/post/1
やhttp://localhost:3000/post/nextjs
にアクセスしてみてください。
Post: 1 や Post: nextjs という文字が画面に表示されたかと思います。
簡単に解説しておきますと、基本的に Next.js では pages ディレクトリ以下のファイル名(.jsより前の部分)がルーティングを構成する要素となりますので、今回作成した [post].js で考えると、[post]
の部分がルーティングを構成する要素となります。
Next.js では、このあたりを動的にキャッチし、クエリオブジェクトとして持つことができるんですね!
また、複数の動的な値をキャッチしたい場合は、先ほど作成した post ディレクトリの中に[hoge]
ディレクトリを作成し、その中に[huga].js
を作成すると、http://localhost:3000/post/today/comment
というリクエストに対して today や comment と行った値をキャッチすることもできます。
その他いくつかのパターンが存在しますので、詳しくはNext公式動的ルートをご確認いただければと思います。以上、少し長くなってきましたので、今回はここまでにして、次回に続けたいと思います。
次回は、この動的ルートを活用し、ルーティングの作成と、該当するマークダウンファイル(ブログ記事)の読み取りを行っていきたいと思います。最終的にはレイアウトを整え、サーバーにデプロイまでいきましょう!
乞うご期待!
- 投稿日:2021-03-05T10:34:55+09:00
Twilio Videoのサンプルコードで無料プランGoを使う方法
はじめに
Twilio社は高クオリティなビデオアプリケーションのサンプルコードを公開しています。
https://github.com/twilio/twilio-video-app-react何もせずに、このサンプルコードを利用すると、Twilio Videoの一番高額なプラン
Group
でルームが作られます。
ちょっと試すときは、Go
というTwilio Videoの無料プランで試したいと思う方もいらっしゃるのではないでしょうか。そこで本記事では、上記ビデオアプリケーションで
Go
へプラン変更する方法をご紹介いたします。修正箇所
twilioビデオのサンプルコードは、twilio cliのコマンドを使ってデプロイしています。
そのコマンドにVideoのプランを設定するオプションがあるのですが、そのオプションのデフォルトがGroup
になっているのが、原因です。なので、プランを変更するためには、オプションの
--room-type
にgo
を指定してあげます。package.json修正前 "deploy:twilio-cli": "cross-env REACT_APP_SET_AUTH=passcode npm run build && twilio rtc:apps:video:deploy --authentication=passcode --app-directory ./build" 修正後 "deploy:twilio-cli": "cross-env REACT_APP_SET_AUTH=passcode npm run build && twilio rtc:apps:video:deploy --authentication=passcode --room-type=go --app-directory ./build"おまけ
修正しても反映されないときは下記コマンドを使って、一度ビデオアプリケーションを削除してから、再度デプロイしてみてください。
twilio rtc:apps:video:delete
- 投稿日:2021-03-05T10:33:29+09:00
【Material-ui】makeStylesを使った子要素のcss変更のやり方
やりたかったこと
結論
通常はopacityを0にしておいて、hover時に1に変更する。
makeStylesを使った場合はちょっと特殊な書き方だったので、makeStylesを使いたい人は参考にしてください。const useStyles = makeStyles({ ... image_item_bar: { opacity: 0, }, image_item: { '&:hover': { cursor: 'pointer', "& $image_item_bar": { opacity: 1.0, } } }, }); export default function GridImageList() { const classes = useStyles() return ( <div className={classes.root}> <ImageList variant="masonry" cols={3} gap={8}> {itemData.map((item) => ( <ImageListItem key={item.img} className={classes.image_item} > <img srcSet={`${item.img}?w=161&fit=crop&auto=format 1x, ${item.img}?w=161&fit=crop&auto=format&dpr=2 2x`} alt={item.title} className={classes.img} /> <ImageListItemBar title={item.title} actionIcon={ <IconButton aria-label={`info about ${item.title}`} className={classes.icon} > <DeleteIcon /> </IconButton> } className={classes.image_item_bar} /> </ImageListItem> ))} </ImageList> </div> ); }
- 投稿日:2021-03-05T10:21:50+09:00
React と Video.js を使って Amazon IVS プレイヤーを実装する
2021 年より streampack チームに join した endo です。
Qiita に投稿するのは初めてですが、よろしくお願いします。はじめに
Amazon Interactive Video Service (IVS) のプレイヤーを実装する機会があったので書いていこうと思います。
前提
React を使用したプロジェクトにて Video.js が組み込まれている状態を想定しています。
一応ゼロからのセットアップ手順を記載していますが、詳細については各々の公式サイトをご参照ください。React のセットアップ
create-react-app
を使って React の環境を構築します。shellnpx create-react-app 【アプリ名】https://ja.reactjs.org/docs/create-a-new-react-app.html
Video.js のインスール
Video.js が組み込まれていない場合 npm or yarn 経由で Video.js をインストールしてください。
shell$ npm install --save-dev video.jshttps://videojs.com/getting-started/#install-via-npm
プレイヤーの実装
AWS のドキュメントを参考に実装していきます。
注意点として気をつけたいのが IVS プレイヤーを React で実装する場合 npm or yarn でインストールすると現時点ではエラーとなるということです。
したがって、エラーを回避するために動的に JS を script タグで読み込みます。App.js の修正
AmazonIVSPlayer という名前でコンポーネントを作成し import します。
App.jsimport React from "react"; import AmazonIVSPlayer from "./components/AmazonIVSPlayer"; const App = () => { return <AmazonIVSPlayer />; } export default App;プレイヤー部分のコーディング
まずは
Video.js
を import します。import videojs from "video.js"; import "video.js/dist/video-js.css";その後、動的に
amazon-ivs-videojs-tech.min.js
を読み込みます。const script = document.createElement("script"); script.src = "https://player.live-video.net/1.2.0/amazon-ivs-videojs-tech.min.js"; document.body.appendChild(script);
registerIVSTech
関数を使って Video.js の登録をします。option がある時は第二引数に渡します。registerIVSTech(videojs, options);Video.js を使ってプレイヤーの初期化をします。
techOrder
オプションでAmazonIVS
を追加します。const player = videojs( "amazon-ivs-videojs", { techOrder: ["AmazonIVS"], }, () => { // Play stream player.src(PLAYBACK_URL); } );全体的なコードは以下のようになります。
AmazonIVSPlayer.js/* global registerIVSTech */ import React, { useEffect, useRef } from "react"; import videojs from "video.js"; import "video.js/dist/video-js.css"; const AmazonIVSPlayer = () => { const playerRef = useRef(); useEffect(() => { const script = document.createElement("script"); script.src = "https://player.live-video.net/1.2.0/amazon-ivs-videojs-tech.min.js"; document.body.appendChild(script); script.addEventListener("load", () => { const PLAYBACK_URL = "【動画URL】"; registerIVSTech(videojs); // Initialize player const player = videojs( "amazon-ivs-videojs", { techOrder: ["AmazonIVS"], }, () => { console.log("Player is ready to use!"); player.src(PLAYBACK_URL); } ); playerRef.current = player; }); return () => { playerRef.current.dispose(); document.body.removeChild(script); }; }, []); return ( <div> <video id="amazon-ivs-videojs" className="video-js vjs-4-3 vjs-big-play-centered" controls autoPlay playsInline muted ></video> </div> ); }; export default AmazonIVSPlayer;画質選択機能を付けてみる
画質選択機能をつけるにはプラグインを追加します。
amazon-ivs-videojs-tech.min.js
に加えて、amazon-ivs-quality-plugin.min.js
を読み込む必要があります。動的に複数の JS を読み込むことになるので、全ての JS のロードを待つ必要があります。
const loadScripts = [ { src: "https://player.live-video.net/1.2.0/amazon-ivs-videojs-tech.min.js", }, { src: "https://player.live-video.net/1.2.0/amazon-ivs-quality-plugin.min.js", }, ]; // counterを用意して全てのJSの読み込みが終わったらプレイヤーを初期化する let counter = 0; const counterMax = loadScripts.length; loadScripts.forEach((scr, i) => { const script = document.createElement("script"); script.src = scr.src; document.body.appendChild(script); loadScripts[i].ref = script; script.addEventListener("load", () => { counter++; if (counter === counterMax) { // ここからプレイヤーの初期化処理 // ... } }); });
registerIVSQualityPlugin
関数を使って Video.js を登録し、registerIVSQualityPlugin(videojs);プレイヤーの初期化時にプラグインの有効化をします。
player.enableIVSQualityPlugin();全体的には以下のようなコードになると思います。
AmazonIVSPlayer.js/* global registerIVSTech , registerIVSQualityPlugin */ import React, { useEffect, useRef } from "react"; import videojs from "video.js"; import "video.js/dist/video-js.css"; const AmazonIVSPlayer = () => { const playerRef = useRef(); useEffect(() => { const loadScripts = [ { src: "https://player.live-video.net/1.2.0/amazon-ivs-videojs-tech.min.js", ref: null, }, { src: "https://player.live-video.net/1.2.0/amazon-ivs-quality-plugin.min.js", ref: null, }, ]; let counter = 0; const counterMax = loadScripts.length; loadScripts.forEach((scr, i) => { const script = document.createElement("script"); script.src = scr.src; document.body.appendChild(script); loadScripts[i].ref = script; script.addEventListener("load", () => { counter++; if (counter === counterMax) { const PLAYBACK_URL = "【動画URL】"; registerIVSTech(videojs); registerIVSQualityPlugin(videojs); // Initialize player const player = videojs( "amazon-ivs-videojs", { techOrder: ["AmazonIVS"], }, () => { console.log("Player is ready to use!"); // Play stream player.src(PLAYBACK_URL); player.enableIVSQualityPlugin(); } ); playerRef.current = player; } }); }); return () => { playerRef.current.dispose(); loadScripts.forEach(scr => { document.body.removeChild(scr.ref); }); }; }, []); return ( <div> <video id="amazon-ivs-videojs" className="video-js vjs-4-3 vjs-big-play-centered" controls autoPlay playsInline muted ></video> </div> ); }; export default AmazonIVSPlayer;まとめ
Reactを使ってのIVSプレイヤーの実装でした。
プレイヤーのUIを作るのは結構大変なので、 Video.js に対応しているのは非常にありがたいですね。参考 URL
https://docs.aws.amazon.com/ivs/latest/userguide/player.html
https://aws.github.io/amazon-ivs-player-docs/1.2.0/web/
https://docs.videojs.com/
https://dev.classmethod.jp/articles/workaround-react-ivs/)