Mit der JavaScript-API steuern Sie aus Ihrer eigenen Seite heraus einen laufenden Meetingraum. Sie muten Teilnehmer, lesen die Teilnehmerliste, senden Chat-Nachrichten, wechseln Geräte und hören auf Events. Das gelingt Ihnen mit einem eingebetteten iFrame genauso wie mit den Web-Komponenten von Veeting Blocks.
Wenn Sie mit einem KI-Coding-Assistenten arbeiten, können Sie den folgenden Text in Ihren Assistenten kopieren und mit einem Satz ergänzen, der beschreibt, was Sie programmieren möchten.
Der Prompt verweist auf unsere Entwicklerdokumentation, die wir für Coding-Assistenten in einer separaten, token-optimierten KI-Version ausliefern.
Lies zuerst diese Seite, bevor Du Code schreibst:
https://www.veeting.com/de/developer-documentation/javascript-apis
Sie dokumentiert die JavaScript-API eines Veeting Rooms
Meetingraums. Halte Dich an diese fünf Regeln:
1. Frage mich zuerst, ob mein Code IM Raum läuft (Veeting Blocks,
ein eigenes Tool) oder in der Seite rund um einen eingebetteten
iFrame. Beide erreichen die API völlig unterschiedlich, und die
Antwort ändert alles Weitere.
2. Warte auf das Event «joined», bevor Du Methoden aufrufst, die
die Anwesenheit im Meeting voraussetzen.
3. «connected» und «disconnected» beziehen sich auf den WebSocket
zu unserer API, nicht auf WebRTC-Medien. Behandle sie nicht als
Medienzustand.
4. Verwende nur Methoden, die auf dieser Seite stehen. Erfinde
keine und rate keine Signatur.
5. Aus einer übergeordneten Seite sprichst Du per postMessage mit
dem Raum: {action, payload} hinein, {event, payload} heraus. Das
geht nur in eine Richtung, Methoden mit Rückgabewert nützen dort
also nichts. Prüfe message.origin bei allem, was ankommt.
Was ich bauen möchte:Das ist wichtiger als alles andere auf dieser Seite, klären Sie es deshalb zuerst.
| Ihr Code läuft | So erreichen Sie die API |
|---|---|
| Im Meetingraum selbst, also in Veeting Blocks oder in einem eigenen Tool | Direkt über den Handler. Die vollständige API, samt Rückgabewerten. |
| In der Seite rund um einen eingebetteten iFrame | Über postMessage. Sie rufen jede Methode ohne Rückgabewert auf und empfangen jedes Event. |
Betten Sie den Raum als iFrame ein, sind Ihre Seite und der Meetingraum zwei verschiedene Dokumente, meist auf zwei verschiedenen Origins. Ihre Seite kommt nicht an das window des Raums heran und der Raum nicht an Ihres. Alles überquert diese Grenze als Nachricht.
Unterschiedliche Origins sind vorgesehen und unterstützt. Der Raum läuft normalerweise unter Ihrer eigenen White-Label-Domain, meeting.example.com, während Ihre Anwendung unter app.example.com oder ganz woanders liegt. Beides braucht keine Sonderbehandlung: Eine andere Subdomain und eine völlig andere Domain verhalten sich hier gleich.
Der Meetingraum sendet jedes Event an sein übergeordnetes Fenster. Hören Sie darauf:
window.addEventListener("message", (message) => {
// Always check the origin. The room posts to any parent, so this check is
// yours to make, and without it any page could forge these events.
if (message.origin !== "https://<DOMAIN-NAME>") {
return;
}
const { event, payload } = message.data;
if (event === "joined") {
console.log("The meeting room is ready");
}
if (event === "participantsUpdated") {
console.log(`${payload.length} participants in the room`);
}
});event ist einer der 12 Namen weiter unten, payload genau das, was dieses Event mitführt. Sie müssen nichts abonnieren: Jedes Event geht an die übergeordnete Seite, ob Sie darauf hören oder nicht.
Senden Sie dem iFrame eine Nachricht mit dem Namen der Methode und ihren Argumenten:
const room = document.getElementById("meeting-frame");
room.contentWindow.postMessage({
action: "muteAudio",
payload: [true]
}, "https://<DOMAIN-NAME>");action ist der Methodenname, payload sind ihre Argumente in der richtigen Reihenfolge als Array. Eine Methode ohne Argumente braucht trotzdem payload: [] oder gar nichts.
Weil der Weg nur in eine Richtung führt, gelten zwei Grenzen:
get beginnt, nützt über diese Grenze hinweg also nichts. Lesen Sie die Teilnehmer aus dem Event participantsUpdated statt über getParticipantsList(), und die Raumkonfiguration aus meetingRoomConfigUpdated.Ihr eigener Mute-Button und Ihr eigener Teilnehmerzähler, in Ihrer eigenen Seite, ausserhalb des iFrames:
<button id="mute">Mute</button>
<span id="count">0</span> participants
<iframe id="meeting-frame"
src="https://<DOMAIN-NAME>/meeting/<MEETING-ID>"
allow="microphone;camera;encrypted-media;fullscreen;autoplay;display-capture;layout-animations;">
</iframe>
<script>
const ROOM_ORIGIN = "https://<DOMAIN-NAME>";
const room = document.getElementById("meeting-frame");
let muted = false;
window.addEventListener("message", (message) => {
if (message.origin !== ROOM_ORIGIN) {
return;
}
if (message.data.event === "participantsUpdated") {
document.getElementById("count").textContent = message.data.payload.length;
}
});
document.getElementById("mute").addEventListener("click", () => {
muted = !muted;
room.contentWindow.postMessage({ action: "muteAudio", payload: [muted] }, ROOM_ORIGIN);
});
</script>Der übrige Teil dieses Abschnitts gilt für Code, der im Meetingraum läuft: Veeting Blocks oder ein eigenes Tool. Betten Sie einen iFrame ein, verwenden Sie stattdessen die Nachrichten oben.
Die API existiert erst, wenn der Meetingraum vollständig geladen ist. Aus einem Skript, das beim Laden der Seite läuft, erreichen Sie sie deshalb noch nicht. Definieren Sie stattdessen auf window eine Funktion wlvmrApiReady. Sobald der Raum bereit ist, ruft er sie auf und übergibt Ihnen den Namen des Objekts, unter dem er sich registriert hat.
window["wlvmrApiReady"] = (handler) => {
if (!window[handler]) {
console.error(`Handler window.${handler} not found!`);
return;
}
// Every API method lives on this object
window[handler].muteAudio(true);
};Daraus folgen zwei Regeln. Beide gehen häufig vergessen:
wlvmrApiReady, bevor der Meetingraum lädt. Weisen Sie die Funktion später zu, ist der Aufruf längst erfolgt und Sie erhalten den Handler nie.window[handler] zu, nie über einen festen Namen.Warten Sie auf den Raum, abonnieren Sie Events und rufen Sie erst dann Methoden auf:
window["wlvmrApiReady"] = (handler) => {
if (!window[handler]) {
console.error(`Handler window.${handler} not found!`);
return;
}
const api = window[handler];
api.on("joined", () => {
console.log("The meeting room is ready to use");
});
api.on("participantsUpdated", (participants) => {
console.log(`${participants.length} participants in the room`);
});
api.on("chatMessage", (message) => {
console.log(`${message.fromParticipantName}: ${message.message}`);
});
api.setAudioInputDeviceId("default", false);
api.setVideoInputDeviceId("default", true);
};Sie abonnieren mit on(event, callback). Es gibt 12 Events.
| Event | Löst aus, wenn | Payload |
|---|---|---|
beforeConnecting | Der Raum gleich seine Medien verbindet | keine |
connected | Der WebSocket zur Veeting-API steht und verwendet wird | keine |
joined | Der Meetingraum einsatzbereit ist | keine |
disconnected | Der WebSocket zur Veeting-API getrennt oder ungenutzt ist | keine |
leave | Der Teilnehmer das Meeting verlässt | keine |
participantsUpdated | Jemand beitritt, geht oder seinen Zustand ändert | IApiParticipant[] |
chatMessage | Eine Gruppen-Chatnachricht eintrifft | IApiChatMessage |
privateChatMessage | Eine private Chatnachricht eintrifft | IApiChatMessage |
meetingDurationUpdated | Sich die verbleibende Meeting-Zeit ändert | IApiRemainingTimeUpdate |
meetingRoomConfigUpdated | Sich die Raumkonfiguration ändert | IMeetingRoomConfig |
customMessage | Ein anderer Teilnehmer eine eigene Nachricht sendet | ICustomMessage |
screenshareStateChange | Ein Screensharing startet oder endet | IScreenshareState |
Hinweis:
connectedunddisconnectedbeschreiben den WebSocket zu unserer API, nicht die WebRTC-Medien. Ein Teilnehmer kann von den Medien getrennt sein und trotzdem das Whiteboard nutzen.
| Methode | Beschreibung |
|---|---|
getVersion(): string | Gibt den Versionsstring des laufenden Meetingraums zurück. |
getParticipantsList(): IApiParticipant[] | Gibt die aktuelle Teilnehmerliste zurück. |
leaveMeeting(): void | Trennt die Verbindung zum Server und verlässt den Meetingraum. |
enableFollowMe(enabled: boolean): void | Aktiviert Follow Me. Sie brauchen dafür Moderationsrechte. |
| Methode | Beschreibung |
|---|---|
muteAudio(muted: boolean): void | Schaltet Audio stumm oder wieder ein. |
toggleMuteAudio(): void | Schaltet die Audio-Stummschaltung um. |
muteVideo(muted: boolean): void | Schaltet Video stumm oder wieder ein. |
toggleMuteVideo(): void | Schaltet die Video-Stummschaltung um. |
setVolume(volume: number, meetingParticipantId?: string): void | Setzt die Wiedergabelautstärke, entweder für einen Teilnehmer oder für alle. |
connect(mediaConfig?: { audio: boolean, video: boolean }): void | Verbindet die Medien. Sind sie bereits verbunden, passiert nichts. Beim Beitritt verbindet der Raum die Medien ohnehin selbst. |
disconnect(): void | Trennt die Medien. Sind sie bereits getrennt, passiert nichts. |
restartMediaConnections(): void | Startet die Medienverbindungen neu. Das hilft nach einem Gerätewechsel. |
enterVideoFullscreen(): void | Wechselt in den Fullscreen. Ausser in Chrome scheitert das in den meisten Browsern, denn Fullscreen verlangt eine User-Interaktion. |
| Methode | Beschreibung |
|---|---|
getMediaDeviceSettings(): IMediaDeviceSettings | Gibt die aktuell gewählten Geräte und die Auflösung zurück. |
getMediaDeviceAudioInputList(audioOnly: boolean): MediaDeviceInfo[] | Gibt die verfügbaren Mikrofone zurück. audioOnly beschränkt die Berechtigungsabfrage auf Audio. |
getMediaDeviceAudioOutputList(audioOnly: boolean): MediaDeviceInfo[] | Gibt die verfügbaren Lautsprecher zurück. audioOnly beschränkt die Berechtigungsabfrage auf Audio. |
getMediaDeviceVideoInputList(): MediaDeviceInfo[] | Gibt die verfügbaren Kameras zurück. |
setAudioInputDeviceId(deviceId: string, reconnect: boolean): void | Setzt das Mikrofon. Die API prüft nicht, ob die Geräte-ID gültig ist. |
setAudioOutputDeviceId(deviceId: string, reconnect: boolean): void | Setzt den Lautsprecher. Heute unterstützen das nur Chrome und Edge. |
setVideoInputDeviceId(deviceId: string, reconnect: boolean): void | Setzt die Kamera. Die API prüft nicht, ob die Geräte-ID gültig ist. |
setVideoResolution(resolution: MeetingRoomVideoResolution, reconnect: boolean): void | Setzt die Auflösung des ausgehenden Videos. |
setMediaStreamConstraints(constraints: MediaStreamConstraints, merge?: boolean): void | Setzt Constraints für getUserMedia. merge steht standardmässig auf true und kombiniert Ihre Constraints mit unseren. |
setDisplayMediaConstraints(constraints: MediaStreamConstraints, merge?: boolean): void | Setzt Constraints für getDisplayMedia. merge steht standardmässig auf true. |
reconnect steht standardmässig auf false. Übergeben Sie true, baut der Raum die Medien neu auf und die Änderung greift sofort.
Die drei Listen-Methoden können eine Abfrage auslösen. Sie fragen den Browser nach der Medienberechtigung, um die Gerätenamen lesen zu können. Ein Aufruf kann also einen Berechtigungsdialog öffnen. Rufen Sie sie deshalb dann auf, wenn der Teilnehmer damit rechnet, und nicht beim Laden der Seite.
| Methode | Beschreibung |
|---|---|
setScreensharingInterceptor(callback: () => void): void | Erlaubt einer Electron-Anwendung, Screensharing-Anfragen abzufangen und eine Quelle vorzuwählen. |
startScreensharing(sourceId?: string): void | Startet das Screensharing, auf Wunsch von einer bestimmten Quelle. Darf der Teilnehmer nicht teilen, geschieht nichts. |
stopScreensharing(): void | Beendet das Screensharing. |
forceStopScreensharing(): void | Beendet das Screensharing eines anderen Teilnehmers. Das dürfen nur Moderatoren, sonst blockiert der Server den Aufruf. |
startRecording(): void | Startet die Aufzeichnung. Das gelingt nur, wenn das Meeting für teilweise Aufzeichnung konfiguriert ist. |
stopRecording(): void | Beendet die Aufzeichnung. Es gilt dieselbe Bedingung. |
| Methode | Beschreibung |
|---|---|
sendChatMessage(message: string): void | Sendet eine Gruppen-Chatnachricht. |
sendPrivateChatMessage(message: string, participantId: string): void | Sendet eine private Chatnachricht an einen Teilnehmer. |
sendCustomMessage(message: ICustomMessage): void | Sendet eine eigene Nachricht an alle Teilnehmer. Diese erhalten sie als Event customMessage. |
| Methode | Beschreibung |
|---|---|
setVideoDisplayCalculator(calculator: IVideoDisplayCalculator): void | Überlässt Ihnen die Anordnung der Videos. Siehe Videodarstellung. |
on(event: MeetingRoomApiEvent, callback: ApiEventCallback): void | Abonniert ein Event. |
Setzen Sie Veeting Blocks statt eines eingebetteten Raums ein, erhalten Sie vier zusätzliche Methoden. Mit ihnen steuern Sie den Beitritt selbst:
| Methode | Beschreibung |
|---|---|
isBrowserSupported(): boolean | Meldet, ob der aktuelle Browser ein Meeting ausführen kann. |
loadMeeting(meetingId: string): Promise<IMeetingRoomConfig> | Lädt die Konfiguration eines Meetings. |
joinMeeting(config: IMeetingConnectionConfig): Promise<void> | Tritt dem Meeting bei. |
can(meetingPermission: string): Promise<boolean> | Meldet, ob der aktuelle Teilnehmer eine Berechtigung hat. |
interface IApiParticipant {
id: string;
name: string;
muted?: boolean;
handRaised?: boolean;
fromPSTN?: boolean;
hasVideo?: boolean;
hadVideo?: boolean;
joinedAt: number;
}
interface IApiChatMessage {
fromParticipantId: string;
fromParticipantName: string;
message: string;
}
interface IApiRemainingTimeUpdate {
remainingSeconds: number;
}
interface IScreenshareState {
active: boolean;
}
interface IMediaDeviceSettings {
videoResolution: string;
audioInputDeviceId: string;
audioOutputDeviceId: string;
videoInputDeviceId: string;
}
interface IMeetingConnectionConfig {
meetingId: string;
participantName: string;
participantEmail?: string;
audio: boolean;
video: boolean;
moderatorToken?: string;
interpreterToken?: string;
invisibleToken?: string;
speakerToken?: string;
}
type MediaDirection = "receiveonly" | "sendonly" | "sendreceive";
type JoinMode = "audio-only" | "audio-video" | "video-only" | "no-media";
type ApiEventCallback = (payload: void | IApiParticipant[] | IApiChatMessage
| IApiRemainingTimeUpdate | IMeetingRoomConfig | ICustomMessage | IScreenshareState) => void;wlvmrApiReady zu, nachdem der Meetingraum geladen ist. Die Funktion wird dann nie aufgerufen.joined auf. Der Raum ist dann zwar geladen, das Meeting aber noch nicht betreten.connected für einen Beleg, dass Medien fliessen. Es bezieht sich auf den WebSocket zu unserer API.startScreensharing eine Rückmeldung. Darf der Teilnehmer nicht teilen, kehrt der Aufruf stillschweigend zurück.startRecording in einem Meeting auf, das nicht für teilweise Aufzeichnung konfiguriert ist.forceStopScreensharing ohne Moderationsrechte auf. Der Server blockiert es.Sprechen Sie mit unserem Team über Ihre Pläne.