next-video次のビデオは、next.jsアプリケーションにビデオを追加するためのReactコンポーネントです。自動ビデオ最適化のための機能を備えた<video>要素と次のアプリの両方を拡張します。
import Video from 'next-video' ;
import getStarted from '/videos/get-started.mp4' ;
export default function Page ( ) {
return < Video src = { getStarted } /> ;
} next.jsプロジェクトのルートで、実行してください。
npx -y next-video initこれは(プロンプトを付けて):
next-videoをインストールしますnext.config.jsファイルを更新します/videosディレクトリを作成します。また、 /videosディレクトリ内のビデオファイルを無視するように.gitignoreファイルを更新します。ビデオ、特に妥当なサイズのビデオは、Gitで保存/追跡すべきではありません。または、元のファイルを保存する場合は、追加されたGitignoreラインを削除してGit-LFSをインストールできます。
Vercelは、ビデオファイルが大きく、過度の帯域幅の使用につながる可能性があるため、ビデオに専用のコンテンツプラットフォームを使用することをお勧めします。デフォルトでは、Next-VideoはMUX(開発者向けのビデオAPI)を使用します。これは、video.jsの作成者によって構築され、Patreonのような人気のあるストリーミングアプリをPowersで使用し、そのビデオパフォーマンス監視が世界最大のライブイベントで使用されています。
.env.localに追加します(またはローカルENV変数をエクスポートします) # .env.local
MUX_TOKEN_ID=[YOUR_TOKEN_ID]
MUX_TOKEN_SECRET=[YOUR_TOKEN_SECRET] cd your-next-app
# If your project is using NPM (the default for Next.js)
npm install next-video
# If your project is using Yarn
yarn add next-video
# If your project is using pnpm
pnpm add next-videonext.config.js
CommonJSモジュールを使用している場合:
const { withNextVideo } = require ( 'next-video/process' ) ;
/** @type {import('next').NextConfig} */
const nextConfig = { } ; // Your current Next Config object
module . exports = withNextVideo ( nextConfig ) ; next.config.mjs
ESモジュールを使用している場合:
import { withNextVideo } from 'next-video/process' ;
/** @type {import('next').NextConfig} */
const nextConfig = { } ;
export default withNextVideo ( nextConfig ) ; tsconfig.jsonにビデオインポートタイプを追加しますこれは、TypeScriptを使用している場合にのみ必要であり、ビデオファイルのインポートが欠落しているタイプについて怒鳴らないようにします。 video.d.ts 、 npx next-video initを実行したときにプロジェクトルートに作成されるべきでした。
// video.d.ts
/// <reference types="next-video/video-types/global" />次に、そのファイルをtsconfig.jsonのincludeに追加します。
{
// ...
"include" : [ "video.d.ts" , "next-env.d.ts" , /* ... */ ]
// ...
} /videosディレクトリにビデオをローカルに追加し、 npx next-video syncを実行します。ビデオは自動的にリモートストレージにアップロードされ、最適化されます。 /videos /[file-name /videos/[file-name].jsonファイルも作成されています。これらは、ローカルビデオファイルを新しいリモートホストのビデオ資産にマッピングするために使用されます。これらのJSONファイルはGITにチェックする必要があります。
npx next-video sync
また、 next-video sync -w DEVスクリプトに追加して、DEVサーバーの実行中に/videosに追加されるように動画を自動的に同期することもできます。
// package.json
"scripts" : {
"dev" : "next dev & npx next-video sync -w" ,
} ,これで、アプリケーションで<Video>コンポーネントを使用できます。 awesome-video.mp4 to /videosというファイルを追加したとしましょう
import Video from 'next-video' ;
import awesomeVideo from '/videos/awesome-video.mp4' ;
export default function Page ( ) {
return < Video src = { awesomeVideo } /> ;
}ビデオがアップロードされ、処理されている間、 <Video>ローカルファイルを再生しようとします。これは、ローカル開発中にのみ発生します。これは、ローカルファイルがGITリポジトリにアップロードされることはないためです。
すでにリモートでホストされているビデオ(AWS S3など)の場合は、リモートURLをインポートしてページを更新します。これにより/videosフォルダーにローカルJSONファイルが作成され、Syncスクリプトがビデオのアップロードを開始します。
import Video from 'next-video' ;
import awesomeVideo from 'https://www.mydomain.com/remote-video.mp4' ;
export default function Page ( ) {
return < Video src = { awesomeVideo } /> ;
}ホストされたビデオがMP4のような単一のファイルである場合、ファイルはより良い配信可能性と互換性のために自動的に最適化されます。
場合によっては、インポート時にリモートビデオURLを使用できない場合があります。
次のコードを使用して/api/video用の次の.jsアプリで新しいAPIエンドポイントを作成することで解決できます。
アプリルーター(next.js> = 13)
// app/api/video/route.js
export { GET } from 'next-video/request-handler' ;ページルーター(next.js)
// pages/api/video/[[...handler]].js
export { default } from 'next-video/request-handler' ;次に、 src属性をリモートビデオのURLに設定し、ページを更新すると、ビデオが処理を開始します。
import Video from 'next-video' ;
export default function Page ( ) {
return < Video src = "https://www.mydomain.com/remote-video.mp4" /> ;
} themeプロップを<Video>コンポーネントに渡すことで、プレイヤーのテーマを変更できます。
その他のテーマについては、player.styleを参照してください。
import Video from 'next-video' ;
import Instaplay from 'player.style/instaplay/react' ;
import awesomeVideo from '/videos/awesome-video.mp4' ;
export default function Page ( ) {
return < Video src = { awesomeVideo } theme = { Instaplay } /> ;
} v1.1.0以降、プレーヤーコンポーネントを直接インポートして、アップロードおよび処理機能なしで使用できます。
import Player from 'next-video/player' ;
// or
import BackgroundPlayer from 'next-video/background-player' ;
export default function Page ( ) {
return < Player
src = "https://www.mydomain.com/remote-video.mp4"
poster = "https://www.mydomain.com/remote-poster.webp"
blurDataURL = "data:image/webp;base64,UklGRlA..."
/> ;
}カスタムポスターとBludataurlをプロップとして渡すことでビデオに追加できます。
import Video from 'next-video' ;
import awesomeVideo from '/videos/awesome-video.mp4' ;
import awesomePoster from '../public/images/awesome-poster.jpg' ;
export default function Page ( ) {
return < Video
src = { awesomeVideo }
poster = { awesomePoster . src }
blurDataURL = { awesomePoster . blurDataURL }
/> ;
}これは良い解決策ですが、デフォルトのプロバイダーによる自動ポスターとBludataurlと同じレベルの最適化を提供しません。
同じレベルの最適化を取得するには、スロット付きポスター要素を使用できます。
スロット付きポスター画像要素( next/imageなど)をビデオに追加して、 slot="poster"属性を持つ子供として渡します。
これで、画像は使用済みの画像コンポーネントのすべての利点を取得し、ビデオプレーヤーコントロールの背後にうまく配置されます。
import Image from 'next/image' ;
import Video from 'next-video' ;
import awesomeVideo from '/videos/awesome-video.mp4' ;
import awesomePoster from '../public/images/awesome-poster.jpg' ;
export default function Page ( ) {
return (
< Video src = { awesomeVideo } >
< Image
slot = "poster"
src = { awesomePoster }
placeholder = "blur"
alt = "Some peeps doing something awesome"
/>
</ Video >
) ;
}カスタムプレーヤーコンポーネントをas Propに渡すことで、プレーヤーをカスタマイズできます。
カスタムプレーヤーコンポーネントは、次の小道具を受け入れます。
asset :処理された資産には、有用な資産メタデータとアップロードステータスが含まれています。src :資産の準備ができた場合、文字列ビデオソースURL。poster :資産の準備ができた場合、文字列画像ソースURL。blurDataURL :プレースホルダーとして使用できる文字列Base64画像ソースURL。 import Video from 'next-video' ;
import ReactPlayer from './player' ;
import awesomeVideo from '/videos/awesome-video.mp4' ;
export default function Page ( ) {
return < Video as = { ReactPlayer } src = { awesomeVideo } /> ;
} // player.tsx
'use client' ;
import type { PlayerProps } from 'next-video' ;
import ReactPlayer from 'react-player' ;
export default function Player ( props : PlayerProps ) {
let { asset , src , poster , blurDataURL , thumbnailTime , ... rest } = props ;
let config = { file : { attributes : { poster } } } ;
return < ReactPlayer
url = { src }
config = { config }
width = "100%"
height = "100%"
{ ... rest }
/> ;
} <BackgroundVideo>コンポーネントを使用して、プレーヤーコントロールのないバックグラウンドとしてビデオを追加できます。これにより、JSプレーヤーサイズの約50%を節約し、バックグラウンドビデオの使用に最適化されています。
<BackgroundVideo>コンポーネントは、前のセクションで見たようなカスタムプレーヤーです。
以下の例のthumbnailTimeクエリパラメーターは、ビデオの指定された時間にポスター画像を生成し、画像をぼかすために使用されます( muxプロバイダーでの使用に限定)。
import BackgroundVideo from 'next-video/background-video' ;
import getStarted from '/videos/country-clouds.mp4?thumbnailTime=0' ;
export default function Page ( ) {
return (
< BackgroundVideo src = { getStarted } >
< h1 > next-video </ h1 >
< p >
A React component for adding video to your Next.js application.
It extends both the video element and your Next app with features
for automatic video optimization.
</ p >
</ BackgroundVideo >
) ;
}ビデオ処理とホスティングのために、さまざまなプロバイダーから選択できます。デフォルトのプロバイダーはMUXです。プロバイダーを変更するには、Next-Video構成にproviderオプションを追加できます。一部のプロバイダーは、 providerConfigプロパティで渡すことができる追加の構成が必要です。
// next.config.js
const { withNextVideo } = require ( 'next-video/process' ) ;
/** @type {import('next').NextConfig} */
const nextConfig = { } ;
module . exports = withNextVideo ( nextConfig , {
provider : 'backblaze' ,
providerConfig : {
backblaze : { endpoint : 'https://s3.us-west-000.backblazeb2.com' }
}
} ) ;必要な環境変数を備えたサポートプロバイダー:
| プロバイダー | 環境vars | プロバイダー構成 | 価格リンク |
|---|---|---|---|
mux (デフォルト) | MUX_TOKEN_IDMUX_TOKEN_SECRET | 価格設定 | |
vercel-blob | BLOB_READ_WRITE_TOKEN | 価格設定 | |
backblaze | BACKBLAZE_ACCESS_KEY_IDBACKBLAZE_SECRET_ACCESS_KEY | endpointbucket (オプション) | 価格設定 |
amazon-s3 | AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY | endpointbucket (オプション) | 価格設定 |
cloudflare-r2 | R2_ACCESS_KEY_IDR2_SECRET_ACCESS_KEYR2_CF_API_TOKEN ( bucketUrlPublic setの場合はオプション) | bucket (オプション)bucketUrlPublic ( R2_CF_API_TOKEN setの場合はオプション) | 価格設定 |
| Mux(デフォルト) | VercelBlob | バックブレイズ | Amazon S3 | CloudFlare R2 | |
|---|---|---|---|---|---|
| Off-Repoストレージ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CDNによる配信 | ✅ | ✅ | - | - | ✅ |
| BYOプレーヤー | ✅ | ✅ | ✅ | ✅ | ✅ |
| ストリーミング用に圧縮されています | ✅ | - | - | - | |
| 遅いネットワーク(HLS)に適応する | ✅ | - | - | - | |
| 自動プレースホルダーポスター | ✅ | - | - | - | |
| タイムラインホバーサムネイル | ✅ | - | - | - | |
| ソース形式をストリーミングします | ✅ | * | * | * | * |
| AIキャプションと字幕 | ✅ | - | - | - | |
| ビデオ分析 | ✅ | - | - | - | |
| 価格設定 | 議事録ベース | GBベース | GBベース | GBベース | GBベース |
*ビデオ処理なしでホスティングプロバイダーに必要なWeb互換MP4ファイル
デフォルトでは、Assetメタデータは/videosディレクトリのJSONファイルに保存されます。メタデータをデータベースまたはその他の場所に保存する場合は、ストレージフックを別のNext Video構成ファイルにカスタマイズできます。
以下の例は、JSONファイルストレージのデフォルトのストレージフックを示しています。
これらのフックは、 loadAsset 、 saveAsset 、およびupdateAsset機能の本体を変更することにより、ニーズに合わせてカスタマイズできます。
// next-video.mjs
import { NextVideo } from 'next-video/process' ;
import path from 'node:path' ;
import { mkdir , readFile , writeFile } from 'node:fs/promises' ;
export const { GET , POST , handler , withNextVideo } = NextVideo ( {
// Other next-video config options should be added here if using a next-video config file.
// folder: 'videos',
// path: '/api/video',
loadAsset : async function ( assetPath ) {
const file = await readFile ( assetPath ) ;
const asset = JSON . parse ( file . toString ( ) ) ;
return asset ;
} ,
saveAsset : async function ( assetPath , asset ) {
try {
await mkdir ( path . dirname ( assetPath ) , { recursive : true } ) ;
await writeFile ( assetPath , JSON . stringify ( asset ) , {
flag : 'wx' ,
} ) ;
} catch ( err ) {
if ( err . code === 'EEXIST' ) {
// The file already exists, and that's ok in this case. Ignore the error.
return ;
}
throw err ;
}
} ,
updateAsset : async function ( assetPath , asset ) {
await writeFile ( assetPath , JSON . stringify ( asset ) ) ;
}
} ) ;次に、 next.config.mjsファイルにwithNextVideo関数をインポートします。
// next.config.mjs
import { withNextVideo } from './next-video.mjs' ;
/** @type {import('next').NextConfig} */
const nextConfig = { } ;
export default withNextVideo ( nextConfig ) ;最後に、 GET and POSTをインポートするか、 handler APIルートで機能します。ハンドラーは、ビデオソースURLを使用したurlクエリまたはボディパラメーターを期待しています。
これらはハンドラーにとって最も最小限の例です。通常、エラー処理と検証、認証、承認を追加することになります。
アプリルーター(next.js> = 13)
// app/api/video/route.js
export { GET , POST } from '@/next-video' ;ページルーター(next.js)
// pages/api/video/[[...handler]].js
export { handler as default } from '@/next-video' ; デフォルトのプレーヤーは、メディアクロムで構築されています。
<video>要素で再生されます。<mux-video>で再生されます。<hls-video>で再生されます。<dash-video>で再生されます。<Video>コンポーネントは、 <video>要素のすべての小道具と次の追加の小道具を受け入れます。
src (Asset | String):ビデオアセットオブジェクト(インポート)またはソースURL。poster (staticimagedata |文字列):ビデオのプレースホルダー画像。 (MUXビデオ用に自動生成)blurDataURL (String):プレースホルダーとして使用できるBase64画像ソースURL。 (MUXビデオ用に自動生成)theme (Reactコンポーネント):プレーヤーテーマコンポーネント。その他のテーマについては、player.styleを参照してください。as (React Component):カスタムプレーヤーコンポーネント。カスタムプレーヤーを参照してください。transform (関数):アセットオブジェクト(SRCおよびポスター)を変換するカスタム関数。loader (関数):文字列ベースのビデオURLを解決するために使用されるカスタム関数(インポートではありません)。 MUXビデオソースを使用した<Video>コンポーネントは、次の追加の小道具を受け入れます。
startTime (number):ビデオの開始時間は秒単位です。streamType ( "on-demand" | "live"):ビデオのストリームタイプ。デフォルトは「オンデマンド」です。customDomain (String):MUXビデオに使用するカスタムドメインを割り当てます。beaconCollectionDomain (String):MUXデータ収集に使用するカスタムドメインを割り当てます。注:MUXデータ監視に適用するには、PlaybackIDの前に設定する必要があります。envKey (String):これはMUXデータの環境キーです。 MUXビデオを使用する場合、これは自動的に設定されます。別のプロバイダーを使用する場合は、これを独自のキーに設定できます。disableTracking (Boolean):ビデオ再生のMUXデータ追跡を無効にします。disableCookies (Boolean):MUXデータで使用されるCookieを無効にします。preferPlayback ( "mse" | "native"): <mux-video>メディアソース拡張機能またはネイティブ再生を使用しようとするかどうかを指定します(利用可能な場合)。値が提供されていない場合、 <mux-video> 、コンテンツと再生環境に最適と見なされるものに基づいて選択します。maxResolution ( "720p" | "1080p" | "1440p" | "2160p"):このビデオに配信される最大解像度を指定します。minResolution ( "480p" | "540p" | "720p" | "1080p" | "1440p" | "2160p"):このビデオに配信される最小解像度を指定します。programStartTime (number):PDTベースのインスタントクリップをメディアストリームの開始に適用します。programEndTime (number):PDTベースのインスタントクリップをメディアストリームの最後に適用します。assetStartTime (number):メディアのタイムラインベースのインスタントクリップをメディアストリームの開始に適用します。assetEndTime (number):メディアのタイムラインベースのインスタントクリップをメディアストリームの最後に適用します。renditionOrder (String):SRCプレイリストでレンディションが提供される順序を変更します。初期セグメントの負荷に影響を与える可能性があります。現在、下降順序で「DESC」のみをサポートしています。metadataVideoId (String):これは、データベースのこのビデオのレコードにマッピングされるMUXデータに送信される任意のIDです。metadataTitle (String):これは、メタデータとしてMUXデータに渡されるビデオの任意のタイトルです。タイトルを追加すると、MUXデータダッシュボードに便利なコンテキストが得られます。 (オプションですが、奨励されています)metadataViewerUserId (String):ログインユーザーがいる場合、これはデータベースのユーザーにマップされ、MUXデータに送信される匿名化されたID値である必要があります。名前、ユーザー名、電子メールアドレスなどの個人識別可能な情報を公開しないように注意してください。 (オプションですが、奨励されています)metadata* (文字列):このメタデータ*構文は、任意のMUXデータメタデータフィールドを渡すために使用できます。playbackToken (String): src URLに署名するための再生トークン。thumbnailToken (String): poster URLに署名するためのトークン。storyboardToken (文字列):ストーリーボードURLに署名するためのトークン。drmToken (String):DRMライセンスと関連するURLに署名するためのトークン。targetLiveWindow (number):ライブコンテンツのシーク可能な範囲を表すオフセット。 Infinityは、ライブコンテンツ全体がシークできることを意味します(別名「標準DVR」)。 streamTypeとともに使用して、表示するUI/コントロールを決定します。liveEdgeOffset (number):ライブコンテンツの「ライブエッジ」を演奏するものとして扱われる最も初期の再生時間。debug (Boolean):基礎となる再生エンジン(現在はHLS.JS)とMUX-埋め込みのデバッグモードを有効にし、コンソールに追加情報を提供します。 {
"Version" : " 2012-10-17 " ,
"Statement" : [
{
"Effect" : " Allow " ,
"Action" : [
" s3:ListAllMyBuckets " ,
" s3:CreateBucket " ,
" s3:PutBucketOwnershipControls "
],
"Resource" : " * "
},
{
"Effect" : " Allow " ,
"Action" : [
" s3:PutBucketPublicAccessBlock " ,
" s3:PutBucketAcl " ,
" s3:PutBucketCORS " ,
" s3:GetObject " ,
" s3:PutObject " ,
" s3:PutObjectAcl " ,
" s3:ListBucket "
],
"Resource" : " arn:aws:s3:::next-videos-* "
}
]
}パブリックアクセスのためにバケットを構成します:
bucket名を提供し、パブリックアクセスのために構成されていることを確認してくださいbucketUrlPublic Keyの下でプロバイダー構成でパブリックURLを指定しますCloudFlare APIキーを提供します:
R2_CF_API_TOKENこのことをローカルに開発したい場合は、この吸盤をクローンしてリンクできます。知ってください...今は素晴らしい時間ではありません。
cdnpm install && npm run buildcd ../ (またはテストアプリを作成する場所に戻る)npx create-next-appcd your-next-appnpx link ../next-video (またはこのレポをクローン化したところはどこでも)