java MP3轉碼pcm 與 切割音訊
阿新 • • 發佈:2019-03-22
需求1: 呼叫語音聽寫介面, 類似百度要pcm格式音訊, 但是發現百度給的mp3轉pcm的demo轉出的音訊識別錯誤, 不知道我是不是copy錯哪裡了...
需求2: 大量音訊需要切分成多個小句子(參看jdk11 HttpClient 爬蟲中, 爬了***網的音訊, 其中有個精聽練習, 音訊分為多個段落,我需要按照這個段落切分成一個個小音訊)
以上這兩個需求我最終都選擇了ffmpeg來實現.
下載並安裝ffmpeg
windows10配置
下載, 配置環境變數到Path, cmd測試ffmpeg命令
CentOS配置
略, 百度一下
mp3轉pcm
/** * MP3轉換PCM檔案方法 * * @param mp3filePath 原始檔案路徑 * @param pcmFilePath 轉換檔案的儲存路徑 */ public static boolean mp32pcm(String mp3filePath, String pcmFilePath) { // String command = "ffmpeg -y -i mp3filePath -acodec pcm_s16le -f s16le -ac 1 -ar 16000 pcmFilePath"; try { String command1 = "ffmpeg -y -i "; String command2 = " -acodec pcm_s16le -f s16le -ac 1 -ar 16000 "; Runtime runtime = Runtime.getRuntime(); Process exec = runtime.exec(command1 + mp3filePath + command2 + pcmFilePath); exec.waitFor(); exec.destroy(); return true; } catch (Exception e) { System.out.println("MP3轉換PCM檔案 失敗"); } return false; }
-y |
允許覆蓋 |
-i test.mp3 |
原始檔 |
-acodec pcm_s16le |
編碼器 |
-f s16le |
強制檔案格式 |
-ac 2 |
雙聲道 |
-ar 16000 |
取樣率 |
音訊分割
音訊分割先需要知道在哪裡分割, 看看下圖
有每句話的起始時間, 可以使用爬蟲爬一下, 我的方法是使用爬到每個頁面的資訊, 先存到一個excel裡(使用easypoi), 過程就不寫了, 爬蟲的部分可以看看我上一篇jdk11 HttpClient 爬蟲中的第二部分, 匯出的檔案如下
然後讀取並解析這個檔案(easypoi), 輪詢, 切割, 就這麼easy
class KmcJtPojo {
@Excel(name = "名稱")
private String name;
@Excel(name = "父節點名稱")
private String parentName;
@Excel(name = "原文")
private String enText;
@Excel(name = "譯文")
private String cnText;
@Excel(name = "音訊檔案")
private String filePath;
@Excel(name = "開始表")
private Double startSecond;
@Excel(name = "結束秒")
private Double endSecond;
@Excel(name = "總秒")
private Double allSecond;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public String getEnText() {
return enText;
}
public void setEnText(String enText) {
this.enText = enText;
}
public String getCnText() {
return cnText;
}
public void setCnText(String cnText) {
this.cnText = cnText;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public Double getStartSecond() {
return startSecond;
}
public void setStartSecond(Double startSecond) {
this.startSecond = startSecond;
}
public Double getEndSecond() {
return endSecond;
}
public void setEndSecond(Double endSecond) {
this.endSecond = endSecond;
}
public Double getAllSecond() {
return allSecond;
}
public void setAllSecond(Double allSecond) {
this.allSecond = allSecond;
}
}
public class 本地音訊切割根據Excel {
@Test
public void cutAudio() {
String excelFilePath = "H:\\精聽匯出檔案.xls";
String audioFilePath= "H:\\jt_speak\\";
List<KmcJtPojo> list = ExcelImportUtil.importExcel(new File(excelFilePath), KmcJtPojo.class, new ImportParams());
List<KmcJtPojo> bigs = list.stream().filter(t -> StringUtils.isNotEmpty(t.getName())).collect(Collectors.toList());
//建立資料夾
bigs.forEach(t -> {
File file = new File(audioFilePath + t.getName().trim().replace(" ", "_"));
if (!file.exists()) {
file.mkdir();
}
});
//遍歷children節點 切割音訊
List<KmcJtPojo> children = list.stream().filter(t -> StringUtils.isNotEmpty(t.getParentName())).collect(Collectors.toList());
children.parallelStream().forEach(t -> {
try {
// String command1 = "ffmpeg -ss 00:00:00 -t 00:02:00 -i 輸入檔名.mp3輸出檔名_1.mp3 -y";
String command0 = "ffmpeg -ss ";
String command1 = " -t ";
String command2 = " -i ";
String command3 = " -c copy ";
String command4 = " -y";
Runtime runtime = Runtime.getRuntime();
String replace = t.getParentName().trim().replace(" ", "_") + ".mp3";
Process exec = runtime.exec(command0 + t.getStartSecond() + command1 + t.getAllSecond() +
command2 + audioFilePath+ replace + command3 + audioFilePath+ t.getFilePath() + command4);
exec.waitFor();
exec.destroy();
} catch (Exception e) {
System.out.println("MP3切割失敗" + t.getFilePath());
}
});
}
}