从视频文件中提取音频 [英] Extracting audio from a video file

查看:75
本文介绍了从视频文件中提取音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:这篇文章与矿.我正在尝试将音频数据提取为二进制文件,像我之前提到的那样单独播放音频文件没有问题.

Edit: This post is no duplicate of mine. I am trying to extract the audio data as binary, got no problems with playing the audio file as separate as I mentioned before.

我正在尝试使用 网络音频 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 方法的帮助下创建下载文件的链接时,它的大小几乎与视频文件相同.

When I uncomment the two lines at the end, I am hearing the sound of the uploaded video file. Though, when I create a link to download the file with the help of getChannelData method, it's almost the same size as video file.

我期望 decodedAudioData 只有音频二进制数据,并将其发送到我的网络服务,这是我唯一需要的.然而,这并没有像我预期的那样奏效.有人知道在客户端提取视频文件音频的方法吗?提前致谢.

I was expecting decodedAudioData to have only audio binary data, and send that to my webservice, which is the only one I need. However, that didn't work out as I expected. Anyone knows a way to extract audio of a video file on client-side? Thanks in advance.

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

Here is the getBuffer method in case anyone wants to know:

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

编辑:我能够使用 decodeAudioData 函数内的 rel="noreferrer">OfflineAudioContext.

Edit: I was able to decode the video file and get audiobuffer by using OfflineAudioContext inside decodeAudioData function.

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 是一个音频缓冲区,输出数据没有问题,使用 Audacity 的导入原始数据选项.但问题是,新文件(用 renderedBuffer.getChannelData(0) 填充)的大小比原始视频大.那不是应该小一点,因为它只包含视频文件的音频吗?

renderedBuffer is an audiobuffer, had no problem outputting the data, tested with Audacity's import raw data option. But the problem is, the new file (filled with renderedBuffer.getChannelData(0)) has higher size than the original video has. Isn't that supposed to have lower size since it only contains audio of the video file?

推荐答案

好吧,其实我已经有了答案.原始音频数据是巨大的,这就是为什么它的大小甚至比视频本身还要大.

Ok, I actually had the answer already. Raw audio data is huge, that's why it's even greater than the video itself in size.

var offlineAudioContext = new OfflineAudioContext(numberOfChannels, sampleRate * duration, sampleRate);
var soundSource = offlineAudioContext.createBufferSource();
...
reader.readAsArrayBuffer(blob); // video file
reader.onload = function () {
  var videoFileAsBuffer = reader.result; // arraybuffer
  audioContext.decodeAudioData(videoFileAsBuffer).then(function (decodedAudioData) {
    myBuffer = decodedAudioData;
    soundSource.buffer = myBuffer;
    soundSource.connect(offlineAudioContext.destination);
    soundSource.start();

    offlineAudioContext.startRendering().then(function (renderedBuffer) {
      console.log(renderedBuffer); // outputs audiobuffer
    }).catch(function (err) {
      console.log('Rendering failed: ' + err);
    });
  });
};

之后,我能够使用 (renderedbuffer) 转换为 wav 文件rel="nofollow noreferrer">audiobuffer-to-wav 库.OfflineAudioContext 只需要修改裁剪后的音频.

After that, I was able to convert the audiobuffer (renderedbuffer) into a wav file by using audiobuffer-to-wav library. OfflineAudioContext is just needed to modify the cropped audio.

这是 js 小提琴示例. decodedAudioData 如果你不这样做就足够了不想覆盖音频数据.

Here is the js fiddle example. decodedAudioData method will suffice if you don't want to override the audio data.

这篇关于从视频文件中提取音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆