一、功能
1、录音功能:参考微信小程序官方文档【媒体 / 录音 / RecorderManager】
2、上传录音功能:微信小程序上传本地录音,只能通过选择好友的分享及自己的好友列表有分享过的录音,使用wx.uploadFile即可。
3、播放录音/音频功能:最简单的就是使用audio。
二、逻辑
1、录音:用户点击开始录音的图标之后,上面的红色计时开始计时,如果用户再次点击图标暂停时,判断录音的时长等是否达到要求,如果达到要求自动关闭popup(uView2)并且返回相关的数据,根据返回数据里面的音频url,调取上传文件接口,最后到页面显示audio。
2、上传本地录音:使用微信官方的wx.chooseMessageFile,拉起朋友列表,选择某个朋友点进去就可以查看到是否有audio,如果有点击后就可以调取上传文件接口,最后到页面显示audio
3、audio:audio的封面poster,名称name,作者author都可以根据自己的需求更改
4、缺点:这里我是直接使用audio偷了懒,其实微信官方文档有给音频模块的相关数据,比如wx.createInnerAudioContext();拿到相关实例,写一点代码就可以了【媒体 / 音频 / wx.createInnerAudioContext】
三、页面
1、audio
2、录音
四、代码
1、HTML
(1)、audio
<view class="audioModal" v-if="formTimbreData.audioUrl !== ''">
<view style="margin-bottom: 20rpx;">
<audio :src="formTimbreData.audioUrl" controls
:poster="根据自己的需求显示audio的封面海报" :name="name" :author="author">
</audio>
</view>
<view>
<u-button type="success" :customStyle="{ width: '150rpx' }"
text="重录声音" @click="reRecording()">
</u-button>
</view>
</view>
(2)、录音
<u-popup :show="showTimbre" @close="closeTimbre" :round="10" closeable>
<view style="padding: 20rpx;">
<view style="text-align: center;font-weight: 600;margin:20rpx 0">定制个人专属声音</view>
<view style="display: flex;flex-direction: column;align-items: center;">
<view style="font-size: 28rpx; color: red; margin-bottom: 10rpx;">
{{ timer.minutes }}:{{ timer.seconds }}.{{ timer.milliseconds }}
</view>
<image style="text-align: center;width: 100rpx; height: 100rpx;" :src="这里时红色的⚪图标,可以根据显示自己想要的图标" @click="toggleRecording()"/>
<view v-if="recording==true" style="margin-top: 20rpx;" >正在录音中...</view>
<view v-else-if="recording==false" style="margin-top: 20rpx;" >点击开始录音</view>
</view>
<button class="localBtn" @click="localTimbre()">上传本地音频</button>
</view>
</u-popup>
2、JS
(1)、基础代码
//data 数据
formTimbreData: {
audioUrl: '',
name: '',
sex: 1,
},
showTimbre: false,
showVideo: false,
shaking: false,
showNotify: false,
recording: false, // 标记录音状态
endRecording: false, // 标记录音结束
isTimbrePause:false,//录音是否播放
recorderManager: null, // 微信录音管理器
videoPath: '',// 选择的视频路径
options: {
duration: 60000,
sampleRate: 44100,
numberOfChannels: 1,
encodeBitRate: 192000,
format: 'aac',
frameSize: 50
},
timer: { minutes: "00", seconds: "00", milliseconds: "00" },
author: '',
// name为当天时间戳
name: "",
//menthods 方法
// 初始化录音管理器
initRecorder() {
if (!this.recorderManager) {
this.recorderManager = wx.getRecorderManager();
console.log("recorderManager", this.recorderManager);
this.recorderManager.onStop((res) => {
console.log("初始化录音管理器", res);
if(this.showTimbre==false){
return;
}
// 如果录音时长小于1秒,则提示重新录音
const { tempFilePath } = res;
console.log("tempFilePath", tempFilePath);
if (res.duration < 10000) {
wx.showToast({
title: "录音时长不能低于10秒",
icon: "none",
});
return;
}
//可以根据返回的数据做其他的限制
this.uploadRecording(tempFilePath);
});
}
},
// 切换录音状态
toggleRecording() {
console.log("切换录音状态this.recording", this.recording);
if (this.recording) {
this.stopRecording();
} else {
this.startRecording();
}
},
// 开始录音
startRecording() {
this.initRecorder();
this.recorderManager.start(this.options)
this.recorderManager.onStart((res) => {
console.log('录音中...',res);
});
this.resetTimer();
this.startTimer();
this.recording = true;
},
// 停止录音
stopRecording() {
console.log("this.recorderManager", this.recorderManager);
if (this.recorderManager) {
console.log("停止录音");
this.recorderManager.stop();
}
this.recording = false;
this.endRecording = true;
this.stopTimer();
console.log("this.showTimbre", this.showTimbre);
if(this.showTimbre==false){
wx.showToast({ title: "正在处理录音...", icon: "none" });
}
},
// 上传录音文件
uploadRecording(filePath) {
console.log("上传录音文件", filePath);
wx.uploadFile({
url: 这里写你的接口,
filePath,
name: "这里的名字根据你的接口要求写",
success: (res) => {
const { data } = JSON.parse(res.data);
this.formTimbreData.audioUrl = data.fullPath;
wx.showToast({ title: "上传成功", icon: "success" });
const time = new Date().getTime();
//设置audio的名字--使用时间显示
this.name = this.formatTimestampToDateTime(time);
console.log("this.name", this.name);
this.showTimbre=false;
},
fail: () => {
wx.showToast({ title: "上传失败", icon: "none" });
},
});
},
// 上传本地音频
localTimbre() {
wx.chooseMessageFile({
count: 1,
type: "file",
extension: ["mp3", "wav"],
success: (res) => {
console.log("选择音频文件", res);
// 格式只能是mp3/m4a/wav
if (res.tempFiles[0].path.indexOf(".mp3") == -1 &&
res.tempFiles[0].path.indexOf(".m4a") == -1
&& res.tempFiles[0].path.indexOf(".wav") == -1) {
wx.showToast({
title: "音频格式只能是mp3/m4a/wav",
icon: "none",
});
return;
}
//这里也可以根据返回的参数做其他限制
const { path } = res.tempFiles[0];
this.uploadRecording(path);
},
});
},
// 重录声音
reRecording(){
this.showTimbre=true;
this.resetTimer();
},
(2)、时间模块代码
// 录音时间
startTimer() {
let startTime = Date.now();
this.intervalId = setInterval(() => {
const elapsed = Date.now() - startTime;
const minutes = Math.floor(elapsed / 60000).toString().padStart(2, "0");
const seconds = Math.floor((elapsed % 60000) / 1000).toString().padStart(2, "0");
const milliseconds = Math.floor((elapsed % 1000) / 10).toString().padStart(2, "0");
this.timer = { minutes, seconds, milliseconds };
}, 10);
},
stopTimer() {
clearInterval(this.intervalId);
this.intervalId = null;
},
// 重置
resetTimer() {
this.timer = { minutes: "00", seconds: "00", milliseconds: "00" };
},
closeTimbre() {
// 如果还在录音中,停止录音
if (this.recording) {
this.stopRecording();
}
this.showTimbre=false;
this.recording = false;
this.endRecording = false;
this.stopTimer();
this.resetTimer();
},
// 格式化时间
formatTimestampToDateTime(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 补零处理
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},