デシベルレベルが高くなるにつれて要素を明るくするなど、ページアニメーションを調整するために情報を使用できるように
質問する
9357 次
2 に答える
17
このアプローチは、Chrome / Safari で機能します。
+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>
重要なことはここで起こります:
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 ) + '%'
}
基本的に、生の PCM データ (-1 から 1 までの値) を 2048 サンプルごとに取得し、それらをループ処理して、一定期間の平均信号レベルを計算します。
その後、その値を使用してアニメーションを実行できます。
編集: RMS を使用するように更新されました。ジェイソンが指摘したように、これはより意味のある測定値です。
于 2012-12-06T00:46:38.730 に答える
13
はい、生のPCMサンプルを取得する必要があります(Kennisが言及しているように)。ただし、全体的な音量レベルを計算するには、値のRMS(二乗平均平方根)を取得する必要があります。また、最初のチャンネルだけでなく、ストリーム内のすべてのチャンネルに注意を払うことをお勧めします(たとえば、ステレオストリームの音量レベルを正確に反映できます)。
いくつかのトリックがあります(加算ではなく、チャネル間で同じサンプルの乗算を使用するようにしてください)。次に、それらをすべて一緒に追加します(これもケニスが行っているように)。実際のデシベルが必要な場合は、ログステップも必要です。
この他の質問への答えとして例があります。
関連コード:
var rms = Math.sqrt(sum / (_buffer.length / 2));
var decibel = 20 * (Math.log(rms) / Math.log(10));
于 2012-12-06T01:29:55.257 に答える