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

前端调用浏览器录音功能且生成文件(vue)

如果可以实现记得点赞分享,谢谢老铁~

首先在页面中给两个按钮,分别是“开始录音”,“结束录音”。以及录音成功后生成一个下载语音的链接。

1. 先看页面展示
<template><div><button @click="startRecording" :disabled="isRecording">Start Recording</button><button @click="stopRecording" :disabled="!isRecording">Stop Recording</button><a v-if="downloadLink" :href="downloadLink" download="recording.pcm">Download Recording</a></div>
</template>
2. 看vue3.0的代码实现
<script setup>
import { ref, onBeforeUnmount } from 'vue';const isRecording = ref(false);
const downloadLink = ref('');
let audioContext = null;
let processor = null;
let socket = null;
let mediaStream = null;
let audioChunks = [];
let silenceTimeout = null;
const silenceDelay = 2000; // 停止录音的延迟时间(毫秒)
const desiredSampleRate = 16000; // 期望的采样率为16kHzconst startRecording = async () => {try {mediaStream = await navigator.mediaDevices.getUserMedia({ audio: {sampleRate: desiredSampleRate,sampleSize: 16,channelCount: 1,} });audioContext = new (window.AudioContext || window.webkitAudioContext)({sampleRate: desiredSampleRate});const source = audioContext.createMediaStreamSource(mediaStream);processor = audioContext.createScriptProcessor(4096, 1, 1);source.connect(processor);processor.connect(audioContext.destination);socket = new WebSocket('ws://yourserver.com');socket.binaryType = 'arraybuffer';// 接收 WebSocket 消息socket.onmessage = (event) => {const receivedData = event.data;console.log('Received data from server:', receivedData);// 这里可以处理接收到的数据,例如显示在 UI 上};processor.onaudioprocess = processAudio;isRecording.value = true;audioChunks = []; // 清空之前的音频数据} catch (error) {console.error('Error accessing media devices.', error);}
};const stopRecording = async () => {if (processor) {processor.disconnect();}if (mediaStream) {mediaStream.getTracks().forEach(track => track.stop());}if (audioContext && audioContext.state !== 'closed') {await audioContext.close();audioContext = null}if (socket) {socket.close();}isRecording.value = false;createDownloadLink();
};const processAudio = (event) => {const inputBuffer = event.inputBuffer;const outputBuffer = new Float32Array(inputBuffer.length);inputBuffer.copyFromChannel(outputBuffer, 0);const pcmData = convertFloat32ToPCM(outputBuffer);// 检查音量是否为静音const isSilent = outputBuffer.every(sample => Math.abs(sample) < 0.01);if (!isSilent) {clearTimeout(silenceTimeout);silenceTimeout = setTimeout(() => stopRecording(), silenceDelay);}if (socket && socket.readyState === WebSocket.OPEN) {socket.send(pcmData);}audioChunks.push(pcmData);
};const convertFloat32ToPCM = (input) => {const buffer = new ArrayBuffer(input.length * 2);const output = new DataView(buffer);for (let i = 0; i < input.length; i++) {const s = Math.max(-1, Math.min(1, input[i]));output.setInt16(i * 2, s < 0 ? s * 0x8000 : s * 0x7FFF, true);}return buffer;
};const createDownloadLink = () => {const blob = new Blob(audioChunks, { type: 'application/octet-stream' });downloadLink.value = URL.createObjectURL(blob);
};onBeforeUnmount(() => {stopRecording();
});
</script>
解释

audioChunks 数组:
存储录音过程中的 PCM 数据块。

processAudio 方法:
将 PCM 数据块添加到 audioChunks 数组中。

stopRecording 方法:
停止录音,并调用 createDownloadLink 方法生成下载链接。

createDownloadLink 方法:
将存储的音频数据块创建为一个 Blob 对象,并生成一个下载链接。

downloadLink 变量:
存储生成的下载链接,供用户下载录音文件。

注意事项

确保WebSocket服务器可以处理PCM数据。
处理音频数据时,注意性能问题,避免阻塞主线程。
Web Audio API和WebSocket在不同浏览器上的实现可能会有所不同,确保在目标浏览器上测试。

OK,收工!如果可以实现记得点赞分享,谢谢老铁~

相关文章:

前端调用浏览器录音功能且生成文件(vue)

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 首先在页面中给两个按钮&#xff0c;分别是“开始录音”&#xff0c;“结束录音”。以及录音成功后生成一个下载语音的链接。 1. 先看页面展示 <template><div><button click"startRecording…...

「大数据」Kappa架构

Kappa架构是一种处理大数据的架构&#xff0c;它作为Lambda架构的替代方案出现。Kappa架构的核心思想是简化数据处理流程&#xff0c;通过使用单一的流处理层来同时处理实时和批量数据&#xff0c;从而避免了Lambda架构中需要维护两套系统&#xff08;批处理层和速度层&#xf…...

详细分析Element Plus中的ElMessageBox弹窗用法(附Demo及模版)

目录 前言1. 基本知识2. Demo3. 实战4. 模版 前言 由于需要在登录时&#xff0c;附上一些用户说明书的弹窗 对于ElMessageBox的基本知识详细了解 可通过官网了解基本的语法知识ElMessageBox官网基本知识 1. 基本知识 Element Plus 是一个基于 Vue 3 的组件库&#xff0c;其中…...

Python自动化工具(桌面自动化、Web自动化、游戏辅助)

工具介绍 连点工具是一款可以模拟键鼠后台操作的连点器工具。支持鼠标连点、键鼠脚本录制&#xff0c;支持辅助您实现办公自动化以及辅助游戏操作。功能简洁易用&#xff0c;非常方便操作。连点工具让您在在玩游戏、网购抢购的时候全自动点击鼠标&#xff01;主要功能有&#…...

opencv进阶 ——(五)图像处理之马赛克

一、遍历图像并对每个马赛克区域进行像素化处理 for (int y 0; y < image.rows; y blockSize) {for (int x 0; x < image.cols; x blockSize) {cv::Rect rect cv::Rect(x, y, std::min(blockSize, image.cols - x), std::min(blockSize, image.rows - y));cv::Scal…...

电机控制系列模块解析(22)—— 零矢量刹车

一、零矢量刹车 基本概念 逆变器通常采用三相桥式结构&#xff0c;包含六个功率开关元件&#xff08;如IGBT或MOSFET&#xff09;&#xff0c;分为上桥臂和下桥臂。每个桥臂由两个反并联的开关元件组成&#xff0c;上桥臂和下桥臂对应于电机三相绕组的正负端。正常工作时&…...

自定义一个SpringBoot场景启动器

前言 一个刚刚看完SpringBoot自动装配原理的萌新依据自己的理解写下的文章&#xff0c;如有大神发现错误&#xff0c;敬请斧正&#xff0c;不胜感激。 分析SpringBoot自动配置原理 SpringBoot的启动从被SpringBootApplication修饰的启动类开始,SpringBootApplicaiotn注解中最…...

UDP的报文结构和注意事项

UDP协议是在传输层的协议。 UDP无连接&#xff0c;不可靠传输&#xff0c;面向数据报&#xff0c;全双工。 UDP的报文结构 学习网络协议&#xff0c;最主要的就是报文格式。 对于UDP来说&#xff0c;应用层的数据到达&#xff0c;UDP之后&#xff0c;就会给应用层的数据报前面…...

rust语言一些规则学习

目录 rust中迭代器的使用&#xff08;iter().map()与for循环的区别&#xff09;map()与for的描述区别总结 最后更新时间2024-05-24 rust中迭代器的使用&#xff08;iter().map()与for循环的区别&#xff09; map()与for的描述 rust源码中关于iter().map()函数的解释&#xff…...

QML基本语法介绍

为什么使用QML 开发者效率 将前后端分离,QML和JavaScript语言主要用于前度UI的方法,后端有C++来完成绘制。将JavaScript和C++分开能够快速迭代开发; 跨平台移植性 基于Qt平台的统一抽象概念,现在可以更加容易和快速和将Qt移植到更多的平台上。 开发的开放 Qt是由Qt-Proje…...

学习和分享关于 Vue.js 的路由(vue-router)

学习和分享关于 Vue.js 的路由&#xff08;vue-router&#xff09;是一个非常有价值的主题&#xff0c;因为路由是构建单页应用程序&#xff08;SPA&#xff09;的核心部分。本文将介绍 Vue.js 路由的基本概念和实现&#xff0c;并展示一个典型的项目目录结构。 目录 Vue.js 路…...

小猪APP分发:一站式免费应用推广解决方案

在竞争激烈的移动应用市场中&#xff0c;寻找一个高效且成本友好的方式来推广自己的应用程序&#xff0c;成为了众多开发者面临的共同挑战。幸运的是&#xff0c;像"小猪APP分发www.appzhu.cn"这样的平台应运而生&#xff0c;为开发者提供了一个全面、免费的应用分发…...

新抖:抖音的数据分析平台,敢用深色系,别的真不敢!

举报 评论 0...

独享IP是原生IP吗?二者有何区别?

原生IP&#xff1a; 原生IP是指由Internet服务提供商&#xff08;ISP&#xff09;直接分配给用户的IP地址&#xff0c;这些IP地址通常反映了用户的实际地理位置和网络连接。原生IP是用户在其所在地区或国家使用的真实IP地址&#xff0c;与用户的物理位置直接相关。在跨境电商中…...

AI大模型探索之路-实战篇7:Function Calling技术实战:自动生成函数

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5&#xff1a;探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6&#xff1a;掌握Function Calling的详细流程 目录 系列篇章&#x1f4a…...

Android14 - 绘制系统 - 概览

从Android 12开始&#xff0c;Android的绘制系统有结构性变化&#xff0c; 在绘制的生产消费者模式中&#xff0c;新增BLASTBufferQueue&#xff0c;客户端进程自行进行queue的生产和消费&#xff0c;随后通过Transation提交到SurfaceFlinger&#xff0c;如此可以使得各进程将缓…...

Add object from object library 从对象库中添加内置器件

Add object from object library 从对象库中添加内置器件 正文正文 对于 Lumerical,有些时候我们在使用中,可能需要从 Object library 中添加器件,通常我们的做法是手动添加。如下图所示,我们添加一个 Directional Coupler 到我们的工程文件中: 但是这种操作方式不够智能…...

天诚公租房/人才公寓WiFi人脸识别物联网智能门锁解决方案

人才是引领城市高质量发展的重要因素&#xff0c;城市要想吸纳人才的保障便是人才公寓。近年来&#xff0c;全国各地一二三线城市都在大力建设人才公寓&#xff0c;集聚菁英人才&#xff0c;倾力打造人才高地。 一、人才公寓如火如荼建设 2023年底&#xff0c;山东德州提出三年…...

JAVA学习-练习试用Java实现“子集”

问题&#xff1a; 给定一个整数数组 nums&#xff0c;数组中的元素互不相同。返回该数组所有可能的子集&#xff08;幂集&#xff09;。解集不能包含重复的子集。可以按任意顺序返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[…...

揭秘《庆余年算法番外篇》:范闲如何使用维吉尼亚密码解密二皇子密信

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...