Comment mettre en place des appels vidéo dans Next.js

Un appel vidéo a l’air d’une seule fonctionnalité, et dans une application Next.js, il en réunit plusieurs. Deux navigateurs doivent se trouver et s’entendre sur la façon de se connecter. La personne appelée doit l’entendre sonner, quelle que soit la page où elle se trouve. Certains réseaux ne laissent jamais passer une connexion directe. Et avant tout cela, votre application doit décider qui peut appeler qui.
La plupart des tutoriels s’arrêtent à deux navigateurs sur une même page, qui s’échangent des offres à la main. Cet article passe en revue chaque partie dont une vraie application a besoin, avec un exemple complet qui fonctionne : le site de rencontre de notre guide Next.js, où deux membres se retrouvent pour un rendez-vous vidéo dans leur chat. Vous pouvez l’essayer en ligne : choisissez qui vous serez, puis ouvrez-le dans une fenêtre de navigation privée, choisissez quelqu’un d’autre, et lancez l’appel.
Ce qu’il faut à un appel vidéo
- La signalisation et la sonnerie. Avant la moindre image, les deux navigateurs échangent des offres et des candidats réseau par l’intermédiaire d’un serveur, et l’appel doit sonner dans chaque onglet que la personne appelée a ouvert. Il faut pour cela des connexions ouvertes en permanence, ce qu’une fonction serverless ne peut pas garder (pourquoi, et que faire).
- Un chemin entre les navigateurs. En direct quand leurs réseaux le permettent, et par un relais quand ce n’est pas le cas (les serveurs STUN et TURN expliqués).
- Qui peut appeler qui. Une règle sur votre serveur, fondée sur les données de votre application, vérifiée avant que quoi que ce soit ne sonne.
- La caméra et le micro. Une seule demande d’autorisation du navigateur, le changement d’appareil, le micro coupé et la caméra éteinte.
- Un écran d’appel. La sonnerie, décrocher et refuser, les deux vidéos, la durée, raccrocher.
- Des serveurs multimédias, dès qu’un appel réunit plus de deux personnes (comment fonctionnent les appels de groupe).
Vous pouvez construire chacun de ces éléments vous-même sur WebRTC. Ou bien vous laissez un cloud temps réel gérer les connexions, la sonnerie et les relais, pendant que votre serveur garde la seule partie qui vous appartient vraiment : la règle. C’est ce que fait le site de rencontre, avec WordPlus Cloud.
L’exemple : des rendez-vous vidéo sur un site de rencontre
Les membres du site trouvent les personnes qu’ils recherchent, voient qui est en ligne, discutent, et se donnent rendez-vous en vidéo avant de se rencontrer en personne. C’est une application Next.js avec l’App Router et Postgres, et sa partie temps réel tient en quelques fichiers. Ses appels se construisent en quatre étapes.
1. Qui peut appeler qui
Sur un site de rencontre, deux personnes peuvent se parler quand chacune recherche l’autre et qu’aucune n’a bloqué l’autre. Le site écrit cette règle une seule fois, dans canMeet, et représente un chat par un numéro et ses membres. mayChat indique qu’une personne peut utiliser un chat quand elle en est membre et peut encore rencontrer chacun des autres. Les appels sont déclarés par le nom du salon du chat, avec cette règle pour les deux personnes :
realtime.calls('chat:{id}', async (user, other, { id }) => {
// The one asking: who calls, as they call, or who is called, as they answer.
const userMayChat = await mayChat(user, id);
// The other one of the call.
const otherMayChat = await mayChat(other, id);
return userMayChat && otherMayChat;
});Elle s’exécute pour la personne qui appelle, puis à nouveau pour la personne appelée quand elle décroche. Un blocage prend donc effet immédiatement : dès que l’un bloque l’autre, canMeet répond non, et l’appel suivant est refusé.
2. Où la règle s’exécute
Quand une page demande à appeler, ou à décrocher, elle s’adresse d’abord au serveur du site lui-même, 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);
}currentUserId() repose sur l’authentification propre au site, si bien que la session y fonctionne comme sur n’importe quelle page. Quand la règle dit oui, la page reçoit un laissez-passer signé avec le secret de l’application, et WordPlus Cloud s’en sert pour faire sonner l’appel chez l’autre personne. La route répond en une seule requête courte, exactement ce pour quoi un hébergement serverless est fait.
3. La sonnerie sur chaque page
Le layout des pages réservées aux membres connectés établit la connexion une seule fois, et rend l’écran d’appel à côté des pages :
'use client';
import '@wordplus/realtime-ui/calls.css';
import '@wordplus/realtime-ui/chat.css';
import { useRealtime } from '@wordplus/realtime/react';
import { CallScreen } from '@wordplus/realtime-ui/react';
export function Screens() {
return <CallScreen rt={useRealtime()} />;
}<Screens /> se trouve dans RealtimeProvider, dans app/(app)/layout.tsx, si bien qu’un appel sonne sur n’importe quelle page qu’un membre a ouverte, dans chaque onglet et sur chaque appareil, et cesse de sonner partout dès qu’il est décroché à un endroit. L’écran d’appel est celui de Better Messages, rendu dans l’arbre React du site lui-même, si bien que le CSS du site s’y applique.
4. L’appel dans son chat
Sur un site de rencontre, l’appel a sa place dans la conversation. Le chat de la page d’un membre accueille son appel, à côté des messages :
<Chat
rt={useRealtime()}
room={room}
to={to}
name={name}
avatar={avatar}
call
startCall={start}
/>Sa barre du haut montre l’autre personne avec ses boutons d’appel. Le bouton vidéo d’une fiche du catalogue ouvre le chat avec l’appel qui démarre (startCall), si bien que le rendez-vous commence là où les deux peuvent aussi s’écrire.
Le chat n’est qu’un endroit parmi d’autres pour un appel. Un CallButton en lance un depuis n’importe où, un CallSpot affiche les appels dans la partie de la page de votre choix, et useCalls vous donne chaque appel pour dessiner votre propre écran.
Ce que vous obtenez en plus
- Une seule demande. Le navigateur demande une seule fois l’accès à la caméra et au micro, ensemble.
- L’appel se connecte toujours. Un appel entre deux personnes passe directement d’un navigateur à l’autre quand c’est possible, par des relais sur les ports que tout réseau laisse ouverts quand ça ne l’est pas, et par des serveurs multimédias quand même ces relais ne passent pas, en basculant de l’un à l’autre sans raccrocher, chiffré sur chaque chemin.
- Il tient bon. La connexion, et l’appel avec elle, reste en place pendant que le membre passe d’une page du site à l’autre.
- Les appels de groupe sur la même API. Un salon qui réunit plus de personnes tourne sur des serveurs multimédias, avec son propre bouton et son propre écran d’appel de groupe (les appels vidéo pour les applications).
Essayez, puis construisez votre propre application
Sur la démo en ligne, les onze personnes sont rien qu’à vous pendant une journée, si bien que personne d’autre ne voit ce que vous y écrivez ni qui vous y appelez. 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 du site de rencontre construit tout le site, avec chaque fichier de sa partie temps réel en entier, et les appels dans Next.js présente toutes les façons de lancer un appel dans votre propre application.
WordPlus Cloud for Apps a un prix selon les connexions simultanées, à partir de 1 000, facturé au mois ou à l’année. Découvrez ce qu’il apporte aux applications, ou consultez les tarifs pour les applications. Des questions sur votre intégration ? Écrivez-nous.