前言
在工作之中,遇到这样的一个场景,在录制教学视频(只有系统声音)时,由于其他原因无法录制音频,后期需要进行视频音频的合成,当时的想法是调用各大厂的语音合成接口进行文字转音频的合成。音频有了,接下来就是把音频以及在视频中的时间点发给视频剪辑的同事,一个一个音频进行加入,最后发现这种重复的工作效率很低,就直接使用ffmpeg进行音视频处理,要求:视频按照指定时间点插入音频,添加片头片尾,添加背景音乐
一、调用接口语音合成生成音频文件
首先通过excel将所有的要合成的文本以及其对应的时间点读取,我的excel文件类似这样的。
使用POI将excel中的数据读取
public HashMap<String,List<String>> readXls(String path) throws Exception {
InputStream is = new FileInputStream(path);
// HSSFWorkbook 标识整个excel
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);
HashMap<String,List<String>> result = new HashMap<String, List<String>>();
int size = hssfWorkbook.getNumberOfSheets();
// 循环每一页,并处理当前循环页
HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0);
List<String> rowList = new ArrayList<String>();
List<String> rowList2 = new ArrayList<String>();
List<String> rowList3 = new ArrayList<String>();
// 处理当前页,循环读取每一行
for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
// HSSFRow表示行
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
int minColIx = hssfRow.getFirstCellNum();
int maxColIx = hssfRow.getLastCellNum();
// 遍历改行,获取处理每个cell元素
HSSFCell cell = hssfRow.getCell(0);
if (cell != null) {
rowList.add(getStringVal(cell));
}
HSSFCell cell2 = hssfRow.getCell(1);
if (cell2 != null) {
rowList2.add(getStringVal(cell2));
}
HSSFCell cell3 = hssfRow.getCell(2);
if (cell3 != null) {
rowList3.add(getStringVal(cell3));
}
}
result.put("time",rowList);
result.put("text",rowList2);
result.put("name",rowList3);
return result;
}
在读取数据后,使用阿里语音合成接口将这些文本,转换为音频文件,并且以时间点命名;
/**
* 通过阿里巴巴语音合成进行单线程语音合成
* @param list_time
* @param list_text
* @param list_name
* @throws InterruptedException
*/
public static void buildWavByAlibaba(List<String> list_time,List<String> list_text,List<String> list_name,String title) throws InterruptedException {
String appKey = ""; //在阿里巴巴控制台中输入自己的appKey
String id = ""; //自己的id
String secret = ""; //自己的秘钥
String url = ""; // 默认即可,默认值:wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1
AlibabaTts alibabaTts = new AlibabaTts(appKey, id, secret, url);
for(int i=0;i<list_time.size();i++){
alibabaTts.process(list_name.get(i).toString(),list_time.get(i).toString(),list_text.get(i).toString());
Thread.sleep(1000);
}
alibabaTts.process(list_name.get(