第三章 “我要点爆”微信小程序云开发之点爆方式页面和爆炸之音页面制作

点爆方式选择页面制作

在app.json中配置页面路径增加selectbao点爆方式选择,编译创建页面文件,点爆方式选择页面通过单选按钮组选择跳转到相应的点爆页面。

<view class="the_header">
  <text>选择点爆方式</text>
  <image src="/images/fencun.png"></image>
</view>
<view class="select_check">
  <radio-group bindchange="selectway">
    <radio checked='true' value='爆炸之音'>爆炸之音</radio>
    <radio value='疯狂点击'>疯狂点击</radio>
    <radio value='糖果点爆'>糖果点爆</radio>
  </radio-group>
</view>
<view class="select_button">
  <button bindtap="next">下一步</button>
</view>

给单选按钮组增加bindchange属性的方法,控制获取所选项,当点击下一步时触发点击事件,通过next方法判断跳转不同的页面。

Page({
  data: {
    wway: '爆炸之音'
  },
  selectway: function (e) {
    this.setData({
      wway: e.detail.value
    })
  },
  next: function () {
    let wway = this.data.wway
    wx.setStorageSync('wway', wway)
    if (wway == '爆炸之音') {
      wx.navigateTo({
        url: '../selecty/selecty'
      })
    } else if (wway == '疯狂点击') {
      wx.navigateTo({
        url: '../selectd/selectd'
      })
    } else {
      wx.navigateTo({
        url: '../selectt/selectt'
      })
    }
  },
  onLoad: function () {
    wx.setNavigationBarTitle({
      title: '点爆方式'
    })
  }
})

运行效果图:


爆炸之音方式制作

在app.json中增加爆炸之音录音页面selecty和爆炸之音确认页面selectyok,在selecty中我们进行录音操作,在selectyok中我们进行语音试听和爆文发布操作。

selecty.wxml中设置一个button录音按钮,并使用bindtouchstart和bindtouchend属性进行录音控制,与语音记录相同。

<view class="the_header">
  <text>爆炸之音</text>
  <image src="/images/fencun.png"></image>
</view>
<view class="button1">
  <button bindtouchstart="touchdown" bindtouchend="touchup"><image src="/images/yuyin5.png"></image></button>
</view>

在录音过程中调用帧文件监听的回调事件RecorderManager.onFramRecorded(function callback)对帧文件进行监听,用sum记录帧文件的大小和,用sumt记录帧文件的个数。

    //监听帧文件
    recorderManager.onFrameRecorded((res) => {
      const { frameBuffer } = res
      sum += frameBuffer.byteLength
      sumt++
    })

在停止录音后,使用下方算法对热度值进行简单计算。

    if (sumt > 10) {
      var wn = (sum - 1500) / (sumt - 1) - 2300
    } else {
      var wn = (sum - 1500) / (sumt - 1) - 3000
    }

在云开发控制台存储中新建baovoice文件夹用于保存爆炸之音所录的语音,同时新建云函数updateBaovoice,云函数用于修改用户users表中baovoice的数量值,用于记录用户所录入爆炸之音的个数和对语音文件进行命名。云函数创建并完成配置与编写后,上传并部署。


updateBaovoice/index.js

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

js中对语音进行操作,完成录音后跳转到爆炸之音确认页面selectyok

//录音管理
const recorderManager = wx.getRecorderManager()
var tempFilePath
var sum = 0
var sumt = 0;
Page({
  data: {

  },
  //按钮点下开始录音
  touchdown: function () {
    const options = {
      duration: 300000,//指定录音的时长,单位 ms
      sampleRate: 16000,//采样率
      numberOfChannels: 1,//录音通道数
      encodeBitRate: 96000,//编码码率
      format: 'mp3',//音频格式,有效值 aac/mp3
      frameSize: 5 //指定帧大小,单位 KB
    }
    //监听帧文件
   recorderManager.onFrameRecorded((res) => {
      const { frameBuffer } = res
      sum += frameBuffer.byteLength
      sumt++
    })
    //开始录音
    recorderManager.start(options);
    recorderManager.onStart(() => {
      console.log('recorder start')
    })
    //错误回调
    recorderManager.onError((res) => {
      console.log(res);
    })
  },
  //停止录音
  touchup: function () {
    wx.showLoading({
      title: '',
      mask: true
    })
    recorderManager.stop();
    if (sumt > 10) {
      var wn = (sum - 1500) / (sumt - 1) - 2300
    } else {
      var wn = (sum - 1500) / (sumt - 1) - 3000
    }
    wx.setStorageSync('wnum', parseInt(wn))
    sum = 0
    sumt = 0
    recorderManager.onStop((res) => {
      this.tempFilePath = res.tempFilePath
      console.log('停止录音', 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 是包含以上定义的记录的数组
          console.log('查询用户:', res)
          //将名字定为id号+个数号+.mp3
          var newbaovoice = res.data[0].baovoice + 1
          var baofilename = wx.getStorageSync('openId') + newbaovoice + '.mp3'
          //调用云函数,修改爆语音数量,向云函数传值
          wx.cloud.callFunction({
            name: 'updateBaovoice',
            data: {
              openId: wx.getStorageSync('openId'),
              baovoice: newbaovoice
            },
            success: res => {
              //上传录制的音频到云
              wx.cloud.uploadFile({
                cloudPath: 'baovoice/' + baofilename,
                filePath: tempFilePath, // 文件路径
                success: res => {
                  console.log(res.fileID)
                  //保存点爆语音fileID,方便后面播放
                  wx.setStorageSync('fileIDd', res.fileID)
                  //将数据保存到本地
                  wx.setStorageSync('baofilename', baofilename)
                  wx.setStorageSync('ybaotempFilePath', tempFilePath)
                  //关闭加载
                  wx.hideLoading()
                  //跳转到听语音的页面
                  wx.navigateTo({
                    url: '../selectyok/selectyok'
                  })
                },
                fail: err => {
                  // handle error
                  console.error(err)
                }
              })
            }
          })
        },
        fail: err => {

        }
      })
    })
    setTimeout((() => {
      //关闭加载
      wx.hideLoading()
    }), 4000)
  },
  onLoad: function () {
    wx.setNavigationBarTitle({
      title: '爆炸之音'
    })
  }
})

爆炸之音确认页面

<view class="the_header">
  <text>爆炸之音</text>
  <image src="/images/fencun.png"></image>
</view>
<view class="button1">
  <image src="/images/yuyin6.png" bindtap="play"></image>
  <text>爆炸热度:{{wtemperature}}</text>
</view>
<view class="selectd_button">
  <button bindtap="add">确定</button>
</view>
<view class="the_btn">
    <button bindtap="seal">封存</button>
</view>

新建爆文信息集合bao和封存信息集合seal,两个集合的结构相同,如下:

字段名 数据类型 主键 非空 描述
_id String ID
_openid String 用户唯一标识
avaterUrl String
gender String 性别
province String 地区
temperature number 热度值
userId String ID
username String 用户名
wmood String 心情颜色(文本)
text String 爆文文本
time String 操作时间
wway String 点爆方式(文本)
ymood String 心情颜色(语音)
yway String 点爆方式(语音)
filename String 语音文件名
filelDd String 爆炸之音地址
baofilename String 爆炸之音文件名

js模块加载,在miniprogram下新建utils文件,同时在utils文件下新建一个utils.js文件,用于创建事件函数

utils.js

const formatTime = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()
  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formaDate = date => {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  return [year, month, day].map(formatNumber).join('-')
}
const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}
module.exports = {
  formatTime: formatTime,
  formaDate: formaDate
}

js模块加载require方法,引用utils.js文件,获取一个util对象,调用对象中的formatTime方法来获取当前时间。

var util = require('../../utils/utils.js');

selectyok.js中我们完成录音的试听,同时通过爆文记录页面保存在本地的wy变量值,判断是文本记录还是语音记录,从而设置不同的data属性列表,完整的selectyok.js代码如下:

var util = require('../../utils/utils.js');
//音频组件控制
const innerAudioContext = wx.createInnerAudioContext()
const db = wx.cloud.database()
const _ = db.command;
Page({
  data: {
    wtemperature: 0,
    theplay: true
  },
  //播放声音
  play: function () {
    if (this.data.theplay) {
      this.setData({
        theplay: false
      })
      innerAudioContext.autoplay = true
      innerAudioContext.src = wx.getStorageSync('ybaotempFilePath'),
        innerAudioContext.onPlay(() => {
          console.log('开始播放')
        }),
        innerAudioContext.onEnded(() => {
          this.setData({
            theplay: true
          })
        })
      innerAudioContext.onError((res) => {
        console.log(res.errMsg)
        console.log(res.errCode)
      })
    }
  },
  //页面被卸载时被执行
  onUnload: function () {
    innerAudioContext.stop();
  },
  //当点击确认后如果语音在播放则关闭
  onHide: function () {
    innerAudioContext.stop()
  },
  //将数据写入数据库
  add: function () {
    wx.showLoading({
      title: '',
      mask: true
    })
    var wy = wx.getStorageSync("wy")
    if(wy == "w"){
      var data = {
        userId: wx.getStorageSync('userId'),
        openId: wx.getStorageSync('openId'),
        username: wx.getStorageSync('username'),
        gender: wx.getStorageSync('gender'),
        province: wx.getStorageSync('province'),
        avaterUrl: wx.getStorageSync('avater'),
        text: wx.getStorageSync('wtext'),
        wmood: wx.getStorageSync('wmood'),
        wway: wx.getStorageSync('wway'),
        baofilename: wx.getStorageSync('baofilename'),
        fileIDd: wx.getStorageSync('fileIDd'),
        temperature: wx.getStorageSync('wnum'),
        time: util.formatTime(new Date())
      }
    }else{
      var data = {
        userId: wx.getStorageSync('userId'),
        openId: wx.getStorageSync('openId'),
        username: wx.getStorageSync('username'),
        gender: wx.getStorageSync('gender'),
        province: wx.getStorageSync('province'),
        avaterUrl: wx.getStorageSync('avater'),
        filename: wx.getStorageSync('filename'),
        fileIDy: wx.getStorageSync('fileIDy'),
        ymood: wx.getStorageSync('ymood'),
        yway: wx.getStorageSync('wway'),
        baofilename: wx.getStorageSync('baofilename'),
        fileIDd: wx.getStorageSync('fileIDd'),
        temperature: wx.getStorageSync('wnum'),
        time: util.formatTime(new Date())
      }
    }
    db.collection('bao').add({
      data: data,
      success: res => {
        console.log('bao存入成功')
        wx.showToast({
          title: '点爆成功',
        })
        setTimeout(() => {
          wx.navigateTo({
            url: '../success/success'
          })
        }, 1000)
        wx.hideLoading()
      }
    })

  },
  //封存
  seal: function () {
    wx.showLoading({
      title: '',
      mask: true
    })
    var wy = wx.getStorageSync("wy")
    if (wy == "w") {
      var data = {
        userId: wx.getStorageSync('userId'),
        openId: wx.getStorageSync('openId'),
        username: wx.getStorageSync('username'),
        gender: wx.getStorageSync('gender'),
        province: wx.getStorageSync('province'),
        avaterUrl: wx.getStorageSync('avater'),
        text: wx.getStorageSync('wtext'),
        wmood: wx.getStorageSync('wmood'),
        wway: wx.getStorageSync('wway'),
        baofilename: wx.getStorageSync('baofilename'),
        fileIDd: wx.getStorageSync('fileIDd'),
        temperature: wx.getStorageSync('wnum'),
        time: util.formatTime(new Date())
      }
    } else {
      var data = {
        userId: wx.getStorageSync('userId'),
        openId: wx.getStorageSync('openId'),
        username: wx.getStorageSync('username'),
        gender: wx.getStorageSync('gender'),
        province: wx.getStorageSync('province'),
        avaterUrl: wx.getStorageSync('avater'),
        filename: wx.getStorageSync('filename'),
        fileIDy: wx.getStorageSync('fileIDy'),
        ymood: wx.getStorageSync('ymood'),
        yway: wx.getStorageSync('wway'),
        baofilename: wx.getStorageSync('baofilename'),
        fileIDd: wx.getStorageSync('fileIDd'),
        temperature: wx.getStorageSync('wnum'),
        time: util.formatTime(new Date())
      }
    }
    db.collection('seal').add({
      data: data,
      success: res => {
        console.log('seal存入成功')
        wx.showToast({
          title: '封存成功',
        })
        setTimeout(() => {
          wx.navigateTo({
            url: '../success/success'
          })
        }, 1000)
        wx.hideLoading()
      }
    })
  },
  onLoad: function () {
    wx.setNavigationBarTitle({
      title: '爆炸之音'
    })
    let temperature = wx.getStorageSync('wnum')
    this.setData({
      wtemperature: temperature
    })
  }
})

效果图:(可以看到爆炸热度为-1500,原因是在开发者工具的模拟器中所进行的录音功能对于录音文件与移动端格式不同,所以热度值无法计算)


创建爆文操作成功后提示页success,success页面只显示一个成功的提示文字,然后通过延时定时器自动或手动点击跳转到首页世界页面。

success.wxml

<view class="the_header">
  <text>点爆成功</text>
  <image src="/images/fencun.png"></image>
</view>
<view class="button1" bindtap="goindex">
  <image src="/images/baook.png"></image>
</view>

让导航页面重新加载,跳转导航的页面可以通过switchTab,但默认情况是不会重新加载数据的,通过这三行代码,当进入首页index时,让页面重新加载调用页面的onLoad方法,达到刷新数据的作用。
var page = getCurrentPages().pop();
if (page == undefined || page==null) return;
page.onLoad();

success.js完整代码:

Page({
  data: {

  },
  goindex: function () {
    wx.switchTab({
      url: '../index/index',
    })
  },
  //监听页面自动跳转
  onShow: function () {
    setTimeout(() => {
      wx.reLaunch({
        url: '../index/index',
        success: function (e) {
          var page = getCurrentPages().pop();
          if (page == undefined || page == null) return;
          page.onLoad();
        }
      })
    }, 2000)
  },
  onLoad: function () {
    wx.setStorageSync('wtext', '')
    wx.setStorageSync('wmood', 'red')
    wx.setStorageSync('wway', '1')
    wx.setStorageSync('wnum', 0)
  }
})

现在我们可以进行一次完整的爆炸之音点爆方式的演示:


数据库中成功增加数据,说明点爆与发布成功。


项目源码:https://github.com/xiedong2016/dbx

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342