Audio- und Videomanipulation
Die Schönheit des Webs besteht darin, dass Sie Technologien kombinieren können, um neue Formen zu schaffen. Da Audio und Video nativ im Browser verfügbar sind, können wir diese Datenströme mit Technologien wie <canvas>
, WebGL oder Web Audio API direkt modifizieren, z.B. durch Hinzufügen von Hall-/Kompressionseffekten zu Audio oder Grau-/Sepiafiltern zu Videos. 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 Oberfläche zum Zeichnen von Grafiken auf Webseiten; es ist sehr leistungsfähig und lässt sich eng mit Video koppeln.
Die allgemeine Technik ist:
- Schreiben Sie einen Frame des
<video>
-Elements auf das<canvas>
-Element. - Lesen Sie die Daten vom
<canvas>
-Element und manipulieren Sie sie. - Schreiben Sie die manipulierten Daten in Ihr "Anzeige"-
<canvas>
(das effektiv dasselbe Element sein kann). - Pausieren und wiederholen.
Zum Beispiel lassen Sie uns ein Video verarbeiten, um es in Graustufen anzuzeigen. In diesem Fall zeigen wir sowohl das Quellvideo als auch die resultierenden Graustufen-Frames. Normalerweise würden Sie, wenn Sie eine "Video in Graustufen abspielen"-Funktion implementieren, display: none
zum Stil für das <video>
-Element hinzufügen, um das Quellvideo davon abzuhalten, auf dem Bildschirm angezeigt zu werden, während nur das 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);
},
};
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. Zur Effizienzsteigerung sollten Sie in Betracht ziehen, requestAnimationFrame()
anstelle von setTimeout()
zu verwenden, wenn Sie in Browsern arbeiten, die dies unterstützen.
Das gleiche Ergebnis können Sie auch erzielen, indem Sie die grayscale()
-CSS-Funktion auf das Quell-<video>
-Element anwenden.
Hinweis: Aufgrund potenzieller Sicherheitsprobleme, wenn sich Ihr Video auf einer anderen Domain als Ihr Code befindet, müssen Sie CORS (Cross Origin Resource Sharing) auf Ihrem Videoserver aktivieren.
Video und WebGL
WebGL ist eine leistungsstarke API, die Canvas nutzt, um hardwarebeschleunigte 3D- oder 2D-Szenen zu zeichnen. Sie können WebGL mit dem <video>
-Element kombinieren, um Videotexturen zu erstellen, was bedeutet, dass Sie Videos in 3D-Szenen einfügen können.
Hinweis: Sie können den Quellcode dieses Demos auf GitHub finden (siehe es live auch).
Wiedergabegeschwindigkeit
Wir können auch die Geschwindigkeit, mit der Audio und Video abgespielt werden, mit einem Attribut der <audio>
- und <video>
-Elemente namens playbackRate
anpassen. playbackRate
ist eine Zahl, die ein Vielfaches darstellt, das auf die Abspielgeschwindigkeit angewendet wird, z.B. 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 <video>
funktioniert, aber in beiden Fällen die Abspielgeschwindigkeit ändert, jedoch nicht die Tonhöhe. Um die Tonhöhe des Audios zu manipulieren, müssen Sie die Web Audio API verwenden. Siehe 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 <output id="rate-value">1.0</output></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, dann passen Sie den Schieberegler an, um die Wiedergaberate der Medien zu ändern:
Audiomanipulation
Abgesehen von playbackRate
verwenden Sie zur Manipulation von Audio typischerweise die Web Audio API.
Auswahl einer Audioquelle
Die Web Audio API kann Audio aus verschiedenen Quellen erhalten, es dann verarbeiten und an einen AudioDestinationNode
senden, der das Ausgabegerät repräsentiert, an das der Ton nach der Verarbeitung gesendet wird.
Wenn die Audioquelle ist… | Verwenden Sie diesen Web Audio-Knotentyp |
---|---|
Ein Audio-Track aus einem HTML <audio> - oder <video> -Element |
MediaElementAudioSourceNode |
Ein einfacher, roher Audiodatenpuffer im Speicher | AudioBufferSourceNode |
Ein Oszillator, der eine Sinuswelle oder eine andere berechnete Wellenform erzeugt | OscillatorNode |
Ein Audio-Track von WebRTC (wie zum Beispiel das Mikrofoneingangssignal, das Sie mit getUserMedia() erhalten können). |
MediaStreamAudioSourceNode |
Audiofilter
Die Web Audio API verfügt über zahlreiche 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. <output id="freq-value">1.0</output>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: Wenn Sie nicht CORS aktiviert haben, um Sicherheitsprobleme zu vermeiden, sollte Ihr Video sich auf der gleichen Domain wie Ihr Code befinden.
Häufige Audiofilter
Dies sind einige gängige Arten von Audiofilter, die Sie anwenden können:
- Tiefpass: Ermöglicht Frequenzen unterhalb der Grenzfrequenz und schwächt Frequenzen überhalb der Grenze ab.
- Hochpass: Ermöglicht Frequenzen oberhalb der Grenzfrequenz und schwächt Frequenzen unterhalb der Grenze ab.
- Bandpass: Ermöglicht einen Frequenzbereich und schwächt die Frequenzen unterhalb und oberhalb dieses Frequenzbereichs ab.
- Tiefpass-Shelf: Lässt alle Frequenzen durch, fügt aber einen Boost (oder eine Abschwächung) der tieferen Frequenzen hinzu.
- Hochpass-Shelf: Lässt alle Frequenzen durch, fügt aber einen Boost (oder eine Abschwächung) der höheren Frequenzen hinzu.
- Peaking: Lässt alle Frequenzen durch, fügt jedoch einen Boost (oder eine Abschwächung) eines Frequenzbereichs hinzu.
- Notch: Lässt alle Frequenzen durch, außer für einen Satz Frequenzen.
- Allpass: Lässt alle Frequenzen durch, ändert jedoch die Phasenbeziehung zwischen den verschiedenen Frequenzen.
Hinweis:
Siehe BiquadFilterNode
für weitere Informationen.
Faltungen und Impulse
Es ist auch möglich, Impulsantworten auf Audio mit dem ConvolverNode
anzuwenden. Eine Impulsantwort ist der Klang, der nach einem kurzen Schallimpuls (wie einem Händeklatschen) erzeugt wird. Eine Impulsantwort wird die Umgebung anzeigen, in der der Impuls erzeugt wurde (z.B. 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 albern; wie, kleine Kinder werden kichern) Beispiel an.
Räumliches Audio
Wir können Audio auch mit einem Panner-Knoten positionieren. Ein Panner-Knoten—PannerNode
—ermöglicht es uns, einen Quellkegel sowie Positionierungs- und Richtungselemente zu definieren, alles im 3D-Raum, der mit Hilfe von 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: Sie können ein Beispiel in unserem GitHub-Repository finden (sehen Sie es live auch).
JavaScript-Codecs
Es ist auch möglich, Audio auf niedriger Ebene mit JavaScript zu manipulieren. Dies kann hilfreich sein, wenn Sie Audio-Codecs erstellen möchten.
Derzeit existieren Bibliotheken für die folgenden Formate:
Hinweis: Bei Audiocogs können Sie ein paar Demos ausprobieren; Audiocogs bietet auch ein Framework, Aurora.js, das dazu gedacht ist, Ihnen zu helfen, Ihre eigenen Codecs in JavaScript zu erstellen.
Beispiele
Siehe auch
Leitfäden
- Manipulieren von Videos mit Canvas
- HTML playbackRate erklärt
- Verwendung der Web Audio API
- Grundlagen der Web-Audio-Raumklangverarbeitung
- Verwendung von Videoframes als WebGL-Textur (Sie können auch die THREE.js WebGL-Bibliothek (und andere) verwenden, um diesen Effekt zu erzielen)
- Texturanimationen 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
- Weitere Infos zu räumlichem Audio
- Webmedientechnologien