当前位置: 首页 > ds >正文

js实现音频的录制

<!DOCTYPE html>
<html lang="zh"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>录音</title>
</head><body><h1>录音</h1><div><button onclick="getDeviceList()">获取设备列表</button><button onclick="checkSupportType()">检查支持的类型</button><button id="start">开始录音</button><button id="pause">暂停录音</button><button id="resume">继续录音</button><button id="stop">停止录音</button><button id="play">播放录音</button><button id="download">下载录音</button></div><script>const start = document.getElementById("start");const pause = document.getElementById("pause");const resume = document.getElementById("resume");const stop = document.getElementById("stop");const play = document.getElementById("play");const download = document.getElementById("download");const audioType = 'audio/webm';//audio/ogg和audio/webm两种格式通用// 录音相关变量let mediaRecorder;let chunks = []init();//初始化 function init() {//禁用按钮setDisabled(start, startHandler);setDisabled(pause, pauseHandler);setDisabled(resume, resumeHandler);setDisabled(stop, stopHandler);setDisabled(play, playHandler);setDisabled(download, downloadHandler);// 检查浏览器兼容性if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {alert("您的浏览器不支持录音功能,请更换浏览器后重试!");return;}setEnabled(start, startHandler);}/*** 获取设备列表*/function getDeviceList() {if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {console.log("enumerateDevices() not supported.");} else {navigator.mediaDevices.enumerateDevices().then((devices) => {devices.forEach((device) => {//console.log(device);//device.kind: videoinput audioinput audiooutputconsole.log(`${device.kind}: ${device.label} id = ${device.deviceId}`);});}).catch((err) => {console.log(`${err.name}: ${err.message}`);});}}/*** 元素禁用*/function setDisabled(element, removeFunction) {element.disabled = true;if (removeFunction) {element.removeEventListener("click", removeFunction);}}/*** 元素启用*/function setEnabled(element, addFunction) {console.log('setEnabled');console.log(element);element.disabled = false;if (addFunction) {element.addEventListener("click", addFunction);}}function checkSupportType() {const types = ["video/webm","audio/webm","video/webm;codecs=vp8","video/webm;codecs=daala","video/webm;codecs=h264","audio/webm;codecs=opus","video/mp4",];for (const type of types) {let res = MediaRecorder.isTypeSupported(type)//true不一定表示一定可以使用console.log(`${type}是否支持:${res}`);}}/*** 开始录音*/function startHandler() {//开始录音const constraints = { audio: true }//const constraints = { audio: true, video: true }//https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedianavigator.mediaDevices.getUserMedia(constraints).then((stream) => {//mimeType支持webm和ogg,ogg不需要设置options的mineTypelet options = {};if (audioType == "audio/webm") {options = { mimeType: 'audio/webm; codecs=opus' };}mediaRecorder = new MediaRecorder(stream, options);//设置的mimeType类型console.log(mediaRecorder.mimeType);//状态inactive recording pausedconsole.log(mediaRecorder.state);//navigator.mediaDevices.getUserMedia的stream 对象console.log(stream);//视频采用的编码比率console.log(mediaRecorder.videoBitsPerSecond);//音频采用的编码比率console.log(mediaRecorder.audioBitsPerSecond);if (mediaRecorder.state != "inactive") {alert('麦克风正在使用中,请先关闭再试!');return;}mediaRecorder.ondataavailable = (e) => {console.log('接收到收据');chunks.push(e.data)}chunks = [];mediaRecorder.start();console.log('开始录音');setDisabled(start, startHandler);setEnabled(pause, pauseHandler);setEnabled(stop, stopHandler);setDisabled(resume, resumeHandler);setDisabled(play, playHandler);setDisabled(download, downloadHandler);}).catch((err) => {console.log(err.name);switch (err.name) {case "AbortError":alert("设备无法使用");break;case "NotAllowedError":alert("您拒绝了访问您的设备!");break;case "NotFoundError":alert("未找到设备");break;case "NotReadableError":alert("设备不可读");break;case "OverconstrainedError":alert("无法满足要求");break;case "SecurityError":alert("安全错误");break;case "TypeError":alert("类型错误");break;case "NotSupportedError":alert("浏览器不支持");break;}})}/*** 暂停录音*/function pauseHandler() {if (!mediaRecorder || mediaRecorder.state != "recording") {alert('未开始录音');return;}mediaRecorder.pause();console.log('暂停录音');setDisabled(start, startHandler);setDisabled(pause, pauseHandler);setDisabled(stop, stopHandler);setEnabled(resume, resumeHandler);setDisabled(play, playHandler);setDisabled(download, downloadHandler);}/*** 继续录音*/function resumeHandler() {if (!mediaRecorder || mediaRecorder.state != "paused") {alert('未暂停录音');return;}mediaRecorder.resume();console.log('继续录音');setDisabled(start, startHandler);setEnabled(pause, pauseHandler);setEnabled(stop, stopHandler);setDisabled(resume, resumeHandler);setDisabled(play, playHandler);setDisabled(download, downloadHandler);}/*** 停止录音*/function stopHandler() {if (!mediaRecorder || mediaRecorder.state != "recording") {alert('未开始录音');return;}mediaRecorder.stop();console.log('停止录音');setEnabled(start, startHandler);setDisabled(pause, pauseHandler);setDisabled(stop, stopHandler);setDisabled(resume, resumeHandler);setEnabled(play, playHandler);setEnabled(download, downloadHandler);}/*** 播放录音*/function playHandler() {if (!chunks || chunks.length <= 0) {alert('未有录音信息');return;}console.log('播放录音');// 创建音频文件const audioBlob = new Blob(chunks, { type: audioType });var audio = new Audio();audio.src = URL.createObjectURL(audioBlob);// 监听音频播放完毕的事件audio.addEventListener('ended', function () {// 销毁<audio>元素console.log('音频播放完毕,销毁<audio>元素');audio = null;});audio.play();}/*** 下载录音*/function downloadHandler() {if (!chunks || chunks.length <= 0) {alert('未有录音信息');return;}console.log('下载录音');// 创建音频文件const audioBlob = new Blob(chunks, { type: audioType });const a = document.createElement('a');a.href = URL.createObjectURL(audioBlob);let audioExt = 'webm';if (audioType == 'audio/webm') {audioExt = 'webm';}if (audioType == 'audio/ogg') {audioExt = 'ogg';}a.download = `recording_${new Date().toISOString().replace(/[:.]/g, '-')}.${audioExt}`;document.body.appendChild(a);a.click();document.body.removeChild(a);}</script>
</body></html>

支持点击录制、暂停、继续录制、停止录制、播放、下载的功能,可以下载试试效果~~

在这里插入图片描述

参考

https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia
https://developer.mozilla.org/zh-CN/docs/Web/API/MediaStream
https://developer.mozilla.org/zh-CN/docs/Web/API/MediaRecorder
https://gitee.com/qxscj/js-demo/blob/master/html+css/38-1.html

http://www.xdnf.cn/news/8742.html

相关文章:

  • Vue 样式不一致问题全面分析与解决方案
  • 专业学习|经济学与管理学常用分析工具详解
  • 【人工智能】微调秘籍:解锁AI大模型的定制化魔法
  • python装饰器的简单理解
  • (2)-玩转Fiddler抓包-再识Fiddler
  • 天地图实景三维数据分享(江苏)
  • 【iOS】内存分区
  • 第2周 PINN核心技术揭秘: 如何用神经网络求解偏微分方程
  • 消息中间件之kafka
  • WSL 下面 Buildroot + QEMU 环境记录一下
  • [特殊字符] 使用增量同步+MQ机制将用户数据同步到Elasticsearch
  • Linux(6)——第一个小程序(进度条)
  • LeetCode 2942.查找包含给定字符的单词:使用库函数完成
  • 台式机安装新的固态硬盘后无显示
  • 【C语言练习】060. 使用指针操作字符串
  • Kotlin全栈工程师转型路径
  • Vue-创建应用/挂载应用/根组件模版-.vue单文件/应用配置
  • Cesium中根据不同条件设置3D Tiles样式
  • 【VBA 中GetOpenFilename】常用友好的人机交互文件全路径选择模式
  • 计算机视觉与深度学习 | 基于 YOLOv8 + BeautyGAN + CodeFormer + Face Parsing 实现简单的人脸美颜
  • 【来自纳米AI-大模型】ubuntu 24.04 登陆界面分辨率太高,内容显示得特别小 问题解决方案(亲测有效)
  • lua脚本学习笔记1:Vscode添加lua环境_lua基本语法
  • HarmonyOS赋能套件介绍
  • 开篇:MCP理论理解和学习
  • 元组可以比较大小吗?一次返回多个值?编程语言的元组?声明变量一定需要指定类型吗?
  • Ubuntu20.04 gr-gsm完整安装教程
  • Kanass V1.1.1版本发布,支持查看项目/迭代/事项进度
  • 剖析 Spring 中 @ResponseBody 原理与 Tomcat NIO 写事件(SelectionKey.OP_WRITE)的协作机制
  • MySQL分库分表
  • vue3中使用computed