语音消息实现(聊天向)

news2024/11/18 9:28:47

语音消息实现记录下:

SpringBoot+Vue3客服项目,网页录制发送语音消息

在这里插入图片描述
在这里插入图片描述

Vue中使用js-audio-recorder插件实现录音功能并实现上传Blob数据到SpringBoot后台接口

2fps/recorder github地址

Recorder的API

语音测试地址

[Web] 4分钟搭建一个简洁好看的 WebSocket 网页聊天室(代码已经fork)

南生论坛中有聊天部分

风宇博客聊天

Demo版本

前端

页面效果

在这里插入图片描述

安装js-audio-recorder

npm install js-audio-recorder@1.0.7

代码

<template>
    <div class="chat-box">
    
        <div class="btn-box">
            <button @mousedown="startRecord" @mouseup="stopRecord">
                <i :class="[{ 'iconfont': true }, isRecording ? 'icon-maikefeng' : 'icon-maikefeng-xianxing']"></i>
            </button>
            <button @click="playAudio">播放音频</button>
            <button @click="downloadAudio">下载音频</button>
        </div>
        
        <div>
        
            <hr />
            
            <div class="block-box">
                <span>audio标签+以src的方式手动播放</span>
                <audio src="http://127.0.0.1:8081/file/audio/1686623639628.wav" controls preload="true"></audio>
            </div>
            
            <div>
            	<!-- 没有写controls,它就自动隐藏了 -->
                <audio ref="hiddenAudioRef" :src="autoRemoteSrc" class="hide"></audio>
                <button @click="playRemoteAudio">播放指定的远程音频</button>
            </div>
            
        </div>
        
    </div>
</template>

<script>

import Recorder from 'js-audio-recorder'

export default {

    name: 'Chat',
    
    data() {
        return {
        	// 当前是否正在录制音频
            isRecording: false,
			// 播放远程音频的url
            autoRemoteSrc: ''
        }
    },
    
    mounted() {
        this.recorder = new Recorder({
            sampleBits: 16,                 // 采样位数,支持 8 或 16,默认是16
            sampleRate: 16000,              // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
            numChannels: 1,                 // 声道,支持 1 或 2, 默认是1
            // compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换,默认是false
        });
        window.recorder = this.recorder
    },
    methods: {
    
        // 开始录制音频
        startRecord() {
            this.isRecording = true
            this.recorder.start().then(() => {
                // 开始录音
            }, (error) => {
                // 出错了
                console.log(`${error.name} : ${error.message}`);
            });
        },
        
        // 结束录制音频
        stopRecord() {
            console.log(this.recorder.duration); // 获取录音的总时长
            console.log(this.recorder.fileSize); // 录音文件大小(单位:字节)
            this.isRecording = false
            this.recorder.stop()
        },
        
        // 播放刚刚录制的音频
        playAudio() {
            if (this.recorder.duration <= 0) {
                alert('请先录制')
            }
            this.recorder.play()
        },
        
        // 下载刚刚录制的音频到本地
        downloadAudio() {
            if (this.recorder.duration <= 0) {
                alert('请先录制')
            }
            let wavBlob = this.recorder.getWAVBlob()
            const newWAVbolb = new Blob([wavBlob], { type: 'audio/wav' })
            const wavFile = new File([newWAVbolb], new Date().getTime() + '.wav')
            let wavFileURL = window.URL.createObjectURL(wavFile)
            let tmpLink = document.createElement('a')
            tmpLink.style.display = 'none'
            tmpLink.href = wavFileURL
            tmpLink.setAttribute('download', wavFile.name)
            document.body.appendChild(tmpLink)
            tmpLink.click()
            document.body.removeChild(tmpLink)
            window.URL.revokeObjectURL(wavFileURL)
        },
        
        // 播放远程音频
        playRemoteAudio() {
            this.$refs.hiddenAudioRef.src = 'http://127.0.0.1:8081/file/audio/1686622424132.wav'
            this.$refs.hiddenAudioRef.play()
            window.hiddenAudioRef = this.$refs.hiddenAudioRef
        }
    }
}
</script>

<style style="scoped">
@import url("//at.alicdn.com/t/c/font_4119031_hzm54m8oys.css");

.chat-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
}

.btn-box {
    margin-bottom: 10px;
}

button {
    min-width: 100px;
    height: 50px;
    background: #fff;
    border: 1px solid #ccc;
    margin-right: -1px;
    cursor: pointer;
}

.block-box {
    border: 1px solid #ccc;
    display: flex;
    align-items: center;
    margin-bottom: 10px;
}
</style>

后端

在这里插入图片描述

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/file/**")
                .addResourceLocations("file:/D:/Projects/dynamic-datasource-demo/file/");
    }
}

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

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

相关文章

如何购买北京法拍房

1、对于有限购的法拍房来说&#xff0c;在没有购房者资格的前提下&#xff0c;请不要跟拍&#xff0c;就算是房子拍下来了&#xff0c;没办法过户的话&#xff0c;房子还不能算是你的&#xff0c;弃权则被罚保证金。2、对于没有限购的法拍房来说&#xff0c;在没有购房资格的前…

动态规划dp —— 24.最长湍流子数组

解释&#xff1a;数组中子数组中相邻数值一升一降称为湍流子数组 示例1&#xff1a; 1.状态表示 是什么&#xff1f;dp表中里的值所表示的含义就是状态表示 因为i位置是有两种情况&#xff1a;1.上升趋势 2.下降趋势 所以需要定义两种状态表示来把两种情况分开 f[i]表示&am…

抖音自动生成视频、字幕、自动上传发布

dy-auto ✨ 抖音自动生成视频、字幕、自动上传发布✨ 项目地址 点击进入https://github.com/Richard0403/dy-auto 录屏效果 https://github.com/Richard0403/dy-auto/assets/14147304/21400a42-9296-4956-9517-ced8d8bf4737 技术架构 名称功能ffmpeg处理视频的生成&…

Vue中如何进行Markdown文档展示与解析?

Vue中如何进行Markdown文档展示与解析&#xff1f; Markdown是一种轻量级的标记语言&#xff0c;可以在文本中使用简单的标记来表示格式和排版。在Vue项目中&#xff0c;Markdown文档的使用越来越普遍&#xff0c;因此在Vue中如何进行Markdown文档展示与解析也成为了一个热门话…

数据湖仓一体化架构:探究新一代数据处理的可能性

一、引言 随着大数据的快速发展&#xff0c;企业不断寻求高效、灵活和经济的方法来处理和管理海量数据。在这种背景下&#xff0c;数据湖和数据仓库这两种不同的架构模式各自展现出其独特的优势。而数据湖仓一体化架构&#xff0c;是对这两种模式优势的综合&#xff0c;为企业…

9. WebGPU 平移变换

我们将开始编写与顶点缓冲区文章中的示例类似的代码&#xff0c;但这次将绘制单个 F 而不是一堆圆&#xff0c;并使用索引缓冲区来保持数据更小。 让我们在像素空间而不是裁剪空间中工作&#xff0c;就像 Canvas 2D API 我们将制作一个 F&#xff0c;将从 6 个三角形构建它 …

高级 IO(select poll epoll)

目录 五种IO模型 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 ​异步IO 小结 同步通信 vs 异步通信(synchronous communication/ asynchronous communication) 同步和异步关注的是消息通信机制 阻塞 vs 非阻塞 其他高级IO 非阻塞IO fcntl 实现函数SetNoBlock I/O…

Windows Server AD域控服务器升级/迁移(AD域控的五大角色转移)

Windows Server AD域控服务器升级/迁移&#xff08;AD域控的五大角色转移&#xff09; 新域控服务器安装配置域控服务器&#xff0c;加入现有域域控角色迁移到新域控服务器原域控服务器降级退域 本文主要介绍在现有域环境下如何进行域控服务器的迁移/升级操作。对于域结构的网络…

python自动化测试框架:unittest测试用例编写及执行

本文将介绍 unittest 自动化测试用例编写及执行的相关内容&#xff0c;包括测试用例编写、测试用例执行、测试报告等内容。 官方文档&#xff1a; https://docs.python.org/zh-cn/3/library/unittest.mock.html 1. 测试用例编写 在 unittest 中&#xff0c;一个测试用例通常…

【二等奖方案】系统访问风险识别「QDU」团队解题思路

第十届CCF大数据与计算智能大赛&#xff08;2022 CCF BDCI&#xff09;已圆满结束。大赛官方竞赛平台DataFountain&#xff08;简称DF平台,官号统称DataFountain 或DataFountain数据科学&#xff09;正在陆续释出各赛题获奖队伍的方案思路。 本方案为【系统访问风险识别】赛题…

精选个人创业计划

精选个人创业计划精选篇1 一、企业概况 以突出“新鲜”“精致”为主要特色。坐落于河北区昆纬路的一个小店&#xff0c;主营鲜花与礼品的零售。它没有亮丽的装潢设计&#xff0c;而是着重朴实的风格&#xff0c;突出了产品的“精”与“美”&#xff0c;成为人们五彩斑斓生活中不…

五年磨一剑——Sealos 云操作系统正式发布!

这是个宏伟的计划 这是一个宏伟的计划&#xff0c;漫长且有趣。 2018 年的某个夜晚&#xff0c;夜深人静&#xff0c;我挥舞键盘&#xff0c;敲下了 Sealos 的第一行代码。当时仓库命名为 “kubeinit”&#xff0c;后来觉得格局太小&#xff0c;我不可能只做一个安装 Kuberne…

2023.6.8-TS-yum update集群后奔溃故障(已解决)

2023.6.8-TS-yum update集群后奔溃故障(已解决) 1、故障背景 自己在安装falco软件时&#xff0c;使用yum update升级了系统后&#xff0c;就出现这个情况了。。。 2、报错现象 kubeclt无法查看pod kubectl get poE0608 09:38:49.094714 2268 memcache.go:265] couldnt ge…

【沐风老师】3dMax一键多边形门(PolyDoor)、窗(PolyWindow)插件使用方法详解

3dMax一键多边形门、窗插件使用教程 3dMax一键多边形门&#xff08;PolyDoor&#xff09;、窗&#xff08;PolyWindow&#xff09;插件&#xff0c;将选择的多边形面一键转化为门、窗模型。你可以通过编辑多边形的线框&#xff08;边&#xff09;来定义门、窗的样式&#xff0…

【备战秋招】每日一题:4月23日美团春招:题面+题目思路 + C++/python/js/Go/java带注释

2023大厂笔试模拟练习网站&#xff08;含题解&#xff09; www.codefun2000.com 最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据&#xff0c;挂载到我们的OJ上&#xff0c;供大家学习交流&#xff0c;体会笔试难度。现已录入200道互联网大厂模拟练习题&a…

Stable Diffusion WebUI 环境

Stable Diffusion 是热门的文本到图像的生成扩散模型&#xff0c;本文介绍了如何准备其 WebUI 环境。 Stability AI Stability API Extension for Automatic1111 WebUI Stable Diffusion web UI 环境基础 OS: Ubuntu 22.04.2 LTSKernel: 5.19.0CPU: AMD Ryzen 7 3700XGPU: N…

Docker六脉神剑 - Mac极速体验

说到Docker, 现在可是"家喻户晓"。但是随着Docker的生态越来越强大, 资料越来越多, 反而对新手越来越不友好, 好多人准备学习一下, 但是又不知从哪入手&#xff1f; 想要玩Docker, 首先要先明白, Docker是干嘛的&#xff1f;可以解决什么问题&#xff1f;使用Docker可…

Linux中的用户和组的分类

目录 Linux中的用户和组的分类 用户分类 超级用户 系统用户 普通用户 组的分类 基本组&#xff08;私有组&#xff09; 附加组&#xff08;公有组&#xff09; 系统组 Linux中用户和用户组的配置文件 在Linux中&#xff0c;用户账号、密码、用户组信息和用户组密码均…

【滤波】无迹卡尔曼滤波

本文主要翻译自rlabbe/Kalman-and-Bayesian-Filters-in-Python的第10章节10-Unscented-Kalman-Filter&#xff08;无迹卡尔曼滤波&#xff09;。 %matplotlib inline# format the book import book_format book_format.set_style()前文 在上一章中&#xff0c;我们讨论了非线…

Elasticsearch:使用 ELSER 进行语义搜索

Elastic Learned Sparse EncodeR&#xff08;或 ELSER&#xff09;是一种由 Elastic 训练的 NLP 模型&#xff0c;使你能够使用稀疏向量表示来执行语义搜索。 语义搜索不是根据搜索词进行字面匹配&#xff0c;而是根据搜索查询的意图和上下文含义检索结果。 本教程中的说明向你…