微信小程序實現錄音格式為mp3,並上傳到雲開發環境


前言

微信小程序中可以實現錄音的主要有wx.startRecord()和wx.getRecorderManager(),其中wx.startRecord()從微信開發者工具基礎庫1.6后停止維護,開始啟用更加強大的wx.getRecorderManager()。

一、關於wx.startRecord()的坑

wx.startRecord()使用還是相當容易的,微信官方示例便是使用wx.startRecord()。

1     wx.startRecord({
2       success(res) {
3         const tempFilePath = res.tempFilePath
4         console.log(res)
5       }
6     })
7     setTimeout(function () {
8       wx.stopRecord() // 結束錄音
9     }, 3000)

成功錄音的返回值為一個含有音頻臨時路徑的對象

1 errMsg: "startRecord:ok"
2 tempFilePath: "http://tmp/wx88e053d45b28e2cf.o6zAJs-nrru-YZpqRQeb-X8EzBfk.JVhmiR78K4oY2e7522995230f041a81c5967a4e1598c.silk"

 

 這個silk格式為加密格式,在真機上可以播放,上傳到服務器以后,其它用戶無法播放,只有上傳者可以播放。

如果要分享給別人,得先解密,再轉換為其它格式,網上的教程很多,但是比較麻煩

二、關於wx.getRecorderManager()的實戰解析

有一個項目,需要使用錄音,上傳到雲存儲后,分享給其它人。

  1 const recorderManager = wx.getRecorderManager()
  2 const backgroundAudio = wx.getBackgroundAudioManager()
  3 var util = require('../../utils/util.js');
  4 Page({
  5   data: {
  6     openRecordingdis: "block", //顯示錄機圖標
  7     shutRecordingdis: "none", //隱藏停止圖標
  8     recordingTimeqwe: 0, //錄音計時
  9     setInter: "", //錄音名稱
 10     soundUrl: ""
 11   },
 12 
 13   //錄音計時器
 14   recordingTimer: function() {
 15     var that = this;
 16     //將計時器賦值給setInter
 17     that.data.setInter = setInterval(
 18       function() {
 19         var time = that.data.recordingTimeqwe + 1;
 20         that.setData({
 21           recordingTimeqwe: time
 22         })
 23       }, 1000);
 24   },
 25 
 26 
 27   //開始錄音
 28   openRecording: function() {
 29     var that = this;
 30     wx.getSystemInfo({
 31       success: function(res) {
 32         that.setData({
 33           shutRecordingdis: "block",
 34           openRecordingdis: "none"
 35         })
 36       }
 37     })
 38     const options = {
 39       duration: 60000, //指定錄音的時長,單位 ms,最大為10分鍾(600000),默認為1分鍾(60000)
 40       sampleRate: 16000, //采樣率
 41       numberOfChannels: 1, //錄音通道數
 42       encodeBitRate: 96000, //編碼碼率
 43       format: 'mp3', //音頻格式,有效值 aac/mp3
 44       frameSize: 50, //指定幀大小,單位 KB
 45     }
 46     //開始錄音計時   
 47     that.recordingTimer();
 48     //開始錄音
 49     recorderManager.start(options);
 50     recorderManager.onStart(() => {
 51       console.log('。。。開始錄音。。。')
 52     });
 53     //錯誤回調
 54     recorderManager.onError((res) => {
 55       console.log(res);
 56     })
 57   },
 58 
 59   //結束錄音
 60   shutRecording: function() {
 61     var that = this;
 62     wx.getSystemInfo({
 63       success: function(res) {
 64         that.setData({
 65           shutRecordingdis: "none",
 66           openRecordingdis: "block"
 67         })
 68       }
 69     })
 70     recorderManager.stop();
 71     recorderManager.onStop((res) => {
 72       const that = this
 73       let timestamp = util.formatTime2(new Date());
 74       console.log('。。停止錄音。。', res.tempFilePath)
 75       const {
 76         tempFilePath
 77       } = res;
 78       //結束錄音計時  
 79       clearInterval(that.data.setInter);
 80       wx.cloud.uploadFile({
 81         cloudPath: "sounds/"+timestamp + '-' + this.randomNum(10000, 99999) + '.mp3',
 82         filePath: tempFilePath,
 83         // 成功回調
 84         success: res => {
 85           console.log('上傳成功', res)
 86           that.setData({
 87             soundUrl: res.fileID,
 88             // time: util.formatTime1(new Date())
 89           })
 90         },
 91       })
 92 
 93     })
 94   },
 95 
 96   //錄音播放
 97   recordingAndPlaying: function(eve) {
 98 
 99     // console.log(eve)
100     var tempsound = eve.currentTarget.dataset.soundid
101     tempsound = "https://6e65-newdj-d79af2-1257790921.tcb.qcloud.la/sounds"+this.midstr(tempsound)
102     // console.log(tempsound)
103     wx.playBackgroundAudio({
104       //播放地址
105       dataUrl: tempsound
106     })
107   },
108 
109   //生成從minNum到maxNum的隨機數
110   randomNum(minNum, maxNum) {
111     switch (arguments.length) {
112       case 1:
113         return parseInt(Math.random() * minNum + 1, 10);
114         break;
115       case 2:
116         return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
117         break;
118       default:
119         return 0;
120         break;
121     }
122   },
123   midstr(str) {
124     var strnum = str.lastIndexOf('/')
125     var ministr = str.substr(strnum)
126     return ministr
127   },
128 })

 

 1.首先聲明錄音組件

const recorderManager = wx.getRecorderManager()

2. 開始錄音的實現

 1   //開始錄音
 2   openRecording: function() {
 3     var that = this;
 4     wx.getSystemInfo({
 5       success: function(res) {
 6         that.setData({
 7           shutRecordingdis: "block",
 8           openRecordingdis: "none"
 9         })
10       }
11     })
12     const options = {
13       duration: 60000, //指定錄音的時長,單位 ms,最大為10分鍾(600000),默認為1分鍾(60000)
14       sampleRate: 16000, //采樣率
15       numberOfChannels: 1, //錄音通道數
16       encodeBitRate: 96000, //編碼碼率
17       format: 'mp3', //音頻格式,有效值 aac/mp3
18       frameSize: 50, //指定幀大小,單位 KB
19     }
20     //開始錄音計時   
21     that.recordingTimer();
22     //開始錄音
23     recorderManager.start(options);
24     recorderManager.onStart(() => {
25       console.log('。。。開始錄音。。。')
26     });
27     //錯誤回調
28     recorderManager.onError((res) => {
29       console.log(res);
30     })
31   },

 3. 結束錄音的實現

 1  //結束錄音
 2   shutRecording: function() {
 3     var that = this;
 4     wx.getSystemInfo({
 5       success: function(res) {
 6         that.setData({
 7           shutRecordingdis: "none",
 8           openRecordingdis: "block"
 9         })
10       }
11     })
12     recorderManager.stop();
13     recorderManager.onStop((res) => {
14       const that = this
15       let timestamp = util.formatTime2(new Date());
16       console.log('。。停止錄音。。', res.tempFilePath)
17       const {
18         tempFilePath
19       } = res;
20       //結束錄音計時  
21       clearInterval(that.data.setInter);
22       wx.cloud.uploadFile({
23         cloudPath: "sounds/"+timestamp + '-' + this.randomNum(10000, 99999) + '.mp3',
24         filePath: tempFilePath,
25         // 成功回調
26         success: res => {
27           console.log('上傳成功', res)
28           that.setData({
29             soundUrl: res.fileID,
30             // time: util.formatTime1(new Date())
31           })
32         },
33       })
34     })
35   },

 

第13行,錄音停止后,生成mp3格式的臨時文件,以jason格式提示,包含時長,文件大小和臨時文件名

1 {
2 duration: 2532
3 fileSize: 42268
4 tempFilePath: "http://tmp/wx88e053d45b28e2cf.o6zAJs-nrru-YZpqRQeb-X8EzBfk.73z3a3qIwC7yc13f32e3d179133ac77ca7851ec7d25b.durationTime=2532.mp3"
5 }

 

第15行,生成一個時間戳,用來生成文件名,

第22行,上傳至雲存儲,為了避免出現同時有多個進程上傳的極端情況,加了一個5位數的隨機數,

第29行,上傳成功后,將生成的雲文件ID返給data變量soundUrl

1 {
2 errMsg: "cloud.uploadFile:ok"
3 fileID: "cloud://newdj-d79af2.6e65-newdj-d79af2-1257790921/sounds/20190731162324-40454.mp3"
4 }

 

4.播放雲存儲里的錄音

 1   //錄音播放
 2   recordingAndPlaying: function(eve) {
 3     // console.log(eve)
 4     var tempsound = eve.currentTarget.dataset.soundid
 5     tempsound = "https://6e65-newdj-d79af2-1257790921.tcb.qcloud.la/sounds" + this.midstr(tempsound)
 6     // console.log(tempsound)
 7     wx.playBackgroundAudio({
 8       //播放地址
 9       dataUrl: tempsound
10     })
11   },

 

點擊播放按鈕時,把錄音的雲文件名傳遞到JS

1 <view bindtap='recordingAndPlaying' data-soundid="{{soundUrl}}">
2   <image class="progress_img" src='/images/play.png'></image>
3 </view>

 

data-soundid--->eve.currentTarget.dataset.soundid

然后第5行,將雲文件名,轉換為可供真機使用的https文件,midstr(tempsound)函數是取"/"之后的文件名,

"https://6e65-newdj-d79af2-1257790921.tcb.qcloud.la/sounds",為本項目所使用雲開發環境所對應的路徑

將"cloud://newdj-d79af2.6e65-newdj-d79af2-1257790921/sounds"替換后即可使用。 注意標黑部分,通過對兩個路徑的比對,可以找到cloud://轉https://的規律:

"cloud://雲環境ID."===>"https://",之后再加上".tcb.qcloud.la"即可

5.生成隨機數的通用函數

 1   //生成從minNum到maxNum的隨機數
 2   randomNum(minNum, maxNum) {
 3     switch (arguments.length) {
 4       case 1:
 5         return parseInt(Math.random() * minNum + 1, 10);
 6         break;
 7       case 2:
 8         return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
 9         break;
10       default:
11         return 0;
12         break;
13     }
14   },

 

6.取"/"右側的字符串

  midstr(str) {
    var strnum = str.lastIndexOf('/')
    var ministr = str.substr(strnum)
    return ministr
  },

 

 

三、WXML的實現

 1 <view class='progress_box' bindtap='openRecording' style="display:{{openRecordingdis}}">
 2   <view class="progress_bgs">
 3     <view class="progress_bg">
 4       <image class="progress_img" src='/images/record.png'></image>
 5     </view>
 6   </view>
 7 </view>
 8 <view class='progress_box' bindtap='shutRecording' style="display:{{shutRecordingdis}}">
 9   <view class="progress_bgs">
10     <view class="progress_bg">
11       <image class="progress_img" src='/images/stop.png'></image>
12     </view>
13   </view>
14 </view>
15 <view bindtap='recordingAndPlaying' data-soundid="{{soundUrl}}">
16   <image class="progress_img" src='/images/play.png'></image>
17 </view>

 

里面的圖片換成自己的,僅實現功能,沒有調播放按鈕的位置。

 

四、WXSS的實現

 1 .topicRecording {
 2   float: left;
 3   width: 40%;
 4   height: 100%;
 5   position: relative;
 6 }
 7  
 8  
 9 .progress_box {
10   width: 130rpx;
11   height: 130rpx;
12   margin-left: -65rpx;
13   position: absolute;
14   bottom: 0;
15   left: 50%;
16   display: flex;
17   align-items: center;
18   justify-content: center;
19   background: #ccc;
20   border-radius: 50%;
21 }
22  
23 .progress_bgs {
24   width: 114rpx;
25   height: 114rpx;
26   background: #fff;
27   border-radius: 50%;
28   margin: 9rpx;
29 }
30  
31 .progress_bg {
32   width: 106rpx;
33   height: 106rpx;
34   margin: 5rpx;
35   position: absolute;
36   background: #444;
37   border-radius: 50%;
38 }
39 
40 .progress_img {
41   width: 82rpx;
42   height: 82rpx;
43   border-radius: 50%;
44   margin: 12rpx;
45 }

 

 樣式借鑒下就好了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM