从视频文件中提取音频

时间:2018-03-06 21:21:40

标签: javascript web-audio-api

修改This post与我的不重复。我试图将音频数据提取为二进制文件,没有像我之前提到的单独播放音频文件那样出现问题。

我正在尝试使用Web Audio Api从客户端的视频文件中提取音频。

var audioContext = new(window.AudioContext || window.webkitAudioContext)();
fileData = new Blob([input.files[0]]);
var videoFileAsBuffer = new Promise(getBuffer);
videoFileAsBuffer.then(function (data) {
    audioContext.decodeAudioData(data).then(function (decodedAudioData) {
        mySoundBuffer = decodedAudioData;
        soundSource = audioContext.createBufferSource();
        soundSource.buffer = mySoundBuffer;
        // soundSource.connect(audioContext.destination);
        // soundSource.start();
    });

当我在最后取消注释两行时,我听到上传的视频文件的声音。但是,当我在getChannelData方法的帮助下创建下载文件的链接时,它与视频文件的大小几乎相同。

我希望decodedAudioData只有音频二进制数据,并将其发送到我的webservice,这是我唯一需要的。但是,这没有像我预期的那样有效。有谁知道在客户端提取视频文件的音频的方法?提前谢谢。

以下是getBuffer方法,以防有人想知道:

function getBuffer(resolve) {
    var reader = new FileReader();
    reader.onload = function () {
        var arrayBuffer = reader.result;
        resolve(arrayBuffer);
    }
    reader.readAsArrayBuffer(fileData);
}

编辑:我能够使用 decodeAudioData 函数内的OfflineAudioContext解码视频文件并获取audiobuffer。

var offlineAudioContext = new OfflineAudioContext(2, 44100 * 100, 44100);
var soundSource = offlineAudioContext.createBufferSource();
...
soundSource.connect(offlineAudioContext.destination);
soundSource.start();
offlineAudioContext.startRendering().then(function (renderedBuffer) {
    console.log(renderedBuffer); // outputs audiobuffer
    var song = audioContext.createBufferSource();
    song.buffer = renderedBuffer;
    song.connect(audioContext.destination);
    song.start();
}).catch(function (err) {
    console.log('Rendering failed: ' + err);
});

renderedBuffer是一个audiobuffer,输出数据没有问题,使用Audacity的导入原始数据选项进行测试。但问题是,新文件(填充renderedBuffer.getChannelData(0))的大小比原始视频大。是不是应该有较小的尺寸,因为它只包含视频文件的音频?

2 个答案:

答案 0 :(得分:1)

好的,我实际上已经得到了答案。原始音频数据非常庞大,这就是为什么它的大小甚至比视频本身还要大。

0

之后,我可以使用audiobuffer-to-wav库将audiobuffer (renderedbuffer)转换为wav文件。只需要OfflineAudioContext来修改裁剪的音频。

修改 如果您不想覆盖音频数据,js fiddle example. decodingAudioData 方法就足够了。

答案 1 :(得分:-1)

我正在使用此代码提取音频:

// initialize the audioContext
var audioContext = new webkitAudioContext();
var video = document.getElementById("myVideo");
var mediaSource = audioContext.createMediaElementSource(video);
var analyser = audioContext.createAnalyser();
mediaSource.connect(analyser);
analyser.connect(audioContext.destination);
// this will give you the sound data

video.play();

function getSoundData() {
   var sample = new Float32Array(analyser.frequencyBinCount);
   return analyser.getFloatFrequencyData(sample);  
}

修改

到目前为止,我还没有运行此代码,但我认为这也应该有效:

XMLHttpRequest提取到您的视频(也使用本地文件),而不是使用WebAudio API。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://test.com/myvideo.mp4', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {
    var binaryData = this.response;
    console.log(binaryData)
};

xhr.send();

编辑2:

var audioFileUrl = 'video.mp3';

fetch(audioFileUrl)
  .then(function(res) {
    res.blob().then(function(blob) {
      var size = blob.size;
      var type = blob.type;

      var reader = new FileReader();
      reader.addEventListener("loadend", function() {

        var base64FileData = reader.result.toString();

        var mediaFile = {
          fileUrl: audioFileUrl,
          size: blob.size,
          type: blob.type,
          src: base64FileData
        };

      });

      reader.readAsDataURL(blob);

    });
  });

或尝试使用某种代码:

<audio id="audio" src="http://yourvideo.com/video.mp4" controls autoplay></audio>


function getAudio() {
  var elem = document.getElementById("audio")

  // get Base 64 string from elem.src
}

我希望它有用,因为对我来说,到目前为止,这几条线路工作得很好:)