最近项目使用uniapp开发微信小程序,需要实现一个长按时进行语音录制,限制录制时间最大为60秒,录制完成后,可点击播放,播放时再次点击停止播放,录制完成长按实现删除功能,删除后又可重新录制(如上图所示)。

HTML部分

<template><view class="record-layer"><view class="record-box"><view class="record-btn-layer" v-if="tempFilePath == ''"><button class="record-btn" :class="longPress == '1' ? 'record-btn-1' : 'record-btn-2'"  @longpress="longpressBtn()" @touchend="touchendBtn()"><image src="../../static/img/record-ico.png"/><text>{{longPress == '1' ? '按住说话' : '说话中...'}}</text></button></view><view class="record-btn-layer" v-else><button class="record-btn" @longpress="delShow = true" @click="playBtn()" :class="playStatus == '1' ? 'record-btn-2' : 'record-btn-1'"><image src="../../static/img/scale-ico.png"/><text>{{playStatus == '1' ? (count+'s') : '点击播放'}}</text></button></view><!-- 语音音阶动画 --><view class="prompt-layer prompt-layer-1" v-if="longPress == '2'"><view class="prompt-loader"><view class="em" v-for="(item,index) in 15" :key="index"></view></view><text class="p">{{'剩余:' + count + 's'}}</text><text class="span">松手结束录音</text></view><!-- 删除 --><view class="prompt-layer prompt-layer-2" v-if="delShow" @click.stop="delBtn()"><text>删除</text></view></view></view>
</template>

JS部分

<script>const recorderManager = uni.getRecorderManager()const innerAudioContext = uni.createInnerAudioContext()var init // 录制时长计时器var timer // 播放 录制倒计时export default {data() {return {count: null, // 录制倒计时longPress: '1', // 1显示 按住说话 2显示 说话中delShow: false, // 删除提示框显示隐藏time: 0, //录音时长duration: 60000, //录音最大值ms 60000/1分钟tempFilePath: '', //音频路径playStatus: 0, //录音播放状态 0:未播放 1:正在播放}},methods: {// 倒计时countdown(val){let _then = this;_then.count = Number(val);timer = setInterval(function() {if(_then.count > 0){_then.count--} else {_then.longPress = '1';clearInterval(timer);}}, 1000);},// 长按录音事件longpressBtn(){this.longPress = '2';this.countdown(60); // 倒计时clearInterval(init) // 清除定时器recorderManager.onStop((res) => {this.tempFilePath = res.tempFilePath;this.recordingTimer(this.time);})const options = {duration: this.duration, // 指定录音的时长,单位 mssampleRate: 16000, // 采样率numberOfChannels: 1, // 录音通道数encodeBitRate: 96000, // 编码码率format: 'mp3', // 音频格式,有效值 aac/mp3frameSize: 10, // 指定帧大小,单位 KB}this.recordingTimer();recorderManager.start(options);// 监听音频开始事件recorderManager.onStart((res) => {console.log(res)})},// 长按松开录音事件touchendBtn(){this.longPress = '1';recorderManager.onStop((res) => {this.tempFilePath = res.tempFilePath})this.recordingTimer(this.time)recorderManager.stop()},recordingTimer(time){var that = this;if (time == undefined) {// 将计时器赋值给initinit = setInterval(function() {that.time++}, 1000);} else {clearInterval(init)}},// 删除录音delBtn(){this.delShow = false;this.time = 0this.tempFilePath = ''this.playStatus = 0innerAudioContext.stop()},// 播放playBtn(){innerAudioContext.src = this.tempFilePath//在ios下静音时播放没有声音,默认为true,改为false就好了。// innerAudioContext.obeyMuteSwitch = false//点击播放if (this.playStatus == 0) {this.playStatus = 1;innerAudioContext.play();this.countdown(this.time); // 倒计时} else {this.playStatus = 0;innerAudioContext.pause()}// //播放结束innerAudioContext.onEnded(() => {this.playStatus = 0;innerAudioContext.stop();})},}}
</script>

CSS部分

<style>/* 语音录制开始--------------------------------------------------------------------- */.record-layer{width: 100%;padding: 300px 0;box-sizing: border-box;}.record-box{width: 100%;position: relative;}.record-btn-layer{width: 100%;}.record-btn-layer button::after {border: none;}.record-btn-layer button{font-size: 14px;line-height: 38px;width: 100%;height: 38px;border-radius: 8px;text-align: center;background: #FFD300;}.record-btn-layer button image{width: 16px;height: 16px;margin-right: 4px;vertical-align: middle;}.record-btn-layer .record-btn-2{background: rgba(255, 211, 0, 0.2);}/* 提示小弹窗 */.prompt-layer{border-radius: 8px;background: #FFD300;padding: 8px 16px;box-sizing: border-box;position: absolute;left: 50%;transform: translateX(-50%);}.prompt-layer::after{content: '';display: block;border: 6px solid rgba(0,0,0,0);border-top-color: rgba(255, 211, 0, 1);position: absolute;bottom: -10px;left: 50%;transform: translateX(-50%);}.prompt-layer-1{font-size: 12px;width: 128px;text-align: center;display: flex;flex-direction: column;align-items: center;justify-content: center;top: -80px;}.prompt-layer-1 .p{color: #000000;}.prompt-layer-1 .span{color: rgba(0,0,0,.6);}.prompt-loader .em{}/* 语音音阶------------- */.prompt-loader {width: 96px;height: 20px;display: flex;align-items: center;justify-content: space-between;margin-bottom: 6px;}.prompt-loader .em {display: block;background: #333333;width: 1px;height: 10%;margin-right: 2.5px;float: left;}.prompt-loader .em:last-child {margin-right: 0px;}.prompt-loader .em:nth-child(1) {animation: load 2.5s 1.4s infinite linear;}.prompt-loader .em:nth-child(2) {animation: load 2.5s 1.2s infinite linear;}.prompt-loader .em:nth-child(3) {animation: load 2.5s 1s infinite linear;}.prompt-loader .em:nth-child(4) {animation: load 2.5s 0.8s infinite linear;}.prompt-loader .em:nth-child(5) {animation: load 2.5s 0.6s infinite linear;}.prompt-loader .em:nth-child(6) {animation: load 2.5s 0.4s infinite linear;}.prompt-loader .em:nth-child(7) {animation: load 2.5s 0.2s infinite linear;}.prompt-loader .em:nth-child(8) {animation: load 2.5s 0s infinite linear;}.prompt-loader .em:nth-child(9) {animation: load 2.5s 0.2s infinite linear;}.prompt-loader .em:nth-child(10) {animation: load 2.5s 0.4s infinite linear;}.prompt-loader .em:nth-child(11) {animation: load 2.5s 0.6s infinite linear;}.prompt-loader .em:nth-child(12) {animation: load 2.5s 0.8s infinite linear;}.prompt-loader .em:nth-child(13) {animation: load 2.5s 1s infinite linear;}.prompt-loader .em:nth-child(14) {animation: load 2.5s 1.2s infinite linear;}.prompt-loader .em:nth-child(15) {animation: load 2.5s 1.4s infinite linear;}@keyframes load {0% {height: 10%;}50% {height: 100%;}100% {height: 10%;}}/* 语音音阶-------------------- */.prompt-layer-2{top: -40px;}.prompt-layer-2 .text{color: rgba(0, 0, 0, 1);font-size: 12px;}/* 语音录制结束---------------------------------------------------------------- */
</style>

以上部分是整体代码,没有想象中的那么流利,但是功能都有实现,欢迎借鉴(其中包含CSS实现语音音阶动画效果,自行复制即可获取)。

下放网上找的案例,挺不错的,推荐测试

<template><view class="sound-recording"><view class="time">{{status==0?'录音时长':(status==3?'录音已完成':'正在录音中')}}:{{time}} 秒</view><view class="btn"><view :class="status==3?'show':'hide'" @click="reset" hover-class="jump-hover">重新录制</view><view :class="status==3 && playStatus==0?'show':'hide'" @click="bofang" hover-class="jump-hover">{{playStatus==1?'录音播放中':'播放录音'}}</view></view><view class="progress"><text class="txt">最大录音时长({{duration/1000}}秒 = {{duration/60000}}分钟)</text><progress :percent="time*(100/(duration/1000))" border-radius="10" color="green" stroke-width="10" backgroundColor="#fff" /></view><view class="anniu"><view :class="status==0?'row':'no-clicking'" @click="kaishi" hover-class="jump-hover">开始</view><view :class="status==1?'row':'no-clicking'" @click="zanting" hover-class="jump-hover">暂停</view><view :class="status==2?'row':'no-clicking'" @click="jixu" hover-class="jump-hover">继续</view><view :class="status==1 || status==2?'row':'no-clicking'" @click="tingzhi" hover-class="jump-hover">停止</view></view></view>
</template><script>const recorderManager = uni.getRecorderManager()const innerAudioContext = uni.createInnerAudioContext()var initexport default {data() {return {time: 0, //录音时长duration: 600000, //录音最大值ms 600000/10分钟tempFilePath: "", //音频路径status: 0, //录音状态 0:未开始录音 1:正在录音 2:暂停录音 3:已完成录音playStatus: 0, //录音播放状态 0:未播放 1:正在播放}},methods: {kaishi: function() {clearInterval(init) //清除定时器//监听录音自动结束事件(如果不加,录音时间到最大值自动结束后,没获取到录音路径将无法正常进行播放)recorderManager.onStop((res) => {console.log('recorder stop', res)this.tempFilePath = res.tempFilePaththis.status = 3this.recordingTimer(this.time)})const options = {duration: this.duration, //指定录音的时长,单位 mssampleRate: 16000, //采样率numberOfChannels: 1, //录音通道数encodeBitRate: 96000, //编码码率format: 'mp3', //音频格式,有效值 aac/mp3frameSize: 10, //指定帧大小,单位 KB}this.recordingTimer()recorderManager.start(options)// 监听音频开始事件recorderManager.onStart((res) => {console.log('recorder start')this.status = 1})console.log(this.status);},/*** 暂停录音*/zanting: function() {console.log('zanting');recorderManager.onPause(() => {console.log('recorder pause')this.status = 2})this.recordingTimer(this.time)recorderManager.pause()},/*** 继续录音*/jixu: function() {this.status = 1this.recordingTimer()recorderManager.resume()},/*** 停止录音*/tingzhi: function() {debuggerrecorderManager.onStop((res) => {console.log('recorder stop', res)this.tempFilePath = res.tempFilePaththis.status = 3})this.recordingTimer(this.time)recorderManager.stop()},/*** 播放录音*/bofang: function() {//音频地址console.log(this.tempFilePath);innerAudioContext.src = this.tempFilePath//在ios下静音时播放没有声音,默认为true,改为false就好了。// innerAudioContext.obeyMuteSwitch = false//点击播放if (this.playStatus == 0) {this.playStatus = 1innerAudioContext.play()}// //播放结束innerAudioContext.onEnded(() => {innerAudioContext.stop()this.playStatus = 0})},recordingTimer: function(time) {var that = thisif (time == undefined) {//将计时器赋值给initinit = setInterval(function() {var time = that.time + 1;that.time = time}, 1000);} else {clearInterval(init)console.log("暂停计时")}},/*** 重新录制*/reset: function() {var that = thiswx.showModal({title: "重新录音",content: "是否重新录制?",success(res) {if (res.confirm) {that.time = 0that.tempFilePath = ''that.status = 0that.playStatus = 0innerAudioContext.stop()}}})}}}
</script><style>.sound-recording {background-color: rgb(234, 234, 234);margin: 10rpx 30rpx;border-radius: 20rpx;padding: 5rpx 0rpx;}.btn {margin: 0rpx 100rpx;display: flex;justify-content: space-between;align-items: center;}.btn .show {padding: 10rpx;width: 200rpx;font-size: 25rpx;display: flex;justify-content: center;align-items: center;background-color: rgb(178, 228, 228);border-radius: 20rpx;border: 5rpx solid rgb(127, 204, 214);}.btn .hide {padding: 10rpx;width: 200rpx;font-size: 25rpx;display: flex;justify-content: center;align-items: center;border-radius: 20rpx;border: 5rpx solid #eee;pointer-events: none;background-color: rgba(167, 162, 162, 0.445);}.time {line-height: 70rpx;text-align: center;font-size: 30rpx;}.progress {margin: 20rpx;}.play {margin: 0rpx 20rpx;}.txt {display: flex;justify-content: center;line-height: 60rpx;font-size: 25rpx;}.anniu {margin: 10rpx 50rpx;display: flex;justify-content: space-between;}.row {display: flex;justify-content: center;align-items: center;border-radius: 50%;font-size: 25rpx;width: 80rpx;height: 80rpx;background-color: rgb(178, 228, 228);border: 5rpx solid rgb(127, 204, 214);}.jump-hover {transform: scale(0.9);}/*禁止点击*/.anniu .no-clicking {pointer-events: none;background-color: rgba(167, 162, 162, 0.445);display: flex;justify-content: center;align-items: center;border-radius: 50%;font-size: 25rpx;width: 80rpx;height: 80rpx;border: 5rpx solid rgb(241, 244, 245);}
</style>

uniapp小程序实现录音 uniapp小程序长按录音 点击播放等功能(CSS实现语音音阶动画效果)相关推荐

  1. uniapp小程序实现长按录音、上滑取消的与语言录入模块(CSS实现语音音阶动画效果)

    这里写目录标题 语言录入模块 实现效果 HTML部分 JS部分 CSS部分 总结 语言录入模块 实现效果 HTML部分 代码如下: <template><view :class=&q ...

  2. 小程序=》添加同声传译插件,做简单的播放文本功能

    一.进入小程序管理后台,菜单拉到最底下的"设置" 二.设置=>第三方设置=>插件管理=>添加插件,输入"微信同声传译"即可添加 三.修改app ...

  3. 前后端分离项目,vue+uni-app+php+mysql在线教育视频点播小程序系统 开题报告

      毕业论文 基于Vue.js视频点播小程序系统 开题报告 学    院: 专    业: 年    级: 学生姓名: 指导教师: 黄菊华   XXXX大学本科生毕业论文(设计)开题报告书 姓   名 ...

  4. 【小程序动画合集】10种小程序动画效果实现方法,文章太长建议收藏!

    前言 一提小程序与动画,首先想到的是什么?嗯,微信小程序独创了一套动画玩法,官方支持3种动画方案,分别是 createAnimation . this.animate 和 CSS3动画 . 1. cr ...

  5. 修复录音笔或其它录音设备损坏的WAV/MP3录音文件或0kb字节文件

    由于录音笔等录音类数码产品长时间录音的自身可靠性和人为原因导致的录音文件损坏情况.例如以下几种情况:一.录音笔在录音过程中电量不足断电.卡机死机.录音结束忘记保存或强行关机都会导致录音文件wav损坏. ...

  6. uniapp 录音_uni-app小程序录音上传解决方案(后续更新Taro版)

    能力依赖 录音功能的要求与限制 与当前页面其余音频播放/录音功能互斥 是否在录音中状态显示 结束/不须要录音时,回收RecorderManager对象 材料 Codeing(结果代码直接看最后) 构造 ...

  7. uni-app微信小程序登录;uni-app微信登录小程序;uni-app微信登录app;

    思路: 通过uni-app文档可知:实现微信登录,无论是app还是小程序,都需要唯一标识openid,然后通过openid取掉后端的登录接口,获取cookie然后做登录跳转: [-[-[必须先调用微信 ...

  8. [js] 微信小程序实现轨迹回放,微信原生小程序,基于uniapp的小程序?

    [js] 微信小程序实现轨迹回放,微信原生小程序,基于uniapp的小程序? 需要写出轨迹拖动,进度条,开始,暂停,结束功能. 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一 ...

  9. 计算机毕业设计Python+uniapp扫码点餐微信小程序(小程序+源码+LW)

    计算机毕业设计Python+uniapp扫码点餐微信小程序(小程序+源码+LW) 该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程 项目运行 环境配置: Pychram社区版+ pyth ...

最新文章

  1. 图像指针与矩阵格式转换——Mat转uchar*及uchar*转Mat代码实现
  2. 差分进化算法_差分进化算法
  3. html点击屏幕向右移动,HTML – 一旦打开,如何使移动页面适合屏幕?
  4. ES6解构赋值学习总结
  5. 《Too Much Heaven》
  6. git reset, git checkout, git revert 区别 (译)
  7. 为什么python工程师掌握这些就够了_Python工程师薪资飙升,Python这些技能你掌握了吗...
  8. 微软开源 TensorFlow-DirectML,为 WSL2 提供 GPU 支持
  9. C语言float数据类型介绍、示例和应用经验
  10. 再说人行分数解读分的作用
  11. Swift类属性 static
  12. 自用shell命令搜集
  13. c语言数字分解一个数,关于一道分解整数为N个连数整数的编程题
  14. Activity与Service之间交互并播放歌曲
  15. Integer与int比较的坑
  16. 关于sqlserver中SqlParameter的用法注意事项
  17. Odoo 序列和工作流
  18. 电脑进入pe时蓝屏_进入PE系统也会蓝屏?运行PE系统蓝屏原因及解决方法
  19. 22478计算机代码,数字2247代表啥意思 2247数字意思
  20. html p标签颜色代码,html里的颜色标签肿么写?

热门文章

  1. 华丽且专业的天气软件WeatherPro v1.5.2汉化版
  2. 英语四级bt总结法(必过)
  3. 计算机网络习题库 pdf,计算机网络题库(附答案修正版).pdf
  4. 申请SSL证书验证域名所有权限的其他方法Alternative Methods of Domain Control Validation (DCV)
  5. Starling TextField
  6. go-pitaya学习笔记(7)-custom_metrics demo分析
  7. android发送文件到微信,微信怎么发送文件给别人 微信发送文件给好友方法
  8. 关于出版《AR开发权威指南-ARFoundation》(2020-10-19更新)
  9. Potato靶机测试
  10. CSS 学习成长笔记(3)