Skip to content

Voix ​

(3.0.0+ — transport LiveKit, remplace le maillage WebRTC des versions 2.x) Référence complète du système vocal : rejoindre un salon vocal, diffuser de l'audio, et écouter la présence des participants. Voir aussi le guide Salons vocaux pour une introduction pas-à-pas.

Changement majeur en 3.0.0

Le SDK ne fait plus sa propre signalisation WebRTC en maillage (un RTCPeerConnection par participant) — il se connecte au SFU LiveKit self-hosted de BloumeChat, exactement comme le client web. L'API publique (VoiceConnection, play(), setState()…) reste la même dans l'esprit, mais VoicePeerConnection a disparu et l'événement audioPacket (Opus brut) est remplacé par audioFrame (PCM déjà décodé). Voir le CHANGELOG.

Notation des signatures

Les signatures sont écrites en notation TypeScript, mais s'appellent à l'identique en JavaScript — voir Utiliser le SDK en JavaScript.

VoiceManager ​

Accessible via client.voice. Gère la connexion vocale unique du bot — la session socket du bot ne peut être membre que d'un seul salon vocal à la fois côté serveur, VoiceManager ne suit donc jamais qu'une seule VoiceConnection.

Propriété/MéthodeTypeDescription
connectionVoiceConnection | null (getter)La connexion vocale active, ou null.
join(channel, options?)Promise<VoiceConnection>Rejoint un salon vocal — quitte d'abord la connexion précédente si elle existe. Préférez channel.join().
leave()voidQuitte le salon vocal actif, si le bot y est connecté.

VoiceStateManager ​

(4.1.0+) Accessible via client.voiceStates. Cache de l'état vocal courant de chaque utilisateur connu (userPublicId → VoiceState), alimenté automatiquement par les événements voice:* (voir le guide Événements) — aucun appel réseau, aucun fetch à faire. BloumeChat n'expose aucune route REST « état vocal courant » : ce cache est la seule source pour répondre à « dans quel salon vocal est cet utilisateur ? ».

PropriétéTypeDescription
cacheCollection<string, VoiceState>Clé = userPublicId. Voir Collection.

Préférez member.voice

Si vous avez déjà un Member sous la main, member.voice fait exactement client.voiceStates.cache.get(member.user.id) — plus lisible dans la plupart des cas.

Cache best-effort

Une entrée n'existe que si le bot a déjà reçu au moins un événement voice:* concernant cet utilisateur (le rejoindre un salon en fait partie). Un utilisateur en vocal avant le démarrage du bot n'y apparaîtra qu'après le prochain événement le concernant — ce n'est pas une garantie équivalente à une requête REST.

Channel.join(options?): Promise<VoiceConnection> ​

ts
join(options?: VoiceJoinOptions): Promise<VoiceConnection>

Rejoint ce salon vocal. Lève une BloumeChatVoiceError si channel.type !== "VOICE", ou si le serveur ne confirme pas la connexion avant options.timeoutMs.

VoiceJoinOptions ​

ts
interface VoiceJoinOptions {
  selfMute?: boolean;   // rejoint directement en muet — défaut false
  selfDeaf?: boolean;   // rejoint directement en sourdine — défaut false
  timeoutMs?: number;   // délai max d'attente de confirmation serveur — défaut 15000
}

Channel.leave(): void ​

Quitte ce salon vocal si le bot y est actuellement connecté (ne fait rien sinon, y compris si le salon n'est pas de type "VOICE").

VoiceConnection ​

Retournée par channel.join() / client.voice.join(). Étend EventEmitter.

Propriétés ​

PropriétéTypeDescription
channelIdstringIdentifiant public du salon vocal.
state"connecting" | "ready" | "destroyed"État de la connexion.
participantsVoiceUser[] (getter)Snapshot courant des participants (y compris le bot).
isPlayingboolean (getter)true si un flux audio est en cours de lecture (et non en pause).
isPausedboolean (getter)true si la lecture est en pause.

Méthodes — état ​

MéthodeDescription
setState(state: VoiceStateUpdate): voidEnvoie un patch d'état brut (muted, deafened, speaking…).
setMuted(muted: boolean): voidRaccourci pour setState({ muted }).
setDeafened(deafened: boolean): voidRaccourci pour setState({ deafened }).

Méthodes — lecture audio ​

play(resource, options?): void ​

ts
play(resource: string | NodeJS.ReadableStream, options?: PlayOptions): void

Décode resource (chemin de fichier, URL http(s), ou flux Readable) via FFmpeg (sauf inputType: "raw") et publie une trame PCM de 20ms toutes les 20ms sur la piste audio LiveKit du bot — LiveKit encode l'Opus et diffuse à tous les participants du salon. Interrompt toute lecture déjà en cours.

PlayOptions ​
ts
interface PlayOptions {
  inputType?: "auto" | "raw";  // "raw" attend un flux PCM s16le 48kHz stéréo déjà décodé — défaut "auto"
  volume?: number;             // multiplicateur linéaire appliqué avant l'encodage Opus — défaut 1
  ffmpegArgs?: string[];       // arguments FFmpeg additionnels insérés juste après `-i <input>`
}
ts
connection.play("./musique.mp3");
connection.play("https://example.com/stream.mp3", { volume: 0.7 });

// Flux PCM brut déjà décodé (pas de passage par FFmpeg)
connection.play(pcmReadableStream, { inputType: "raw" });
js
connection.play("./musique.mp3");
connection.play("https://example.com/stream.mp3", { volume: 0.7 });

connection.play(pcmReadableStream, { inputType: "raw" });

Autres contrôles ​

MéthodeDescription
pause(): voidSuspend la lecture (position conservée). Ne fait rien si rien ne joue.
resume(): voidReprend une lecture en pause.
setVolume(volume: number): voidAjuste le volume en cours de lecture (0 = silence, 1 = inchangé).
stopPlaying(): voidArrête et libère le pipeline de décodage/encodage.

Méthodes — cycle de vie ​

MéthodeDescription
destroy(): voidQuitte le salon et se déconnecte de LiveKit. Idempotent (sans effet si déjà détruite). Préférez channel.leave() / client.voice.leave().

Événements ​

EventPayloadNotes
ready—Le salon LiveKit est rejoint et la piste audio du bot est publiée.
destroyed—La connexion a été fermée (départ volontaire ou expulsion).
userJoinedVoiceUserUn autre participant a rejoint le salon (présence — indépendant du transport média).
userLeftuserPublicId: stringUn participant est parti.
userStateUpdateVoiceUserStateDataÉtat d'un participant modifié (muet, sourdine, parle, partage d'écran…).
playerStart—La lecture audio démarre.
playerFinish—La lecture audio se termine (fin de flux ou stopPlaying()).
audioFrame(userPublicId: string, samples: Int16Array, sampleRate: number, channels: number)Trame PCM décodée reçue d'un participant — voir Audio entrant. LiveKit décode déjà l'Opus pour vous, contrairement à l'ancien audioPacket (Opus brut) — PCM directement exploitable pour de la reconnaissance vocale.
errorErrorErreur de connexion LiveKit ou de pipeline audio.

Types ​

VoiceUser ​

ts
interface VoiceUser {
  userPublicId: string;
  userName: string;
  userTag: string;
  userImage: string | null;
  socketId: string;
  muted: boolean;
  deafened: boolean;
  speaking: boolean;
  joinedAt: number;
  isStreaming: boolean;
  isCameraOn: boolean;
  cameraStreamId?: string | null;
  screenStreamId?: string | null;
  cameraTrackId?: string | null;
  screenTrackId?: string | null;
}

VoiceState ​

(4.1.0+) L'état vocal courant d'un utilisateur, tel que mis en cache par VoiceStateManager (client.voiceStates) et exposé par member.voice. Étend VoiceUser en y ajoutant le salon concerné.

ts
interface VoiceState extends VoiceUser {
  channelId: string;
}

VoiceStateUpdate ​

Patch partiel accepté par connection.setState() — tous les champs sont optionnels, seuls ceux fournis sont modifiés côté serveur.

ts
interface VoiceStateUpdate {
  muted?: boolean;
  deafened?: boolean;
  speaking?: boolean;
  isStreaming?: boolean;
  isCameraOn?: boolean;
  cameraStreamId?: string | null;
  screenStreamId?: string | null;
  cameraTrackId?: string | null;
  screenTrackId?: string | null;
}

VoiceUserJoinedData ​

ts
interface VoiceUserJoinedData {
  channelPublicId: string;
  user: VoiceUser;
  users: VoiceUser[]; // snapshot complet du salon au moment de l'événement
}

VoiceUserStateData ​

ts
interface VoiceUserStateData extends VoiceStateUpdate {
  channelPublicId: string;
  userPublicId: string;
}

VoiceUsersSnapshot ​

ts
interface VoiceUsersSnapshot {
  channelPublicId: string;
  users: VoiceUser[];
  startedAt?: number;
}

VoiceIncomingCallData ​

ts
interface VoiceIncomingCallData {
  channelPublicId: string;
  fromUser: { userPublicId: string; userName: string; userImage: string | null };
}

Toutes les exportations ​

ts
import {
  VoiceManager,
  VoiceStateManager,
  VoiceConnection,
  AudioPlayer,
  BloumeChatVoiceError,
} from "bloumechat";

import type {
  VoiceUser,
  VoiceState,
  VoiceStateUpdate,
  VoiceUserJoinedData,
  VoiceUserLeftData,
  VoiceUserStateData,
  VoiceUsersSnapshot,
  VoiceIncomingCallData,
  VoiceCallCancelledData,
  VoiceJoinOptions,
  PlayOptions,
  AudioResource,
  VoiceConnectionState,
  LiveKitTokenData,
} from "bloumechat";

AudioPlayer est un détail d'implémentation

Il est exporté pour un usage avancé (inspection, tests), mais dans l'immense majorité des cas vous n'interagissez qu'avec VoiceConnection — le SDK crée et gère AudioPlayer en interne.

Voir aussi ​

SDK publié sous licence ISC.