javascript网络音频分析器:精确时间的getByteFrequencyData?

时间:2017-09-05 14:02:30

标签: javascript time web-audio-api

基于网络音频分析器API,我正在创建一个基于实时频谱绘制图像的音频动画(就像移动到声音频率的经典条形图形,除了它不是条形图绘制但更复杂的东西)。

它工作正常,我唯一的问题是我无法在精确的时间停止图像。 当我想让它停止时让我们说5秒钟,然后有时它停在5.000021,或5.000013,或5.0000098,...... 问题是频谱(以及基于此频谱的图像)在5.000021,或5.000013或5.0000098处不相同,...... 这意味着当用户想要看到对应于5s的图像时,每次他看到略微不同的图像,并且我希望只有一个图像对应于5s(通常图像在每次尝试时只是略有不同,但是有时差异非常大。)

以下是我的代码摘录:

var ctx = new AudioContext();
var soundmp3 = document.getElementById('soundmp3');
soundmp3.src = URL.createObjectURL(this.files[0]);
var audioSrc = ctx.createMediaElementSource(soundmp3);
var analyser = ctx.createAnalyser();
analyser.fftSize =   2048;
analyser.smoothingTimeConstant = 0.95;
audioSrc.connect(analyser);
audioSrc.connect(ctx.destination);
var frequencyData = new Uint8Array(analyser.frequencyBinCount);

function renderFrame() {
   if(framespaused) return;
      drawoneframe();
      requestAnimationFrame(renderFrame); 
    };

function drawoneframe(){
  analyser.getByteFrequencyData(frequencyData);
   // drawing of my image ...
 };

function gotomp3(timevalue){
  soundmp3.pause(); 
  newtime = timevalue;
  backtime = newtime - 0.2000;  
  soundmp3.currentTime = backtime;
  soundmp3.play();

  function boucle(){
   if(soundmp3.currentTime >= timevalue){     
     if(Math.abs(soundmp3.currentTime-newtime) <= 0.0001){
      drawoneframe();
      soundmp3.pause();
      soundmp3.currentTime = timeatgetfrequency;
      return;
     } else {
        soundmp3.pause();   
        soundmp3.currentTime = backtime;
        soundmp3.play();              
     };
   }      
   setTimeout(boucle, 1);    
  };
  boucle();
};


document.getElementById("fieldtime").onkeydown = function (event) {if    (event.which == 13 || event.keyCode == 13) {
    gotomp3(document.getElementById("fieldtime").value);
    return false;
  } 
  return true;
  };

代码说明:如果用户在“fieldtime”(= newtime)输入一个值并按下enter键,那么我先返回0.2秒,开始播放并在currentTime非常接近newtime时停止(我必须请先返回,因为当我直接进入newtime并在之后立即停止时,analyser.getByteFrequencyData在newtime时还没有值。使用boucle()我设法让它在非常精确的时间停止:如果newtime = 5,那么drawoneframe();被称为5.000xx,但问题是,每次用户输入5作为新时间时,显示的图像略有不同。

所以我的问题是:有人知道如何在每次用户输入新时间的同时实现这一目标,图像将完全相同吗?

我不太清楚soundmp3.currentTime在哪些时候更新了?对于44.1kHz的采样率,我猜它类似于每0.0227ms,但这是否意味着它正好更新为0,0.0227ms,0.0454ms,......或者只是大约? 我考虑过平滑分析仪的结果,因此对于小的时间变化,变化较小。将analyser.smoothingTimeConstant设置为接近1的值是不够的。但也许有另一种方法可以做到这一点。 我不需要高精度的结果,我只是想如果用户想要看到对应于x秒的图像,那么每次进入x秒时,他都会看到完全相同的图像。

非常感谢您的帮助。 米雷耶

0 个答案:

没有答案