通过javascript记录网站的内部音频

问题描述

我制作了this webapp来创作音乐,我想添加一个功能以.mp3 / wav / whateverFileFormatPossible的形式下载乐曲,我一直在寻找如何做到这一点的很多次,并且总是放弃我找不到有关此操作的示例,只有发现的是麦克风录音机,但我想记录网站的最终音频目标。 我以这种方式播放音频

const a_ctx = new(window.AudioContext || window.webkitaudiocontext)()
function playAudio(buf){
    const source = a_ctx.createBufferSource()
    source.buffer = buf
    source.playbackRate.value = pitchKey;
    //Other code to modify the audio like adding reverb and changing volume
    source.start(0)
}

其中buf是AudioBuffer。

总而言之,我想录制整个窗口的音频,但无法解决

link to the whole website code on github

解决方法

也许您可以使用MediaStream Recording API(https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API):

MediaStream Recording API(有时简称为Media Recording API或MediaRecorder API)与Media Capture and Streams API和WebRTC API紧密相关。 MediaStream Recording API使捕获MediaStream或HTMLMediaElement对象生成的数据以进行分析,处理或保存到磁盘成为可能。使用起来也非常容易。

此外,您可以查看以下主题:new MediaRecorder(stream[,options]) stream can living modify?。似乎正在讨论一个相关问题,可能会为您提供一些见识。

以下代码生成一些随机噪声,应用一些变换,播放它并创建一个音频控件,该控件允许通过“另存音频为...”从上下文菜单中下载噪声(我需要更改扩展名保存的文件到.wav以便播放。)

<html>
<head>
<script>

const context = new(window.AudioContext || window.webkitAudioContext)()

async function run()
{
    var myArrayBuffer = context.createBuffer(2,context.sampleRate,context.sampleRate);
    // Fill the buffer with white noise;
    // just random values between -1.0 and 1.0
    for (var channel = 0; channel < myArrayBuffer.numberOfChannels; channel++) {
      // This gives us the actual array that contains the data
      var nowBuffering = myArrayBuffer.getChannelData(channel);
      for (var i = 0; i < myArrayBuffer.length; i++) {
        // audio needs to be in [-1.0; 1.0]
        nowBuffering[i] = Math.random() * 2 - 1;
      }
    }
    playAudio(myArrayBuffer)
}

function playAudio(buf){
    const streamNode = context.createMediaStreamDestination();
    const stream = streamNode.stream;
    const recorder = new MediaRecorder( stream );
    const chunks = [];
    recorder.ondataavailable = evt => chunks.push( evt.data );
    recorder.onstop = evt => exportAudio( new Blob( chunks ) );

    const source = context.createBufferSource()
    source.onended = () => recorder.stop();
    source.buffer = buf
    source.playbackRate.value = 0.2
    source.connect( streamNode );
    source.connect(context.destination);
    source.start(0)
    recorder.start();
}

function exportAudio( blob ) {
  const aud = new Audio( URL.createObjectURL( blob ) );
  aud.controls = true;
  document.body.prepend( aud );
}


</script>
</head>
<body onload="javascript:run()">
<input type="button" onclick="context.resume()" value="play"/>
</body>
</html>

这是您要找的吗?