很久没写文章了,这是之前写过的项目用的,所以。。直接上代码吧
<style lang="scss">
page {
height: 100%;
}
.main {
display: flex;
flex-direction: column;
height: 100%;
}
.output-audio {
width: 160rpx;
margin: 5rpx 30rpx;
.audio {
position: relative;
top: 0;
left: 0;
height: 28rpx;
padding: 20rpx;
border-radius: 35rpx;
background-color: #226fe3;
border: 1px solid #f0f0f0;
.ico {
width: 26rpx;
height: 28rpx;
float: left;
}
.time {
position: absolute;
top: 18rpx;
right: -50rpx;
font-size: 24rpx;
}
}
}
.section {
flex: 0 0 100rpx;
width: 100%;
height: 100rpx;
padding: 15rpx;
box-sizing: border-box;
z-index: 1;
background-color: #ffffff;
.input-view {
width: 100%;
height: 70rpx;
.input-icon {
display: inline-block;
.audio-icon {
width: 70rpx;
height: 70rpx;
}
}
.audio-btn {
display: inline-block;
width: 700rpx;
height: 70rpx;
font-size: 32rpx;
color: #747474;
background-color: #f7f6f6;
line-height: 70rpx;
margin: 0 auto;
}
}
}
</style>
<template>
<view class="main">
<!-- 录音音频区 -->
<block
wx:for="{{audioArr}}"
wx:key="content"
wx:for-item="item"
wx:for-index="index"
data-state="{{item.state}}"
>
<view class="output-audio" style="width: {{item.time < 8 ? 64 : item.time * 8}}rpx;">
<view class="audio" wx:if="{{item.state==false}}" data-index="{{index}}" @tap="audioPlay">
<image
class="ico"
src="../images/play-icon.png"
/>
<label class="time">{{item.time}}"</label>
</view>
<view class="audio" wx:if="{{item.state==true}}" data-index="{{index}}" @tap="audioStop">
<image
class="ico"
src="../images/play-icon-gif.gif"
/>
<label class="time">{{item.time}}"</label>
</view>
</view>
</block>
<!-- 录音点击区域 -->
<view class="section">
<view class="input-view">
<button
class="audio-btn"
@longpress="handleRecordStart"
@touchend="handleRecordStop"
@touchmove="handleTouchMove"
>{{text}}</button>
</view>
</view>
</view>
</template>
<script>
import wepy from "wepy";
import qiniuUploader from "../common/qiniuUploader.js"; // 七牛Js
export default class Index extends wepy.page {
config = {
navigationBarTitleText: "语音测试",
navigationBarBackgroundColor: "#181b24",
navigationBarTextStyle: "white"
};
mixins = [];
data = {
showAudioState: false, // 是否显示底部按住说话状态
recorderManager: null, // 录音对象
innerAudioContext: null, // 音频对象
text: "按住 说话", // 按钮文本
options: {
duration: 10000, //指定录音的时长,单位 ms
sampleRate: 16000, //采样率
numberOfChannels: 1, //录音通道数
encodeBitRate: 96000, //编码码率
format: "mp3", //音频格式,有效值 aac/mp3
frameSize: 50 //指定帧大小,单位 KB
},
startPoint: {}, //记录长按录音开始点信息,用于后面计算滑动距离。
touchLengt: 0, // 上滑的距离
audioArr: [
{
src: "http://mp3.djwma.com/mp3/爆袭全站欢快节奏感觉那是杠杠滴.mp3",
time: 30,
state: false
},
{
src: "http://mp3.djwma.com/mp3/好听的欧美男声 网络流行.mp3",
time: 50,
state: false
}
] // 音频数据数组
};
computed = {};
methods = {
// 是否显示底部按住说话
showAudio () {
this.showAudioState = !this.showAudioState
this.$apply()
},
// 触摸按住说话进行录音
handleRecordStart(e) {
this.touchLengt = 0;
this.startPoint = e.touches[0];
this.text = "松开结束";
this.$apply();
this.recorderManager.start(this.options); //开始录音
this.recorderManager.onStart(() => {
console.log("已经开始了哦~");
});
wepy.showToast({
title: "正在录音,上划取消发送",
icon: "none",
duration: 60000 //先定义个60秒,后面可以手动调用wx.hideToast()隐藏
});
},
// 松开触摸按住说话进行判断是否发送或取消
handleRecordStop() {
if (this.touchLengt > 50) {
this.recorderManager.stop();
this.recorderManager.onStop(res => {
console.log("停止录音", res.tempFilePath);
});
this.text = "按住说话";
wepy.hideToast(); //结束录音、隐藏Toast提示框
} else {
this.recorderManager.stop();
this.recorderManager.onStop(res => {
const { tempFilePath } = res; // 获得临时音频链接
const duration = Math.ceil(res.duration / 1000) // 计算出时长
this.audioArr.push({ // 添加到音频展示列表中
src: tempFilePath,
time: duration,
state: false
});
this.setData({
audioArr: this.audioArr
});
// 以下是上传到服务器的代码,如七牛
// let audioURL = ''
// API.getQiniuToken().then(data => { // 七牛请求获得token校验
// qiniuUploader.upload(tempFilePath, (res) => {
// audioURL = 'https://...(这里写域名)' + res.key
// this.audioArr.push({
// src: audioURL,
// time: duration,
// state: false
// });
// this.setData({
// audioArr: this.audioArr
// });
// }, (error) => {
// console.error('error: ' + JSON.stringify(error));
// },
// {
// uptoken: data.token,
// region: 'ECN', // 华东区
// key: `slls/audio/${Math.random().toString(36).slice(2,10)}_${Date.parse(new Date())}.mp3` // 音频路径命名
// },
// // (progress) => {
// // console.log('上传进度', progress.progress)
// // console.log('已经上传的数据长度', progress.totalBytesSent)
// // console.log('预期需要上传的数据总长度', progress.totalBytesExpectedToSend)
// // },
// );
// })
});
this.text = "开始录音";
wepy.hideToast(); //结束录音、隐藏Toast提示框
}
},
// 监听触摸向上滑动距离
handleTouchMove(e) {
const moveLenght =
e.touches[e.touches.length - 1].clientY - this.startPoint.clientY; //移动距离
if (Math.abs(moveLenght) > 50) {
wepy.showToast({
title: "松开手指,取消发送",
icon: "none",
duration: 60000
});
this.touchLengt = Math.abs(moveLenght);
console.log(this.touchLengt);
} else {
wepy.showToast({
title: "正在录音,上划取消发送",
icon: "none",
duration: 60000
});
}
},
//音频播放
audioPlay(e) {
const index = e.currentTarget.dataset.index;
const audioArr = this.audioArr;
this.innerAudioContext.autoplay = true;
this.innerAudioContext.src = audioArr[index].src;
// 切换显示状态
for (let i = 0; i < audioArr.length; i++) {
audioArr[i].state = false;
}
audioArr[index].state = true;
this.innerAudioContext.play();
//开始监听
this.innerAudioContext.onPlay(() => {
this.setData({
audioArr: audioArr
});
});
//结束监听
this.innerAudioContext.onEnded(() => {
audioArr[index].state = false;
this.setData({
audioArr: audioArr
});
});
console.log("1", audioArr[index].src);
},
// 音频停止
audioStop(e) {
const index = e.currentTarget.dataset.index;
const audioArr = this.audioArr;
//切换显示状态
for (let i = 0; i < audioArr.length; i++) {
audioArr[i].state = false;
}
audioArr[index].state = false;
this.innerAudioContext.stop();
//开始监听
this.innerAudioContext.onStop(() => {
audioArr[index].state = false;
this.setData({
audioArr: audioArr
});
});
//结束监听
this.innerAudioContext.onEnded(() => {
audioArr[index].state = false;
this.setData({
audioArr: audioArr
});
});
console.log("2", audioArr);
}
};
events = {};
onLoad(options) {
this.recorderManager = wepy.getRecorderManager();
this.innerAudioContext = wepy.createInnerAudioContext();
this.$apply();
}
}
</script>以上就是主要代码,下面附上七牛上传的JS库代码(直接复制新建JS,放在你们喜欢的地方引入哟。。)
// created by gpake
(function() {
var config = {
qiniuRegion: '',
qiniuImageURLPrefix: '',
qiniuUploadToken: '',
qiniuUploadTokenURL: '',
qiniuUploadTokenFunction: null,
qiniuShouldUseQiniuFileName: false
}
module.exports = {
init: init,
upload: upload,
}
// 在整个程序生命周期中,只需要 init 一次即可
// 如果需要变更参数,再调用 init 即可
function init(options) {
config = {
qiniuRegion: '',
qiniuImageURLPrefix: '',
qiniuUploadToken: '',
qiniuUploadTokenURL: '',
qiniuUploadTokenFunction: null,
qiniuShouldUseQiniuFileName: false
};
updateConfigWithOptions(options);
}
function updateConfigWithOptions(options) {
if (options.region) {
config.qiniuRegion = options.region;
} else {
console.error('qiniu uploader need your bucket region');
}
if (options.uptoken) {
config.qiniuUploadToken = options.uptoken;
} else if (options.uptokenURL) {
config.qiniuUploadTokenURL = options.uptokenURL;
} else if(options.uptokenFunc) {
config.qiniuUploadTokenFunction = options.uptokenFunc;
}
if (options.domain) {
config.qiniuImageURLPrefix = options.domain;
}
config.qiniuShouldUseQiniuFileName = options.shouldUseQiniuFileName
}
function upload(filePath, success, fail, options, progress, cancelTask) {
if (null == filePath) {
console.error('qiniu uploader need filePath to upload');
return;
}
if (options) {
updateConfigWithOptions(options);
}
if (config.qiniuUploadToken) {
doUpload(filePath, success, fail, options, progress, cancelTask);
} else if (config.qiniuUploadTokenURL) {
getQiniuToken(function() {
doUpload(filePath, success, fail, options, progress, cancelTask);
});
} else if (config.qiniuUploadTokenFunction) {
config.qiniuUploadToken = config.qiniuUploadTokenFunction();
if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) {
console.error('qiniu UploadTokenFunction result is null, please check the return value');
return
}
doUpload(filePath, success, fail, options, progress, cancelTask);
} else {
console.error('qiniu uploader need one of [uptoken, uptokenURL, uptokenFunc]');
return;
}
}
function doUpload(filePath, success, fail, options, progress, cancelTask) {
if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) {
console.error('qiniu UploadToken is null, please check the init config or networking');
return
}
var url = uploadURLFromRegionCode(config.qiniuRegion);
var fileName = filePath.split('//')[1];
if (options && options.key) {
fileName = options.key;
}
var formData = {
'token': config.qiniuUploadToken
};
if (!config.qiniuShouldUseQiniuFileName) {
formData['key'] = fileName
}
var uploadTask = wx.uploadFile({
url: url,
filePath: filePath,
name: 'file',
formData: formData,
success: function (res) {
var dataString = res.data
if(res.data.hasOwnProperty('type') && res.data.type === 'Buffer'){
dataString = String.fromCharCode.apply(null, res.data.data)
}
try {
var dataObject = JSON.parse(dataString);
//do something
var imageUrl = config.qiniuImageURLPrefix + '/' + dataObject.key;
dataObject.imageURL = imageUrl;
// console.log(dataObject);
if (success) {
success(dataObject);
}
} catch(e) {
console.log('parse JSON failed, origin String is: ' + dataString)
if (fail) {
fail(e);
}
}
},
fail: function (error) {
console.error(error);
if (fail) {
fail(error);
}
}
})
uploadTask.onProgressUpdate((res) => {
progress && progress(res)
})
cancelTask && cancelTask(() => {
uploadTask.abort()
})
}
function getQiniuToken(callback) {
wx.request({
url: config.qiniuUploadTokenURL,
success: function (res) {
var token = res.data.uptoken;
if (token && token.length > 0) {
config.qiniuUploadToken = token;
if (callback) {
callback();
}
} else {
console.error('qiniuUploader cannot get your token, please check the uptokenURL or server')
}
},
fail: function (error) {
console.error('qiniu UploadToken is null, please check the init config or networking: ' + error);
}
})
}
function uploadURLFromRegionCode(code) {
var uploadURL = null;
switch(code) {
case 'ECN': uploadURL = 'https://up.qbox.me'; break;
case 'NCN': uploadURL = 'https://up-z1.qbox.me'; break;
case 'SCN': uploadURL = 'https://up-z2.qbox.me'; break;
case 'NA': uploadURL = 'https://up-na0.qbox.me'; break;
case 'ASG': uploadURL = 'https://up-as0.qbox.me'; break;
default: console.error('please make the region is with one of [ECN, SCN, NCN, NA, ASG]');
}
return uploadURL;
}
})();觉得好用的亲们。。点个赞留个言伐。我在博客园也是同个昵称哟