Fähigkeiten, Einschränkungen und Einstellungen
Baseline
Weitgehend verfügbar
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit September 2017 browserübergreifend verfügbar.
Dieser Artikel behandelt die beiden Konzepte Einschränkungen und Fähigkeiten sowie Medieneinstellungen. Er enthält außerdem ein Beispiel, den Constraint Exerciser. Mit dem Constraint Exerciser können Sie ausprobieren, wie sich unterschiedliche Einschränkungssätze auf die Audio- und Videospuren auswirken, die von den A/V-Eingabegeräten des Computers stammen, etwa von seiner Webcam und seinem Mikrofon.
Historisch gesehen war das Schreiben von Skripten für das Web, die eng mit Web-APIs zusammenarbeiten, mit einer bekannten Herausforderung verbunden: Ihr Code muss häufig wissen, ob eine API vorhanden ist und, falls ja, welche Einschränkungen sie auf dem User Agent hat, auf dem der Code ausgeführt wird. Das herauszufinden war oft schwierig. Üblicherweise musste man dazu eine Kombination verschiedener Dinge prüfen: welcher User Agent (oder Browser) verwendet wird, welche Version er hat, ob bestimmte Objekte existieren, ob verschiedene Funktionen wie erwartet arbeiten und welche Fehler auftreten. Das Ergebnis war viel anfälliger Code oder die Abhängigkeit von Bibliotheken, die diese Fragen für Sie klären und anschließend Polyfills bereitstellen, um Lücken in der Implementierung zu schließen.
Fähigkeiten und Einschränkungen ermöglichen es dem Browser und der Website oder App, Informationen darüber auszutauschen, welche einschränkbaren Eigenschaften die Implementierung des Browsers unterstützt und welche Werte sie jeweils annehmen können.
Überblick
Der Ablauf sieht folgendermaßen aus (am Beispiel von MediaStreamTrack):
- Rufen Sie bei Bedarf
MediaDevices.getSupportedConstraints()auf, um die Liste der unterstützten Einschränkungen zu erhalten. Sie zeigt, welche einschränkbaren Eigenschaften der Browser kennt. Das ist nicht immer erforderlich, da unbekannte Eigenschaften ignoriert werden, wenn Sie sie angeben. Wenn Sie auf bestimmte Eigenschaften jedoch angewiesen sind, können Sie zunächst prüfen, ob sie in der Liste stehen. - Sobald das Skript weiß, ob die gewünschten Eigenschaften unterstützt werden, kann es die Fähigkeiten der API und ihrer Implementierung prüfen. Dazu untersucht es das Objekt, das die
getCapabilities()-Methode der Spur zurückgibt. Dieses Objekt führt jede unterstützte Einschränkung sowie die unterstützten Werte oder Wertebereiche auf. - Anschließend wird die
applyConstraints()-Methode der Spur aufgerufen, um die API wie gewünscht zu konfigurieren. Dabei werden die gewünschten Werte oder Wertebereiche für die einschränkbaren Eigenschaften angegeben. - Die
getConstraints()-Methode der Spur gibt den Einschränkungssatz zurück, der beim letzten Aufruf vonapplyConstraints()übergeben wurde. Er muss nicht den tatsächlichen aktuellen Zustand der Spur wiedergeben: Angeforderte Werte können angepasst worden sein, und Standardwerte der Plattform sind darin nicht enthalten. Eine vollständige Darstellung der aktuellen Konfiguration der Spur erhalten Sie mitgetSettings().
In der Media Capture and Streams API besitzen sowohl MediaStream als auch MediaStreamTrack einschränkbare Eigenschaften.
Prüfen, ob eine Einschränkung unterstützt wird
Wenn Sie wissen müssen, ob der User Agent eine bestimmte Einschränkung unterstützt, können Sie navigator.mediaDevices.getSupportedConstraints() aufrufen. So erhalten Sie eine Liste der einschränkbaren Eigenschaften, die der Browser kennt:
const supported = navigator.mediaDevices.getSupportedConstraints();
document.getElementById("frameRateSlider").disabled = !supported["frameRate"];
In diesem Beispiel werden die unterstützten Einschränkungen abgerufen. Eine Steuereinheit, mit der Benutzer die Bildrate konfigurieren können, wird deaktiviert, falls die Einschränkung frameRate nicht unterstützt wird.
Definition von Einschränkungen
Eine einzelne Einschränkung ist ein Objekt, dessen Name der einschränkbaren Eigenschaft entspricht, für die ein gewünschter Wert oder Wertebereich angegeben wird. Dieses Objekt enthält null oder mehr einzelne Einschränkungen sowie gegebenenfalls ein Unterobjekt namens advanced. Dieses enthält einen weiteren Satz von null oder mehr Einschränkungen, die der User Agent nach Möglichkeit erfüllen muss. Der User Agent versucht, die Einschränkungen in der Reihenfolge zu erfüllen, in der sie im Einschränkungssatz angegeben sind.
Am wichtigsten ist zu verstehen, dass die meisten Einschränkungen keine Anforderungen, sondern Wünsche sind. Es gibt Ausnahmen, auf die wir gleich eingehen.
Einen bestimmten Wert für eine Einstellung anfordern
In den meisten Fällen kann für jede Einschränkung ein bestimmter Wert angegeben werden, der den gewünschten Wert der Einstellung bezeichnet. Zum Beispiel:
const constraints = {
width: 1920,
height: 1080,
aspectRatio: 1.777777778,
};
myTrack.applyConstraints(constraints);
In diesem Fall geben die Einschränkungen an, dass für fast alle Eigenschaften beliebige Werte zulässig sind, aber eine standardmäßige High-Definition-Videogröße (HD) mit dem üblichen Seitenverhältnis von 16:9 gewünscht wird. Es gibt keine Garantie, dass die resultierende Spur diese Werte aufweist, aber der User Agent sollte versuchen, möglichst viele davon zu erfüllen.
Die Priorisierung der Eigenschaften ist einfach: Wenn sich die angeforderten Werte zweier Eigenschaften gegenseitig ausschließen, wird die Eigenschaft verwendet, die im Einschränkungssatz zuerst aufgeführt ist. Wenn der Browser im obigen Beispiel etwa keine Spur mit 1920 × 1080, aber eine mit 1920 × 900 bereitstellen könnte, würde er Letztere bereitstellen.
Einfache Einschränkungen wie diese, die einen einzelnen Wert angeben, gelten nie als zwingend erforderlich. Der User Agent versucht, den angeforderten Wert bereitzustellen, garantiert aber keine Übereinstimmung. Wenn Sie beim Aufruf von MediaStreamTrack.applyConstraints() einfache Werte für Eigenschaften verwenden, wird die Anfrage daher immer erfolgreich sein: Diese Werte gelten als Wünsche, nicht als Anforderungen.
Einen Wertebereich angeben
Manchmal ist für eine Eigenschaft jeder Wert innerhalb eines bestimmten Bereichs akzeptabel. Sie können Bereiche mit einem Mindestwert, einem Höchstwert oder beidem angeben und bei Bedarf auch einen idealen Wert innerhalb des Bereichs festlegen. Wenn Sie einen idealen Wert angeben, versucht der Browser, diesem unter Berücksichtigung der anderen angegebenen Einschränkungen so nahe wie möglich zu kommen.
const supports = navigator.mediaDevices.getSupportedConstraints();
if (
!supports["width"] ||
!supports["height"] ||
!supports["frameRate"] ||
!supports["facingMode"]
) {
// We're missing needed properties, so handle that error.
} else {
const constraints = {
width: { min: 640, ideal: 1920, max: 1920 },
height: { min: 400, ideal: 1080 },
aspectRatio: 1.777777778,
frameRate: { max: 30 },
facingMode: { exact: "user" },
};
myTrack
.applyConstraints(constraints)
.then(() => {
/* do stuff if constraints applied successfully */
})
.catch((reason) => {
/* failed to apply constraints; reason is why */
});
}
Hier stellen wir zunächst sicher, dass die einschränkbaren Eigenschaften unterstützt werden, für die passende Werte gefunden werden müssen (width, height, frameRate und facingMode). Anschließend legen wir Einschränkungen fest, die eine Breite von mindestens 640 und höchstens 1920 (vorzugsweise 1920), eine Höhe von mindestens 400 (idealerweise 1080), ein Seitenverhältnis von 16:9 (1,777777778) und eine Bildrate von höchstens 30 Bildern pro Sekunde anfordern. Außerdem ist als Eingabegerät nur eine zum Benutzer gerichtete Kamera („Selfie-Kamera“) zulässig. Wenn die Einschränkungen für width, height, frameRate oder facingMode nicht erfüllt werden können, wird das von applyConstraints() zurückgegebene Promise zurückgewiesen.
Hinweis:
Einschränkungen, die mit max, min oder exact angegeben werden, gelten immer als zwingend erforderlich. Kann eine solche Einschränkung beim Aufruf von applyConstraints() nicht erfüllt werden, wird das Promise zurückgewiesen.
Erweiterte Einschränkungen
Sogenannte erweiterte Einschränkungen werden erstellt, indem dem Einschränkungssatz eine Eigenschaft advanced hinzugefügt wird. Ihr Wert ist ein Array zusätzlicher Einschränkungssätze, die als optional gelten. Für diese Funktion gibt es nur wenige, wenn überhaupt, Anwendungsfälle. Da zudem erwogen wird, sie aus der Spezifikation zu entfernen, wird sie hier nicht weiter behandelt. Wenn Sie mehr erfahren möchten, lesen Sie Abschnitt 11 der Media Capture and Streams-Spezifikation nach Beispiel 2.
Fähigkeiten prüfen
Mit MediaStreamTrack.getCapabilities() können Sie eine Liste aller unterstützten Fähigkeiten sowie der Werte oder Wertebereiche abrufen, die diese auf der aktuellen Plattform und im aktuellen User Agent annehmen können. Die Funktion gibt ein Objekt zurück, das jede vom Browser unterstützte einschränkbare Eigenschaft und deren unterstützte Werte oder Wertebereiche aufführt.
Das folgende Codefragment bewirkt beispielsweise, dass Benutzer um Erlaubnis für den Zugriff auf ihre lokale Kamera und ihr Mikrofon gebeten werden. Nach Erteilung der Erlaubnis werden MediaTrackCapabilities-Objekte in der Konsole ausgegeben, die die Fähigkeiten der einzelnen MediaStreamTrack-Spuren beschreiben:
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((stream) => {
const tracks = stream.getTracks();
tracks.map((t) => console.log(t.getCapabilities()));
});
Ein Beispiel für ein solches Fähigkeiten-Objekt sieht so aus:
{
"autoGainControl": [true, false],
"channelCount": {
"max": 1,
"min": 1
},
"deviceId": "jjxEMqxIhGdryqbTjDrXPWrkjy55Vte70kWpMe3Lge8=",
"echoCancellation": [true, false],
"groupId": "o2tZiEj4MwOdG/LW3HwkjpLm1D8URat4C5kt742xrVQ=",
"noiseSuppression": [true, false]
}
Der genaue Inhalt des Objekts hängt vom Browser und der Medienhardware ab.
Einschränkungen anwenden
Die erste und gebräuchlichste Möglichkeit, Einschränkungen zu verwenden, besteht darin, sie beim Aufruf von getUserMedia() anzugeben:
navigator.mediaDevices
.getUserMedia({
video: {
width: { min: 640, ideal: 1920 },
height: { min: 400, ideal: 1080 },
aspectRatio: { ideal: 1.7777777778 },
},
audio: {
sampleSize: 16,
channelCount: 2,
},
})
.then((stream) => {
videoElement.srcObject = stream;
})
.catch(handleError);
In diesem Beispiel werden die Einschränkungen beim Aufruf von getUserMedia() angewendet. Dabei wird ein idealer Optionssatz mit Ausweichmöglichkeiten für das Video angefordert.
Hinweis:
Sie können eine oder mehrere IDs von Medieneingabegeräten angeben, um festzulegen, welche Eingabequellen zulässig sind. Um eine Liste der verfügbaren Geräte zu erhalten, können Sie navigator.mediaDevices.enumerateDevices() aufrufen. Fügen Sie dann die deviceId jedes Geräts, das die gewünschten Kriterien erfüllt, dem MediaConstraints-Objekt hinzu, das schließlich an getUserMedia() übergeben wird.
Sie können die Einschränkungen einer vorhandenen MediaStreamTrack-Spur auch während des Betriebs ändern. Rufen Sie dazu die applyConstraints()-Methode der Spur auf und übergeben Sie ihr ein Objekt mit den Einschränkungen, die Sie anwenden möchten:
videoTrack.applyConstraints({
width: 1920,
height: 1080,
});
In diesem Codefragment wird die von videoTrack referenzierte Videospur so aktualisiert, dass ihre Auflösung möglichst genau 1920 × 1080 Pixeln entspricht (1080p High Definition).
Aktuelle Einschränkungen und Einstellungen abrufen
Es ist wichtig, zwischen Einschränkungen und Einstellungen zu unterscheiden. Mit Einschränkungen geben Sie an, welche Werte Sie für die verschiedenen einschränkbaren Eigenschaften benötigen, wünschen oder akzeptieren können (wie in der Dokumentation zu MediaTrackConstraints beschrieben). Einstellungen dagegen sind die tatsächlichen aktuellen Werte dieser Eigenschaften.
Wirksame Einschränkungen abrufen
Wenn Sie den aktuell auf die Medien angewendeten Einschränkungssatz benötigen, können Sie ihn mit MediaStreamTrack.getConstraints() abrufen, wie das folgende Beispiel zeigt.
function switchCameras(track, camera) {
const constraints = track.getConstraints();
constraints.facingMode = camera;
track.applyConstraints(constraints);
}
Diese Funktion nimmt eine MediaStreamTrack-Spur und einen String entgegen, der die gewünschte Ausrichtung der Kamera angibt. Sie ruft die aktuellen Einschränkungen ab, setzt den Wert von MediaTrackConstraints.facingMode auf den angegebenen Wert und wendet anschließend den aktualisierten Einschränkungssatz an.
Aktuelle Einstellungen einer Spur abrufen
Sofern Sie nicht ausschließlich exakte Einschränkungen verwenden – was ziemlich restriktiv ist und gut überlegt sein sollte –, lässt sich nicht garantieren, welche Werte Sie nach dem Anwenden der Einschränkungen tatsächlich erhalten. Die tatsächlichen Werte der einschränkbaren Eigenschaften in den resultierenden Medien werden als Einstellungen bezeichnet. Wenn Sie das tatsächliche Format und weitere Eigenschaften der Medien kennen müssen, können Sie diese Einstellungen mit MediaStreamTrack.getSettings() abrufen. Zum Beispiel:
function whichCamera(track) {
return track.getSettings().facingMode;
}
Diese Funktion verwendet getSettings(), um die aktuell verwendeten Werte der einschränkbaren Eigenschaften der Spur abzurufen, und gibt den Wert von facingMode zurück.
Beispiel: Constraint Exerciser
In diesem Beispiel erstellen wir ein Werkzeug, mit dem Sie Medieneinschränkungen ausprobieren können, indem Sie den Quellcode bearbeiten, der die Einschränkungssätze für Audio- und Videospuren beschreibt. Anschließend können Sie die Änderungen anwenden und das Ergebnis ansehen: sowohl das Aussehen des Streams als auch die tatsächlichen Medieneinstellungen nach dem Anwenden der neuen Einschränkungen.
Das HTML und CSS für dieses Beispiel sind recht einfach und werden hier nicht gezeigt. Sie können den vollständigen Code ansehen, indem Sie auf „Play“ klicken, um ihn im Playground zu öffnen.
Standardwerte und Variablen
Zunächst definieren wir die standardmäßigen Einschränkungssätze als Strings. Diese Strings werden in bearbeitbaren <textarea>-Elementen angezeigt und bilden die anfängliche Konfiguration des Streams.
const videoDefaultConstraintString =
'{\n "width": 320,\n "height": 240,\n "frameRate": 30\n}';
const audioDefaultConstraintString =
'{\n "sampleSize": 16,\n "channelCount": 2,\n "echoCancellation": false\n}';
Diese Standardwerte fordern eine recht übliche Kamerakonfiguration an, ohne eine bestimmte Eigenschaft als besonders wichtig vorauszusetzen. Der Browser sollte versuchen, diesen Einstellungen möglichst genau zu entsprechen, akzeptiert aber auch Werte, die er als hinreichend ähnlich ansieht.
Anschließend initialisieren wir die Variablen für die MediaTrackConstraints-Objekte der Video- und Audiospur sowie die Variablen mit den Referenzen auf die Spuren selbst mit null.
let videoConstraints = null;
let audioConstraints = null;
let audioTrack = null;
let videoTrack = null;
Dann holen wir Referenzen auf alle Elemente, auf die wir zugreifen müssen.
const videoElement = document.getElementById("my-video");
const logElement = document.getElementById("log");
const supportedConstraintList = document.getElementById("supportedConstraints");
const videoConstraintEditor = document.getElementById("videoConstraintEditor");
const audioConstraintEditor = document.getElementById("audioConstraintEditor");
const videoSettingsText = document.getElementById("videoSettingsText");
const audioSettingsText = document.getElementById("audioSettingsText");
Diese Elemente sind:
videoElement-
Das
<video>-Element, das den Stream anzeigt. logElement-
Ein
<div>, in das Fehlermeldungen und andere Protokollausgaben geschrieben werden. supportedConstraintList-
Ein
<ul>(eine ungeordnete Liste), der wir programmgesteuert die Namen aller einschränkbaren Eigenschaften hinzufügen, die der Browser des Benutzers unterstützt. videoConstraintEditor-
Ein
<textarea>-Element, in dem Benutzer den Code für den Einschränkungssatz der Videospur bearbeiten können. audioConstraintEditor-
Ein
<textarea>-Element, in dem Benutzer den Code für den Einschränkungssatz der Audiospur bearbeiten können. videoSettingsText-
Ein
<textarea>-Element (das immer deaktiviert ist), das die aktuellen Einstellungen der einschränkbaren Eigenschaften der Videospur anzeigt. audioSettingsText-
Ein
<textarea>-Element (das immer deaktiviert ist), das die aktuellen Einstellungen der einschränkbaren Eigenschaften der Audiospur anzeigt.
Abschließend setzen wir den aktuellen Inhalt der beiden Editoren für Einschränkungssätze auf die Standardwerte.
videoConstraintEditor.value = videoDefaultConstraintString;
audioConstraintEditor.value = audioDefaultConstraintString;
Anzeige der Einstellungen aktualisieren
Rechts neben jedem Editor für Einschränkungssätze befindet sich ein zweites Textfeld, in dem wir die aktuelle Konfiguration der konfigurierbaren Eigenschaften der jeweiligen Spur anzeigen. Die Funktion getCurrentSettings() aktualisiert diese Anzeige: Sie ruft die aktuellen Einstellungen der Audio- und Videospur ab und fügt den entsprechenden Code in die Anzeigefelder ein, indem sie deren value setzt.
function getCurrentSettings() {
if (videoTrack) {
videoSettingsText.value = JSON.stringify(videoTrack.getSettings(), null, 2);
}
if (audioTrack) {
audioSettingsText.value = JSON.stringify(audioTrack.getSettings(), null, 2);
}
}
Diese Funktion wird aufgerufen, nachdem der Stream zum ersten Mal gestartet wurde, und jedes Mal, wenn wir aktualisierte Einschränkungen angewendet haben, wie Sie weiter unten sehen werden.
Objekte für die Einschränkungssätze der Spuren erstellen
Die Funktion buildConstraints() erstellt aus dem Code in den beiden Editoren die MediaTrackConstraints-Objekte für die Audio- und Videospur.
function buildConstraints() {
try {
videoConstraints = JSON.parse(videoConstraintEditor.value);
audioConstraints = JSON.parse(audioConstraintEditor.value);
} catch (error) {
handleError(error);
}
}
Dazu verwendet sie JSON.parse(), um den Code in jedem Editor in ein Objekt umzuwandeln. Wenn einer der Aufrufe von JSON.parse() eine Ausnahme auslöst, wird handleError() aufgerufen, um die Fehlermeldung im Protokoll auszugeben.
Stream konfigurieren und starten
Die Methode startVideo() übernimmt die Einrichtung und den Start des Videostreams.
function startVideo() {
buildConstraints();
navigator.mediaDevices
.getUserMedia({
video: videoConstraints,
audio: audioConstraints,
})
.then((stream) => {
const audioTracks = stream.getAudioTracks();
const videoTracks = stream.getVideoTracks();
videoElement.srcObject = stream;
if (audioTracks.length > 0) {
audioTrack = audioTracks[0];
}
if (videoTracks.length > 0) {
videoTrack = videoTracks[0];
}
})
.then(
() =>
new Promise((resolve) => {
videoElement.onloadedmetadata = resolve;
}),
)
.then(() => {
getCurrentSettings();
})
.catch(handleError);
}
Dies geschieht in mehreren Schritten:
- Sie ruft
buildConstraints()auf, um aus dem Code in den Editoren dieMediaTrackConstraints-Objekte für beide Spuren zu erstellen. - Sie ruft
navigator.mediaDevices.getUserMedia()auf und übergibt die Einschränkungsobjekte für die Video- und Audiospur. Dadurch wird einMediaStreammit Audio und Video von einer Quelle zurückgegeben, die den Vorgaben entspricht – üblicherweise eine Webcam, wobei Sie mit geeigneten Einschränkungen auch Medien aus anderen Quellen erhalten können. - Sobald der Stream verfügbar ist, wird er mit dem
<video>-Element verknüpft, damit er auf dem Bildschirm sichtbar ist. Außerdem speichern wir die Audio- und Videospur in den VariablenaudioTrackundvideoTrack. - Dann richten wir ein Promise ein, das aufgelöst wird, wenn das Ereignis
loadedmetadataauf dem Videoelement eintritt. - Wenn das geschieht, wissen wir, dass die Wiedergabe des Videos begonnen hat. Daher rufen wir die oben beschriebene Funktion
getCurrentSettings()auf, um die tatsächlichen Einstellungen anzuzeigen, die der Browser unter Berücksichtigung unserer Einschränkungen und der Fähigkeiten der Hardware gewählt hat. - Falls ein Fehler auftritt, protokollieren wir ihn mit der Methode
handleError(), die wir weiter unten im Artikel betrachten.
Außerdem müssen wir einen Event Listener einrichten, der auf Klicks auf die Schaltfläche „Start Video“ reagiert:
document.getElementById("startButton").addEventListener("click", () => {
startVideo();
});
Aktualisierte Einschränkungssätze anwenden
Als Nächstes richten wir einen Event Listener für die Schaltfläche „Apply Constraints“ ein. Wird sie angeklickt und sind noch keine Medien in Verwendung, rufen wir startVideo() auf. Diese Funktion startet dann den Stream mit den angegebenen Einstellungen. Andernfalls gehen wir wie folgt vor, um die aktualisierten Einschränkungen auf den bereits aktiven Stream anzuwenden:
buildConstraints()wird aufgerufen, um aktualisierteMediaTrackConstraints-Objekte für die Audiospur (audioConstraints) und die Videospur (videoConstraints) zu erstellen.- Auf der Videospur wird, sofern vorhanden,
MediaStreamTrack.applyConstraints()aufgerufen, um die neuenvideoConstraintsanzuwenden. Bei Erfolg wird das Feld mit den aktuellen Einstellungen der Videospur anhand des Ergebnisses ihrergetSettings()-Methode aktualisiert. - Danach wird
applyConstraints()auf der Audiospur aufgerufen, sofern eine vorhanden ist, um die neuen Audioeinschränkungen anzuwenden. Bei Erfolg wird das Feld mit den aktuellen Einstellungen der Audiospur anhand des Ergebnisses ihrergetSettings()-Methode aktualisiert. - Falls beim Anwenden eines der Einschränkungssätze ein Fehler auftritt, wird mit
handleError()eine Meldung im Protokoll ausgegeben.
document.getElementById("applyButton").addEventListener("click", () => {
if (!videoTrack && !audioTrack) {
startVideo();
} else {
buildConstraints();
const prettyJson = (obj) => JSON.stringify(obj, null, 2);
if (videoTrack) {
videoTrack
.applyConstraints(videoConstraints)
.then(() => {
videoSettingsText.value = prettyJson(videoTrack.getSettings());
})
.catch(handleError);
}
if (audioTrack) {
audioTrack
.applyConstraints(audioConstraints)
.then(() => {
audioSettingsText.value = prettyJson(audioTrack.getSettings());
})
.catch(handleError);
}
}
});
Die Stoppschaltfläche behandeln
Anschließend richten wir den Handler für die Stoppschaltfläche ein.
document.getElementById("stopButton").addEventListener("click", () => {
if (videoTrack) {
videoTrack.stop();
}
if (audioTrack) {
audioTrack.stop();
}
videoTrack = audioTrack = null;
videoElement.srcObject = null;
});
Er stoppt die aktiven Spuren, setzt die Variablen videoTrack und audioTrack auf null, damit wir wissen, dass die Spuren nicht mehr vorhanden sind, und entfernt den Stream aus dem <video>-Element, indem er HTMLMediaElement.srcObject auf null setzt.
Einfache Unterstützung der Tabulatortaste im Editor
Dieser Code ergänzt die <textarea>-Elemente um eine einfache Unterstützung der Tabulatortaste: Wenn eines der Textfelder zum Bearbeiten der Einschränkungen fokussiert ist, fügt ein Druck auf die Tabulatortaste zwei Leerzeichen ein.
function keyDownHandler(event) {
if (event.key === "Tab") {
const elem = event.target;
const str = elem.value;
const position = elem.selectionStart;
const beforeTab = str.substring(0, position);
const afterTab = str.substring(position, str.length);
const newStr = `${beforeTab} ${afterTab}`;
elem.value = newStr;
elem.selectionStart = elem.selectionEnd = position + 2;
event.preventDefault();
}
}
videoConstraintEditor.addEventListener("keydown", keyDownHandler);
audioConstraintEditor.addEventListener("keydown", keyDownHandler);
Vom Browser unterstützte einschränkbare Eigenschaften anzeigen
Das letzte wichtige Puzzleteil ist Code, der Benutzern als Referenz eine Liste der einschränkbaren Eigenschaften anzeigt, die ihr Browser unterstützt. Jede Eigenschaft ist zur bequemeren Nutzung mit ihrer Dokumentation auf MDN verlinkt. Einzelheiten zur Funktionsweise dieses Codes finden Sie in den Beispielen zu MediaDevices.getSupportedConstraints().
Hinweis: Natürlich kann diese Liste auch nicht standardisierte Eigenschaften enthalten. In diesem Fall ist der Link zur Dokumentation wahrscheinlich wenig hilfreich.
const supportedConstraints = navigator.mediaDevices.getSupportedConstraints();
for (const constraint in supportedConstraints) {
if (Object.hasOwn(supportedConstraints, constraint)) {
const elem = document.createElement("li");
elem.innerHTML = `<code><a href='https://developer.mozilla.org/docs/Web/API/MediaDevices/getSupportedConstraints#${constraint.toLowerCase()}' target='_blank'>${constraint}</a></code>`;
supportedConstraintList.appendChild(elem);
}
}
Fehlerbehandlung
Wir haben außerdem einfachen Code zur Fehlerbehandlung: handleError() wird aufgerufen, um fehlgeschlagene Promises zu behandeln, und die Funktion log() fügt die Fehlermeldung einem speziellen <div> für Protokolleinträge unter dem Video hinzu.
function log(msg) {
logElement.innerHTML += `${msg}<br>`;
}
function handleError(reason) {
log(
`Error <code>${reason.name}</code> in constraint <code>${reason.constraint}</code>: ${reason.message}`,
);
}
Ergebnis
Hier sehen Sie das vollständige Beispiel in Aktion.
Spezifikationen
| Spezifikation |
|---|
| Media Capture and Streams> # dom-mediadevices-getsupportedconstraints> |