HTML + JavaScript 实现网页录制音频与下载

HTML + JavaScript 实现网页录制音频与下载

  • HTML + JavaScript 实现网页录制音频与下载
    • 简介
      • getUserMedia
      • MediaRecorder
      • 获取和处理音频流
      • 实现音频的录制和播放
      • 音频效果的处理
      • 实时语音通话的应用
      • 兼容性和 Latency 问题
    • 项目代码
    • 运行实例
    • 参考
    • 源码下载

HTML + JavaScript 实现网页录制音频与下载

简介

在这个数字化的时代,网页端的音频处理能力已经成为一个非常热门的需求。本文将详细介绍如何利用 getUserMedia 和 MediaRecorder 这两个强大的 API,实现网页端音频的录制、处理和播放等功能。

getUserMedia

getUserMedia 和 MediaRecorder 是 HTML5 中两个非常重要的 API,用于访问设备媒体输入流并对其进行操作。

getUserMedia 允许网页端访问用户设备的媒体输入设备,比如摄像头和麦克风。通过该 API,在获得用户授权后,我们可以获取这些媒体流的数据,并用于各种网页应用场景中。

典型的使用方式如下:

// 请求获取音频流
navigator.mediaDevices.getUserMedia({audio: true
})
.then(stream => {// 在此处理音频流
})

getUserMedia 接受一个 constraints 对象作为参数,通过设置配置来请求获取指定的媒体类型,常见的配置有:

  • audio:Boolean 值,是否获取音频输入。
  • video:Boolean 值,是否获取视频输入。
  • 以及更详细的各种音视频参数设置。

MediaRecorder

MediaRecorder API 可以获取由 getUserMedia 生成的媒体流,并对其进行编码和封装,输出可供播放和传输的媒体文件。

典型的用法如下:

// 获取媒体流
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })// 创建 MediaRecorder 实例 
const mediaRecorder = new MediaRecorder(stream);// 注册数据可用事件,以获取编码后的媒体数据块
mediaRecorder.ondataavailable = event => {audioChunks.push(event.data);
}// 开始录制
mediaRecorder.start();// 录制完成后停止
mediaRecorder.stop(); // 将录制的数据组装成 Blob
const blob = new Blob(audioChunks, {type: 'audio/mp3' 
});

简单来说,getUserMedia 获取输入流,MediaRecorder 对流进行编码和处理,两者结合就可以实现强大的音视频处理能力。

获取和处理音频流

了解了基本 API 使用方法后,我们来看看如何获取和处理音频流。

首先需要调用 getUserMedia 来获取音频流,典型的配置是:

const stream = await navigator.mediaDevices.getUserMedia({audio: {channelCount: 2,  sampleRate: 44100,sampleSize: 16,echoCancellation: true }
});

我们可以指定声道数、采样率、采样大小等参数来获取音频流。

PS:这似乎不管用。

使用 navigator.mediaDevices.enumerateDevices() 可以获得所有可用的媒体设备列表,这样我们就可以提供设备选择功能给用户,而不仅仅是默认设备。

举例来说,如果我们想要让用户选择要使用的录音设备:

// 1. 获取录音设备列表
const audioDevices = await navigator.mediaDevices.enumerateDevices();const mics = audioDevices.filter(d => d.kind === 'audioinput');// 2. 提供设备选择 UI 供用户选择
const selectedMic = mics[0]; // 3. 根据选择配置进行获取流
const constraints = {audio: {deviceId: selectedMic.deviceId}  
};const stream = await navigator.mediaDevices.getUserMedia(constraints);

这样我们就可以获得用户选择的设备录音了。

获得原始音频流后,我们可以利用 Web Audio API 对其进行处理。

例如添加回声效果:

// 创建音频环境
const audioContext = new AudioContext();// 创建流源节点
const source = audioContext.createMediaStreamSource(stream);// 创建回声效果节点
const echo = audioContext.createConvolver();// 连接处理链
source.connect(echo);
echo.connect(audioContext.destination);// 加载回声冲击响应并应用
const impulseResponse = await fetch('impulse.wav');
const buffer = await impulseResponse.arrayBuffer();
const audioBuffer = await audioContext.decodeAudioData(buffer);echo.buffer = audioBuffer;

通过这样的音频处理链,我们就可以在录音时添加回声、混响等音效了。

实现音频的录制和播放

录制音频的步骤:

  1. 调用 getUserMedia 获取音频流。
  2. 创建 MediaRecorder 实例,传入音频流。
  3. 注册数据可用回调,以获取编码后的音频数据块。
  4. 调用 recorder.start() 开始录制。
  5. 录制完成后调用 recorder.stop()。

代码:

let recorder;
let audioChunks = [];// 开始录音 handler
const startRecording = async () => {const stream = await navigator.mediaDevices.getUserMedia({audio: true});recorder = new MediaRecorder(stream);recorder.ondataavailable = event => {audioChunks.push(event.data);};recorder.start();} // 停止录音 handler
const stopRecording = () => {if(recorder.state === "recording") {recorder.stop();}
}

录音完成后,我们可以将音频数据组装成一个 Blob 对象,然后赋值给一个 <audio> 元素的 src 属性进行播放。

代码:

// 录音停止后
const blob = new Blob(audioChunks, { type: 'audio/ogg' }); const audioURL = URL.createObjectURL(blob);const player = document.querySelector('audio');
player.src = audioURL;// 调用播放
player.play();

这样就可以播放刚刚录制的音频了。

后续也可以添加下载功能等。

音频效果的处理

利用 Web Audio API,我们可以添加各种音频效果,进行音频处理。

例如添加回声效果:

const audioContext = new AudioContext();// 原始音频节点
const source = audioContext.createMediaStreamSource(stream);// 回声效果节点
const echo = audioContext.createConvolver();// 连接处理链
source.connect(echo);
echo.connect(audioContext.destination);// 加载冲击响应作为回声效果
const impulseResponse = await fetch('impulse.wav');
const arrayBuffer = await impulseResponse.arrayBuffer();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);echo.buffer = audioBuffer;

这样在录制时音频流就会经过回声效果处理了。

此外,我们还可以添加混响、滤波、均衡器、压缩等多种音频效果,使得网页端也能处理出专业级的音频作品。

实时语音通话的应用

利用 getUserMedia 和 WebRTC 技术,我们还可以在网页端实现实时的点对点语音通话。

简述流程如下:

  1. 通过 getUserMedia 获取本地音视频流。
  2. 创建 RTCPeerConnection 实例。
  3. 将本地流添加到连接上。
  4. 交换 ICE 候选信息,建立连接。
  5. 当检测到连接后,渲染远端用户的音视频流。

这样就可以实现类似 Skype 的网页端语音通话功能了。

代码:

// 1. 获取本地流
const localStream = await navigator.mediaDevices.getUserMedia({audio: true,video: true
});// 2. 创建连接对象
const pc = new RTCPeerConnection();// 3. 添加本地流
localStream.getTracks().forEach(track => pc.addTrack(track, localStream)); // 4. 交换 ICE 等信令,处理 ONADDSTREAM 等事件// ...// 5. 收到远端流,渲染到页面
pc.ontrack = event => {remoteVideo.srcObject = event.streams[0];
}

获取本地输入流后,经过编码和传输就可以实现语音聊天了。

兼容性和 Latency 问题

尽管 getUserMedia 和 MediaRecorder 在现代浏览器中已经得到了较好的支持,但由于不同厂商和版本实现存在差异,在实际应用中还是需要注意一些兼容性问题:

  • 检测 API 支持情况,提供降级方案。
  • 注意不同浏览器对 Codec、采样率等参数支持的差异。
  • 封装浏览器差异,提供统一的 API。

此外,录音和播放也存在一定的延迟问题。我们需要针对 Latency 进行优化,比如使用更小的 buffer 大小,压缩数据包大小等方法。

项目代码

record.html:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Record Page</title><link rel="stylesheet" type="text/css" href="css/record.css"></head><body><div class="app"><audio controls class="audio-player"></audio><button class="record-btn">录音</button><a id="download" download="record.aac"></a></div></body><script src="js/record.js"></script></html>

record.css:

.app {display: flex;justify-content: center;align-items: center;
}.record-btn {margin: 0 10px;
}

record.js:

const recordBtn = document.querySelector(".record-btn")
const player = document.querySelector(".audio-player")
const download = document.querySelector('#download')
if (navigator.mediaDevices.getUserMedia) {let audioChunks = []// 约束属性const constraints = {// 音频约束audio: {sampleRate: 16000, // 采样率sampleSize: 16, // 每个采样点大小的位数channelCount: 1, // 通道数volume: 1, // 从 0(静音)到 1(最大音量)取值,被用作每个样本值的乘数echoCancellation: true, // 开启回音消除noiseSuppression: true, // 开启降噪功能},// 视频约束video: false}// 请求获取音频流navigator.mediaDevices.getUserMedia(constraints).catch(err => serverLog("ERROR mediaDevices.getUserMedia: ${err}")).then(stream => {// 在此处理音频流// 创建 MediaRecorder 实例const mediaRecorder = new MediaRecorder(stream)// 点击按钮recordBtn.onclick = () => {if (mediaRecorder.state === "recording") {// 录制完成后停止mediaRecorder.stop()recordBtn.textContent = "录音结束"}else {// 开始录制mediaRecorder.start()recordBtn.textContent = "录音中..."}}mediaRecorder.ondataavailable = e => {audioChunks.push(e.data)}// 结束事件mediaRecorder.onstop = e => {// 将录制的数据组装成 Blob(binary large object) 对象(一个不可修改的存储二进制数据的容器)const blob = new Blob(audioChunks, { type: "audio/aac" })audioChunks = []const audioURL = window.URL.createObjectURL(blob)// 赋值给一个 <audio> 元素的 src 属性进行播放player.src = audioURL// 添加下载功能download.innerHTML = '下载'download.href = audioURL}},() => {console.error("授权失败!");});
} else {console.error("该浏览器不支持 getUserMedia!");
}

运行实例

打开 record.html,首先获取麦克风权限:

在这里插入图片描述

点击“允许”。

在这里插入图片描述

页面有一个 audio-player 和一个 buttom。

点击“录音”按钮,就开始录音了。

再点一次按钮,停止录音,数据传回给 audio-player,可以在网页上播放录音。

在这里插入图片描述

点击“下载”,可以下载录制的音频。

PS:音频文件名称设置为 record.aac,文件格式为 WebM,音频格式为 opus,单声道,采样率 48kHz,位深 32bit。

参考

  1. Blob 的所有 Type 类型
  2. getUserMedia() 音频约束

源码下载

CSDN:Web Record.zip

GitHub:Web-Record

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/233162.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

银行测试:第三方支付平台业务流,功能/性能/安全测试方法

1、第三方支付平台的功能和结构特点 在信用方面&#xff0c;第三方支付平台作为中介&#xff0c;在网上交易的商家和消费者之间作一个信用的中转&#xff0c;通过改造支付流程来约束双方的行为&#xff0c;从而在一定程度上缓解彼此对双方信用的猜疑&#xff0c;增加对网上购物…

【lesson18】MySQL内置函数(1)日期函数和字符串函数

文章目录 日期函数函数使用具体使用案例建表插入数据建表插入数据 字符串函数函数使用具体使用案例建表插入数据测试 日期函数 函数使用 获得年月日&#xff1a; 获得时分秒&#xff1a; 获得时间戳&#xff1a; 获得现在的时间&#xff1a; 在日期的基础上加日期&#xf…

C++ Qt开发:TableWidget表格组件

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍TableWidget表格组件的常用方法及灵活运用。 …

基于python的leetcode算法介绍之递归

文章目录 零 算法介绍一 简单示例 辗转相除法Leetcode例题与思路[509. 斐波那契数](https://leetcode.cn/problems/fibonacci-number/)解题思路&#xff1a;题解&#xff1a; [206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)解题思路&#xff1a;题解&…

Jmeter中使用py插件

-安装插件 1、下载插件jython-standalone-2.7.0.jar到jmeter的lib\ext目录下 链接&#xff1a; https://pan.baidu.com/s/13ZXtUwoQEV62M98GaIR26w 提取码&#xff1a;ioyk 2、重启jmeter&#xff0c;查看是否生效&#xff0c;如果这个语言有python的选项说明可以了&#xf…

VMware虚拟机安装Linux操作系统

1.CentOS 7安装 软件选择&#xff0c;安装桌面系统 2.配置虚拟机网卡 3.连接Xshell

测试用例评审流程优化

测试用例评审是QA日常工作流程中的关键一环&#xff0c;是QA同学完善测试用例、交流测试经验的好机会。 负责组内测试用例建设以来&#xff0c;作者对于评审流程做了一些优化工作。本文作者将整个优化过程中的心得体会做了一个总结&#xff0c;希望能给大家带来帮助。 01 原始流…

Model-based value iteration and policy iteration pseudocode

Note that the symbols used in the pseudocode below have the following meanings: MDP: Markov Decision Process;V(s): Value function, the avg reture of one state;π(s): Policy, in the sense that for a given state s, π(s)represents the action that the agent …

【MySQL】 表的操作

// 创建表 create table 表名();// 查看表结构 desc 表名;// 新增一列表信息 alter table 表名 add 字段名 字段类型 (after 原表某一字段名);// 删除一列表信息 alter table 表名 drop 字段名;// 修改表字段名字 alter table 表名 change 原字段名 新字段名 类型; // 新字…

企业微信自动登录自定义系统

方法一&#xff1a;企业微信构造OAuth2链接跳转登录到自定义系统 企业微信自定义应用配置 构造网页授权链接 如果企业需要在打开的网页里面携带用户的身份信息&#xff0c;第一步需要构造如下的链接来获取code参数&#xff1a; https://open.weixin.qq.com/connect/oauth2/…

数据可视化---饼图、环形图、雷达图

类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统计学检验箱…

【微服务】springboot整合minio详解

目录 一、前言 二、Minio 概述 2.1 Minio简介 2.1 Minio特点 三、Minio 环境搭建 3.1 部署过程 3.1.1 拉取镜像 3.1.2 启动容器 3.1.3 访问web页面 四、Minio基本使用 4.1 基本概念 4.2 上传文件演示 4.3 用户管理 4.4 Java操作Minio 4.4.1 导入依赖 4.4.2 上传…

MATLAB 平面拟合并可视化(34)

MATLAB 平面拟合并可视化(34) 一、效果二、代码一、效果 二、代码 % 生成三维点数据 x = rand(100, 1); y = rand(100, 1

Express及mongoose搭建数据库(增删改查)

express是什么&#xff1f; Express.js 是一个基于 Node.js 平台的 Web 应用程序框架&#xff0c;它旨在帮助开发者轻松构建和管理 Web 服务和应用程序。Express 提供了许多强大的功能&#xff0c;使得创建可扩展、灵活且高性能的 Web 应用变得相对容易。 安装Express步骤 确保…

棋牌的电脑计时计费管理系统教程,棋牌灯控管理软件操作教程

一、前言 有的棋牌室在计时的时候&#xff0c;需要使用灯控管理&#xff0c;在开始计时的时候打开灯&#xff0c;在结账后关闭灯&#xff0c;也有的不需要用灯控&#xff0c;只用来计时。 下面以 佳易王棋牌计时计费管理系统软件为例说明&#xff1a; 软件试用版下载或技术支…

LVS+Keepalived集群的介绍和搭建

目录 LVSKeepalived集群的介绍 Keepalived及其工作原理 Keepalived体系主要模块及其作用 一个合格的集群应该具备的特性 健康检查&#xff08;探针&#xff09;的方式 实验&#xff1a;搭建LVSKeepalived集群 实验准备 实验步骤 LVS 部署 配置节点服务器 实验验证 实…

【【UART 传输数据实验】】

UART 传输数据实验 通信方式在日常的应用中一般分为串行通信&#xff08;serial communication&#xff09;和并行通信&#xff08;parallel communication&#xff09;。 我们再来了解下串行通信的特点。串行通信是指数据在一条数据线上&#xff0c;一比特接一比特地按顺序传…

中英购物商城 中英文网店系统怎么选

中英文网店系统能帮助企业将商品卖到不同国家和地区&#xff0c;有效走出国门的工具&#xff0c;在选择中英购物商城时&#xff0c;需要考虑以下几个方面&#xff1a; 1、语言支持&#xff1a;选择一款能够支持中英文双语的购物商城系统是必要的&#xff0c;同时建议选择能确认…

数据结构--图(更新ing~)

树具有灵活性&#xff0c;并且存在许多不同的树的应用&#xff0c;但是就树本身而言有一定的局限性&#xff0c;树只能表示层次关系&#xff0c;比如父子关系。而其他的比如兄弟关系只能够间接表示。 推广--- 图 图形结构中&#xff0c;数据元素之间的关系是任意的。 一、图…

[PTA]分寝室

学校新建了宿舍楼&#xff0c;共有 n 间寝室。等待分配的学生中&#xff0c;有女生 位、男生 位。所有待分配的学生都必须分到一间寝室。所有的寝室都要分出去&#xff0c;最后不能有寝室留空。 现请你写程序完成寝室的自动分配。分配规则如下&#xff1a; 男女生不能混住&…