next-video La prochaine vidéo est un composant React pour ajouter une vidéo à votre application Next.js. Il étend à la fois l'élément <video> et votre prochaine application avec des fonctionnalités d'optimisation vidéo automatique.
import Video from 'next-video' ;
import getStarted from '/videos/get-started.mp4' ;
export default function Page ( ) {
return < Video src = { getStarted } /> ;
} Dans la racine de votre projet Next.js, exécutez:
npx -y next-video initCe sera (avec incitation):
next-video comme dépendancenext.config.js/videos dans votre projet où vous allez mettre tous les fichiers source vidéo. Il mettra également à jour votre fichier .gitignore pour ignorer les fichiers vidéo dans le répertoire /videos . Les vidéos, en particulier n'importe quelle taille raisonnable, ne doivent pas être stockées / suites par Git. Alternativement, si vous souhaitez stocker les fichiers d'origine, vous pouvez supprimer les lignes Gitignore ajoutées et installer GIT-LFS.
Vercel recommande d'utiliser une plate-forme de contenu dédiée pour la vidéo car les fichiers vidéo sont importants et peuvent conduire à une utilisation excessive de la bande passante. Par défaut, Next-Video utilise MUX (une API vidéo pour les développeurs), qui est construite par les créateurs de Video.js, alimente les applications de streaming populaires comme Patreon et dont la surveillance des performances vidéo est utilisée sur les plus grands événements en direct du monde.
.env.local (ou aussi que vous exportez des variables ENV locales) # .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
Si vous utilisez des modules 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
Si vous utilisez des modules ES:
import { withNextVideo } from 'next-video/process' ;
/** @type {import('next').NextConfig} */
const nextConfig = { } ;
export default withNextVideo ( nextConfig ) ; tsconfig.json Ceci n'est requis que si vous utilisez TypeScript et que vous vous assurez que vos importations de fichiers vidéo ne vous crient pas pour les types manquants. video.d.ts aurait dû être créé dans la racine de votre projet lorsque vous exécutez npx next-video init , sinon vous pouvez le créer manuellement:
// video.d.ts
/// <reference types="next-video/video-types/global" /> Ensuite, ajoutez ce fichier au tableau include dans tsconfig.json .
{
// ...
"include" : [ "video.d.ts" , "next-env.d.ts" , /* ... */ ]
// ...
} Ajoutez des vidéos localement au répertoire /videos , puis exécutez npx next-video sync . Les vidéos seront automatiquement téléchargées sur le stockage à distance et optimisées. Vous remarquerez /videos/[file-name].json file-namemal..json que des fichiers sont également créés. Ceux-ci sont utilisés pour cartographier vos fichiers vidéo locaux sur les nouveaux actifs vidéo hébergés à distance. Ces fichiers JSON doivent être vérifiés dans GIT.
npx next-video sync
Vous pouvez également ajouter next-video sync -w avec le script de développement pour synchroniser automatiquement les vidéos car elles sont ajoutées aux /videos pendant que le serveur de développement s'exécute.
// package.json
"scripts" : {
"dev" : "next dev & npx next-video sync -w" ,
} , Vous pouvez désormais utiliser le composant <Video> de votre application. Disons que vous avez ajouté un fichier appelé awesome-video.mp4 à /videos
import Video from 'next-video' ;
import awesomeVideo from '/videos/awesome-video.mp4' ;
export default function Page ( ) {
return < Video src = { awesomeVideo } /> ;
} Alors qu'une vidéo est en cours de téléchargement et de traitement, <Video> tentera de lire le fichier local. Cela ne se produit que pendant le développement local car le fichier local n'est jamais téléchargé sur votre dépôt git.
Pour les vidéos qui sont déjà hébergées à distance (par exemple sur AWS S3), importez l'URL distante et actualisez la page. Cela crée un fichier JSON local dans le dossier /videos et le script de synchronisation démarrera le téléchargement de la vidéo.
import Video from 'next-video' ;
import awesomeVideo from 'https://www.mydomain.com/remote-video.mp4' ;
export default function Page ( ) {
return < Video src = { awesomeVideo } /> ;
}Si la vidéo hébergée est un seul fichier comme un MP4, le fichier sera automatiquement optimisé pour une meilleure délivrabilité et compatibilité.
Dans certains cas, vous n'avez peut-être pas l'URL vidéo distante disponible au moment de l'importation.
Cela peut être résolu en créant un nouveau point de terminaison de l'API dans votre application Next.js pour /api/video avec le code suivant.
Routeur d'application (next.js> = 13)
// app/api/video/route.js
export { GET } from 'next-video/request-handler' ;Pages Router (Next.js)
// pages/api/video/[[...handler]].js
export { default } from 'next-video/request-handler' ; Définissez ensuite l'attribut src à l'URL de la vidéo distante, actualisez la page et la vidéo commencera à traiter.
import Video from 'next-video' ;
export default function Page ( ) {
return < Video src = "https://www.mydomain.com/remote-video.mp4" /> ;
} Vous pouvez modifier le thème du lecteur en passant le theme Prop en composant <Video> .
Voir le joueur.style pour plus de thèmes.
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 } /> ;
} Depuis v1.1.0 vous pouvez importer directement le composant de lecteur et l'utiliser sans aucune fonction de téléchargement et de traitement.
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..."
/> ;
}Vous pouvez ajouter une affiche personnalisée et Blurdataurl à la vidéo en les faisant passer sous forme d'accessoires.
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 }
/> ;
}Il s'agit d'une bonne solution, mais elle ne fournira pas le même niveau d'optimisation que l'affiche automatique et Blurdataurl par le fournisseur par défaut.
Pour obtenir le même niveau d'optimisation, vous pouvez utiliser un élément d'affiches à fentes.
Ajoutez un élément d'image de l'affiche à fente (comme next/image ) à la vidéo en le faisant passer comme un enfant avec un attribut slot="poster" .
Maintenant, votre image bénéficiera de tous les avantages du composant d'image utilisé et il sera bien placé derrière les commandes du lecteur vidéo.
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 >
) ;
} Vous pouvez personnaliser le lecteur en passant un composant de lecteur personnalisé à l' as Prop.
Le composant de joueur personnalisé accepte les accessoires suivants:
asset : L'actif traité, contient des métadonnées d'attente utiles et du statut de téléchargement.src : une URL de source vidéo de chaîne si l'actif est prêt.poster : URL de source d'image de chaîne si l'actif est prêt.blurDataURL : URL de source d'image Base64 String Base64 qui peut être utilisée comme espace réservée. 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 }
/> ;
} Vous pouvez utiliser un composant <BackgroundVideo> pour ajouter une vidéo en arrière-plan sans commandes de lecteur. Cela permet d'économiser environ 50% de la taille du lecteur JS et est optimisé pour l'utilisation de la vidéo d'arrière-plan.
Le composant <BackgroundVideo> est un lecteur personnalisé comme vous l'avez vu dans la section précédente.
Le paramètre de requête thumbnailTime dans l'exemple ci-dessous est utilisé pour générer une image d'affiche et brouiller l'image à l'heure spécifiée de la vidéo (limité à l'utilisation avec le fournisseur 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 >
) ;
} Vous pouvez choisir entre différents fournisseurs de traitement vidéo et d'hébergement. Le fournisseur par défaut est MUX. Pour modifier le fournisseur, vous pouvez ajouter une option provider dans la configuration de la vidéo suivante. Certains fournisseurs nécessitent une configuration supplémentaire qui peut être transmise dans la propriété 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' }
}
} ) ;Provideurs soutenus avec leurs variables d'environnement requises:
| Fournisseur | Environnement VARS | Configuration du fournisseur | Lien de tarification |
|---|---|---|---|
mux (par défaut) | MUX_TOKEN_IDMUX_TOKEN_SECRET | Prix | |
vercel-blob | BLOB_READ_WRITE_TOKEN | Prix | |
backblaze | BACKBLAZE_ACCESS_KEY_IDBACKBLAZE_SECRET_ACCESS_KEY | endpointbucket (facultatif) | Prix |
amazon-s3 | AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY | endpointbucket (facultatif) | Prix |
cloudflare-r2 | R2_ACCESS_KEY_IDR2_SECRET_ACCESS_KEYR2_CF_API_TOKEN (facultatif lorsque set bucketUrlPublic ) | bucket (facultatif)bucketUrlPublic (Facultatif lorsque R2_CF_API_TOKEN SET) | Prix |
| MUX (par défaut) | Vercel Blob | Imperméable | Amazon S3 | Cloudflare r2 | |
|---|---|---|---|---|---|
| Stockage hors réfins | ✅ | ✅ | ✅ | ✅ | ✅ |
| Livraison via CDN | ✅ | ✅ | - | - | ✅ |
| Joueur BYO | ✅ | ✅ | ✅ | ✅ | ✅ |
| Comprimé pour le streaming | ✅ | - | - | - | |
| S'adapter aux réseaux lents (HLS) | ✅ | - | - | - | |
| Affiche d'espaceur d'espaceur automatique | ✅ | - | - | - | |
| Chronologie en survol des miniatures | ✅ | - | - | - | |
| Diffuser n'importe quel format source | ✅ | * | * | * | * |
| Légendes de l'IA et sous-titres | ✅ | - | - | - | |
| Analyse vidéo | ✅ | - | - | - | |
| Prix | Procès-verbal | GB | GB | GB | GB |
* Fichiers MP4 compatibles avec le Web requis pour héberger les fournisseurs sans traitement vidéo
Par défaut, les métadonnées d'actifs sont stockées dans un fichier JSON dans le répertoire /videos . Si vous souhaitez stocker les métadonnées dans une base de données ou ailleurs, vous pouvez personnaliser les crochets de stockage dans un fichier de configuration séparé de Next-Video.
La configuration d'exemple ci-dessous affiche les crochets de stockage par défaut pour le stockage de fichiers JSON.
Ces crochets peuvent être personnalisés pour répondre à vos besoins en modifiant le corps des fonctions loadAsset , saveAsset et 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 ) ) ;
}
} ) ; Importez ensuite la fonction withNextVideo dans votre fichier next.config.mjs .
// next.config.mjs
import { withNextVideo } from './next-video.mjs' ;
/** @type {import('next').NextConfig} */
const nextConfig = { } ;
export default withNextVideo ( nextConfig ) ; Enfin, importez les fonctions GET et POST ou handler dans vos itinéraires API comme bon vous semble. Les gestionnaires attendent une requête url ou un paramètre corporel avec l'URL de la source vidéo.
Ce sont les exemples les plus minimes pour les gestionnaires, vous pourriez généralement ajouter plus d'erreurs et de validation, d'authentification et d'autorisation.
Routeur d'application (next.js> = 13)
// app/api/video/route.js
export { GET , POST } from '@/next-video' ;Pages Router (Next.js)
// pages/api/video/[[...handler]].js
export { handler as default } from '@/next-video' ; Le lecteur par défaut est construit avec Media Chrome.
<video> natif.<mux-video> .<hls-video> .<dash-video> . Le composant <Video> accepte tous les accessoires de l'élément <video> et les accessoires supplémentaires suivants:
src (Asset | String): l'objet Asset vidéo (Import) ou URL source.poster (statimagedata | string): une image d'espace réservé pour la vidéo. (Auto généré pour des vidéos en mux)blurDataURL (String): une URL de source d'image Base64 qui peut être utilisée comme espace réservée. (Auto généré pour des vidéos en mux)theme (composant React): le composant de thème du lecteur. Voir le joueur.style pour plus de thèmes.as (Composant React): un composant de lecteur personnalisé. Voir le joueur personnalisé.transform (fonction): une fonction personnalisée pour transformer l'objet d'actif (Src et affiche).loader (fonction): une fonction personnalisée utilisée pour résoudre les URL vidéo basées sur des chaînes (pas les importations). Le composant <Video> avec une source vidéo en mux accepte les accessoires supplémentaires suivants:
startTime (numéro): l'heure de début de la vidéo en secondes.streamType ("à la demande" | "live"): le type de flux de la vidéo. La valeur par défaut est "à la demande".customDomain (String): attribue un domaine personnalisé à utiliser pour la vidéo MUX.beaconCollectionDomain (String): attribue un domaine personnalisé à utiliser pour la collecte de données MUX. Remarque: doit être défini avant PlayBackID pour s'appliquer à la surveillance des données MUX.envKey (String): Il s'agit de la clé d'environnement pour les données MUX. Si vous utilisez MUX Video, cela est automatiquement défini pour vous. Si vous utilisez un fournisseur différent, vous pouvez le définir sur votre propre clé.disableTracking (boolean): désactive le suivi des données MUX de la lecture vidéo.disableCookies (booléen): désactive les cookies utilisés par les données MUX.preferPlayback ("MSE" | "natif"): Spécifiez si <mux-video> doit essayer d'utiliser l'extension de la source multimédia ou la lecture native (si disponible). Si aucune valeur n'est fournie, <mux-video> choisira en fonction de ce qui est jugé optimal pour le contenu et l'environnement de lecture.maxResolution ("720p" | "1080p" | "1440p" | "2160p"): Spécifiez la résolution maximale que vous souhaitez livrer pour cette vidéo.minResolution ("480p" | "540p" | "720p" | "1080p" | "1440p" | "2160p"): Spécifiez la résolution minimale que vous souhaitez livrer pour cette vidéo.programStartTime (numéro): appliquez des clips instantanés basés sur PDT au début du flux multimédia.programEndTime (Number): Appliquez des clips instantanés basés sur PDT à la fin du flux multimédia.assetStartTime (Number): appliquez des clips instantanés basés sur la chronologie des médias au début du flux multimédia.assetEndTime (Number): appliquez des clips instantanés basés sur le calendrier des médias à la fin du flux multimédia.renditionOrder (String): Modifiez l'ordre dans lequel les interprétations sont fournies dans la liste de lecture SRC. Peut avoir un impact sur les charges de segment initiales. Actuellement, ne prend en charge que "DESC" pour l'ordre descendant.metadataVideoId (String): Il s'agit d'un ID arbitraire envoyé aux données MUX qui devrait ramener à un enregistrement de cette vidéo dans votre base de données.metadataTitle (String): Il s'agit d'un titre arbitraire pour votre vidéo qui sera transmis sous forme de métadonnées dans les données MUX. L'ajout d'un titre vous donnera un contexte utile dans votre tableau de bord de données MUX. (facultatif, mais encouragé)metadataViewerUserId (String): Si vous avez un utilisateur connecté, cela devrait être une valeur d'ID anonymisée qui revient à l'utilisateur de votre base de données qui sera envoyée aux données MUX. Prenez soin de ne pas exposer des informations personnelles identifiables comme les noms, les noms d'utilisateur ou les adresses e-mail. (facultatif, mais encouragé)metadata* (chaîne): cette syntaxe de métadonnées * peut être utilisée pour passer tous les champs de métadonnées de données de données en mux arbitraires.playbackToken (String): Le jeton de lecture pour signer l'URL src .thumbnailToken (String): Le jeton pour signer l'URL poster .storyboardToken (String): Le jeton pour signer l'URL du storyboard.drmToken (String): le jeton pour la signature de licence DRM et les URL connexes.targetLiveWindow (numéro): un décalage représentant la plage de recherche pour le contenu en direct, où Infinity signifie que le contenu en direct est recherchable (aka "DVR standard"). Utilisé avec streamType pour déterminer les UI / contrôles à montrer.liveEdgeOffset (numéro): la première fois de lecture qui sera traitée comme jouant "at the live edge" pour le contenu en direct.debug (Boolean): Active le mode de débogage pour le moteur de lecture sous-jacent (actuellement HLS.JS) et MUX, fournissant des informations supplémentaires dans la console. {
"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-* "
}
]
}Configurez le seau pour l'accès public:
bucket dans la configuration du fournisseur et assurez-vous qu'il est configuré pour l'accès publicbucketUrlPublicFournir une clé API CloudFlare:
R2_CF_API_TOKENSi vous voulez développer cette chose localement, vous pouvez cloner et lier cette ventouse. Sachez juste ... ce n'est pas un bon moment pour le moment.
cd dans le reponpm install && npm run buildcd ../ (ou retour à où vous souhaitez créer une application de test)npx create-next-appcd your-next-appnpx link ../next-video (ou partout où vous avez cloné ce repo)