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 } /> ;
} 다음에 JS 프로젝트의 루트에서 실행 :
npx -y next-video init이것은 (프롬프트와 함께) :
next-video 종속성으로 설치하십시오next.config.js 파일을 업데이트하십시오/videos 디렉토리를 만듭니다. 또한 /videos 디렉토리에서 비디오 파일을 무시하기 위해 .gitignore 파일을 업데이트합니다. 비디오, 특히 합리적인 크기의 비디오는 GIT에 의해 저장/추적해서는 안됩니다. 또는 원본 파일을 저장하려면 추가 된 Gitignore 라인을 제거하고 GIT-LFS를 설치할 수 있습니다.
Vercel은 비디오 파일이 크고 과도한 대역폭 사용으로 이어질 수 있으므로 비디오 용 전용 컨텐츠 플랫폼을 사용하는 것이 좋습니다. 기본적으로 Next-Video는 MUX (개발자를위한 비디오 API)를 사용합니다. 이는 Patreon과 같은 인기있는 스트리밍 앱의 제작자에 의해 구축 된 MUX (개발자를위한 비디오 API)를 사용하며 전 세계 최대의 라이브 이벤트에서 비디오 성능 모니터링이 사용됩니다.
.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
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를 사용하는 경우에만 필요하며 비디오 파일 가져 오기가 누락 된 유형에 대해 소리를 내지 않도록하십시오. npx next-video init 실행할 때 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 /videos/[file-name].json 파일도 생성됩니다. 이들은 로컬 비디오 파일을 새로운 원격 호스팅 된 비디오 자산에 매핑하는 데 사용됩니다. 이 JSON 파일은 git에 체크인해야합니다.
npx next-video sync
DEV 스크립트에 next-video sync -w 추가하여 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 Repo에 업로드되지 않기 때문에 로컬 개발 중에 만 발생합니다.
이미 원격으로 호스팅 된 비디오 (예 : 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 용 Next.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..."
/> ;
}소품으로 전달하여 사용자 정의 포스터를 추가하고 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> 구성 요소를 사용하여 플레이어 컨트롤이없는 배경으로 비디오를 추가 할 수 있습니다. 이로 인해 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입니다. 제공자를 변경하려면 차세대 비디오 구성에서 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 SET의 선택 사항) | 가격 |
| MUX (기본값) | Vercel Blob | 백 블레이즈 | 아마존 S3 | CloudFlare R2 | |
|---|---|---|---|---|---|
| 오프 레포 스토리지 | ✅ | ✅ | ✅ | ✅ | ✅ |
| CDN을 통한 배달 | ✅ | ✅ | - | - | ✅ |
| BYO 플레이어 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 스트리밍을 위해 압축 | ✅ | - | - | - | |
| 느린 네트워크 (HLS)에 적응 | ✅ | - | - | - | |
| 자동 자리 표시 자 포스터 | ✅ | - | - | - | |
| 타임 라인 호버 썸네일 | ✅ | - | - | - | |
| 모든 소스 형식을 스트리밍하십시오 | ✅ | * | * | * | * |
| AI 캡션 및 자막 | ✅ | - | - | - | |
| 비디오 분석 | ✅ | - | - | - | |
| 가격 | 분 기반 | GB 기반 | GB 기반 | GB 기반 | GB 기반 |
*비디오 처리없이 제공하는 호스팅에 필요한 웹 호환 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 and 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 (Asset | String) : 비디오 자산 개체 (가져 오기) 또는 소스 URL.poster (staticimagedata | String) : 비디오의 자리 표시 자 이미지. (MUX 비디오 용 자동 생성)blurDataURL (String) : 자리 표시 자로 사용할 수있는 Base64 이미지 소스 URL. (MUX 비디오 용 자동 생성)theme (반응 구성 요소) : 플레이어 테마 구성 요소. 더 많은 테마는 player.style을 참조하십시오.as (React Component) : 사용자 정의 플레이어 구성 요소. 커스텀 플레이어를 참조하십시오.transform (기능) : 자산 개체 (SRC 및 포스터)를 변환하는 사용자 정의 기능.loader (function) : 문자열 기반 비디오 URL을 해결하는 데 사용되는 사용자 정의 기능 (가져 오기). MUX 비디오 소스가있는 <Video> 구성 요소는 다음과 같은 추가 소품을 허용합니다.
startTime (번호) : 비디오의 시작 시간은 초입니다.streamType ( "주문형"| "라이브") : 비디오의 스트림 유형. 기본값은 "주문형"입니다.customDomain (String) : MUX 비디오에 사용할 사용자 정의 도메인을 할당합니다.beaconCollectionDomain (String) : MUX 데이터 수집에 사용할 사용자 지정 도메인을 할당합니다. 참고 : MUX 데이터 모니터링에 적용하려면 재생 전에 설정해야합니다.envKey (String) : 이것은 MUX 데이터의 환경 키입니다. MUX 비디오를 사용하는 경우 자동으로 설정됩니다. 다른 공급자를 사용하는 경우이를 자신의 키로 설정할 수 있습니다.disableTracking (부울) : 비디오 재생의 MUX 데이터 추적을 비활성화합니다.disableCookies (부울) : MUX 데이터에서 사용하는 쿠키를 비활성화합니다.preferPlayback ( "MSE"| "Native") : <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입니다.metadataTitle (String) : MUX 데이터로 메타 데이터로 전달되는 비디오의 임의의 제목입니다. 제목을 추가하면 MUX 데이터 대시 보드에서 유용한 컨텍스트가 제공됩니다. (선택 사항이지만 장려)metadataViewerUserId (String) : 로그인 한 사용자가있는 경우 MUX 데이터로 전송 될 데이터베이스의 사용자에게 다시 맵핑하는 익명화 된 ID 값이어야합니다. 이름, 사용자 이름 또는 이메일 주소와 같은 개인 식별 정보를 노출시키지 않도록주의하십시오. (선택 사항이지만 장려)metadata* (문자열) :이 메타 데이터* 구문은 임의의 MUX 데이터 메타 데이터 필드를 통과하는 데 사용될 수 있습니다.playbackToken (String) : src URL에 서명하기위한 재생 토큰.thumbnailToken (String) : poster URL에 서명하기위한 토큰.storyboardToken (String) : 스토리 보드 URL에 서명하기위한 토큰.drmToken (String) : DRM 라이센스 및 관련 URL에 서명하기위한 토큰.targetLiveWindow (Number) : 라이브 컨텐츠를위한 추구 가능한 범위를 나타내는 오프셋, Infinity 전체 라이브 컨텐츠를 찾을 수 있음을 의미합니다 (일명 "표준 DVR"). streamType 와 함께 사용하여 어떤 UI/컨트롤을 보여줄지 결정합니다.liveEdgeOffset (숫자) : 라이브 콘텐츠를 위해 "The Live Edge"를 재생하는 가장 빠른 재생 시간.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이 일을 현지에서 개발하려면이 빨판을 복제하고 연결할 수 있습니다. 그냥 알아요 ... 지금은 좋은 시간이 아닙니다.
cdnpm install && npm run buildcd ../ (또는 테스트 앱을 만들려면 어디로 가든)npx create-next-appcd your-next-appnpx link ../next-video (또는이 리포지어를 복제 한 곳)