Audio- und Videomanipulation
Die Schönheit des Webs liegt darin, dass Sie Technologien kombinieren können, um neue Formen zu erschaffen. Da 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. Zum Beispiel, indem wir Nachhall-/Kompressionseffekte zu Audio hinzufügen oder Grau-/Sepia-Filter zu Video. Dieser Artikel bietet eine Referenz, um zu erklären, was Sie tun müssen.
Videomanipulation
Die Fähigkeit, die Pixelwerte jedes Frames eines Videos zu lesen, kann sehr nützlich sein.
Video und Canvas
Das <canvas>-Element bietet eine Fläche zum Zeichnen von Grafiken auf Webseiten; es ist sehr leistungsfähig und kann eng mit Video verbunden werden.
Die allgemeine Technik besteht darin:
- Ein Frame vom
<video>-Element in das<canvas>-Element zu schreiben. - Die Daten vom
<canvas>-Element zu lesen und zu manipulieren. - Die manipulierten Daten auf Ihr "Anzeigecanvas" zu schreiben (welches effektiv dasselbe Element sein kann).
- Anhalten und wiederholen.
Zum Beispiel, lassen Sie uns ein Video im Graustufenformat darstellen. In diesem Fall zeigen wir sowohl das Quellvideo als auch die Ausgabe-Graustufenframes. Normalerweise würden Sie, wenn Sie eine "Video in Graustufen abspielen"-Funktion implementieren, wahrscheinlich display: none zum Stil des <video>-Elements hinzufügen, um zu verhindern, dass das Quellvideo auf dem Bildschirm angezeigt wird, während nur das Canvas die veränderten Frames zeigt.
HTML
Wir können unseren Videoplayer und unser <canvas>-Element wie folgt 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 aufrufen
processor.doLoad();
Ergebnis
Dies ist ein Beispiel, das zeigt, wie man Videoframes mit einem Canvas manipuliert. Für mehr Effizienz sollten Sie in Betracht ziehen, requestAnimationFrame() anstelle von setTimeout() zu verwenden, wenn es von Browsern unterstützt wird.
Das gleiche Ergebnis kann erreicht werden, indem die grayscale() CSS-Funktion auf das Quell-<video>-Element angewendet wird.
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 eine leistungsfähige API, die Canvas verwendet, um hardware-beschleunigte 3D- oder 2D-Szenen zu zeichnen. Sie können WebGL und das <video>-Element kombinieren, um Videotexturen zu erstellen, was bedeutet, dass Sie Video in 3D-Szenen platzieren können.
Hinweis: Den Quellcode dieses Demos finden Sie auf GitHub (siehe es live auch).
Wiedergabegeschwindigkeit
Wir können auch die Rate, mit der Audio und Video abgespielt werden, einstellen, 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 werden soll, zum Beispiel stellt 0.5 halbe Geschwindigkeit und 2 doppelte Geschwindigkeit dar.
Beachten Sie, dass die playbackRate-Eigenschaft sowohl mit <audio> als auch <video> funktioniert, aber in beiden Fällen die Wiedergabegeschwindigkeit verändert, jedoch nicht die Tonhöhe. Um die Tonhöhe der Audiodatei 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 den Schieberegler an, um die Wiedergabegeschwindigkeit des Mediums zu ändern:
Audiomanipulation
Abgesehen von playbackRate werden Sie zur Manipulation von Audiodateien normalerweise die Web Audio API verwenden.
Auswahl einer Audioquelle
Die Web Audio API kann Audio aus verschiedenen Quellen empfangen, dann verarbeiten und zurück an einen AudioDestinationNode senden, welcher das Ausgabegerät repräsentiert, an das der Ton nach der Verarbeitung gesendet wird.
| Wenn die Audioquelle ist… | Verwenden Sie diesen Web-Audio-Node-Typ |
|---|---|
Ein Audiotrack von einem HTML <audio> oder <video> Element |
MediaElementAudioSourceNode |
| Ein reiner, roher Audiodaten-Buffer im Speicher | AudioBufferSourceNode |
| Ein Oszillator, der eine Sinuswelle oder eine andere berechnete Wellenform erzeugt | OscillatorNode |
Ein Audiotrack von WebRTC (zum Beispiel das Mikrofoneingangssignal, das Sie mit getUserMedia() erhalten können). |
MediaStreamAudioSourceNode |
Audiofilter
Die Web Audio API hat viele verschiedene Filter/Effekte, die auf Audio mit dem BiquadFilterNode angewendet werden können, zum Beispiel.
<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: Sofern Sie nicht CORS aktiviert haben, sollte zu Vermeidung von Sicherheitsproblemen Ihr Video auf derselben Domain wie Ihr Code liegen.
Häufige Audiofilter
Dies sind einige gängige Arten von Audiofiltern, die Sie anwenden können:
- Tiefpass: Lässt Frequenzen unterhalb der Grenzfrequenz passieren und dämpft Frequenzen oberhalb der Grenzfrequenz.
- Hochpass: Lässt Frequenzen oberhalb der Grenzfrequenz passieren und dämpft Frequenzen unterhalb der Grenzfrequenz.
- Bandpass: Lässt einen Frequenzbereich durch und dämpft die Frequenzen unterhalb und oberhalb dieses Bereichs.
- Low Shelf: Lässt alle Frequenzen durch, fügt jedoch einen Schub (oder eine Dämpfung) zu den tieferen Frequenzen hinzu.
- High Shelf: Lässt alle Frequenzen durch, fügt jedoch einen Schub (oder eine Dämpfung) zu den höheren Frequenzen hinzu.
- Peaking: Lässt alle Frequenzen durch, fügt jedoch einen Schub (oder eine Dämpfung) zu einem Frequenzbereich hinzu.
- Kerbe: Lässt alle Frequenzen durch, außer für einen Satz von Frequenzen.
- Allpass: Lässt alle Frequenzen durch, verändert jedoch die Phasenbeziehung zwischen den einzelnen Frequenzen.
Hinweis:
Weitere Informationen finden Sie bei BiquadFilterNode.
Faltungen und Impulse
Es ist auch möglich, Impulsantworten auf Audio anzuwenden, indem der ConvolverNode verwendet wird. Eine Impulsantwort ist der Ton, der nach einem kurzen Schallimpuls (wie einem Händeklatschen) erzeugt wird. Eine Impulsantwort wird die Umgebung signalisieren, in der der Impuls erzeugt wurde (zum Beispiel ein Echo, das durch Klatschen 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 sich unser HolySpaceCow-Beispiel für ein angewandtes (aber sehr, sehr albernes) Beispiel an.
Räumliches Audio
Wir können Audio auch mit einem Panner-Node positionieren. Ein Panner-Node—PannerNode—ermöglicht es uns, eine Quellkegel sowie positionale und richtungsweisende Elemente zu definieren, alles in einem 3D-Raum, der mit 3D-Kartesischen Koordinaten definiert wird.
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: Ein Beispiel in unserem GitHub-Repository (sehen Sie es live auch) finden Sie dort.
Beispiele
Siehe auch
>Leitfäden
- Manipulieren von Video mit Canvas
- HTML-Wiedergabegeschwindigkeit (
playbackRate) erklärt - Verwendung der Web Audio API
- Grundlagen der räumlichen Audiowiedergabe im Web
- Verwendung von Videoframes als WebGL-Textur (Sie können auch die THREE.js WebGL-Bibliothek (und andere) verwenden, um diesen Effekt zu erzielen)
- Texturen animieren 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
- Mehr Informationen über Räumliches Audio
- Web-Medientechnologien