知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!
您當前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
小程序錄音功能實現(xiàn)
發(fā)表時間:2021-3-15
發(fā)布人:葵宇科技
瀏覽次數(shù):63
前言
在開發(fā)小程序過程中,有一個實現(xiàn)錄音功能并播放錄音,將錄音上傳至服務(wù)器的需求。開發(fā)過程中使用了Taro框架,錄音功能通過 Taro.getRecorderManager()
接口實現(xiàn),上傳錄音至服務(wù)器通過 Taro.uploadFile
接口實現(xiàn),播放錄音使用 Taro.createInnerAudioContext()
接口實現(xiàn)。下面就詳細介紹整個流程是如何實現(xiàn)的。
小程序錄音
首先獲取錄音管理器模塊:
const recorderManager = Taro.getRecorderManager();
復(fù)制代碼
在組件掛載完畢時注冊錄音監(jiān)聽事件:
useEffect(() => {
// 監(jiān)聽錄音開始
recorderManager.onStart(() => {
console.log('開始錄音');
});
// 監(jiān)聽錄音暫停
recorderManager.onPause(() => {
console.log('暫停錄音');
});
// 監(jiān)聽錄音繼續(xù)
recorderManager.onResume(() => {
console.log('繼續(xù)錄音');
});
// 監(jiān)聽錄音停止
recorderManager.onStop((res) => {
if (res.duration < 1000) {
Taro.showToast({
title: '錄音時間太短',
duration: 1000,
icon: 'none',
});
} else {
console.log('停止錄音');
fileUpload(res.tempFilePath);
}
});
recorderManager.onError(() => {
Taro.showToast({
title: '錄音失敗!',
duration: 1000,
icon: 'none',
});
});
}, []);
復(fù)制代碼
在錄音 onStop
的回調(diào)函數(shù)中,我們可以獲取到錄音的臨時地址 res.tempFilePath
,但這個地址是有有效期限的,所以我們需要將這個錄音上傳至服務(wù)器后臺,進行保存,后續(xù)才能正常使用。
onStop
回調(diào)函數(shù)中我們調(diào)用了 fileUpload
函數(shù)實現(xiàn)文件上傳, fileUpload
函數(shù)的實現(xiàn)如下:
const fileUpload = (tempFilePath) => {
Taro.uploadFile({
url: 'http://127.0.0.1:7001/record', // 服務(wù)器地址
filePath: tempFilePath,
name: 'file', // 這個隨便填
header: {
'content-type': 'multipart/form-data', // 格式必須是這個
Authorization: Taro.getStorageSync('token'),
},
// formData用于傳輸除文件以外的一些信息
formData: {
record_name: '朗誦作品',
poem_id: poemInfo.id,
category: poemInfo.category,
},
success: (res) => {
console.log(res);
const url = res.data;
playAudio(url); // 播放錄音
},
fail: (error) => {
console.log('failed!');
console.error(error);
},
});
};
復(fù)制代碼
需要注意的點是: header
中的 content-type
必須是 multipart/form-data
。
錄音事件的處理
第一次點擊 handleClick
就會觸發(fā)開始錄音,之后會通過當前狀態(tài)判斷是暫停錄音還是繼續(xù)錄音。 handleComplete
用于停止錄音。
const handleClick = () => {
const curPause = pause;
setPause(!curPause);
if (firstRecord) {
setfirstRecord(false);
recorderManager.start({
duration: 60000,
sampleRate: 44100,
numberOfChannels: 1,
encodeBitRate: 192000,
format: 'mp3',
frameSize: 50,
});
Taro.showToast({
title: '開始錄音',
duration: 1000,
icon: 'none',
});
} else {
if (curPause) {
recorderManager.pause(); // 暫停錄音
} else {
recorderManager.resume(); // 繼續(xù)錄音
}
}
};
const handleComplete = () => {
recorderManager.stop(); // 停止錄音
};
復(fù)制代碼
后臺實現(xiàn)錄音存儲并返回錄音地址
網(wǎng)上大多數(shù)博客都沒有涉及這塊內(nèi)容,下面就介紹一下如何實現(xiàn),后臺框架我用的是阿里的 egg.js
。
文件上傳需要配置的東西可見官方文檔: egg.js文件上傳 。我們這里使用它的第一種 File
模式來實現(xiàn)。
因為 egg.js
框架內(nèi)置了 Multipart
插件,可以解析上傳的 multipart/form-data
類型的數(shù)據(jù)。
首先,現(xiàn)在配置文件 config.default.js
中寫入 multipart
配置:
module.exports = (app) => {
const config = (exports = {});
...
config.multipart = {
mode: 'file',
fileSize: '50mb',
}
...
return {
...config,
...userConfig,
};
};
復(fù)制代碼
然后,在 router.js
中定義路由:
// 提交錄音
router.post('/record', auth, controller.record.postRecord);
復(fù)制代碼
在 controller
目錄下定義 record.js
文件寫入如下內(nèi)容:
const Controller = require('egg').Controller;
class RecordController extends Controller {
async postRecord() {
const { ctx } = this;
const file = ctx.request.files[0];
const { record_name, poem_id, category } = ctx.request.body;
const res = await ctx.service.record.postRecord(file, record_name, poem_id, category);
ctx.body = res;
}
}
module.exports = RecordController;
復(fù)制代碼
在 service
目錄下定義 record.js
寫入具體實現(xiàn):
const Service = require('egg').Service;
let OSS = require('ali-oss');
let aliInfo = {
// https://help.aliyun.com/document_detail/31837.html
region: 'oss-cn-guangzhou',
bucket: 'poem-mini-program',
accessKeyId: 'xxx', // 填入阿里云的accessKeyId
accessKeySecret: 'xxx', // 填入阿里云的accessKeySecret
};
let client = new OSS(aliInfo);
class RecordService extends Service {
async postRecord(file, record_name, poem_id, category) {
const url = await this.uploadOSS(file);
await this.updateRecord(url, record_name, poem_id, category);
return url;
}
async uploadOSS(file) {
const { ctx } = this;
let result;
try {
// 處理文件,比如上傳到云端
result = await client.put(file.filename, file.filepath);
} finally {
// 需要刪除臨時文件
await ctx.cleanupRequestFiles();
}
return result.url;
}
async updateRecord(url, record_name, poem_id, category) {
const { ctx } = this;
console.log('從ctx.locals中取openid');
console.log(ctx.locals.openid);
const openid = ctx.locals.openid;
// 將用戶信息記錄到數(shù)據(jù)庫中
const res = await ctx.model.Record.create({
record_name: record_name,
record_url: url,
poem_id: poem_id,
category: category,
openid: openid,
});
}
}
module.exports = RecordService;
復(fù)制代碼
這里需要注意的是:
- 需要注冊阿里云賬號,并在對象存儲那里新建一個存儲桶用于存放音頻,也就是云存儲的實現(xiàn)。
- 需要安裝
ali-oss
npm包,用于連接阿里云對象存儲。在后臺接收到前端上傳的臨時文件后,就會將音頻上傳至阿里云對象存儲中(client.put
)。
播放錄音
細心的小伙伴可以注意到在使用 Taro.uploadFile
接口上傳錄音后,在 success
回調(diào)中調(diào)用了 playAudio
函數(shù)用于播放音頻,接下來講一下播放音頻是如何實現(xiàn)的。
首先,使用 Taro.createInnerAudioContext
獲取 audio
的上下文對象:
const innerAudioText = Taro.createInnerAudioContext();
復(fù)制代碼
和錄音一樣,在組件掛載完成時,注冊監(jiān)聽事件:
useEffect(() => {
innerAudioText.onPlay(() => {
console.log('開始播放');
});
innerAudioText.onError((e) => {
console.log('播放異常');
console.log(e);
});
}, []);
復(fù)制代碼
在錄音文件上傳成功后,調(diào)用 playAudio
方法用于播放錄音:
const playAudio = (url) => {
innerAudioText.autoplay = true;
innerAudioText.src = http://www.wxapp-union.com/url;
};
復(fù)制代碼
在 src
被賦予值的時候,錄音就會開始播放。
總結(jié)
以上就是整個錄音功能和錄音播放功能實現(xiàn)的整個流程,如有疑問歡迎大家一起交流。
相關(guān)案例查看更多
相關(guān)閱讀
- 跳轉(zhuǎn)小程序
- 云南小程序開發(fā)
- 云南省建設(shè)廳網(wǎng)站
- 小程序表單
- 小程序開發(fā)公司
- 大理小程序開發(fā)
- 網(wǎng)站建設(shè)案例
- 百度小程序
- 云南科技公司
- 汽車報廢管理
- 昆明小程序設(shè)計
- 百度小程序開發(fā)公司
- 網(wǎng)站建設(shè)費用
- 昆明小程序公司
- 小程序密鑰
- 網(wǎng)站制作
- 云南網(wǎng)站建設(shè) 網(wǎng)絡(luò)服務(wù)
- 報廢車管理系統(tǒng)
- 云南網(wǎng)站建設(shè)方案 doc
- 昆明小程序開發(fā)聯(lián)系方式
- 云南小程序定制
- 云南百度小程序
- 網(wǎng)站建設(shè)專業(yè)品牌
- 網(wǎng)站建設(shè)哪家強
- 云南網(wǎng)站設(shè)計
- 網(wǎng)絡(luò)公司電話
- 企業(yè)網(wǎng)站
- 云南小程序開發(fā)哪家好
- 北京小程序開發(fā)
- web開發(fā)