WebRTC打开麦克风,获取音频,在网页上显示音量。
先从播放音频入手。准备一个现成的音频文件。
界面上放一个audio元素,提前准备好一个音频文件,路径填入src
<audio id="sample-audio" src="God_knows_01.mp3" controls autoplay></audio>
audio有默认的样式。打开网页就可以利用这个来播放示例音频了。
html页面上放audio,meter,button等等
<audio id="play-audio" controls autoplay></audio>
<div id="meters">
<div id="instant">
<div class="label">实时:</div>
<meter high="0.25" max="1" value="0"></meter>
<div class="value"></div>
</div>
<div id="slow">
<div class="label">秒级:</div>
<meter high="0.25" max="1" value="0"></meter>
<div class="value"></div>
</div>
<div id="clip">
<div class="label">Clip:</div>
<meter max="1" value="0"></meter>
<div class="value"></div>
</div>
</div>
<div>
<button id="startBtn">启动</button>
<button id="stopBtn" disabled>停止</button>
</div>
<div id="msg"></div>
引入js脚本
<!-- 使用本地的适配器 -->
<script src="../js/adapter-latest.js" async></script>
<script src="js/soundmeter.js"></script>
<script src="js/main.js"></script>
在使用WebRTC之前,先来看音频相关的方法和类。
要使用web的音频api,需要用到AudioContext
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.audioContext = new AudioContext();
} catch (e) {
alert('Web Audio API 不支持');
}
创建js处理音频的工具,接受3个数字参数
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/BaseAudioContext/createScriptProcessor
监听音频数据
基本用法
var audioCtx = new AudioContext();
var scriptNode = audioCtx.createScriptProcessor(4096, 1, 1);
scriptNode.onaudioprocess = function(event) { /* ... */ }
本文示例使用这个监听。但它目前已经不推荐使用(deprecated)了。
参考:https://developer.mozilla.org/en-US/docs/Web/API/ScriptProcessorNode/onaudioprocessbrowser_compatibility
完整soundmeter.js代码如下
'use strict';
// 这个类生成音频音量相关的数值
function SoundMeter(context) {
this.context = context;
this.instant = 0.0; // 实时
this.slow = 0.0; // 秒级
this.clip = 0.0;
this.script = context.createScriptProcessor(2048, 1, 1);
const that = this;
this.script.onaudioprocess = function (event) {
const input = event.inputBuffer.getChannelData(0); // 得到一个长度为2048的数组
let i;
let sum = 0.0;
let clipcount = 0;
for (i = 0; i < input.length; ++i) {
sum += input[i] * input[i];
if (Math.abs(input[i]) > 0.99) {
clipcount += 1;
}
}
console.log('clip count', clipcount);
that.instant = Math.sqrt(sum / input.length);
that.slow = 0.95 * that.slow + 0.05 * that.instant;
that.clip = clipcount / input.length;
};
}
SoundMeter.prototype.connectToSource = function (stream, callback) {
console.log('SoundMeter connecting');
try {
this.mic = this.context.createMediaStreamSource(stream);
this.mic.connect(this.script);
this.script.connect(this.context.destination);
if (typeof callback !== 'undefined') {
callback(null);
}
} catch (e) {
console.error(e);
if (typeof callback !== 'undefined') {
callback(e);
}
}
};
SoundMeter.prototype.stop = function () {
console.log('SoundMeter 正在停止');
this.mic.disconnect();
this.script.disconnect();
};
获取页面元素
'use strict';
const instantMeter = document.querySelector('instant meter');
const slowMeter = document.querySelector('slow meter');
const clipMeter = document.querySelector('clip meter');
const instantValueDisplay = document.querySelector('instant .value');
const slowValueDisplay = document.querySelector('slow .value');
const clipValueDisplay = document.querySelector('clip .value');
const playAudio = document.querySelector('play-audio');
const msgEle2 = document.querySelector("msg");
const startBtn = document.getElementById("startBtn");
const stopBtn = document.getElementById('stopBtn');
let meterRefresh = null;
const constraints = window.constraints = {
audio: true,
video: false
};
开启麦克风,和之前打开摄像头类似,用的也是getUserMedia方法。
startBtn.onclick = function (e) {
startBtn.disabled = true;
stopBtn.disabled = false;
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.audioContext = new AudioContext();
} catch (e) {
alert('Web Audio API 不支持.');
}
navigator.mediaDevices.getUserMedia(constraints).then(gotAudioStream).catch(onErr);
};
成功打开麦克风后,处理音频流
function gotAudioStream(stream) {
stream.oninactive = function () {
console.log('音频停止');
};
window.stream = stream;
playAudio.srcObject = stream;
console.log('对接麦克风的音频');
const soundMeter = window.soundMeter = new SoundMeter(window.audioContext);
soundMeter.connectToSource(stream, function (e) {
if (e) {
alert(e);
return;
}
meterRefresh = setInterval(() => {
instantMeter.value = instantValueDisplay.innerText =
soundMeter.instant.toFixed(2);
slowMeter.value = slowValueDisplay.innerText =
soundMeter.slow.toFixed(2);
clipMeter.value = clipValueDisplay.innerText =
soundMeter.clip;
}, 100);
});
}
function onErr(error) {
const errorMessage = '报错 navigator.MediaDevices.getUserMedia : ' + error.message + ' ' + error.name;
msgEle2.innerText = errorMessage;
console.error(errorMessage);
}
创建soundMeter,对接到音频流soundMeter.connectToSource(stream, function(e){});
设置一个定时器setInterval,定时刷新音量数据
把音频流停下
stopBtn.onclick = function (e) {
console.log('停止');
startBtn.disabled = false;
stopBtn.disabled = true;
window.stream.getTracks().forEach(track => track.stop());
window.soundMeter.stop();
clearInterval(meterRefresh);
instantMeter.value = instantValueDisplay.innerText = '';
slowMeter.value = slowValueDisplay.innerText = '';
clipMeter.value = clipValueDisplay.innerText = '';
}
运行效果链接
用getUserMedia打开麦克风,获取音频流。使用AudioContext的功能,得到音频音量的数值。
本文链接:WebRTC音频音量
原本笔者打算将这件工作交给服务端去完成,但考虑,其实无论是前端还是后台,所做的工作是差不多的,而且交给服务端还需要再额外走一个上传、下载音频的流程,这不仅增添了服务端的压力,而且还有网络流量的开销
CSS 是样式、布局和表示的领域。它充斥着颜色、大小和动画。但是你知道吗,它还可以在网页上控制播放声音。本文介绍了一些技巧。实际上它并不是真正的 hack,而是针对 HTML 和 CSS 的严格实现
JavaScript中可以通过Audio对象的volume属性来控制音频音量。volume属性设置或返回音频的音量,从0.0(静音)到1.0(最大声)。
HTML5 中为视频 video 和音频 audio 元素,提供了属性、方法和事件。这两个元素的常用属性上一节我们已经讲过了,本节我们来讲一下这两个元素的方法。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!