WebRTC打开麦克风,获取音频,在网页上显示音量。

播放示例音频

先从播放音频入手。准备一个现成的音频文件。

界面上放一个audio元素,提前准备好一个音频文件,路径填入src

<audio id="sample-audio" src="God_knows_01.mp3" controls autoplay></audio>

audio有默认的样式。打开网页就可以利用这个来播放示例音频了。

WebRTC打开麦克风

准备

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>
  • 使用了本地的适配器
  • main.js 主要的控制逻辑
  • soundmeter.js 计算音频音量的方法

soundmeter.js

在使用WebRTC之前,先来看音频相关的方法和类。

要使用web的音频API,需要用到AudioContext

try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.audioContext = new AudioContext();
} catch (e) {
alert('Web Audio API 不支持');
}

AudioContext.createScriptProcessor(int, int, int)

创建js处理音频的工具,接受3个数字参数

  • bufferSize

    • 缓冲区大小,以样本帧为单位。具体来讲,数值必须是以下这些值当中的某一个: 256, 512, 1024, 2048, 4096, 8192, 16384. 如果不传,或者参数为0,则取当前环境最合适的缓冲区大小, 取值为2的幂次方的一个常数,在该node的整个生命周期中都不变.
    • 该取值控制着audioprocess事件被分派的频率,以及每一次调用多少样本帧被处理. 较低bufferSzie将导致一定的延迟。较高的bufferSzie就要注意避免音频的崩溃和故障。推荐作者不要给定具体的缓冲区大小,让系统自己选一个好的值来平衡延迟和音频质量。
    • 重要: Webkit (version 31)要求调用这个方法的时候必须传入一个有效的bufferSize .
  • numberOfInputChannels
    • 值为整数,用于指定输入node的声道的数量,默认值是2,最高能取32.
  • numberOfOutputChannels
    • 值为整数,用于指定输出node的声道的数量,默认值是2,最高能取32.

参考:https://developer.mozilla.org/zh-CN/docs/Web/API/BaseAudioContext/createScriptProcessor

AudioContext.onaudioprocess

监听音频数据

基本用法

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/onaudioprocess#browser_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();
};

js

获取页面元素

'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音频音量

WebRTC与音频音量的更多相关文章

  1. 单独编译使用WebRTC的音频处理模块

    块,每块个点,(12*64=768采样)即AEC-PC仅能处理48ms的单声道16kHz延迟的数据,而 - 加载编译好的NS模块动态库 接下来只需要按照 此文 的描述在 android 的JAVA代码 ...

  2. 【单独编译使用WebRTC的音频处理模块 - android】

    更新 [2015年2月15日] Bill 这段时间没有再关注 WebRTC 以及音频处理的相关信息,且我个人早已不再推荐单独编译 WebRTC 中的各个模块出来使用.实际上本文的参考价值已经很小了,甚 ...

  3. //点击按钮加减音频音量到最小会出现bug什么意思???

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 千位分隔符,音频音量加强,transform 垂直居中

    1.最近做阴阳师日本官网,其中有个功能是获取预约人数,设计稿上的人数是这样151,567,000,想了想自己写还有点麻烦,于是网上copy了代码,再修改了下. 其中,有一点需要注意的是:函数中的str ...

  5. WebRTC APM音频处理流程概述

    本文主要介绍WebRTC的APM. 现在主要介绍一下audio_processing.h. 首先插入了几个类,这些都是audio_processing的核心模块. class AudioFrame; ...

  6. C++ 调节PCM音频音量大小

    在用解码器解码音频数据得到PCM音频数据块之后,可以在将数据送给声卡播放之前调节其音量大小,具体的实现函数如下: void RaiseVolume(char* buf, UINT32 size, UI ...

  7. WebRTC的音频编码(转)

    一.一个典型的IP通信模型 二.Server2Server技术分类 Server2Server这块也是一个专门的领域,这里只简单分个类. 1.同一国家相同运营商之间: 同一运营商之间也有丢包,在铁通, ...

  8. webrtc的音频处理模块apm( audio processing)下载与编译出libwebrtc_audio_preprocessing.so

    webrtc代码在android和chromium项目中都有.但是android中的那个带有Android.mk,稍微修改下就能用ndk-build编译出libwebrtc_audio_preproc ...

  9. 基于webRTC技术 音频和视频,IM解

    由于原来的文章 http://blog.csdn.net/voipmaker  转载注明出处. 基于WebRTC技术可实现点对点音视频.即时通信.视频会议.最新的系统组件包含: TeleICE NAT ...

随机推荐

  1. [atARC087F]Squirrel Migration

    对这棵树重心情况分类讨论: 1.若这棵树存在两个重心,分别记作$x$和$y$,如果将$(x,y)$断开,两棵子树大小都相同(都为$\frac{n}{2}$),此时$p_{i}$与$i$必然不同属于一个 ...

  2. 三、MapReduce编程实例

    前文 一.CentOS7 hadoop3.3.1安装(单机分布式.伪分布式.分布式 二.JAVA API实现HDFS MapReduce编程实例 @ 目录 前文 MapReduce编程实例 前言 注意 ...

  3. springboot和mybatis集成

    springboot和mybatis集成 pom  <?xml version="1.0" encoding="UTF-8"?> <proje ...

  4. Electron快速入门

    node -v npm -v 安装node环境 my-electron-app/ ├── package.json ├── main.js └── index.html 为您的项目创建一个文件夹并安装 ...

  5. Java二次开发海康SDK-对接门禁机

    写在最前 SDK版本:CH-HCNetSDKV6.1.6.45_build20210302_win64 参考文档:海康SDK使用手册_V6.1 对接测试设备型号:DS-K1T671M 设备序列号:E5 ...

  6. 调用clapack库注意事项

    寒假期间在自己开发的模型DGOM里成功的用clapack替换了MKL,这里就介绍下遇到的几个坑,希望能够帮助别人少走弯路. 1. 调用clapack函数时注意整数类型为integer. 虽然clapa ...

  7. GWAS与GS模型介绍与比较

    目录 1.GWAS模型 1.1卡方检验 1.2 相关性系数的t检验 1.3 一般线性模型GLM 1.4 混合线性模型MLM 1.5 压缩混合线性模型CMLM 1.6 SUPER 1.7 FarmCPU ...

  8. python10-高阶函数

    def use_filer(l): """ 获取指定列表/元组中的奇数 :param l: lsit/tuple :return: """ ...

  9. python包之drmaa:集群任务管理

    目录 1. drmaa简介 2. 安装和配置 3. 示例 3.1 开始和终止会话 3.2 运行工作 3.3 等待工作 3.4 控制工作 3.5 查询工作状态 4. 应用 4.1 写一个简单应用 4.2 ...

  10. JVM2 类加载子系统

    目录 类加载子系统 类加载器子系统 类加载器ClassLoader角色 类加载的过程 案例 加载Loading 连接Linking 初始化Intialization clinit() 类的加载器 虚拟 ...