最近有寫一個(gè)自定義的語音輸入界面,大概流程與正常微信發(fā)語音的流程相仿.效果截圖如下:
下面貼代碼了:(代碼很長(zhǎng),可直接復(fù)制運(yùn)行,效果會(huì)比較直觀)
wxml:
<view class='voice-mask' wx:if="{{showVoiceMask}}" bindtap='hideVoiceMask'></view>
<view class='voice-enter-note' wx:if = "{{showVoiceMask && !startRecording}}"></view>
<image class='voice-enter-note-image' src='/pages/interaction/tempImage/voiceAnimation/appstore_ic_interaction_addMedia_voiceStart.png' wx:if = "{{showVoiceMask && !startRecording}}"></image>
<image src='/pages/interaction/tempImage/appstore_ic_interaction_addMedia_voiceMask_voiceButton.png' class='voice-button' wx:if="{{showVoiceMask}}" bindtouchstart="startRecording" bindtouchend="stopRecording" bindtouchmove="moveToCancle"></image>
<view class='voice-note' wx:if="{{showVoiceMask && startRecording}}">
</view>
<view class='record-voice-animations' wx:if="{{showVoiceMask && startRecording && !cancleRecording}}">
? ? <image src='/pages/interaction/tempImage/voiceAnimation/appstore_ic_interaction_addMedia_voiceAnimation_1.png' wx:if="{{recordAnimationNum===1}}"></image>
? <image src='/pages/interaction/tempImage/voiceAnimation/appstore_ic_interaction_addMedia_voiceAnimation_2.png' wx:if="{{recordAnimationNum===2}}"></image>
? <image src='/pages/interaction/tempImage/voiceAnimation/appstore_ic_interaction_addMedia_voiceAnimation_3.png' wx:if="{{recordAnimationNum===3}}"></image>
? <image src='/pages/interaction/tempImage/voiceAnimation/appstore_ic_interaction_addMedia_voiceAnimation_4.png' wx:if="{{recordAnimationNum===4}}"></image>
? <image src='/pages/interaction/tempImage/voiceAnimation/appstore_ic_interaction_addMedia_voiceAnimation_5.png' wx:if="{{recordAnimationNum===0}}"></image>
? </view>
<view class='cancle-record-voice' wx:if="{{showVoiceMask && startRecording && cancleRecording}}">
? ? <image src='/pages/interaction/tempImage/voiceAnimation/appstore_ic_interaction_addMedia_voiceAnimation_cancleVoice.png'></image>
wxss:
.voice-mask {
? position: fixed;
? top: 0rpx;
? left: 0rpx;
? width: 750rpx;
? height: 1230rpx;
? background-color: #000000;
? opacity: 0.6;
? display: flex;
? flex-direction: column;
? align-items: center;
? z-index: 10;
}
.voice-enter-note {
? position: absolute;
? width: 320rpx;
? height: 320rpx;
? left: 215rpx;
? top: 380rpx;
? z-index: 30;
? background-color: #000000;
? opacity: 0.5;
? border-radius: 15rpx;
}
.voice-enter-note-image {
? position: absolute;
? width: 292rpx;
? height: 207rpx;
? left: 229rpx;
? top: 436.5rpx;
? z-index: 40;
}
.voice-button {
? position: absolute;
? width: 160rpx;
? height: 160rpx;
? bottom: 90rpx;
? left: 295rpx;
? z-index: 20;
}
.voice-note {
? position: absolute;
? width: 320rpx;
? height: 320rpx;
? left: 215rpx;
? top: 380rpx;
? z-index: 30;
? background-color: #000000;
? opacity: 0.5;
? border-radius: 15rpx;
}
.record-voice-animations {
? position: absolute;
? width: 292rpx;
? height: 207rpx;
? left: 229rpx;
? top: 436.5rpx;
? z-index: 40;
}
.record-voice-animations image {
? width: 292rpx;
? height: 207rpx;
}
.cancle-record-voice {
? position: absolute;
? width: 292rpx;
? height: 207rpx;
? left: 229rpx;
? top: 436.5rpx;
? z-index: 40;
}
.cancle-record-voice image {
? width: 292rpx;
? height: 207rpx;
}
js:
// 開始錄音
? startRecording:function (e) {
? ? console.log('開始錄音');
? ? this.setData({
? ? ? selectType: 'voice',
? ? ? startRecording:true
? ? })
? ? this.startVoiceRecordAnimation();
? ? var that = this;
? ? const recorderManager = wx.getRecorderManager();
? ? recorderManager.start({
? ? ? format: 'mp3',
? ? });
? ? recorderManager.onStart(() => {
? ? ? console.log('recorder start')
? ? })
? },
? // 結(jié)束錄音
? stopRecording: function (e) {
? ? console.log('結(jié)束錄音');
? ? var that = this;
? ? const recorderManager = wx.getRecorderManager();
? ? recorderManager.stop();
? ? recorderManager.onStop((res) => {
? ? ? console.log('recorder stop', res)
? ? ? const { tempFilePath } = res;
? ? ? if (res.duration < 1000) {
? ? ? ? wx.showToast({
? ? ? ? ? title: '說話時(shí)間太短!',
? ? ? ? ? icon:'none'
? ? ? ? })
? ? ? ? this.stopVoiceRecordAnimation();
? ? ? ? that.setData({
? ? ? ? ? startRecording: false
? ? ? ? })
? ? ? ? return;
? ? ? }
? ? ? if (this.data.cancleRecording === false) {
? ? ? ? if (tempFilePath.length !== 0) {
? ? ? ? ? var recordLength = 0;
? ? ? ? ? if (res.duration / 1000 < 22) {
? ? ? ? ? ? recordLength = 160;
? ? ? ? ? } else {
? ? ? ? ? ? recordLength = (res.duration / 1000) / 60 * 440;
? ? ? ? ? }
? ? ? ? ? var recordTime = (res.duration / 1000).toFixed(0);
? ? ? ? ? console.log('recordLength' + recordLength);
? ? ? ? ? that.setData({
? ? ? ? ? ? recordingLength: recordLength,
? ? ? ? ? ? recordingTime: recordTime,
? ? ? ? ? ? voiceTempFilePath: tempFilePath,
? ? ? ? ? ? selectResource: true,
? ? ? ? ? ? showVoiceMask: false,
? ? ? ? ? ? startRecording: false
? ? ? ? ? })
? ? ? ? ? that.stopVoiceRecordAnimation();
? ? ? ? }
? ? ? } else {
? ? ? ? that.setData({
? ? ? ? ? selectResource: false,
? ? ? ? ? showVoiceMask: false,
? ? ? ? ? startRecording: false,
? ? ? ? ? cancleRecording:false
? ? ? ? })
? ? ? ? that.stopVoiceRecordAnimation();
? ? ? }
? ? })
? },
? //向上滑動(dòng)取消錄音
? moveToCancle: function (event) {
? ? let currentY = event.touches[0].pageY;
? ? if (this.data.lastVoiceYPostion !== 0) {
? ? ? if (currentY - this.data.lastVoiceYPostion < 0 && currentY < 470) {
? ? ? ? this.setData({
? ? ? ? ? cancleRecording:true
? ? ? ? })
? ? ? }
? ? }
? ? this.setData({
? ? ? lastVoiceYPostion: currentY
? ? })
? },
? //麥克風(fēng)幀動(dòng)畫?
? startVoiceRecordAnimation:function () {
? ? var that = this;
? ? //話筒幀動(dòng)畫?
? ? var i = 1;
? ? that.data.recordAnimationSetInter = setInterval(function () {
? ? ? i++;
? ? ? i = i % 5;
? ? ? that.setData({
? ? ? ? recordAnimationNum: i
? ? ? })
? ? }, 300);
? },
? // 停止麥克風(fēng)動(dòng)畫計(jì)時(shí)器
? stopVoiceRecordAnimation:function () {
? ? var that = this;
? ? clearInterval(that.data.recordAnimationSetInter);
? },
以上就是關(guān)于這個(gè)界面的實(shí)現(xiàn)代碼啦,寫的不好還請(qǐng)多多指教.
還有關(guān)于錄音之后播放音頻的相關(guān)問題,請(qǐng)查看我的上一篇帖子:微信小程序-InnerAudioContext()播放音頻
謝謝大家~~