Comment mettre en place le live streaming dans Next.js

Une diffusion en direct ressemble à une seule fonctionnalité, et dans une application Next.js, il y en a plusieurs. Quelqu’un passe en direct depuis le navigateur, ou depuis un encodeur comme OBS. Tous ceux qui ont le droit de regarder le voient et l’entendent au même moment, assez près pour poser une question et obtenir la réponse. Les spectateurs écrivent dans un chat, réagissent, et certains montent sur scène avec leur propre caméra. Et avant tout cela, votre application doit décider qui diffuse, qui regarde et qui apprend qu’une diffusion a commencé.
Cet article passe en revue chaque partie dont une vraie application a besoin, avec un exemple complet qui fonctionne : Live Lessons, le site de cours en direct de notre guide Next.js, où des professeurs de cuisine, de musique et de fitness passent en direct dans leurs leçons, et où les élèves regardent, posent des questions et montent sur scène. Vous pouvez l’essayer en ligne : soyez Mia et passez en direct depuis son studio, puis ouvrez sa leçon dans une fenêtre privée en tant qu’Ava, l’une de ses élèves, pour regarder et lever la main.
Ce que demande une diffusion en direct
- L’image qui entre. La caméra et le micro depuis le navigateur, un écran partagé avec son son, ou un encodeur en WHIP pour des scènes et plusieurs caméras.
- L’image qui sort, vers beaucoup de monde, au même moment. Une diffusion dont le public répond passe par WebRTC, comme les appels, à travers des serveurs média qui la relaient à chaque spectateur (comment fonctionnent les serveurs média). Ses connexions restent ouvertes pendant toute la diffusion, ce qu’une fonction serverless ne peut pas tenir (pourquoi, et que faire).
- Qui diffuse et qui regarde. Une règle sur votre serveur, avec vos propres données : le professeur diffuse, les élèves du cours regardent, et tout le monde peut regarder une leçon ouverte.
- Un studio et un lecteur. Passer en direct et terminer, la caméra et l’écran, le chat, les réactions et le nombre de spectateurs.
- La scène. Un spectateur lève la main, le professeur l’invite, et tout le monde le voit à côté de lui.
- Savoir ce qui est en direct. Des listes des diffusions en cours qui se mettent à jour d’elles-mêmes, et un avis pour ceux qui veulent le savoir.
Vous pouvez construire chacune de ces parties vous-même, sur WebRTC et vos propres serveurs média. Ou vous laissez un cloud temps réel s’occuper des médias, du studio et du lecteur, pendant que votre serveur garde la seule partie qui vous appartient vraiment : la règle. C’est ce que fait Live Lessons, avec WordPlus Cloud.
L’exemple : des cours en direct
Les professeurs ont des cours, chacun avec ses leçons. Une leçon est ouverte à tous, ou réservée aux élèves de son cours. Un professeur passe en direct dans une leçon depuis son studio, et les élèves regardent sur la page de la leçon. C’est une application Next.js avec l’App Router, Better Auth et Postgres, et sa partie temps réel tient en quelques fichiers. Cinq étapes font ses diffusions.
1. Qui peut regarder
Chaque leçon a sa diffusion, nommée d’après son numéro : lesson:7. Le site les déclare une seule fois, selon ce modèle, avec la règle :
realtime.streams(
'lesson:{id}',
async (user, { id }) => {
const lesson = await lessonOf(id);
if (!lesson) return false;
const me = user === null ? null : String(user);
if (me === lesson.teacher) return { role: 'host', quality: '1080p' };
return (await mayWatch(me, lesson)) ? 'viewer' : false;
},
{ stage: true, reactions: true },
);Le professeur est l’hôte, avec une image jusqu’en 1080p. Celui que mayWatch laisse entrer est spectateur, et user vaut null pour un visiteur non connecté, si bien qu’une leçon ouverte ne demande aucun compte. Tous les autres reçoivent false. Les réglages acceptent des invités sur scène et les réactions. La page de la leçon interroge le même mayWatch, donc la page et la diffusion ne se contredisent jamais.
2. Où s’exécute la règle
Quand une page demande à passer en direct, ou à regarder, elle s’adresse d’abord au serveur du site, dans un route handler :
import { currentUserId } from '@/lib/auth';
import { realtime } from '@/lib/realtime';
export async function POST(request: Request) {
// JSON only, which a page of another site can't send here.
if (!request.headers.get('content-type')?.includes('application/json')) {
return new Response(null, { status: 415 });
}
const ask = await request.json();
const user = await currentUserId();
const pass = await realtime.authorizeCall(ask, user);
return Response.json(pass);
}C’est la même route que celle des appels vidéo du site de rencontre (comment mettre en place les appels vidéo dans Next.js). La règle s’exécute avec la session du site, et la page reçoit un laissez-passer pour la diffusion, signé avec le secret de l’application, ou la raison du refus. La route répond en une requête courte, exactement ce que l’hébergement serverless fait bien.
3. Le studio du professeur
Un professeur passe en direct depuis une page à lui, avec le studio de WordPlus Cloud dedans :
<LiveStream
name={roomOf(lesson.id)}
view="studio-page"
title={`${lesson.position}. ${lesson.title}`}
url={`/lessons/${lesson.id}`}
backUrl="/studio"
/>Le studio occupe la hauteur que la page lui donne : l’image aussi grande que possible, avec la caméra, l’écran, OBS et Go live en dessous, et à côté, en onglets, le chat, les invités avec les mains levées, et la diffusion avec le lien de la leçon à partager. Avant cela, la page vérifie que la personne qui demande enseigne la leçon, et renvoie toute autre personne vers la leçon. À la connexion, un professeur arrive sur la liste de ses leçons, chacune à un clic du direct.
4. La page de la leçon
Les élèves regardent là où se trouve la leçon :
<LiveStream
name={roomOf(lesson.id)}
title={lesson.title}
loginUrl="/signin"
studioUrl={teaches ? `/studio/${lesson.id}` : undefined}
/>Un seul élément dessine le lecteur et son chat. Avant le début de la leçon, il l’indique, et il se lance dès que le professeur passe en direct, sans recharger. Un élève connecté peut écrire, réagir et appuyer sur Ask to join on stage. Un visiteur regarde et lit, avec le moyen de se connecter. Le professeur voit le chemin vers son studio au-dessus du lecteur.
5. Ce qui est en direct, toujours à jour
WordPlus Cloud sait quelles diffusions sont en direct et combien de personnes regardent chacune, donc le site ne tient aucune table pour cela :
export async function liveNow(): Promise<Map<string, number>> {
const live = new Map<string, number>();
for (const stream of await realtime.listStreams()) {
const lesson = lessonIn(stream.name);
if (lesson) live.set(lesson, stream.viewers);
}
return live;
}La page d’accueil liste ainsi les leçons en direct. Pour que cette liste reste à jour sur les pages déjà ouvertes, WordPlus Cloud envoie au site un webhook quand une diffusion commence et quand elle se termine, et le site le transmet à un salon que rejoint chaque page, y compris celle d’un visiteur :
realtime.room('live', { public: true });
realtime.on('stream.ended', async ({ stream }) => {
if (lessonIn(stream)) await realtime.to('live').emit('changed');
});export function LiveNow() {
const router = useRouter();
useRoom('live', { changed: () => router.refresh() });
return null;
}LiveNow se trouve dans le layout, donc chaque page redemande ses listes au serveur, sans recharger. Le webhook stream.live fait de même, et prévient en plus les élèves du cours, et pour une leçon ouverte les abonnés de son professeur, par un avis sur la page où ils se trouvent : « Mia is live: Your first tune ».
La scène, sans code de votre part
stage: true dans la règle suffit pour la scène. Pendant qu’une leçon est en direct, un élève lève la main depuis le lecteur, le professeur la voit sous Guests et appuie sur Invite, et dès que l’élève accepte, tout le monde le voit à côté du professeur, caméra et micro. Le professeur peut lui couper le micro ou le faire descendre de scène, et l’élève peut la quitter lui-même et revenir au visionnage sans recharger.
Ce qui est inclus
- Depuis le navigateur ou avec OBS. Le studio passe en direct avec la caméra, avec un écran et son son, ou les deux, ou reçoit OBS ou tout autre encodeur en WHIP.
- Au même moment. La diffusion passe par WebRTC, donc une question dans le chat arrive au professeur pendant qu’il est encore sur le sujet.
- Un chat bien tenu. Les modérateurs épinglent, suppriment, rendent muet un moment, expulsent et bannissent, et la règle peut faire d’un assistant du professeur un modérateur :
{ role: 'viewer', mod: true }. - Retirer l’accès. Quand un élève quitte un cours, le site le retire des leçons en direct de ce cours avec
realtime.stream(name).kick(), et la règle dit non à partir de là.
Essayez, puis construisez le vôtre
Sur la démo en ligne, les professeurs et les élèves sont rien qu’à vous pendant une journée, si bien que personne d’autre ne voit ce que vous y diffusez ou écrivez. Sous chaque page, How this page works montre le code qui la fait fonctionner, étape par étape, avec les valeurs de la page que vous avez ouverte.
Le guide de Live Lessons construit tout le site, avec chaque fichier de sa partie temps réel en entier, et les diffusions en direct dans Next.js présente toutes les façons de mettre une diffusion dans votre propre application, y compris avec votre propre interface.
WordPlus Cloud for Apps a un prix selon les connexions simultanées, à partir de 1 000, facturé au mois ou à l’année. Avec 1 000 connexions, les diffusions en direct ne sont pas décomptées jusqu’à 50 spectateurs à la fois, et chaque tranche de 1 000 connexions en plus en ajoute 20. Au-delà, chaque spectateur de plus prend un crédit par minute, compté seulement pendant que la diffusion est en direct. Découvrez le live streaming pour les applications, ou consultez les tarifs pour les applications. Des questions sur votre intégration ? Écrivez-nous.