Audio- und Videomanipulation
Die Schönheit des Webs liegt darin, dass Sie Technologien kombinieren können, um neue Formen zu schaffen. Da Audio und Video nativ im Browser unterstützt werden, können wir diese Datenströme mit Technologien wie <canvas>
, WebGL oder Web Audio API verwenden, um Audio und Video direkt zu verändern. Beispielsweise können Sie Audio mit Hall- oder Kompressionseffekten versehen oder Video mit Graustufen- oder Sepiafiltern ausstatten. Dieser Artikel bietet eine Referenz, die erklärt, was Sie tun müssen.
Videomanipulation
Die Fähigkeit, die Pixelwerte von jedem Frame eines Videos auszulesen, 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 ist:
- Schreiben Sie einen Frame vom
<video>
-Element in das<canvas>
-Element. - Lesen Sie die Daten vom
<canvas>
-Element und manipulieren Sie diese. - Schreiben Sie die manipulierten Daten in Ihr "Anzeige"-
<canvas>
(das effektiv dasselbe Element sein kann). - Anhalten und wiederholen.
Zum Beispiel, um ein Video in Graustufen anzuzeigen. In diesem Fall zeigen wir sowohl das Quellvideo als auch die ausgegebenen Graustufen-Frames. Normalerweise, wenn Sie eine Funktion "Video in Graustufen abspielen" implementieren würden, würden Sie wahrscheinlich display: none
zum Stil des <video>
-Elements hinzufügen, um zu verhindern, dass das Quellvideo auf dem Bildschirm angezeigt wird, während nur der Canvas die veränderten Frames zeigt.
HTML
Wir können unseren Videoplayer und das <canvas>
-Element so 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();
},
false,
);
},
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);
return;
},
};
Sobald die Seite geladen ist, können Sie folgendes aufrufen:
processor.doLoad();
Ergebnis
Dies ist ein ziemlich einfaches Beispiel, das zeigt, wie man Videoframes mit einer Canvas manipuliert. Aus Effizienzgründen sollten Sie in Betracht ziehen, requestAnimationFrame()
anstelle von setTimeout()
zu verwenden, wenn Sie auf Browsern arbeiten, die dies unterstützen.
Sie können das gleiche 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 vorhanden ist, müssen Sie CORS (Cross Origin Resource Sharing) auf Ihrem Videoserver aktivieren.
Video und WebGL
WebGL ist eine leistungsstarke API, die 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 in 3D-Szenen einfügen können.
Hinweis: Sie finden den Quellcode dieses Demos auf GitHub (siehe es live ebenfalls).
Wiedergabegeschwindigkeit
Wir können auch die Geschwindigkeit, mit der Audio und Video abgespielt werden, über ein Attribut des <audio>
- und <video>
-Elements namens playbackRate
einstellen. playbackRate
ist eine Zahl, die ein Vielfaches darstellt, das auf die Wiedergabegeschwindigkeit angewendet wird, zum Beispiel steht 0.5 für halbe Geschwindigkeit, während 2 für doppelte Geschwindigkeit steht.
Beachten Sie, dass die playbackRate
-Eigenschaft sowohl mit <audio>
als auch mit <video>
funktioniert, aber in beiden Fällen die Wiedergabegeschwindigkeit, jedoch nicht die Tonhöhe ändert. Um die Tonhöhe des Audios zu verändern, müssen Sie die Web Audio API verwenden. Siehe die AudioBufferSourceNode.playbackRate
-Eigenschaft.
HTML
<video
id="my-video"
controls
src="https://jplayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v"></video>
JavaScript
const myVideo = document.getElementById("my-video");
myVideo.playbackRate = 2;
Bearbeitbares Beispiel
Hinweis: Versuchen Sie das playbackRate-Beispiel live.
Audiomanipulation
Abgesehen von playbackRate
werden Sie normalerweise die Web Audio API verwenden, um Audio zu manipulieren.
Auswahl einer Audioquelle
Die Web Audio API kann Audio von verschiedenen Quellen empfangen, dieses 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 Node-Typ |
---|---|
Ein Audiotrack von einem HTML <audio> - oder <video> -Element |
MediaElementAudioSourceNode |
Ein einfacher Roh-Audiodatenpuffer im Speicher | AudioBufferSourceNode |
Ein Oszillator, der eine Sinuswelle oder eine andere berechnete Wellenform erzeugt | OscillatorNode |
Ein Audiospur von WebRTC (wie das Mikrofoneingangssignal, das Sie mit getUserMedia() erhalten können. |
MediaStreamAudioSourceNode |
Audiofilter
Die Web Audio API verfügt über viele verschiedene Filter/ Effekte, die anhand des BiquadFilterNode
angewendet werden können, zum Beispiel.
HTML
<video id="my-video" controls src="my-video.mp4" type="video/mp4"></video>
JavaScript
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 = 25;
Bearbeitbares Beispiel
Hinweis: Wenn Sie CORS nicht aktiviert haben, um Sicherheitsprobleme zu vermeiden, sollte Ihr Video sich auf derselben Domain wie Ihr Code befinden.
Häufige Audiofilter
Dies sind einige häufige Arten von Audiofiltern, die Sie anwenden können:
- Tiefpass: Lässt Frequenzen unterhalb der Grenzfrequenz passieren und dämpft Frequenzen darüber.
- Hochpass: Lässt Frequenzen oberhalb der Grenzfrequenz passieren und dämpft Frequenzen darunter.
- Bandpass: Lässt einen Frequenzbereich passieren und dämpft die Frequenzen darunter und darüber.
- Tiefstellsieb: Lässt alle Frequenzen durch, fügt jedoch eine Verstärkung (oder Dämpfung) der niedrigeren Frequenzen hinzu.
- Hochstellsieb: 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.
- Kerbe: Lässt alle Frequenzen durch, außer für eine Reihe von Frequenzen.
- Allpass: Lässt alle Frequenzen durch, ändert jedoch die Phasenbeziehung zwischen den verschiedenen Frequenzen.
Hinweis:
Weitere Informationen finden Sie unter BiquadFilterNode
.
Konvolutionen und Impulse
Es ist auch möglich, Impulsantworten auf Audio unter Verwendung des ConvolverNode
anzuwenden. Eine Impulsantwort ist der Ton, der nach einem kurzen Impuls von Geräusch (wie ein Händeklatschen) erzeugt wird. Eine Impulsantwort wird die Umgebung kennzeichnen, in der der Impuls erstellt wurde (zum Beispiel ein Echo, das durch Händeklatschen in einem Tunnel erzeugt wird).
Beispiel
const convolver = context.createConvolver();
convolver.buffer = this.impulseResponseBuffer;
// Connect the graph.
source.connect(convolver);
convolver.connect(context.destination);
Sehen Sie sich dieses Codepen für ein angewandtes (aber sehr, sehr albernes; so, dass kleine Kinder kichern, lustiges) Beispiel an.
Räumliches Audio
Wir können auch Audio mit einem Panner-Node positionieren. Ein Panner-Node—PannerNode
—ermöglicht es uns, einen Quellenkegel sowie positionsbezogene und Richtungselemente zu definieren, alles in einem 3D-Raum, der durch 3D-kartesische 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 (siehe es live ebenfalls).
JavaScript-Codecs
Es ist auch möglich, Audio auf einer niedrigen Ebene mit JavaScript zu manipulieren. Dies kann nützlich sein, wenn Sie Audio-Codecs erstellen möchten.
Derzeit existieren Bibliotheken für die folgenden Formate:
Hinweis: Bei Audiocogs können Sie einige Demos ausprobieren; Audiocogs bietet auch ein Framework, Aurora.js, das Ihnen helfen soll, Ihre eigenen Codecs in JavaScript zu erstellen.
Beispiele
Siehe auch
Tutorials
- Manipulieren von Video mittels Canvas
- HTML playbackRate erklärt
- Verwendung der Web Audio API
- Grundlagen der Web Audio Räumlichkeit
- Verwendung von Videoframes als WebGL-Textur (Sie können auch die THREE.js WebGL-Bibliothek (und andere) verwenden, um diesen Effekt zu erzielen)
- Animieren von Texturen in WebGL
- Entwicklung von Spielaudio mit der Web Audio API (Raumeffekte und Filter) (2012)
Referenz
- Die
<audio>
- und<video>
-Elemente - Die
HTMLMediaElement
API - Das
<canvas>
-Element - Web Audio API
- AudioContext
- Mehr Informationen über Räumliches Audio
- Web-Medientechnologien