Java工具類之音訊播放與mp3轉pcm-yellowcong
阿新 • • 發佈:2019-01-27
今天玩百度的api,我不知道為啥,就是識別不了俺的mp3,俺就怒了,啥JB破玩意,連個mp3都識別不了,還搞毛線,後來發現mp3的音訊包含檔案頭描述啥的,而pcm的音訊格式就純音訊了,沒有檔案頭資訊,百度的語音識別不支援mp3的,所以,我需要一個工具類,將mp3格式的音訊轉化為pcm的,這樣我就可以玩語音識別了。
依賴jar包
<dependency>
<groupId>com.googlecode.soundlibs</groupId>
<artifactId>mp3spi</artifactId>
<version >1.9.5.4</version>
</dependency>
工具程式碼
package com.yellowcong.baidu.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
/**
* 建立日期:2018年1月14日
* 建立時間:下午10:09:39
* 建立者 :yellowcong
* 機能概要:MP3轉PCM Java方式實現
* http://ai.baidu.com/forum/topic/show/496972
*/
public class AudioUtils {
private static AudioUtils audioUtils = null;
private AudioUtils(){}
//雙判斷,解決單利問題
public static AudioUtils getInstance(){
if(audioUtils == null){
synchronized (AudioUtils.class) {
if(audioUtils == null){
audioUtils = new AudioUtils();
}
}
}
return audioUtils;
}
/**
* MP3轉換PCM檔案方法
*
* @param mp3filepath 原始檔案路徑
* @param pcmfilepath 轉換檔案的儲存路徑
* @return
* @throws Exception
*/
public boolean convertMP32Pcm(String mp3filepath, String pcmfilepath){
try {
//獲取檔案的音訊流,pcm的格式
AudioInputStream audioInputStream = getPcmAudioInputStream(mp3filepath);
//將音訊轉化為 pcm的格式儲存下來
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, new File(pcmfilepath));
return true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
/**
* 播放MP3方法
*
* @param mp3filepath
* @throws Exception
*/
public void playMP3(String mp3filepath) throws Exception {
//獲取音訊為pcm的格式
AudioInputStream audioInputStream = getPcmAudioInputStream(mp3filepath);
// 播放
if (audioInputStream == null){
System.out.println("null audiostream");
return;
}
//獲取音訊的格式
AudioFormat targetFormat = audioInputStream.getFormat();
DataLine.Info dinfo = new DataLine.Info(SourceDataLine.class, targetFormat, AudioSystem.NOT_SPECIFIED);
//輸出裝置
SourceDataLine line = null;
try {
line = (SourceDataLine) AudioSystem.getLine(dinfo);
line.open(targetFormat);
line.start();
int len = -1;
// byte[] buffer = new byte[8192];
byte[] buffer = new byte[1024];
//讀取音訊檔案
while ((len = audioInputStream.read(buffer)) > 0) {
//輸出音訊檔案
line.write(buffer, 0, len);
}
// Block等待臨時資料被輸出為空
line.drain();
//關閉讀取流
audioInputStream.close();
//停止播放
line.stop();
line.close();
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("audio problem " + ex);
}
}
/**
* 建立日期:2018年1月14日<br/>
* 建立時間:下午9:53:14<br/>
* 建立使用者:yellowcong<br/>
* 機能概要:獲取檔案的音訊流
* @param mp3filepath
* @return
*/
private AudioInputStream getPcmAudioInputStream(String mp3filepath) {
File mp3 = new File(mp3filepath);
AudioInputStream audioInputStream = null;
AudioFormat targetFormat = null;
try {
AudioInputStream in = null;
//讀取音訊檔案的類
MpegAudioFileReader mp = new MpegAudioFileReader();
in = mp.getAudioInputStream(mp3);
AudioFormat baseFormat = in.getFormat();
//設定輸出格式為pcm格式的音訊檔案
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;
}
}
測試程式碼
package yellowcong.yuyin;
import org.junit.Test;
import com.yellowcong.baidu.utils.AudioUtils;
/**
* 建立日期:2018年1月14日
* 建立時間:下午10:09:39
* 建立者 :yellowcong
* 機能概要:MP3轉PCM Java方式實現
*/
public class TestAudioUtils {
//測試播放音訊
@Test
public void testPaly() throws Exception{
AudioUtils utils = AudioUtils.getInstance();
utils.playMP3("D:/xx.mp3");
}
@Test
public void testConvert() throws Exception{
AudioUtils utils = AudioUtils.getInstance();
utils.convertMP32Pcm("D:/xx.mp3", "D:/xx.pcm");
}
}
測試的播放音訊,我就不能截圖了,截圖截不出來聲音啊,但是轉化的圖片如下,大家可以瞅一眼。