next-video下一个视频是用于将视频添加到您的下一个.js应用程序的React组件。它既扩展<video>元素和您的下一个应用程序,并具有用于自动视频优化的功能。
import Video from 'next-video' ;
import getStarted from '/videos/get-started.mp4' ;
export default function Page ( ) {
return < Video src = { getStarted } /> ;
} 在您的下一个项目的根源中,运行:
npx -y next-video init这将(随着提示):
next-video作为依赖项安装next.config.js文件/videos目录,这是您将所有视频源文件放置的地方。它还将更新您的.gitignore文件,以忽略/videos目录中的视频文件。视频,尤其是任何合理尺寸的视频,不应由Git存储/跟踪。另外,如果您想存储原始文件,则可以删除添加的gitignore行并安装git-lfs。
Vercel建议使用专用的内容平台进行视频,因为视频文件很大,并且可能导致过多的带宽使用情况。默认情况下,Next-Video使用MAUX(开发人员的视频API),它是由Video.js的创建者构建的,Pateers Pater-Paters-Patreon等流行的流媒体应用程序,其视频性能监视用于世界上最大的现场活动。
.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-video next.config.js
如果您使用的是CONCORJS模块:
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时才需要这是必需的,并确保您的视频文件导入不会大喊您丢失类型。当您运行npx next-video init时,应该在您的项目root中创建video.d.ts ,如果不是,则可以手动创建它:
// 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].json 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 /videos文件
import Video from 'next-video' ;
import awesomeVideo from '/videos/awesome-video.mp4' ;
export default function Page ( ) {
return < Video src = { awesomeVideo } /> ;
}当视频上传和处理视频时, <Video>将尝试播放本地文件。这仅在本地开发过程中发生,因为本地文件永远不会上传到您的git repo。
对于已经远程托管的视频(例如在AWS S3上),请导入远程URL并刷新页面。这将在/videos文件夹中创建本地JSON文件,同步脚本将启动上传视频。
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中使用以下代码创建新的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..."
/> ;
}您可以通过将它们作为道具传递给视频中的自定义海报和Blurdataurl。
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 }
/> ;
}这是一个很好的解决方案,但它不会提供与默认提供商的自动海报和Blurdataurl相同的优化水平。
要获得相同的优化级别,您可以使用开槽的海报元素。
通过带有slot="poster"属性的小时候将视频传递给视频,将其插入的海报图像元素(例如next/image )添加到视频中。
现在,您的图像将获得所用图像组件的所有好处,它将很好地放置在视频播放器控件后面。
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>组件将视频添加为没有玩家控件的背景。这节省了约50%的JS播放器大小,并为背景视频使用而进行了优化。
<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' }
}
} ) ;支持提供者所需的环境变量:
| 提供者 | 环境变量 | 提供者配置 | 定价链接 |
|---|---|---|---|
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集合时可选) | bucket (可选)bucketUrlPublic ( R2_CF_API_TOKEN设置时可选) | 定价 |
| mux(默认) | Vercel Blob | backblaze | 亚马逊S3 | Cloudflare R2 | |
|---|---|---|---|---|---|
| 反repo存储 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 通过CDN交付 | ✅ | ✅ | - | - | ✅ |
| BYO播放器 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 压缩以进行流 | ✅ | - | - | - | |
| 适应缓慢的网络(HLS) | ✅ | - | - | - | |
| 自动占位符海报 | ✅ | - | - | - | |
| 时间轴悬停的缩略图 | ✅ | - | - | - | |
| 流传输任何源格式 | ✅ | * | * | * | * |
| AI字幕和字幕 | ✅ | - | - | - | |
| 视频分析 | ✅ | - | - | - | |
| 定价 | 基于分钟 | 基于GB | 基于GB | 基于GB | 基于GB |
*与Web兼容的MP4文件无需视频处理所需的托管提供商
默认情况下,资产元数据存储在/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 ) ;最后,如您所见,在API路线中导入GET和POST或handler功能。处理人员期望使用视频源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 (资产|字符串):视频资产对象(导入)或源URL。poster (Staticimagedata | String):视频的占位符图像。 (为MUX视频生成的自动)blurDataURL (字符串):可以用作占位符的base64映像源URL。 (为MUX视频生成的自动)theme (React组件):播放器主题组件。有关更多主题,请参见Player.Style。as (React组件):自定义播放器组件。请参阅自定义播放器。transform (函数):用于转换资产对象(SRC和海报)的自定义功能。loader (功能):用于解决基于字符串的视频URL(非导入)的自定义功能。 带有MUX视频源的<Video>组件接受以下其他道具:
startTime (数字):视频的开始时间秒。streamType (“按需” |“ Live”):视频的流类型。默认值为“按需”。customDomain (字符串):分配一个用于MUX视频的自定义域。beaconCollectionDomain (字符串):分配一个用于MUX数据收集的自定义域。注意:必须在播放之前设置以应用于MUX数据监视。envKey (String):这是MUX数据的环境密钥。如果您使用MUX视频,则将自动为您设置。如果您使用其他提供商,则可以将其设置为自己的密钥。disableTracking (布尔值):禁用视频播放的MUX数据跟踪。disableCookies (布尔值):禁用MUX数据使用的cookie。preferPlayback (“ MSE” |“本机”):指定<mux-video>是否应该尝试使用媒体源扩展或本机播放(如果可用)。如果没有提供值,则<mux-video>将根据认为最佳的内容和播放环境选择。maxResolution (“ 720p” |“ 1080p” |“ 1440p” |“ 2160p”):指定您要为此视频提供的最大分辨率。minResolution (“ 480p” |“ 540p” |“ 720p” |“ 1080p” |“ 1440p” |“ 2160p”):指定您要为此视频提供的最小分辨率。programStartTime (编号):将基于PDT的即时剪辑应用于媒体流的开头。programEndTime (编号):将基于PDT的即时剪辑应用于媒体流的末尾。assetStartTime (编号):将基于媒体时间轴的即时剪辑应用于媒体流的开头。assetEndTime (编号):将基于媒体时间轴的即时剪辑应用于媒体流的末尾。renditionOrder (String):更改SRC播放列表中提供的演绎的顺序。可以影响初始段负载。目前仅支持“ desc”下降订单。metadataVideoId (String):这是发送到MUX数据的任意ID,该ID应该映射回数据库中此视频的记录。metadataTitle (字符串):这是您的视频的任意标题,它将以元数据的形式传递到MUX数据中。添加标题将为您提供MIX Data仪表板中有用的上下文。 (可选,但鼓励)metadataViewerUserId (String):如果您有登录用户,则应该是匿名ID值,该值映射回数据库中的用户,将发送到MUX数据。注意不要揭露个人可识别的信息,例如名称,用户名或电子邮件地址。 (可选,但鼓励)metadata* (字符串):此元数据*语法可用于传递任何任意MUX数据元数据字段。playbackToken (字符串):签署src URL的播放令牌。thumbnailToken (字符串):签名poster URL的代币。storyboardToken (字符串):签署故事板URL的标记。drmToken (字符串):签署DRM许可证和相关URL的令牌。targetLiveWindow (编号):代表实时内容可寻求范围的偏移,其中Infinity表示整个实时内容都是可寻求的(又称“标准DVR”)。与streamType一起使用以确定要显示的UI/控件。liveEdgeOffset (数字):最早将其视为现场内容的播放时间。debug (布尔值):启用基础播放引擎(目前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密钥下的提供商配置中指定公共URL提供CloudFlare API密钥:
R2_CF_API_TOKEN如果您想在本地开发这件事,则可以克隆并链接此吸盘。只是知道...现在这不是一个美好的时光。
cd进入存储库npm install && npm run buildcd ../ (或回到要创建测试应用的地方)npx create-next-appcd your-next-appnpx link ../next-video (或任何克隆此回购的地方)