Damit ich die Informationen verwenden, können eine Seite Animation zu koordinieren, wie machen Elemente heller als die Dezibel-Werte höher erhaltenGibt es eine Möglichkeit, Dezibelpegel aus einer Audiodatei zu erhalten und diese Informationen in ein JSON-Array umzuwandeln?
Antwort
Dieser Ansatz in Chrome/Safari funktioniert:
+function(){
var ctx = new AudioContext()
, url = 'https://cf-media.sndcdn.com/OfjMZo27DlvH.128.mp3?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL2NmLW1lZGlhLnNuZGNkbi5jb20vT2ZqTVpvMjdEbHZILjEyOC5tcDMiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE1MTUwNDM5Njd9fX1dfQ__&Signature=FfmL2qUssAKs3Z7EPoYo0Yq8-SAg8rKLPs65EasXwuVkfsOB4joFqeCvVR2elpaG-lJaV4hXpXFiRCDWXNOYyAtO4Oz~sexiPwIoSk8-jWiVbGQRS8TMmUmj7TJzxemMOIj7ugWJKk6PHsrUdgqs9woDpHzxmkGCzk6sfqJEIsdeZJ4rWUFAh4iGWn9M6b0xfzTgndAJmytkNj9raCpWCBVmdr5u-r9nt~q5uF1easNSW9oaFilM4s1Hq2ei~VJye8zW9bzvrGm8idVdy-tiPeMWAKcE8J2VuaS1Ret6jRTRaHTDuiNgA5sZvgTzNpEpKtWI7UmAWI5TrqNVSlxpgQ__&Key-Pair-Id=APKAJAGZ7VMH2PFPW6UQ'
, audio = new Audio(url)
// 2048 sample buffer, 1 channel in, 1 channel out
, processor = ctx.createScriptProcessor(2048, 1, 1)
, meter = document.getElementById('meter')
, source
audio.crossOrigin = 'anonymous'
audio.addEventListener('canplaythrough', function(){
source = ctx.createMediaElementSource(audio)
source.connect(processor)
source.connect(ctx.destination)
processor.connect(ctx.destination)
audio.play()
}, false);
// loop through PCM data and calculate average
// volume for a given 2048 sample buffer
processor.onaudioprocess = function(evt){
var input = evt.inputBuffer.getChannelData(0)
, len = input.length
, total = i = 0
, rms
while (i < len) total += Math.abs(input[i++])
rms = Math.sqrt(total/len)
meter.style.width = (rms * 100) + '%'
}
}()
#meter {
width: 0%;
height: 15px;
margin: 2px 0;
background: green;
-webkit-transition: width .05s;
}
<div id="meter"></div>
Das wichtige Zeug passiert hier:
processor.onaudioprocess = function(evt){
var input = evt.inputBuffer.getChannelData(0)
, len = input.length
, total = i = 0
, rms
while (i < len) total += Math.abs(input[i++])
rms = Math.sqrt(total/len)
meter.style.width = (rms * 100) + '%'
}
Basic Sie greifen die rohen PCM-Daten (Werte von -1 bis 1) alle 2048 Samples auf und durchlaufen diese, um den durchschnittlichen Signalpegel über den gegebenen Zeitraum zu berechnen.
Sie können diesen Wert dann für Ihre Animationen verwenden.
Bearbeiten: Aktualisiert, um RMS zu verwenden, die wie Jason hingewiesen hat, ist eine aussagekräftigere Messung.
Ja, Sie müssen die rohen PCM-Proben greifen (wie Kennis erwähnt). Um jedoch die Gesamtlautstärke zu berechnen, möchten Sie den RMS (Root Mean Square) der Werte ermitteln. Außerdem sollten Sie auf alle Kanäle im Stream achten, nicht nur auf den ersten Kanal (damit Sie beispielsweise den Lautstärkepegel für einen Stereo-Stream genau wiedergeben können).
Es gibt einige Tricks (stellen Sie sicher, dass Sie die Multiplikation der gleichen Samples über die Kanäle hinweg verwenden, nicht die Addition). Dann werden Sie sie alle zusammen hinzufügen (wieder wie Kennis). Wenn Sie eine tatsächliche Dezibel haben möchten, ist auch ein Protokollschritt erforderlich.
Es gibt ein Beispiel als answer to this other question.
Relevante Code:
var rms = Math.sqrt(sum/(_buffer.length/2));
var decibel = 20 * (Math.log(rms)/Math.log(10));
Danke Jason. Sie haben völlig Recht mit RMS. Ich war faul. FWIW, mein Beispiel summiert tatsächlich den linken und rechten Kanal am Prozessorknoten (es sei denn, ich habe die Spezifikation falsch verstanden) - also sollten beide in der Summe dargestellt werden. –
Ah cool! Danke Kevin :). Ich habe mir die Spezifikation nicht angesehen, also wäre ich nicht überrascht :). –
ich einige Probleme, zu verstehen, wie das funktioniert. Ich verwende page-player.js und soundmanager2.js -> www.wave.cat – coiso
Wäre kein [AnalysatorNode] (https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode) Sei viel besser für diese Aufgabe? –
Vielleicht? Sie können es sicherlich profilieren und herausfinden. Zumindest ist es wahrscheinlich erwähnenswert, dass seit diesem Post der 'ScriptProcessorNode' zugunsten des' AudioWorkerNode' veraltet ist. –