第二章 "我要点爆"微信小程序点爆页面的实现与云函数和云存储的应用

    xiaoxiao2022-07-07  179

    点爆页面的实现与云函数和云存储的应用以及录音功能讲解

    点爆页面制作

    点爆页面主要提供文字记录和语音记录两种爆文记录方式,在本页面内输入文字或录入语音后选择心情点击点爆按钮,跳转到点爆方式选择界面。

    首先,我们来实现页面布局,将文字记录和语音记录使用导航切换的方式放在一个页面内。

    导航中在js中设置一个currentTab变量通过数据绑定判断显示文字记录和语音记录的切换, {{item}} ,使用列表渲染wx:for创建导航,同时通过data-index将当前项的的下标index记录,用于在js中控制currentTab的值,并为导航每个组件添加一个点击事件。分别为文字记录和语音记录设置两个form,通过导航切换时currentTab的值和show与hide样式来判断是否显示。

    detonation.wxml

    <view class="the_header"> <text>点爆-抑制不住的心情</text> <image src="/images/fencun.png"></image> </view> <view class="the_nav"> <text class="item {{currentTab==index ? 'active' : ''}}" wx:for="{{navber}}" data-index="{{index}}" wx:key="unique" bindtap="navbarTap">{{item}}</text> </view> <form class="{{currentTab==0 ? 'show' : 'hide'}}"> <view class="the_main"> <text space="ensp"> 我们在路上,点爆,让时间忘不掉你的脚步!</text> <!-- 当点击输入时触发bindinput --> <textarea bindinput="textInput" value="{{baotext.wtext}}" maxlength="-1"></textarea> </view> <view class="the_check"> <!-- 当点击值时触发bindchange --> <radio-group bindchange="changeMood"> <radio checked="checked" value="红色">红色心情</radio> <radio value="黑色">黑色心情</radio> </radio-group> </view> <view class="the_button"> <button bindtap="detonation">点爆</button> </view> </form> <form class="{{currentTab==1 ? 'show' : 'hide'}}"> <view class="the_main"> <text space="ensp"> 我们在路上,点爆,让时间忘不掉你的脚步!</text> <view class="yuyin"> <button bindtouchstart="touchdown" bindtouchend="touchup"><image src="/images/yuyin2.png" bindtap="ystart"></image></button> </view> </view> <view class="the_check"> <radio-group bindchange="changeMoody"> <radio checked="checked">红色心情</radio> <radio>黑色心情</radio> </radio-group> </view> <view class="the_button"> <button bindtap="ydetonation">点爆</button> </view> </form>

    在js页面中将实现登录判断、导航切换、录音功能、文字记录等功能。 在onShow中对用户是否为登录状态进行判断,如果未登录则跳转到user页面。 navbarTap为导航点击切换事件,当文本记录与语音记录导航被点击时触发,将当前点击组件的下标index赋值给控制变量currentTab,通过数据绑定改变导航和页面显示。 textInput为textarea组件中bindinput属性的方法,用于实时记录组件中输入的文本值。 changeMood情绪单选按钮组当选中情绪项发生改变时触发,记录用户选择的情绪颜色。 detonation文字记录点爆按钮点击事件方法,当完成文字记录后,点击点爆按钮即可跳转到爆炸方式选择界面,此时我们把当前页面所有的数据信息暂时保存在本地,方便在最后爆文发布页面提交保存到数据库中。

    录音功能:通过button按钮进行录音,当按下按钮时录音开始,当松开按钮时录音结束跳转到录音试听页面,分别使用button组件的bindtouchstart属性和bindtouchend属性。 这里使用RecorderManager来实现录音操作,在顶部实例化一个唯一的RecorderManager录音管理器,配置录音参数options然后调用start开始录音API开始录音,松开按钮录音结束后调用stop录音结束API,同时调用录音结束的回调函数onStop,将音频文件保存在本地。

    在停止录音后我们要将录音文件保存下来,同时将音频文件上传到云端(这里我们直接进行音频文件的存储,实际上存储音频文件应在爆文提交时才执行),保存音频文件时,为了让用户的每个音频文件文件名唯一,我们用用户的openid+语音文件数来命名,使用云函数获取和修改用户语音数量,使用云存储API上传文件到云,下面我们来进行云函数和云存储的操作介绍。

    云函数的使用与环境配置:

    1、创建云函数

    右键cloudfunctions文件选择新建Node.js云函数,云函数命名为updateVoice用于修改用户语音数量。

    2、安装node.js及npm:

    一:从Node.js官网下载对应平台的安装程序 二:一键安装 三:打开cmd,输入node -v,npm -v如果出现版本号,证明安装成功

    注意:在使用npm可能会出现“npm不是内部或外部命名,与不是可运行程序”的提示,这是由于环境变量问题,需对node进行环境变量配置。

    3、安装wx-server-sdk

    右键updataVoice在终端中打开,运行:

    安装成功后云函数文件夹中会有多一个文件(package-lock.json): 右键上传并部署:所有文件 打开云端控制台可以看到我们云函数中已经有一个云函数了。 在云函数updateVoice下index.js进行云函数代码编写

    console.log("4") // 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() //声明数据库 const db = cloud.database() console.log("3") // 云函数入口函数 exports.main = async (event, context) => { console.log("2") //取得传过来的参数 var voice = event.voice, openId = event.openId; //云函数,更新 try { return await db.collection('users').where({ _openid: openId }).update({ data: { voice: voice }, success: res => { console.log('云函数成功') }, fail: e => { console.error(e) } }) } catch (e) { console.error(e) } }

    在云存储中创建保存音频文件的文件夹voice,用来保存上传到云端的音频文件。

    上传文件时调用wx.cloud.callFunction文件上传API,在上传时云存储路cloudPath设置为云端文件夹名+文件名,filePath设置为录音停止回调函数中获取的文件路径tempFilePath。

    完整的detonation.js代码:

    //录音管理 const recorderManager = wx.getRecorderManager() var tempFilePath; Page({ data: { navber: ['文字记录', '语音记录'],//导航数组 currentTab: 0,//导航判断 wtext: '',//文本 wmood: '红色',//心情red,black ytempFilePath: '', ymood: '红色', theplay: true,//监听是否在录音 }, //监听页面显示,判断是否登录 onShow: function () { //如果本地没有用户登录时保存的openId则提示登录且自动跳转到user页面 let userOpenId = wx.getStorageSync('openId') if (!userOpenId) { wx.showToast({ title: '请先登录~' }) setTimeout(() => { wx.switchTab({ url: '../user/user', }) }, 1500) } else { console.log(userOpenId,"登录状态") } }, //文本记录与语音记录切换 navbarTap: function (e) { this.setData({ currentTab: e.currentTarget.dataset.index }) }, // 文字记录,输入文本事件 textInput: function (e) { this.setData({ wtext: e.detail.value }) }, //文字记录,单选按钮组 changeMood: function (e) { this.setData({ wmood: e.detail.value }) }, //文字记录,点爆按钮跳转 detonation: function (e) { let wtext = this.data.wtext let wmood = this.data.wmood var wy = 'w' if (this.data.currentTab == 0) { if (wtext == '') { wx.showToast({ title: '请输入点爆内容', }) } else { //将数据保存到本地,保存文爆判断 wx.setStorageSync('wtext', wtext) wx.setStorageSync('wmood', wmood) wx.setStorageSync('wy', wy) //跳转页面 wx.navigateTo({ url: '../selectbao/selectbao' }) } } }, //音爆,单选按钮组 changeMoody: function (e) { this.setData({ ymood: e.detail.value }) }, //按钮点下开始录音 touchdown: function () { const options = { duration: 300000,//指定录音的时长,单位 ms sampleRate: 16000,//采样率 numberOfChannels: 1,//录音通道数 encodeBitRate: 96000,//编码码率 format: 'mp3',//音频格式,有效值 aac/mp3 frameSize: 50,//指定帧大小,单位 KB } //开始录音 recorderManager.start(options); recorderManager.onStart(() => { console.log('recorder start') }) //错误回调 recorderManager.onError((res) => { console.log(res) }) }, //停止录音 touchup: function () { //显示加载 wx.showLoading({ title: '', mask: true }) recorderManager.stop(); recorderManager.onStop((res) => { this.tempFilePath = res.tempFilePath //使用解构,获取音频文件 const { tempFilePath } = res //查询用户已有语音,记录,并为文件赋值 //获取数据库引用 const db = wx.cloud.database() const _ = db.command //查找数据库,获得用户语音数量 db.collection('users').where({ _openid: wx.getStorageSync('openId') }).get({ success(res) { // res.data 是包含以上定义的记录的数组 //将名字定为id号+个数号+.mp3 var newvoice = res.data[0].voice + 1 var filename = wx.getStorageSync('openId') + newvoice + '.mp3' console.log(wx.getStorageSync('openId'),res) //调用云函数,修改语音数量,向云函数传值 wx.cloud.callFunction({ name: 'updateVoice', data: { openId: wx.getStorageSync('openId'), voice: newvoice }, success: res => { console.log("1",res) //上传录制的音频到云 wx.cloud.uploadFile({ cloudPath: 'voice/' + filename, filePath: tempFilePath, // 文件路径 success: res => { console.log("5") //保存fileID用于播放云文件语音 wx.setStorageSync('fileIDy', res.fileID) //将数据保存到本地 wx.setStorageSync('filename', filename) wx.setStorageSync('ytempFilePath', tempFilePath) //关闭加载 wx.hideLoading() //跳转到听语音的页面 wx.navigateTo({ url: '../voicebao/voicebao' }) }, fail: err => { // handle error console.error(err) } }) } }) }, fail: err => { } }) }) setTimeout((() => { //关闭加载 wx.hideLoading() }), 4000) }, //音爆,点爆按钮跳转 ydetonation: function (e) { wx.showToast({ title: '请输入点爆语音', }) } })

    运行效果图:

    语音试听页面制作

    在文本记录方式下的点爆按钮点击后直接进入点爆方式选择界面,而语音记录方式中,为了让用户能试听自己的录音,我们多加一个试听页面。语音试听页面与语音记录页面几乎相同,只是改变录音按钮为语音播放按钮。

    配置app.json新建vicebao页面

    为语音播放按钮增加一个点击事件play方法

    <view class="the_header"> <text>点爆-抑制不住的心情</text> <image src="/images/fencun.png"></image> </view> <view class="the_nav"> <text class="item">文字记录</text> <text class="item active">语音记录</text> </view> <form class="show"> <view class="the_main"> <text space="ensp"> 我们在路上,点爆,让时间忘不掉你的脚步!</text> <view class="yuyin"> <image src="/images/yuyin.png" bindtap="play"></image> </view> </view> <view class="the_check"> <radio-group bindchange="changeMood"> <radio checked="checked" value='红色'>红色心情</radio> <radio value='黑色'>黑色心情</radio> </radio-group> </view> <view class="the_button"> <button bindtap="detonation">点爆</button> </view> </form>

    在vicebao.js中实现音频播放,创建一个内部audio上下文InnerAudioContext对象,用于播放音频,设置音频自动播放与音频路径。通过onUnload和onHide对音频播放进行控制,进入点爆方式选择界面时将爆文信息保存到本地。

    //音频组件控制 const innerAudioContext = wx.createInnerAudioContext() Page({ data: { navber: ['文字记录', '语音记录'], currentTab: 2, ymood: '红色', theplay: true }, //播放声音 play: function () { if (this.data.theplay) { this.setData({ theplay: false }) innerAudioContext.autoplay = true innerAudioContext.src = wx.getStorageSync('ytempFilePath'), innerAudioContext.onPlay(() => { console.log('开始播放') }), innerAudioContext.onEnded(() => { this.setData({ theplay: true }) }) innerAudioContext.onError((res) => { console.log(res.errMsg) }) } }, //页面被卸载时执行 onUnload: function () { innerAudioContext.stop() }, //当点击下一步后如果语音在播放则关闭 onHide: function () { innerAudioContext.stop() }, //音爆,单选按钮组 changeMood: function (e) { this.setData({ ymood: e.detail.value }) }, //音爆,点爆按钮跳转 detonation: function (e) { let ymood = this.data.ymood var wy = 'y' //将数据保存到本地,保存语音判断 wx.setStorageSync('ymood', ymood) wx.setStorageSync('wy', wy) //跳转页面 wx.navigateTo({ url: '../selectbao/selectbao' }) }, })

    完成语音试听页面的制作后,我们现在可以进行录音功能的测试,在语音记录界面中对录音进行授权后,按住录音按钮开始录音,当松开录音按钮后页面会自动跳转到录音试听页面。我们打开云开发控制台查看云存储中的voice文件,可以发现成功保存了一条语音文件,说明录音功能已成功。 项目源码:https://github.com/xiedong2016/dbx

    最新回复(0)