我有一个播放 mp3 的网页。我想为每个 mp3 创建一个可视化图表:音量级别与时间的关系,就像 Sound Cloud 所做的那样。我能想到的唯一想法是使用网络音频 API 解码 mp3,连接分析器节点,播放它并记录不同时间的电平。当然有更好的方法。有谁知道它是什么?
这是一个显示问题的小提琴。基本上,每当调用对象createMediaElementSource的方法时,音频元素的输出都会重新路由到返回的. 这一切都很好并且符合规范;但是,当我尝试将输出重新连接到扬声器(使用)时,没有任何反应。AudioContextMediaElementAudioSourceNodedestinationAudioContext
我在这里遗漏了一些明显的东西吗?也许这与跨域音频文件有关?我只是在 Google 上找不到有关该主题的任何信息,并且在规范中没有看到它的注释。
小提琴的代码是:
var a = new Audio();
a.src = "http://webaudioapi.com/samples/audio-tag/chrono.mp3";
a.controls = true;
a.loop = true;
a.autoplay = true;
document.body.appendChild(a);
var ctx = new AudioContext();
// PROBLEM HERE
var shouldBreak = true;
var src;
if (shouldBreak) {
// this one stops playback
// it should redirect output from audio element to the MediaElementAudioSourceNode
// but src.connect(ctx.destination) does not fix it
src = ctx.createMediaElementSource(a);
src.connect(ctx.destination);
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 web 音频 api 将 n 通道音频文件解码为单独的通道,然后将这些通道渲染到画布以直观地创建频率计。
我正在使用 decodeAudioData 解码字节数组缓冲区,然后在单独的函数中分配给音频缓冲区源节点。
// load the specified sound
function loadSound(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
// When loaded decode the data
request.onload = function () {
// decode the data
context.decodeAudioData(request.response, function (buffer) {
// when the audio is decoded play the sound
holdingBuffer = buffer;
setupSound(buffer);
}, onError);
}
request.send();
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,当我尝试解码大约 60mb 以上的音频时,浏览器会因内存空间不足而崩溃。 decodeAudioData 函数非常需要内存!
我想知道是否有人有任何解码更大音频文件的更有效方法的经验?
在网络音频 api 中推送声音时,您可以设置声音以 开始的时间source.start(startTime);。不过我想知道这有多精确。我知道setTimeout()只需将要执行的代码放在事件队列中即可。我认为 Web 音频 api 也是这样做的,但这只是一个猜测。这样一来,他们两个之间就不会有什么区别了。
我尝试在播放声音之前运行一些长时间运行的进程,并且声音确实有延迟。
//...
source.start(startTime + 0.2);
//....
let i = 0;
while( i < 100000){
console.log("p" + i);
i++;
}
Run Code Online (Sandbox Code Playgroud)
网络音频 API 的setTimeout底层使用也是如此。如果是这样,我可以通过使用网络工作者让事情变得更加敏感吗?我知道网络工作者可以访问 setTimeout,但我不确定它是否可以访问网络音频 api。
来自文档:
音频工作人员提供了在网络工作人员上下文中进行直接脚本化音频处理的能力,并由几个接口定义(自 2014 年 8 月 29 日起新)。这些尚未在任何浏览器中实现
这仅解决了音频处理的问题,我不确定是否包括仅播放音频。
我对此进行了研究,根据MediaRecorder.isTypeSupportedChromium 不支持音频/ogg;编解码器=作品。有谁知道是否有与 MediaRecorder 一起使用的替代方案,或者 Chrome 是否计划添加它?
谢谢
如何OfflineAudioContext.startRendering()输出AudioBuffer包含我选择的位深度(16 位或 24 位)的 ?我知道我可以使用 轻松设置输出的采样率AudioContext.sampleRate,但如何设置位深度?
我对音频处理的理解非常有限,所以也许它并不像我想象的那么容易。
编辑#1:
实际上,AudioContext.sampleRate它是只读的,所以如果您知道如何设置输出的采样率,那就太好了。
编辑#2:
我猜采样率是在编码的 WAV 中的通道数之后插入的(在DataView)
给定一个 30 多岁的普通网络视频:
<video src="my-video.mp4"></video>
Run Code Online (Sandbox Code Playgroud)
我怎样才能生成它的音量级别图表?
volume|
level| ******
| * * **
| * * * **
|** * *** *
| ** * * * *
+---------------*-*-----************------+--- time
0 30s
video is and quiet
loud here here
Run Code Online (Sandbox Code Playgroud)
笔记:
应该如何清理 web-audio-api AudioNode 以释放其内存?我正在调用oscillatorNode.stop()并oscillatorNode.disconnect()基于这篇文章,但它似乎没有帮助,最终导致内存泄漏。这篇文章不适用,因为我一停止振荡器节点就删除引用。
我创建了一个显示问题的示例网站。以下是重现的步骤。
<html>
<body>
<button onclick="go()">Go</button>
<button onclick="cancel=true">Cancel</button>
<div id="status"></div>
<script>
var cancel = false;
var statusEl = document.getElementById('status');
async function go() {
cancel = false;
for (var i = 0; i < 100000; i++) {
if (cancel) {
return;
}
statusEl.innerHTML = i;
play();
await new Promise((resolve) => { setTimeout(resolve, 1); });
stop();
}
}
var ctx …Run Code Online (Sandbox Code Playgroud) 我正在做一个在线音频播放器,所以我想在我的应用程序中集成Pitch Shifter,它在Tone js上可用,但在Web Audio API 中不可用......
所以我的想法是将Tonejs Pitch Shifter连接到Web Audio API 的 audioContext。
有什么可能的方法吗?
这是我的代码供参考
var audioCtx = new (window.AudioContext || window.webkitAudioContext);
var mediaElem = document.querySelector('audio');
var stream = audioCtx.createMediaElementSource(mediaElem);
var gainNode = audioCtx.createGain();
stream.connect(gainNode);
// tone js
var context = new Tone.Context(audioCtx); // Which is Mentioned in Tonejs Docs!
var pitchShift = new Tone.PitchShift().toMaster();
pitchShift.connect(gainNode);
// Gives Error!
gainNode.connect(audioCtx.destination);
Run Code Online (Sandbox Code Playgroud) 我正在开发一个 JavaScript 库 ( https://github.com/yvesgurcan/web-midi-player ) 以在 Web 应用程序中启用 MIDI 播放。该库依赖于 Web Audio API 来创建一种播放这些 MIDI 文件的方法 ( https://github.com/yvesgurcan/web-midi-player/blob/test/src/MidiPlayer.js#L50 )。但是,我无法使用 Jest ( https://github.com/yvesgurcan/web-midi-player/blob/test/tests/midiPlayer.js )创建有意义的单元测试,因为这些测试无法访问该window对象更特别的是window.AudioContext。因此,运行我依赖的应用程序代码会AudioContext抛出与此对象不存在相关的错误,并且我实际上无法在库中测试很多东西。
我已经尝试了以下软件包来解决我的问题:jsdom, jsdom-global, 以及web-audio-test-api但这些似乎都没有注入AudioContext环境。
我认为这里的解决方案是存根/模拟,AudioContext但这听起来不像是可靠的单元测试的好解决方案。
你们建议如何测试 Web Audio API?存根是这里唯一可行的解决方案吗?
web-audio-api ×10
javascript ×8
audio ×4
audiocontext ×2
html5-audio ×2
html5-video ×1
jestjs ×1
memory-leaks ×1
midi ×1
mp3 ×1
node.js ×1
tone.js ×1
unit-testing ×1