第三章 “我要点爆”微信小程序云开发之点爆方式页面和爆炸之音页面制作
点爆方式选择页面制作
在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
第三章 “我要点爆”微信小程序云开发之点爆方式页面和爆炸之音页面制作的更多相关文章
- 第六章 “我要点爆”微信小程序云开发实例之爆文详情页制作
爆文详情页制作 从首页中数据列表打开相应详情页面的方法: 给数据列表中每个数据项加一个点击事件,同时将当前数据项的id暂时记录在本地,然后跳转到详情页面detail goopen: function ...
- 第一章 “我要点爆”微信小程序云开发之项目建立与我的页面功能实现
第一章 “我要点爆”微信小程序云开发之项目建立与我的页面功能实现 开发环境搭建 使用自己的AppID新建小程序项目,后端服务选择小程序·云开发,点击新建,完成项目新建. 新建成功后跳转到开发者工具界面 ...
- “我要点爆”微信小程序云开发实例
使用云开发进行微信小程序“我要点爆”的制作 下一章:“我要点爆”微信小程序云开发之项目建立与我的页面功能实现 接下来我将对“我要点爆”微信小程序进行完整的开源介绍 小程序名称: 我要点爆 查看方式:从 ...
- 第五章 “我要点爆”微信小程序云开发实例之从云端获取数据制作首页
下面我们来实现从云端获取数据,完成首页世界页面index的制作,首页分为4个数据列表导航页面,页面具体内容如下: 推荐:为用户推荐最新的点爆信息,它包含文本点爆内容和语音点爆内容. 文爆:筛选出文字点 ...
- 第四章 “我要点爆”微信小程序云开发之疯狂点击与糖果点爆页面制作
疯狂点击点爆方式页面制作 疯狂点击为用户提供一个60秒的按钮点击时间,同时点击过程中有背景音乐,系统根据用户点击按钮的此时来进行热度值的计算. <view class="the_hea ...
- 技本功丨收藏!斜杠青年与你共探微信小程序云开发(下篇)
2019年2月26日,人们为了一个杯子疯了一天. 星巴克猫爪杯,一场已经与猫无关了的“圣杯战争“.网上的倒卖价格,已炒至近千元! 求而不得,舍而不能,得而不惜.这是人最大的悲哀... 所以,请珍惜以下 ...
- 微信小程序云开发-从0打造云音乐全栈小程序
第1章 首门小程序“云开发”课程,你值得学习本章主要介绍什么是小程序云开发以及学习云开发的重要性,并介绍项目的整体架构,真机演示项目功能,详细介绍整体课程安排.课程适用人群以及需要掌握的前置知识.通过 ...
- 微信小程序-云开发(手记)
微信小程序-云开发(手记) 1.创建data.json文件 注意以下几点要求: 入门示例: init方法的env:默认环境配置,传入字符串形式的环境 ID(理解为数据库)可以指定所有服务的默认环境(意 ...
- 微信小程序云开发不完全指北
微信小程序云开发不完全指北 首先必须说明云开发的"云"并不是类似云玩家里的云的意思,而是微信小程序真的提供了云开发的接口以及一个简单的提供存储.数据库服务的虚拟后台(对于一些轻量小 ...
随机推荐
- lazy evaluation and deferring a computation await promise async
Promise - JavaScript | MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_ ...
- JAVA with Cassandra
maven项目,在pom.xml里加入依赖.不是的话下载相应的jar包放到lib目录下.这里驱动包的版本要和你cassandra的大版本一致. <dependency> <group ...
- HDOJ 4689 Derangement DP
DP具体解释见: http://blog.csdn.net/liguan1/article/details/10468139 Derangement Time Limit: 7000/7000 MS ...
- 基于springboot的Dubbo的常规总结
1.引入jar包: <!-- Spring Boot Dubbo 依赖 --> <dependency> <groupId>com.alibaba.spring.b ...
- 动态区间第K大
整体二分. 主要需要注意的一点是,对于每个删除操作,若删除操作被算入贡献,则最开始的插入操作也一定会被算入,所以不必担心删除删错. #include<cstdio> #include< ...
- 人生苦短之Python的urllib urllib2 requests
在Python中涉及到URL请求相关的操作涉及到模块有urllib,urllib2,requests,其中urllib和urllib2是Python自带的HTTP访问标准库,requsets是第三方库 ...
- IPFS 到底是怎么工作的?
简介 我们知道,一个存储服务,最基本的功能就是存和取.IPFS 中提供了这两种语义,那就是 add 和 get 操作. 在 IPFS 系统中执行 add 操作,就是执行了一次存操作,放在网络的概念里, ...
- Web app root system property already set to different value: 'webapp.root'
java.lang.IllegalStateException: Web app root system property already set to different value: 'webap ...
- 渲染树render tree
CSSOM树和DOM树连接在一起形成一个render tree,渲染树用来计算可见元素的布局并且作为将像素渲染到屏幕上的过程的输入. DOM树和CSSOM树连接在一起形成render tree . r ...
- 51Nod - 1055:最长等差数列 (求最长的等差数列)
N个不同的正整数,找出由这些数组成的最长的等差数列. 例如:1 3 5 6 8 9 10 12 13 14 等差子数列包括(仅包括两项的不列举) 1 3 5 1 5 9 13 3 6 9 12 ...