Javascript:来自本地文件的音频不播放没有HTML“<audio>”元素存在

时间:2016-06-11 04:54:21

标签: javascript audio

现在这个真的让我感到难过,所以我希望看看是否有人能够发现我做错事的地方。

基本上,我有一个包含两个元素的页面。一个是HTML5文件处理程序,第二个是按钮。当用户选择文件时,我响应生成的onchange事件,解码音频并构造要使用的缓冲区。我知道有HTML5音频标签,但这将是一个实用程序,需要能够将文件分解为可管理的块。

我做了几次测试,发现我自己解码的音频只会在播放页面上的音频元素后播放。我完全不知道是什么导致了这种行为,因为我在网上研究了几个播放音频的例子。我将在下面添加我的音频引擎。

只是澄清一下,所有内容都由此代码处理。

谢谢。

"use strict";

var AudioFile = function (){
  this.length = 0; // Number of samples
  this.duration = 0; // Time in seconds
  this.sampleRate = 0; // Sample rate
  this.channels = 0; // Number of channels
  this.data = []; //Audio/Waveform data
};

var audioCtx = null;

class AudioEngine {
  constructor (){
    // All of the necessary audio control variables
    if(!audioCtx){
      window.AudioContext = window.AudioContext || window.webkitAudioContext;
      audioCtx = new AudioContext();
    }

    // Will hold audio data waiting to be played
    this.buffer = null;

    // This will hold the decoded audio file upon completion
    this.decodedFile = new AudioFile();

    // Automatically create buffer upon finished decoding?
    this.autoCreateBuffer = true;

    // Specify this if you want to have a function recieve
    // the decoded audio, i.e. completionCallback(decodedFile);
    this.completionCallback = null;
  }

  // This will decode an audio file
  fileCallback (event){
    console.log("file callback");
    this.buffer = null;

    var reader = new FileReader();
    var file = event.target.files[0];
    reader.onload = this.loadCallback.bind(this);

    reader.readAsArrayBuffer(file);
  }

  // Called by fileCallback after file has been loaded
  loadCallback (file){
    console.log("load callback");
    var raw = file.target.result;
    audioCtx.decodeAudioData(raw, this.decodeCallback.bind(this));
  }

  // Called by loadCallback after file has been decoded
  decodeCallback (data){
    console.log("decode callback");
    var audioTemp = new AudioFile();

    audioTemp.length = data.length;
    audioTemp.duration = data.duration;
    audioTemp.sampleRate = data.sampleRate;
    audioTemp.channels = data.numberOfChannels;

    var arr = [];
    for(var i = 0; i < data.numberOfChannels; i++){
      arr.push(new Float32Array(data.length));
      data.copyFromChannel(arr[i], i);
    }

    audioTemp.data = arr.slice(0);
    this.decodedFile = audioTemp;

    if(this.autoCreateBuffer){
      var buffer = audioCtx.createBuffer(audioTemp.channels, audioTemp.length, audioTemp.sampleRate);

      var samples;
      for(var c = 0; c < audioTemp.channels; c++){
        samples = buffer.getChannelData(c);
        for(var i = 0; i < audioTemp.length; i++){
          samples[i] = this.decodedFile.data[c][i];
        }
      }

      this.buffer = buffer;
    }

    if(this.completionCallback){
      this.completionCallback(audioTemp);
    }
  }

  // Play data that is in buffer
  play(){
    if(this.buffer){
      var source = audioCtx.createBufferSource();
      var tmp = this.buffer.getChannelData(0);

      source.buffer = this.buffer;
      source.connect(audioCtx.destination);
      source.start(0);
      console.log("play");
    }
  }
}

1 个答案:

答案 0 :(得分:0)

好的,我已经弄清楚了什么似乎是问题所在。这段代码目前正处于测试阶段,它似乎与在Firefox上打开的控制台有关,这会使声音播放混乱。虽然,它与行为方式并不完全一致,但至少我知道我遇到问题的一般原因。

换句话说,&#34;音频&#34;无论控制台是否打开,元素都没有问题,但在使用JavaScript控制的音频打开/最小化控制台时似乎存在未定义的行为。但是,当控制台关闭时,它总是按预期运行。