Java 實(shí)現(xiàn)麥克風(fēng)自動(dòng)錄音
最近在研究語(yǔ)音識(shí)別,使用百度的sdk。發(fā)現(xiàn)只有識(shí)別的部分,而我需要保存音頻文件,并且實(shí)現(xiàn)當(dāng)有聲音傳入時(shí)自動(dòng)生成音頻文件。
先上代碼:
public class EngineeCore {
String filePath = "E:\\voice\\voice_cache.wav";
AudioFormat audioFormat;
TargetDataLine targetDataLine;
boolean flag = true;
private void stopRecognize() {
flag = false;
targetDataLine.stop();
targetDataLine.close();
}private AudioFormat getAudioFormat() {
float sampleRate = 16000;
// 8000,11025,16000,22050,44100
int sampleSizeInBits = 16;
// 8,16
int channels = 1;
// 1,2
boolean signed = true;
// true,false
boolean bigEndian = false;
// true,false
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}// end getAudioFormat
private void startRecognize() {
try {
// 獲得指定的音頻格式
audioFormat = getAudioFormat();
DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
// Create a thread to capture the microphone
// data into an audio file and start the
// thread running. It will run until the
// Stop button is clicked. This method
// will return after starting the thread.
flag = true;
new CaptureThread().start();
} catch (Exception e) {
e.printStackTrace();
} // end catch
}// end captureAudio method
class CaptureThread extends Thread {
public void run() {
AudioFileFormat.Type fileType = null;
File audioFile = new File(filePath);
fileType = AudioFileFormat.Type.WAVE;
//聲音錄入的權(quán)值
int weight = 2;
//判斷是否停止的計(jì)數(shù)
int downSum = 0;
ByteArrayInputStream bais = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
AudioInputStream ais = null;
try {
targetDataLine.open(audioFormat);
targetDataLine.start();
byte[] fragment = new byte[1024];
ais = new AudioInputStream(targetDataLine);
while (flag) {
targetDataLine.read(fragment, 0, fragment.length);
//當(dāng)數(shù)組末位大于weight時(shí)開(kāi)始存儲(chǔ)字節(jié)(有聲音傳入),一旦開(kāi)始不再需要判斷末位
if (Math.abs(fragment[fragment.length-1]) > weight || baos.size() > 0) {
baos.write(fragment);
System.out.println("守衛(wèi):"+fragment[0]+",末尾:"+fragment[fragment.length-1]+",lenght"+fragment.length);
//判斷語(yǔ)音是否停止
if(Math.abs(fragment[fragment.length-1])<=weight){
downSum++;
}else{
System.out.println("重置奇數(shù)");
downSum=0;
} //計(jì)數(shù)超過(guò)20說(shuō)明此段時(shí)間沒(méi)有聲音傳入(值也可更改)
if(downSum>20){
System.out.println("停止錄入");
break;
}
}
}
//取得錄音輸入流
audioFormat = getAudioFormat();
byte audioData[] = baos.toByteArray();
bais = new ByteArrayInputStream(audioData);
ais = new AudioInputStream(bais, audioFormat, audioData.length / audioFormat.getFrameSize());
//定義最終保存的文件名
System.out.println("開(kāi)始生成語(yǔ)音文件");
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, audioFile);
downSum = 0;
stopRecognize();
} catch (Exception e) {
e.printStackTrace();
} finally {
//關(guān)閉流
try {
ais.close();
bais.close();
baos.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
}// end run
}// end inner class CaptureThread
接下來(lái)測(cè)試
public static void main(String args[]) {
EngineeCore engineeCore = new EngineeCore();
engineeCore.startRecognize();
}
當(dāng)有較高的聲音傳入麥克風(fēng)時(shí),targetDataLine讀取的字節(jié)數(shù)組首位或末位絕對(duì)值會(huì)變大(位置取決于音頻格式中的一些參數(shù),如bigEndian)。傳入音量低,絕對(duì)值會(huì)變小
錄音開(kāi)始。從targetDataLine中讀取的音頻數(shù)據(jù)被保存在ByteArrayOutputStream中。一段時(shí)間音量一直低于權(quán)值時(shí),認(rèn)為無(wú)聲音傳入,結(jié)束錄音。從ByteArrayOutputStream取出字節(jié)數(shù)組,
轉(zhuǎn)為音頻保存在本地文件中。
注意:
從targetDataLine讀取的字節(jié)數(shù)組不能直接用于百度等語(yǔ)音識(shí)別,需要先轉(zhuǎn)為音頻文件,然后讀取音頻文件生成的字節(jié)數(shù)組,才可用于語(yǔ)音識(shí)別。
以上就是Java 實(shí)現(xiàn)麥克風(fēng)自動(dòng)錄音的詳細(xì)內(nèi)容,更多關(guān)于Java 麥克風(fēng)自動(dòng)錄音的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MyBatis動(dòng)態(tài)SQL中的trim標(biāo)簽的使用方法
這篇文章主要介紹了MyBatis動(dòng)態(tài)SQL中的trim標(biāo)簽的使用方法,需要的朋友可以參考下2017-05-05
SpringCloud URL重定向及轉(zhuǎn)發(fā)代碼實(shí)例
這篇文章主要介紹了SpringCloud URL重定向及轉(zhuǎn)發(fā)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
詳解spring Boot 集成 Thymeleaf模板引擎實(shí)例
本篇文章主要介紹了spring Boot 集成 Thymeleaf模板引擎實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
詳解Spring中Spel表達(dá)式和el表達(dá)式的區(qū)別
在?Java?開(kāi)發(fā)中,表達(dá)式語(yǔ)言是一種強(qiáng)大的工具,而SpEL?表達(dá)式與EL?表達(dá)式是我們常常遇到兩種表達(dá)式語(yǔ)言,下面我們就來(lái)看看它們的具體使用與區(qū)別吧2023-07-07
SpringQuartz集群支持JDBC存儲(chǔ)與分布式執(zhí)行的最佳實(shí)踐
SpringQuartz集群通過(guò)JDBC存儲(chǔ)和分布式執(zhí)行機(jī)制,有效解決了單點(diǎn)故障和擴(kuò)展性問(wèn)題,本文將詳細(xì)介紹SpringQuartz集群支持的實(shí)現(xiàn)原理、配置方法和最佳實(shí)踐,助力開(kāi)發(fā)者構(gòu)建穩(wěn)定可靠的分布式調(diào)度系統(tǒng),感興趣的朋友一起看看吧2025-04-04
java編程之基于SpringBoot框架實(shí)現(xiàn)掃碼登錄
本文將介紹基于SpringBoot + Vue + Android實(shí)現(xiàn)的掃碼登錄demo的總體思路,文中附含詳細(xì)示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09
使用JWT作為Spring?Security?OAuth2的token存儲(chǔ)問(wèn)題
這篇文章主要介紹了使用JWT作為Spring?Security?OAuth2的token存儲(chǔ),大家經(jīng)常使用的方法有兩種一種是使用JWT作為T(mén)oken傳遞,一種是使用Redis存儲(chǔ)Token,資源服務(wù)器本地訪問(wèn)Redis校驗(yàn)Token,需要的朋友可以參考下2021-12-12
jcrop 網(wǎng)頁(yè)截圖工具(插件)開(kāi)發(fā)
今天給大家介紹一下一個(gè)web 中經(jīng)常會(huì)用到的截圖(如:頭像等)工具,需要的朋友可以了解下2012-11-11
java 實(shí)例化類詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了java 實(shí)例化類詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03

