javascript - 我可以在不使用麦克风的情况下录制 <audio> 的输出吗?

标签 javascript html audio webrtc html5-audio

我有一个 <audio>元素,我正在改变速度、开始/结束范围和间距。我想看看是否可以录制我在浏览器中听到的音频。但是我不想只用麦克风录音,因为质量较低。

我可以在服务器端实现相同的效果,但我宁愿不这样做,因为我基本上会用两种不同的技术复制相同的功能。


为了回应旗帜投票,因为它“不清楚我在问什么”,我会重新措辞。

我有一个 <audio>在页面上播放的元素。我有一些 javascript 可以控制播放速率、音量等。然后我希望我的浏览器 按照我听到的方式录制音频。这不是麦克风。我想创建一个尽可能接近正在播放的音频文件。如果音量为 75%,则新文件的音量将为 75%。

最佳答案

在支持的浏览器中,您可以使用 MediaElement.captureStream()方法以及 MediaRecorder API .

但请注意,这些技术仍在积极开发中,当前的实现仍然充满错误。
例如,对于您的情况,如果您在录制时更改其音量,当前稳定的 FF 将停止原始媒体音频的渲染......我没有时间搜索关于它的错误报告,但无论如何,这只是一个您会发现的许多错误中的一个。

// here we will save all the chunks of our record
const chunks = [];
// wait for the original media is ready
audio.oncanplay = function() {
  audio.volume = 0.5; // just for your example
  // FF still does prefix this unstable method
  var stream = audio.captureStream ? audio.captureStream() : audio.mozCaptureStream();
  // create a MediaRecorder from our stream
  var rec = new MediaRecorder(stream);
  // every time we've got a bit of data, store it
  rec.ondataavailable = e => chunks.push(e.data);
  // once everything is done
  rec.onstop = e => {
    audio.pause();
    // concatenate our chunks into one file
    let final = new Blob(chunks);
    let a = new Audio(URL.createObjectURL(final));
    a.controls = true;
    document.body.append(a);
  };
  rec.start();
  // record for 6 seconds
  setTimeout(() => rec.stop(), 6000);
  // for demo, change volume at half-time
  setTimeout(() => audio.volume = 1, 3000);
};

// FF will "taint" the stream, even if the media is served with correct CORS...
fetch("https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3").then(resp => resp.blob()).then(b => audio.src = URL.createObjectURL(b));
<audio id="audio" autoplay controls></audio>

对于旧版浏览器,您可以使用 WebAudio API 的 createMediaElementSource方法,通过 API 传递您的音频元素媒体。
从那里,您将能够将原始 PCM 数据提取到 arrayBuffers 并将其保存。

在下面的演示中,我将使用 recorder.js 极大地帮助提取 + 保存到 wav 过程的库。

audio.oncanplay = function(){
  var audioCtx = new AudioContext();
  var source = audioCtx.createMediaElementSource(audio);
  var gainNode = audioCtx.createGain();

  gainNode.gain.value = 0.5;

  source.connect(gainNode);
  gainNode.connect(audioCtx.destination);  

  var rec = new Recorder(gainNode);

   rec.record();
  setTimeout(function(){
    gainNode.gain.value = 1;
    }, 3000);
  setTimeout(function(){
    rec.stop()
    audio.pause();
    rec.exportWAV(function(blob){
      var a = new Audio(URL.createObjectURL(blob));
      a.controls = true;
      document.body.appendChild(a);
      });
    }, 6000);
  };
<script src="https://rawgit.com/mattdiamond/Recorderjs/master/dist/recorder.js"></script>
<audio id="audio" crossOrigin="anonymous" controls src="https://dl.dropboxusercontent.com/s/8c9m92u1euqnkaz/GershwinWhiteman-RhapsodyInBluePart1.mp3" autoplay></audio>

关于javascript - 我可以在不使用麦克风的情况下录制 <audio> 的输出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42336604/

相关文章:

javascript - paper-dropdown-menu 在 lit-element 中不起作用

JavaScript 正则表达式提取字符串的不同部分

javascript - 如何接受姓名和号码输入并将其添加到文档/网页

html - CSS 背景

html - <xmp> 标签的任何替代方案,将 html 呈现为纯文本

移动图像后,HTML + CSS 图像链接将不起作用

c# - 修剪 wav 文件

javascript - 试图实现向上的箭头

audio - 如何将 MP3 文件转换为 Base64 编码的字符串?

c# - 每秒播放不同的WAV声音吗?是从磁盘还是从内存?