小程序简单版录音机

news2024/11/28 10:41:50

先来看看效果

在这里插入图片描述

结构

先来看看页面结构

    <!-- wxml -->
    
<view class="wx-container">
  <view id="title">录音机</view>
  <view id="time">{{hours}}:{{minute}}:{{second}}</view>
  <view class="btngroup">
    <view hover-class="change" catch:tap="play">播放</view>
    <view class="play" hover-class="change" catch:tap="start"></view>
    <view hover-class="change" catch:tap="stop">结束</view>
  </view>
</view>

页面样式

/* pages/radio/index.wxss */
.wx-container {
  width: 100vw;
  height: 100vh;
  margin: 0 auto;
  text-align: center;
  box-sizing: border-box;
}

#title {
  margin: 100rpx auto;
  text-align: center;
  font-size: 50rpx;

}

#time {
  font-size: 150rpx;
}

.btngroup {
  height: 180rpx;
  margin: 100rpx auto;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.btngroup>view:not(.play) {
  width: 120rpx;
  height: 120rpx;
  border-radius: 50%;
  line-height: 120rpx;
  background-color: #eee;
}

.play {
  width: 150rpx;
  height: 150rpx;
  border: solid 50rpx red;
  box-sizing: border-box;
  border-radius: 50%;
  transition: .2s;
  background-color: transparent;
}

.change {
  transition: .2s;
  box-shadow: 0 0 8rpx 8rpx rgb(0, 0, 0);

}

核心代码

计时函数

🆗,接下来要实现点击录音按钮,进行一个计时效果
在这里插入图片描述

这边是一个计时函数,写得比较繁琐,要是各位大大有更好的办法也欢迎补充

Page({
  data: {
    time: 0,
    cleartime: '',
    timer: null,
    hours: '0' + 0, // 时
    minute: '0' + 0, // 分
    second: '0' + 0, // 秒
  },

// -----------------------------
// 计时器
  setInterval() {
    const _this = this
    var second = _this.data.second
    var minute = _this.data.minute
    var hours = _this.data.hours
    _this.data.timer = setInterval(function () { // 设置定时器
      second++
      if (second >= 60) {
        second = 0 //  大于等于60秒归零
        minute++
        if (minute >= 60) {
          minute = 0 //  大于等于60分归零
          hours++
          if (hours < 10) {
            // 少于10补零
            _this.setData({
              hours: '0' + hours
            })
          } else {
            _this.setData({
              hours: hours
            })
          }
        }
        if (minute < 10) {
          // 少于10补零
          _this.setData({
            minute: '0' + minute
          })
        } else {
          _this.setData({
            minute: minute
          })
        }
      }
      if (second < 10) {
        // 少于10补零
        _this.setData({
          second: '0' + second
        })
      } else {
        _this.setData({
          second: second
        })
      }
    }, 1000)
  }
 })

开始事件

现在开始为播放按钮设置事件,那我们先来
获取录音管理器
wx.getRecorderManager() 详细方法请查看官方文档
创建全局音频
wx.createInnerAudioContext()详细方法请查看官方文档

// 获取录音管理器
var tape = wx.getRecorderManager()
// 创建全局音频
var audio = wx.createInnerAudioContext()
Page({
  data: {
    time: 0,
    cleartime: '',
    state: 0, // 0 为停止录音  1 为正在录音   2 为暂停录音
    timer: null,
    hours: '0' + 0, // 时
    minute: '0' + 0, // 分
    second: '0' + 0, // 秒
    tempFilePath: null
  },

  //计时开始
  start() {
    let _this = this;
    switch (this.data.state) {
      case 0:
        _this.setInterval();
        // 开始录音
        tape.start()
        console.log('开始录音');
        this.setData({
          state: 1 // 把state设置为1 (暂停录音状态)
        })
        // audio.destroy() // 释放音频资源
        break
      case 1:
        clearInterval(_this.data.timer);
        // 暂停录音
        tape.pause()
        console.log('暂停录音');
        this.setData({
          state: 2 // 把state设置为2 (继续录音状态)
        })
        break
      case 2:
        _this.setInterval();
        // 继续录音
        tape.resume()
        console.log('继续录音');
        this.setData({
          state: 1 // 把state设置为1 (暂停录音状态)
        })
        break
    }
    // 为了性能考虑 20 秒后自动结束录音  
    setTimeout(() => {
      clearInterval(_this.data.timer);
      tape.stop()
      // 监听结束录音事件
      tape.onStop((res) => {
        this.data.tempFilePath = res.tempFilePath
        console.log('自动保存录音');
        wx.showToast({
          title: '自动保存录音成功',
          mask: true,
          duration: 500,
        })
      })
    }, 20000)
  }
 })

有了这些咱们就可以正常的进行计时和录音功能

结束事件(保存录音)

接下来我们来进行保存录音和把计时器清零的操作

// 结束
  stop() {
    // 如果state处于0(未录音状态)弹出提示
    if (this.data.state == 0) {
      wx.showToast({
        title: '请先开始录音',
        mask: true,
        duration: 500,
        icon: 'error'
      })
      return
    }
    let _this = this;
    this.setData({
      hours: '0' + 0,
      minute: '0' + 0,
      second: '0' + 0,
      state: 0 // 点击结束按钮之后 把 state(状态)初始化为0(未录音状态)
    })
    clearInterval(_this.data.timer);
    // 结束录音 保存录音
    tape.stop()
    // 监听结束录音事件
    tape.onStop((res) => {
      this.data.tempFilePath = res.tempFilePath
      console.log('保存录音');
      wx.showToast({
        title: '保存录音成功',
        mask: true,
        duration: 500,
      })
    })
  },

播放录音

最后一步就很简单了,给音频设置上路径播放音频就好

//播放
  play() {
    // 如果音频路径为空,弹出提示
    if (!this.data.tempFilePath) {
      wx.showModal({
        title: '没有录音',
        content: '请开始录音或保存录音'
      })
      return
    }
    audio.src = this.data.tempFilePath
    // 播放录音的音频
    audio.play()
    wx.showToast({
      title: '播放录音',
      mask: true,
      duration: 500
    })
  },

到这里呢,一个简单版的录音机基本功能就已经完全实现了,下面将附上完整代码,如有错误的地方,请斧正

// 获取录音管理器
var tape = wx.getRecorderManager()
// 创建全局音频
var audio = wx.createInnerAudioContext()
Page({
  data: {
    time: 0,
    cleartime: '',
    state: 0, // 0 为停止录音  1 为正在录音   2 为暂停录音
    timer: null,
    hours: '0' + 0, // 时
    minute: '0' + 0, // 分
    second: '0' + 0, // 秒
    tempFilePath: null
  },

  //计时开始
  start() {
    let _this = this;
    switch (this.data.state) {
      case 0:
        _this.setInterval();
        // 开始录音
        tape.start()
        console.log('开始录音');
        this.setData({
          state: 1 // 把state设置为1 (暂停录音状态)
        })
        // audio.destroy() // 释放音频资源
        break
      case 1:
        clearInterval(_this.data.timer);
        // 暂停录音
        tape.pause()
        console.log('暂停录音');
        this.setData({
          state: 2 // 把state设置为2 (继续录音状态)
        })
        break
      case 2:
        _this.setInterval();
        // 继续录音
        tape.resume()
        console.log('继续录音');
        this.setData({
          state: 1 // 把state设置为1 (暂停录音状态)
        })
        break
    }
    // 为了性能考虑 20 秒后自动结束录音  
    setTimeout(() => {
      clearInterval(_this.data.timer);
      tape.stop()
      // 监听结束录音事件
      tape.onStop((res) => {
        this.data.tempFilePath = res.tempFilePath
        console.log('自动保存录音');
        wx.showToast({
          title: '自动保存录音成功',
          mask: true,
          duration: 500,
        })
      })
    }, 20000)
  },

  //播放
  play() {
    // 如果音频路径为空,弹出提示
    if (!this.data.tempFilePath) {
      wx.showModal({
        title: '没有录音',
        content: '请开始录音或保存录音'
      })
      return
    }
    audio.src = this.data.tempFilePath
    // 播放录音的音频
    audio.play()
    wx.showToast({
      title: '播放录音',
      mask: true,
      duration: 500
    })
  },

  // 结束
  stop() {
    // 如果state处于0(未录音状态)弹出提示
    if (this.data.state == 0) {
      wx.showToast({
        title: '请先开始录音',
        mask: true,
        duration: 500,
        icon: 'error'
      })
      return
    }
    let _this = this;
    this.setData({
      hours: '0' + 0,
      minute: '0' + 0,
      second: '0' + 0,
      state: 0 // 点击结束按钮之后 把 state(状态)初始化为0(未录音状态)
    })
    clearInterval(_this.data.timer);
    // 结束录音 保存录音
    tape.stop()
    // 监听结束录音事件
    tape.onStop((res) => {
      this.data.tempFilePath = res.tempFilePath
      console.log('保存录音');
      wx.showToast({
        title: '保存录音成功',
        mask: true,
        duration: 500,
      })
    })
  },



  // 计时器
  setInterval() {
    const _this = this
    var second = _this.data.second
    var minute = _this.data.minute
    var hours = _this.data.hours
    _this.data.timer = setInterval(function () { // 设置定时器
      second++
      if (second >= 60) {
        second = 0 //  大于等于60秒归零
        minute++
        if (minute >= 60) {
          minute = 0 //  大于等于60分归零
          hours++
          if (hours < 10) {
            // 少于10补零
            _this.setData({
              hours: '0' + hours
            })
          } else {
            _this.setData({
              hours: hours
            })
          }
        }
        if (minute < 10) {
          // 少于10补零
          _this.setData({
            minute: '0' + minute
          })
        } else {
          _this.setData({
            minute: minute
          })
        }
      }
      if (second < 10) {
        // 少于10补零
        _this.setData({
          second: '0' + second
        })
      } else {
        _this.setData({
          second: second
        })
      }
    }, 1000)
  }
})

在这里插入图片描述


  • 失联

最后编辑时间 2024,6,07;9:40

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

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

相关文章

【JavaSE】面向对象---多态

前言 本篇以Java初学者视角写下&#xff0c;难免有不足&#xff0c;或者术语不严谨之处。如有错误&#xff0c;欢迎评论区指正。本篇说明多态相关的知识。若本文无法解决您的问题&#xff0c;可以去最下方的参考文献出&#xff0c;找出想要的答案。 多态概念 多态&#xff08…

【Ardiuno】实验使用ESP32连接Wifi(图文)

ESP32最为精华和有特色的地方当然是wifi连接&#xff0c;这里我们就写程序实验一下适使用ESP32主板连接wifi&#xff0c;为了简化实验我们这里只做了连接部分&#xff0c;其他实验在后续再继续。 由于本实验只要在串口监视器中查看结果状态即可&#xff0c;因此电路板上无需连…

最短路径——迪杰斯特拉与弗洛伊德算法

一.迪杰斯特拉算法 首先对于最短路径来说&#xff1a;从vi-vj的最短路径&#xff0c;不用非要经过所有的顶点&#xff0c;只需要找到路径最短的路径即可&#xff1b; 那么迪杰斯特拉的算法&#xff1a;其实也就与最小生成树的思想类似&#xff0c;找到较小的&#xff0c;然后…

在网上赚钱,可以自由掌控时间,灵活的兼职副业选择

朋友们看着周围的人在网上赚钱&#xff0c;自己也会为之心动&#xff0c;随着电子设备的普及&#xff0c;带动了很多的工作、创业以及兼职副业选择的机会&#xff0c;作为普通人的我们&#xff0c;如果厌倦了世俗的朝九晚五&#xff0c;想着改变一下自己的生活&#xff0c;可以…

STM32 printf 重定向到CAN

最近在调试一款电机驱动板 使用的是CAN总线而且板子上只有一个CAN 想移植Easylogger到上面试试easylogger的效果&#xff0c;先实现pritnf的重定向功能来打印输出 只需要添加以下代码即可实现 代码 #include <stdarg.h> uint8_t FDCAN_UserTxBuffer[512]; void FDCAN_p…

btstack协议栈实战篇--Hello World example

btstack协议栈---总目录-CSDN博客 目录 1.定时计时器设置 2.主要应用程序设置 3.运行log如下图 该示例演示了如何提供周期性定时器来切换LED并将调试消息作为最小BTstack测试发送到控制台。 1.定时计时器设置 由于BTstack中的计时器是单触发的&#xff0c;因此通过在心跳中重新…

从0到1:企业办公审批小程序开发笔记

可行性分析 企业办公审批小程序&#xff0c;适合各大公司&#xff0c;企业&#xff0c;机关部门办公审批流程&#xff0c;适用于请假审批&#xff0c;报销审批&#xff0c;外出审批&#xff0c;合同审批&#xff0c;采购审批&#xff0c;入职审批&#xff0c;其他审批等规划化…

Android Qt开发环境部署

我总结了在Qt中搭建Android开发两个要点&#xff1a; 1.JDK一定要是JDK1.8的 2.要下载目标Android版本的SDK&#xff0c;可以在Android studio SDK查看对应Android SDK版本 下面我们开发搭建。首先需要JDK&#xff0c;链接如下&#xff1a;链接&#xff1a;https://pan.baidu.…

★pwn 24.04环境搭建保姆级教程★

★pwn 24.04环境搭建保姆级教程★ &#x1f338;前言&#x1f33a;Ubuntu 24.04虚拟机&#x1f337;VM&#x1f337;Ubuntu 24.04镜像 &#x1f33a;工具&#x1f337;可能出现的git clone错误&#x1f337;复制粘贴问题&#x1f337;攻击&#x1f337;编题 &#x1f33a;美化&…

【CS.DB】从零到精通:这可能是全网最全面最强大的SQL入门教程

文章目录 1. 什么是SQL&#xff1f;1.1 SQL的历史1.1.1 SQL的标准化过程 2. SQL基础语法2.1 数据库操作2.1.1 创建数据库2.1.2 删除数据库 2.2 表操作2.2.1 创建表2.2.2 删除表2.2.3 修改表 2.3 数据操作2.3.1 插入数据2.3.2 更新数据2.3.3 删除数据 2.4 查询数据2.4.1 基本查询…

【Linux】进程4——进程状态

1.进程状态 什么是状态&#xff1f; 每个人都有状态——颓废&#xff0c;阳光&#xff0c;积极向上。。。。 进程也有状态 在操作系统中&#xff0c;由于进程的数量是非常多的&#xff0c;而系统的资源又非常少&#xff0c;所以不可能每一个进程在每时每刻都会处于上处理机运…

【 技术栈】技术方案到底怎么写?

文章目录 一、背景二、技术方案重要性三、常见的技术方案有哪些内容1、系统用例2、功能整体链路2.1、核心业务流程 3、数据库设计4、接口设计5、非功能设计5.1、性能与稳定性5.2、监控 7、系统风险点评估 四、总结 一、背景 工作中&#xff0c;有一些需求或者技术改造&#xf…

计算机网络--应用层

计算机网络–计算机网络概念 计算机网络–物理层 计算机网络–数据链路层 计算机网络–网络层 计算机网络–传输层 计算机网络–应用层 1. 概述 因为不同的网络应用之间需要有一个确定的通信规则。 1.1 两种常用的网络应用模型 1.1.1 客户/服务器模型&#xff08;Client/Se…

Java面试八股之什么是反射,实现原理是什么

Java中什么是反射&#xff0c;实现原理是什么 Java中的反射&#xff08;Reflection&#xff09;是一种强大的特性&#xff0c;它允许程序在运行时检查和操作类、接口、字段和方法的信息。简而言之&#xff0c;反射机制使得程序能够在运行时动态地了解和使用自身或其他程序集中…

python文件:py,ipynb, pyi, pyc, pyd, pyo都是什么文件?

1、Python文件类型介绍 &#x1f4c1; 1.1 .py 文件&#xff1a;源代码基础 .py 文件是 Python 最基本的源代码文件格式&#xff0c;用于存储纯文本形式的 Python 代码。它是开发者编写程序的主要场所&#xff0c;包含函数、类、变量定义以及执行逻辑。Python 解释器直接读取…

【排序算法】总结篇

✨✨这些 排序算法都是指的 需要进行比较的排序算法 ✨✨下面都是略微讲解一下思路&#xff0c;如果需要详细了解哪一个排序&#xff0c;点击&#x1f449;链接即可 ✨✨对于时间、空间复杂度、稳定性&#xff0c;希望你&#x1f9d1;‍&#x1f393;能够理解记忆&#x1f9d1;…

MyBatisPlus插件生成代码

文章目录 概要安装插件使用插件 概要 MyBatis-Plus 是 MyBatis 的增强工具&#xff0c;旨在简化 MyBatis 的开发。MyBatis-Plus 代码生成器插件可以自动生成项目中常见的代码&#xff0c;如实体类、Mapper 接口、Service 接口和实现类、Controller 等&#xff0c;从而减少手动…

python代码中参数的默认值

python中的函数&#xff0c;可以给形参指定默认值。 带有默认值的参数&#xff0c;可以在调用的时候不传参。 如上图所示&#xff0c;在给函数设定形参的时候可以给函数形参设定默认值&#xff0c;当然默认参数的形参应该在非默认形参的后面。 如果在调用函数的时候&#xff…

SpringBoot整合SpringSecurit(二)通过token进行访问

在文章&#xff1a;SpringBoot整合SpringSecurit&#xff08;一&#xff09;实现ajax的登录、退出、权限校验-CSDN博客 里面&#xff0c;使用的session的方式进行保存用户信息的&#xff0c;这一篇文章就是使用token的方式。 在其上进行的改造&#xff0c;可以先看SpringBoot…

ctfshow-web入门-命令执行(web41_exp与分析)

过滤不严&#xff0c;命令执行 preg_match(/[0-9]|[a-z]|\^|\|\~|\$|\[|\]|\{|\}|\&|\-/i, $c) 过滤掉了数字、字母以及一些符号&#xff0c;之前接触过的无字母 rce 是取反编码再取反&#xff0c;采用不可见字符去绕过正则&#xff0c;但是这里取反符号被过滤掉了&#x…