Audio- und Videomanipulation
Die Schönheit des Webs liegt darin, dass Sie Technologien kombinieren können, um neue Formen zu schaffen. Wenn Audio und Video nativ im Browser vorhanden sind, können wir diese Datenströme mit Technologien wie <canvas>, WebGL oder Web Audio API verwenden, um Audio und Video direkt zu modifizieren, beispielsweise um Hall-/Kompressionseffekte zu Audio hinzuzufügen oder Graustufen-/Sepiafilter zu Video. Dieser Artikel bietet eine Referenz, um zu erklären, was Sie tun müssen.
Videomanipulation
Die Möglichkeit, die Pixelwerte von jedem Frame eines Videos zu lesen, kann sehr nützlich sein.
Video und Canvas
Das <canvas>-Element bietet eine Oberfläche zum Zeichnen von Grafiken auf Webseiten; es ist sehr leistungsfähig und kann eng mit Video gekoppelt werden.
Die allgemeine Technik besteht darin:
- Ein Frame aus dem
<video>-Element auf das<canvas>-Element zu schreiben. - Die Daten vom
<canvas>-Element zu lesen und zu manipulieren. - Die manipulierten Daten auf Ihr "Anzeige"-
<canvas>zu schreiben (das effektiv dasselbe Element sein kann). - Pause und Wiederholung.
Zum Beispiel lassen Sie uns ein Video so verarbeiten, dass es in Graustufen angezeigt wird. In diesem Fall zeigen wir sowohl das Quellvideo als auch die ausgegebenen Graustufen-Frames an. Normalerweise würden Sie, wenn Sie ein "Video in Graustufen abspielen"-Feature implementieren, wahrscheinlich display: none im Stil für das <video>-Element hinzufügen, um zu verhindern, dass das Quellvideo auf dem Bildschirm gezeichnet wird, während nur das Canvas die veränderten Frames zeigt.
HTML
Wir können unseren Videoplayer und das <canvas>-Element folgendermaßen einrichten:
<video id="my-video" controls width="480" height="270" crossorigin="anonymous">
<source
src="https://jplayer.org/video/webm/Big_Buck_Bunny_Trailer.webm"
type="video/webm" />
<source
src="https://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v"
type="video/mp4" />
</video>
<canvas id="my-canvas" width="480" height="270"></canvas>
JavaScript
Dieser Code bearbeitet die Frames.
const processor = {
timerCallback() {
if (this.video.paused || this.video.ended) {
return;
}
this.computeFrame();
setTimeout(() => {
this.timerCallback();
}, 16); // roughly 60 frames per second
},
doLoad() {
this.video = document.getElementById("my-video");
this.c1 = document.getElementById("my-canvas");
this.ctx1 = this.c1.getContext("2d");
this.video.addEventListener("play", () => {
this.width = this.video.width;
this.height = this.video.height;
this.timerCallback();
});
},
computeFrame() {
this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
const frame = this.ctx1.getImageData(0, 0, this.width, this.height);
const l = frame.data.length / 4;
for (let i = 0; i < l; i++) {
const grey =
(frame.data[i * 4 + 0] +
frame.data[i * 4 + 1] +
frame.data[i * 4 + 2]) /
3;
frame.data[i * 4 + 0] = grey;
frame.data[i * 4 + 1] = grey;
frame.data[i * 4 + 2] = grey;
}
this.ctx1.putImageData(frame, 0, 0);
},
};
Sobald die Seite geladen ist, können Sie den folgenden Befehl ausführen:
processor.doLoad();
Ergebnis
Dies ist ein Beispiel, wie man Video-Frames mit einem Canvas manipuliert. Aus Effizienzgründen sollten Sie erwägen, requestAnimationFrame() anstelle von setTimeout() zu verwenden, wenn Sie auf Browsern arbeiten, die es unterstützen.
Sie können dasselbe Ergebnis erzielen, indem Sie die grayscale() CSS-Funktion auf das Quell-<video>-Element anwenden.
Hinweis: Aufgrund potenzieller Sicherheitsprobleme, wenn Ihr Video auf einer anderen Domain als Ihr Code liegt, müssen Sie CORS (Cross-Origin Resource Sharing) auf Ihrem Videoserver aktivieren.
Video und WebGL
WebGL ist ein leistungsstarkes API, das Canvas verwendet, um hardwarebeschleunigte 3D- oder 2D-Szenen zu zeichnen. Sie können WebGL und das <video>-Element kombinieren, um Videotexturen zu erstellen, was bedeutet, dass Sie Video innerhalb von 3D-Szenen einfügen können.
Hinweis: Der Quellcode dieses demos ist auf GitHub (sehen Sie es live auch).
Wiedergabegeschwindigkeit
Wir können auch die Geschwindigkeit anpassen, mit der Audio und Video abgespielt werden, indem wir ein Attribut des <audio>- und <video>-Elements namens playbackRate verwenden. playbackRate ist eine Zahl, die ein Vielfaches darstellt, das auf die Wiedergabegeschwindigkeit angewendet wird, zum Beispiel repräsentiert 0.5 die halbe Geschwindigkeit, während 2 die doppelte Geschwindigkeit repräsentiert.
Beachten Sie, dass die playbackRate-Eigenschaft sowohl mit <audio> als auch <video> funktioniert, aber in beiden Fällen die Wiedergabegeschwindigkeit ändert, jedoch nicht die Tonhöhe. Um die Tonhöhe des Audios zu manipulieren, müssen Sie die Web Audio API verwenden. Sehen Sie die AudioBufferSourceNode.playbackRate-Eigenschaft.
<video id="my-video" controls loop>
<source src="/shared-assets/videos/flower.mp4" type="video/mp4" />
<source src="/shared-assets/videos/flower.webm" type="video/webm" />
</video>
<label for="rate">Playback rate <span id="rate-value">1.0</span></label>
<input type="range" id="rate" name="rate" min="0" max="4" value="1" step=".2" />
const rateSlider = document.getElementById("rate");
const rateValue = document.getElementById("rate-value");
const myVideo = document.getElementById("my-video");
rateSlider.addEventListener("input", () => {
myVideo.playbackRate = rateSlider.value;
rateValue.textContent = parseFloat(rateSlider.value);
});
Starten Sie das Video und passen Sie dann den Schieberegler an, um die Wiedergabegeschwindigkeit des Mediums zu ändern:
Audiomanipulation
Mit Ausnahme von playbackRate verwenden Sie zur Manipulation von Audio in der Regel die Web Audio API.
Auswahl einer Audioquelle
Die Web Audio API kann Audio aus verschiedenen Quellen empfangen, es dann verarbeiten und an einen AudioDestinationNode senden, der das Ausgabegerät darstellt, an das der Ton nach der Verarbeitung gesendet wird.
| Wenn die Audioquelle ist … | Verwenden Sie diesen Web Audio Knoten-Typ |
|---|---|
Eine Audiospur von einem HTML <audio>- oder <video>-Element |
MediaElementAudioSourceNode |
| Ein reiner roher Audiodatenpuffer im Speicher | AudioBufferSourceNode |
| Ein Oszillator, der eine Sinuswelle oder eine andere berechnete Wellenform generiert | OscillatorNode |
Eine Audiospur von WebRTC (wie zum Beispiel das Mikrofoneingangssignal, das Sie mit getUserMedia() erhalten) |
MediaStreamAudioSourceNode |
Audiofilter
Die Web Audio API hat viele verschiedene Filter/Effekte, die auf Audio angewendet werden können, zum Beispiel mit dem BiquadFilterNode.
<video id="my-video" controls loop>
<source src="/shared-assets/videos/friday.mp4" type="video/mp4" />
</video>
<label for="freq">Filter freq. <span id="freq-value">1.0</span>hz</label>
<input type="range" id="freq" name="freq" max="20000" value="1000" step="100" />
const freqSlider = document.getElementById("freq");
const freqValue = document.getElementById("freq-value");
const context = new AudioContext();
const audioSource = context.createMediaElementSource(
document.getElementById("my-video"),
);
const filter = context.createBiquadFilter();
audioSource.connect(filter);
filter.connect(context.destination);
// Configure filter
filter.type = "lowshelf";
filter.frequency.value = 1000;
filter.gain.value = 20;
freqSlider.addEventListener("input", () => {
filter.frequency.value = freqSlider.value;
freqValue.textContent = parseFloat(freqSlider.value);
});
Hinweis: Es sei denn, Sie haben CORS aktiviert, um Sicherheitsprobleme zu vermeiden, sollte Ihr Video auf demselben Domain wie Ihr Code sein.
Häufige Audiofilter
Dies sind einige gängige Arten von Audiofiltern, die Sie anwenden können:
- Tiefpass: Lässt Frequenzen unter der Grenzfrequenz durch und dämpft Frequenzen über der Grenzfrequenz.
- Hochpass: Lässt Frequenzen über der Grenzfrequenz durch und dämpft Frequenzen unter der Grenzfrequenz.
- Bandpass: Lässt einen Bereich von Frequenzen durch und dämpft die Frequenzen über und unter diesem Frequenzbereich.
- Low Shelf: Lässt alle Frequenzen durch, fügt jedoch eine Verstärkung (oder Dämpfung) der unteren Frequenzen hinzu.
- High Shelf: Lässt alle Frequenzen durch, fügt jedoch eine Verstärkung (oder Dämpfung) der höheren Frequenzen hinzu.
- Peaking: Lässt alle Frequenzen durch, fügt jedoch eine Verstärkung (oder Dämpfung) eines Frequenzbereichs hinzu.
- Notch: Lässt alle Frequenzen durch, außer einem Frequenzbereich.
- All Pass: Lässt alle Frequenzen durch, ändert jedoch die Phasenbeziehung zwischen den verschiedenen Frequenzen.
Hinweis:
Siehe BiquadFilterNode für weitere Informationen.
Faltung und Impulsantworten
Es ist auch möglich, Impulsantworten auf Audio mit dem ConvolverNode anzuwenden. Eine Impulsantwort ist der Ton, der nach einem kurzen Schallimpuls (wie z. B. einem Händeklatschen) entsteht. Eine Impulsantwort zeigt die Umgebung an, in der der Impuls erzeugt wurde (zum Beispiel ein Echo, das durch Händeklatschen in einem Tunnel entsteht).
Beispiel
const convolver = context.createConvolver();
convolver.buffer = this.impulseResponseBuffer;
// Connect the graph.
source.connect(convolver);
convolver.connect(context.destination);
Sehen Sie unser HolySpaceCow-Beispiel für ein angewandtes (aber sehr, sehr albernes) Beispiel.
Räumliches Audio
Wir können auch Audio mit einem Panner-Knoten positionieren. Ein Panner-Knoten — PannerNode — ermöglicht es uns, einen Quellkegel sowie Positions- und Richtungselemente zu definieren, alles in einem 3D-Raum, der mit 3D-kartesischen Koordinaten definiert ist.
Beispiel
const panner = context.createPanner();
panner.coneOuterGain = 0.2;
panner.coneOuterAngle = 120;
panner.coneInnerAngle = 0;
panner.connect(context.destination);
source.connect(panner);
source.start(0);
// Position the listener at the origin.
context.listener.setPosition(0, 0, 0);
Hinweis: Sie finden ein Beispiel in unserem GitHub-Repository (sehen Sie es live auch).
Beispiele
Siehe auch
>Leitfäden
- Videomanipulation mit Canvas
- HTML-Wiedergabegeschwindigkeit erklärt
- Verwendung der Web Audio API
- Grundlagen der Web-Audio-Raumklanggestaltung
- Verwendung von Videoframes als WebGL-Textur (Sie können auch die THREE.js WebGL-Bibliothek (und andere) verwenden, um diesen Effekt zu erzielen)
- Animation von Texturen in WebGL
- Entwicklung von Spielaudio mit der Web Audio API (Raumeffekte und Filter) (2012)
Referenz
- Die
<audio>und<video>Elemente - Die
HTMLMediaElementAPI - Das
<canvas>Element - Web Audio API
- AudioContext
- Weitere Informationen zu Spatial Audio
- Web-Medientechnologien