Ein Projekt vor einiger Zeit bestand darin, eine Audio-Kursunterlage zu entwickeln. Nach dem Importieren von Dokumenten, Bildern und anderen Ressourcen erhält die Seite ein PPT-ähnliches Layout, und durch Auswahl eines Bildes kann Audio eingefügt werden. Es gibt zwei Arten der Einzelseitenbearbeitung und globales Bearbeitungsmodell. Es gibt zwei Möglichkeiten, Audio zu importieren: Eine besteht darin, aus der Ressourcenbibliothek zu importieren, und die andere darin, die Aufnahme zu erwähnen.
Ehrlich gesagt war ich am Anfang noch nie mit der Audio-API von HTML5 vertraut, und wir müssen sie vor der Übernahme anhand des Codes optimieren. Natürlich gibt es auch viele Fallstricke. Dieses Mal werde ich auch über meine Gefühle im Zusammenhang mit diesen Fallstricken sprechen (die Initialisierung und der Erwerb einiger grundlegender Objekte werden weggelassen, da diese Inhalte diesmal nicht im Mittelpunkt stehen. Interessierte Studenten können MDN durchsuchen selbst. Dokumentation zu):
Bevor Sie mit der Aufnahme beginnen, müssen Sie zunächst ermitteln, ob das aktuelle Gerät die Audio-API unterstützt. Die frühere Methode navigator.getUserMedia wurde durch navigator.mediaDevices.getUserMedia ersetzt. Normalerweise unterstützen die meisten modernen Browser jetzt die Verwendung von navigator.mediaDevices.getUserMedia. Natürlich stellt MDN auch Kompatibilitätsinformationen bereit.
const promisifiedOldGUM = function(constraints) { // Besorgen Sie sich zuerst getUserMedia, falls vorhanden. const getUserMedia = navigator.getUserMedia ||. // Einige Browser implementieren es einfach nicht – geben ein abgelehntes Versprechen zurück mit einem Fehler // um eine konsistente Schnittstelle beizubehalten if (!getUserMedia) { return Promise.reject( new Error('getUserMedia ist in diesem Browser nicht implementiert') } // Ansonsten schließe den Aufruf an die alte Datei navigator.getUserMedia mit einem Promise um (Navigator, Einschränkungen, Auflösung, Ablehnung);}; // Ältere Browser implementieren mediaDevices möglicherweise überhaupt nicht, daher legen wir zuerst ein leeres Objekt fest (navigator.mediaDevices === undefiniert) { navigator.mediaDevices = {};} // Einige Browser implementieren teilweise mediaDevices. Wir können nicht einfach ein Objekt// mit getUserMedia zuweisen, da dies vorhandene Eigenschaften überschreiben würde.// Hier wir fügt einfach die getUserMedia-Eigenschaft hinzu, wenn sie fehlt.if (navigator.mediaDevices.getUserMedia === undefiniert) { navigator.mediaDevices.getUserMedia = promisifiedOldGUM;}
Da diese Methode asynchron ist, können wir benutzerfreundliche Eingabeaufforderungen für inkompatible Geräte bereitstellen.
navigator.mediaDevices.getUserMedia(constraints).then( function(mediaStream) { // Erfolg }, function(error) { // Fehler const { name } = error; let errorMessage; switch (name) { // Benutzer lehnt Fall ab ' NotAllowedError': case 'PermissionDeniedError': errorMessage = 'Der Benutzer hat den Aufruf des Aufnahmegeräts durch die Webseite verboten'; // Das Aufnahmegerät ist nicht verbunden case 'NotFoundError': case 'DevicesNotFoundError': 'Aufzeichnungsgerät nicht gefunden'; // Andere Fehlerfälle 'NotSupportedError': 'Aufzeichnungsfunktion wird nicht unterstützt'; log (error); } return errorMessage });
Wenn alles gut geht, können wir mit dem nächsten Schritt fortfahren.
(Die Methode zum Erhalten des Kontexts wird hier weggelassen, da sie dieses Mal nicht im Mittelpunkt steht.)
Aufnahme starten, Aufnahme pausierenHier gibt es einen besonderen Punkt: Es muss eine Zwischenvariable hinzugefügt werden, um festzustellen, ob gerade eine Aufzeichnung durchgeführt wird. Denn im Firefox-Browser haben wir ein Problem festgestellt, aber als wir auf „Pause“ geklickt haben, haben wir festgestellt, dass er zu diesem Zeitpunkt nicht angehalten werden konnte. Diese Methode ist nicht möglich. Bei dieser Methode müssen alle Verbindungen getrennt werden. Später habe ich herausgefunden, dass eine Zwischenvariable „this.isRecording“ hinzugefügt werden sollte, um festzustellen, ob gerade eine Aufzeichnung stattfindet. Wenn Sie auf „Start“ klicken, setzen Sie sie auf „true“ und bei „Pause“ auf „false“.
Wenn wir mit der Aufnahme beginnen, gibt es ein Aufnahme-Hörereignis. Wenn „true“ zurückgegeben wird, wird der Stream geschrieben. Wenn „false“ zurückgegeben wird, wird er nicht geschrieben. Beurteilen Sie daher this.isRecording und kehren Sie direkt zurück, wenn es falsch ist
// Einige Initialisierungen const audioContext = new AudioContext(); const sourceNode = audioContext.createMediaStreamSource(mediaStream); const scriptNode = audioContext.createScriptProcessor( BUFFER_SIZE, INPUT_CHANNELS_NUM, OUPUT_CHANNELS_NUM);sourceNode.connect(this.scriptNode);scriptNode.connect(this.audioContext.destination); // Überwachen Sie den Aufnahmeprozess scriptNode.onaudioprocess => { if (!this.isRecording) return; Regelmäßige Aufzeichnung this.buffers.push(event.inputBuffer.getChannelData(0)); Holen Sie sich die Daten des aktuellen Kanals und schreiben Sie sie in das Array};
Natürlich gibt es hier einen Fallstrick, das heißt, es kann nicht mehr verwendet werden, um die aktuelle Aufnahmedauer zu ermitteln, da es sich tatsächlich nicht um eine echte Pause handelt, sondern der Stream nicht geschrieben wird. Wir müssen also auch die Dauer der aktuellen Aufnahme ermitteln, die über eine Formel ermittelt werden muss.
const getDuration = () => { return (4096 * this.buffers.length) / this.audioContext.sampleRate // 4096 ist die Länge eines Streams, sampleRate ist die Abtastrate}
Auf diese Weise erhalten Sie die richtige Aufnahmedauer.
Aufnahme beendenUm die Aufnahme zu beenden, pausiere ich sie zunächst, führe dann bei Bedarf Abhören oder andere Vorgänge aus und setze dann die Array-Länge des Speicherstreams auf 0.
Frequenz abrufengetVoiceSize =analysator => {const dataArray = new Uint8Array(analyser.frequenzBinCount);analysator.getByteFrequencyData(dataArray); const sum = data.reduce((a, b) => a + b); Rückgabesumme;};
Einzelheiten finden Sie unter https://developer.mozilla.org/zh-CN/docs/Web/API/AnalyserNode/frequenzBinCount
andere
Die meisten Probleme, auf die ich dieses Mal stieß, waren Kompatibilitätsprobleme, daher stieß ich auf viele Fallstricke, insbesondere auf der mobilen Seite. Zu Beginn gab es ein Problem, bei dem die Aufnahmedauer falsch geschrieben wurde, was dazu führte, dass sie direkt einfrierte. Diese Erfahrung hat auch einige Lücken in der HTML5-API geschlossen. Das Wichtigste ist natürlich, alle daran zu erinnern, dass diese Art der nativen API-Dokumentation einfach und grob durch direktes Anzeigen von MDN erhalten wird!
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.