uniapp調(diào)用百度語(yǔ)音實(shí)現(xiàn)錄音轉(zhuǎn)文字功能
經(jīng)歷三天時(shí)間各種遇到困難 之后終于實(shí)現(xiàn)了這個(gè)功能,參照網(wǎng)上了許多文章 才找到一個(gè)能正常實(shí)現(xiàn)的方法,網(wǎng)上能找到的例子都不起作用,相信很多人困惑在這,為了避免別人出現(xiàn)這種情況,我分享我的代碼,絕對(duì)可用,包括 uniapp前端使用了recorderManager和java端調(diào)用百度語(yǔ)音轉(zhuǎn)文字,我相信很多人都很需要我寫(xiě)的東西,我只試驗(yàn)了安卓手機(jī),html5 + 里面
plus.speech這個(gè)方式就不要用了,不好用,調(diào)用百度的語(yǔ)音識(shí)別時(shí)在百度的管理控制臺(tái)會(huì)看到dev_id這個(gè)參數(shù)沒(méi)傳的錯(cuò)誤也沒(méi)找到添加這個(gè)參數(shù)的地方,所以在hbuildx里面當(dāng)前項(xiàng)目的app模塊配置這個(gè)地方不需要選
1.非常重要的一個(gè)步驟 manifest.json里面添加android.permission.RECORD_AUDIO這個(gè)權(quán)限,無(wú)論是想真機(jī)調(diào)試,由其是使用了自定義基座一定要在線(xiàn)打個(gè)包,讓基座包含這個(gè)權(quán)限然后在手機(jī)系統(tǒng) 里面應(yīng)用管理當(dāng)前這個(gè)app的權(quán)限管理里面必須要看到有錄音權(quán)限這一項(xiàng)
2.為了能夠在使用recorderManager在進(jìn)入要使用錄音功能的頁(yè)面會(huì)詢(xún)問(wèn)是否允許錄音這樣的權(quán)限,必須要使用recorderManager之前要調(diào)用一次硬件權(quán)限申請(qǐng)。這個(gè)在插件市場(chǎng)里面有一個(gè)https://ext.dcloud.net.cn/plugin?id=594 這個(gè)地址 App權(quán)限判斷和提示這樣的js,用于判斷或申請(qǐng)某個(gè)硬件權(quán)限使用的是native.js的功能。這個(gè)插件引入項(xiàng)目之后會(huì)在當(dāng)前項(xiàng)目目錄的js_sdk這樣一個(gè)文件夾。在里面會(huì)出現(xiàn)wa-permission文件 夾下面會(huì)有一個(gè)permission.js,
3.相關(guān)代碼
uniapp端代碼?
<view class="popup-content" >
<view>{{msg}}</view>
<view>你在說(shuō){{voicetext}}</view>
<button class="uni-btn" type="warn" @touchstart="startvoice" @touchend="endvoice">按說(shuō)語(yǔ)話(huà)松開(kāi)停止</button>
<button class="uni-btn" type="warn" @tap="playvoice" >播放錄音</button>
</view>
<script>
import permision from "@/js_sdk/wa-permission/permission.js"
const recorderManager = uni.getRecorderManager();
const innerAudioContext = uni.createInnerAudioContext();
export default {
data() {
return {
voicetext:"",
msg:"",
voicepath:""
}
},
onLoad() {
this.initaudio()
},
methods: {
async initaudio(){
//注意此處必須為 await 因?yàn)闀?huì)觸發(fā)異步事件,手機(jī)上會(huì)彈出權(quán)限申請(qǐng)對(duì)話(huà)框處理完才能走下一步錄音
let recordauth = await permision.requestAndroidPermission("android.permission.RECORD_AUDIO")
console.log("判斷有沒(méi)有錄音權(quán)限>>>>>>"+recordauth)
if(recordauth==1){
recorderManager.onStart((res)=>{
console.log("開(kāi)始 錄音>>>>>>>>>...")
});
recorderManager.onStop((res)=>{
console.log("recorderstop....res.tempFilePath>>>"+res.tempFilePath)
this.voicepath = res.tempFilePath
this.uploadvoicefile()
// 使用uni.uploadFile上傳到服務(wù)器上,此時(shí)是mp3格式
});
recorderManager.onError( (res)=> {
console.log('onError'+JSON.stringify(res));
});
}
}, //initaudio 方法結(jié)束
startvoice(){
console.log("開(kāi)始錄音")
recorderManager.start({
format:"mp3",
sampleRate: 16000 // 必須設(shè)置是后臺(tái)設(shè)置的參數(shù),不然百度語(yǔ)音識(shí)別不了
});
},
endvoice(){
console.log("結(jié)束錄音")
//注意為了避免說(shuō)話(huà)時(shí)間太短導(dǎo)致這個(gè)api出現(xiàn)bug要加一些延時(shí)
setTimeout(()=>{
recorderManager.stop()
},1000)
},
playvoice(){
console.log("點(diǎn)擊playvoice")
if (this.voicepath) {
console.log("播放聲音")
innerAudioContext.src = this.voicepath;
innerAudioContext.play();
}
},
uploadvoicefile(){
// this.msg = "調(diào)用java端服務(wù)文件路徑"+this.voicepath
uni.uploadFile({
url: 'http://ip:端口/uploadFile(java端接收文件接口名)',
filePath: this.voicepath,//錄音結(jié)束后返回的臨時(shí)路徑,
name: 'file',
formData: {
dev_id:1537 //中文帶標(biāo)點(diǎn)
},
success: (uploadFileRes) => {
let word = uploadFileRes.data
console.log("上傳音頻成功"+word);
},
fail: (res) => {
console.log("上傳音頻失敗"+JSON.stringify(res));
}
});
}
}
}
</script> ```
//注意uploadFile 的url屬性 這個(gè)地方ip不能是localhost或127,如果自已電腦啟動(dòng)java服務(wù)必須 是本機(jī)的真實(shí)ip如192.xxx這種,或者域名什么的,并且java端接口一定要支持跨域,很多人卡到這個(gè)ip上,我也是網(wǎng)上很難找到解決問(wèn)題的貼子
注意filePath這個(gè)路徑就是recorderManager的onStop事件就得到的_doc這種開(kāi)頭的路徑,不需要加什么file:不是像網(wǎng)上某些人說(shuō)的加這種東西
Java端
pom里面需要引用兩個(gè)包??
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.16.3</version>
</dependency>
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version>1.9.5.4</version>
</dependency>
``` import com.baidu.aip.speech.AipSpeech;
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
@RestController
@CrossOrigin(origins = "*")
public class BaiduSpeech {
//設(shè)置APPID/AK/SK
public static final String APP_ID = ""; //去百度語(yǔ)音服務(wù)申請(qǐng)
public static final String API_KEY = "";//去百度語(yǔ)音服務(wù)申請(qǐng)
public static final String SECRET_KEY = "";//去百度語(yǔ)音服務(wù)申請(qǐng)
@RequestMapping(value = "/uploadFile")
public String uploadFile( @RequestParam("dev_id") int dev_id, @RequestParam("file") MultipartFile file) throws Exception {
byte[] pcmbytedata = mp3Convert2pcm(file.getInputStream());
HashMap<String,Object> options = new HashMap<String,Object>();
options.put("dev_pid",dev_id);//
JSONObject jsonfrombaidu = basicBydata(pcmbytedata,"pcm",options);
JSONArray jsonArray = jsonfrombaidu.getJSONArray("result");
String result = jsonArray.getString(0);
System.out.println(result); //解析完的結(jié)果
return result;
}
// 獲取AipSpeech對(duì)象,建議單例使用
public static AipSpeech getClient() {
AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
// 可選:設(shè)置網(wǎng)絡(luò)連接參數(shù)
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
return client;
}
// 語(yǔ)音識(shí)別(來(lái)自文件)
public static JSONObject basicBydata(byte[] voicedata, String fileType,HashMap<String,Object> options) {
AipSpeech client = getClient();
return client.asr(voicedata, fileType, 16000, options);
}
/**
* MP3轉(zhuǎn)換PCM
* @param inputStream MP3輸入流
* @throws Exception
*/
public static byte[] mp3Convert2pcm(InputStream inputStream) throws Exception {
//轉(zhuǎn)換PCM audioInputStream 數(shù)據(jù)
AudioInputStream audioInputStream = getPcmAudioInputStream(inputStream);
byte[] pcmBytes = IOUtils.toByteArray(audioInputStream);
return pcmBytes;
}
/**
* 獲取PCM AudioInputStream 數(shù)據(jù)
* @param inputStream MP3輸入流
* @return AudioInputStream PCM輸入流
*/
private static AudioInputStream getPcmAudioInputStream(InputStream inputStream) {
AudioInputStream audioInputStream = null;
AudioFormat targetFormat = null;
try {
AudioInputStream in = null;
MpegAudioFileReader mp = new MpegAudioFileReader();
in = mp.getAudioInputStream(inputStream);
AudioFormat baseFormat = in.getFormat();
targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,
baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
audioInputStream = AudioSystem.getAudioInputStream(targetFormat, in);
} catch (Exception e) {
e.printStackTrace();
}
return audioInputStream;
}
} ```
到此這篇關(guān)于uniapp調(diào)用百度語(yǔ)音實(shí)現(xiàn)錄音轉(zhuǎn)文字功能的文章就介紹到這了,更多相關(guān)uniapp錄音轉(zhuǎn)文字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Javascript進(jìn)制轉(zhuǎn)換實(shí)例分析
這篇文章主要介紹了Javascript進(jìn)制轉(zhuǎn)換方法,實(shí)例分析了javascript實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換的技巧,需要的朋友可以參考下2015-05-05
JavaScript實(shí)現(xiàn)新年倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)新年倒計(jì)時(shí)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
利用JavaScript實(shí)現(xiàn)棧的數(shù)據(jù)結(jié)構(gòu)示例代碼
棧(stack)又名堆棧,它是一種運(yùn)算受限的線(xiàn)性表,下面這篇文章主要給大家介紹了關(guān)于利用JavaScript實(shí)現(xiàn)棧的數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-08-08
相關(guān)JavaScript在覽器中實(shí)現(xiàn)可視化的四種方式
這篇文章主要介紹了相關(guān)JavaScript在覽器中實(shí)現(xiàn)可視化的四種方式,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-09-09
微信 java 實(shí)現(xiàn)js-sdk 圖片上傳下載完整流程
這篇文章主要介紹了微信 java 實(shí)現(xiàn)js-sdk 圖片上傳下載完整流程的相關(guān)資料,需要的朋友可以參考下2016-10-10
javascript實(shí)現(xiàn)的右下角彈窗實(shí)例
這篇文章主要介紹了javascript實(shí)現(xiàn)的右下角彈窗,實(shí)例分析了javascript實(shí)現(xiàn)右下角彈窗的完整實(shí)現(xiàn)步驟與技巧,需要的朋友可以參考下2015-04-04
火狐下table中創(chuàng)建form導(dǎo)致兩個(gè)table之間出現(xiàn)空白
js加入form導(dǎo)致兩個(gè)table之間出現(xiàn)空白,還有另一種說(shuō)法在table中創(chuàng)建form表單是不符合DOM標(biāo)準(zhǔn)的,會(huì)導(dǎo)致post失效,以及js數(shù)據(jù)傳輸失效2013-09-09

