Audio- und Videomanipulation
Die Schönheit des Webs liegt darin, dass Sie Technologien kombinieren können, um neue Formen zu schaffen. Mit nativem Audio und Video im Browser 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 durch Hinzufügen von Reverb-/Kompressionseffekten zu Audio oder Graustufen-/Sepiafiltern 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 in das<canvas>
-Element zu schreiben. - Die Daten aus dem
<canvas>
-Element zu lesen und zu manipulieren. - Die manipulierten Daten auf Ihr "Anzeige"-
<canvas>
zu schreiben (was effektiv dasselbe Element sein kann). - Pause 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 ausgegebenen Graustufen-Frames. Normalerweise, wenn Sie eine "Video in Graustufen abspielen"-Funktion implementieren würden, würden Sie wahrscheinlich display: none
zum Stil für das <video>
-Element hinzufügen, um das Quellvideo davon abzuhalten, auf dem Bildschirm gezeichnet zu werden, während nur das Canvas die geä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 Änderung der 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. Für mehr Effizienz sollten Sie in Betracht ziehen, 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 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 (sehen Sie es live auch).
Wiedergabegeschwindigkeit
Wir können auch die Geschwindigkeit anpassen, mit der Audio und Video abgespielt werden, indem wir ein Attribut der <audio>
und <video>
-Elemente namens playbackRate
verwenden. playbackRate
ist eine Zahl, die ein Vielfaches darstellt, das auf die Wiedergabegeschwindigkeit angewendet wird, zum Beispiel steht 0,5 für die halbe Geschwindigkeit, während 2 für die doppelte Geschwindigkeit steht.
Beachten Sie, dass die playbackRate
-Eigenschaft sowohl mit <audio>
als auch mit <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. 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 und passen Sie dann den Schieberegler an, um die Wiedergabegeschwindigkeit der Medien zu ändern:
Audiomanipulation
Abgesehen von playbackRate
, wenn Sie Audio manipulieren möchten, verwenden Sie normalerweise die Web Audio API.
Eine Audioquelle auswählen
Die Web Audio API kann Audio von einer Vielzahl von Quellen empfangen, 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 Audiotrack von 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 Audiotrack von WebRTC (wie das Mikrofoneingang, das Sie mit getUserMedia() erhalten können). |
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. <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: Sofern Sie nicht CORS aktiviert haben, sollte Ihr Video aus Sicherheitsgründen auf derselben Domain wie Ihr Code sein.
Allgemeine Audiofilter
Dies sind einige gängige Arten von Audiofiltern, die Sie anwenden können:
- Low Pass: Lässt Frequenzen unterhalb der Grenzfrequenz durch und dämpft Frequenzen über der Grenzfrequenz.
- High Pass: Lässt Frequenzen oberhalb der Grenzfrequenz durch und dämpft Frequenzen unter der Grenzfrequenz.
- Band Pass: Lässt einen Bereich von Frequenzen durch und dämpft die Frequenzen unterhalb und oberhalb dieses Frequenzbereichs.
- Low Shelf: Lässt alle Frequenzen durch, aber fügt den unteren Frequenzen eine Verstärkung (oder Dämpfung) hinzu.
- High Shelf: Lässt alle Frequenzen durch, aber fügt den höheren Frequenzen eine Verstärkung (oder Dämpfung) hinzu.
- Peaking: Lässt alle Frequenzen durch, aber fügt einem Bereich von Frequenzen eine Verstärkung (oder Dämpfung) hinzu.
- Notch: Lässt alle Frequenzen durch, außer für einen Satz von Frequenzen.
- All Pass: Lässt alle Frequenzen durch, ändert aber 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 Impuls von Geräusch (wie einem Händeklatschen) erstellt wird. Eine Impulsantwort wird die Umgebung signalisieren, in der der Impuls erzeugt 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 unser HolySpaceCow Beispiel für ein angewandtes (aber sehr, sehr albernes) Beispiel an.
Räumliches Audio
Wir können auch Audio mithilfe eines Panoramaknotens positionieren. Ein Panoramaknoten—PannerNode
—ermöglicht es uns, einen Quellkegel sowie Positions- und Richtungselemente festzulegen, alles in einem 3D-Raum, definiert durch kartesische 3D-Koordinaten.
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
- Video mit Canvas manipulieren
- HTML playbackRate erklärt
- Die Web Audio API verwenden
- Grundlagen der Web-Audioräumlichkeitsbestimmung
- Video-Frames als WebGL-Textur verwenden (Sie können auch die THREE.js WebGL-Bibliothek (und andere) verwenden, um diesen Effekt zu erzielen)
- Texturen in WebGL animieren
- Spiele-Audio mit der Web Audio API entwickeln (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
- Webmedientechnologien