这是该系列的第二部,第一部完成了将MP4视频转换为PCM音频的工作。请参阅本文中的所有源代码。
从
对象存储服务调用
的第一篇转换的PCM文件仍存储在本地文件系统中。接下来,需要基于百度云的对象存储BOS服务,并将文件上传到云。
首先,必须开设BOS服务,获取相关的access-key,并构建相关的bucket。其次,参考官方API引入相关的maven依赖关系。最后,将本地文件上传到云存储桶,并将相关日志写入本地MySQL数据库。
开通服务
具体服务开通过程忽略不计,补充说明一下,百度云是语音转换免费的,所以BOS是收费的,但是非常便宜。以这个项目为例,总共320MB左右的文件总共不到1韩元,是白菜价格。
首先获取相关密钥,然后在properties中配置。
# 100度云BOS
依赖引入
具体引入的依赖性如下:
GroupIdcom.baidubce/groupId
工件dbce-Java-SDK/工件id
Version0.10.105/version中引入了许多第三方相关性,特别是在通过maven-helper插件分析相关性时,发现了许多相关性冲突,如log4j和commons-logging。
此外,该项目不直接依赖com.google.guava,但bce-java-sdk也会发生这种依赖冲突。为此,必须首先在bce-java-sdk中单独引入com.google.guava(不包括com.google.guava依赖关系)。
Dependency
groupid com . Google . guava/groupid
工件guava/工件id
version 17.0/版本
/dependency
文件上传程序编写
在此项目中,相关功能封装在BosFileService中。主要基于BosClient操作文件。
1、导入bucket下的所有文件:
Bo (Thomas _ bucket _ name)。get contents();2、根据文件密钥获取7天有效URL:
Bo (Thomas _ bucket _ name、objectkey、7 * 24 * 60 * 60);3、上传单个文件:
putobjectresponseresponse=bo(Thomas _ bucket _ name,key,());4、上传成功后返回eTag,并将其写入本地数据库。
()。etag (etag)。filename (filename)。build();5、目录中所有文件的批量上传:
Files.list (rootpath)。foreach (path-{
If(路径){
//递归遍历目录
count . add and get(batch upload file(path));
} else {
//上载文件
count . getandadd(upload file(path));
}
});文件上传到
录音转写服务调用
云BOS完成后,通过以下100度基于云AI的语音识别(录音/写入)服务提交离线转换作业。
开设免费语音战士服务,获取相关密钥。根据Restful API提交翻译作业。查询发送操作结果,并将发送成功结果保存到本地数据库中。首先,将应用ai的相关密钥写入属性文件,同时记录相关API的调用路径。
Thomas . ai . access-URL=https://AIP . Bai dubce . com/oauth/2.0/token
Thomas . ai . create-URL=https://AIP . Bai dubce . com/RPC/2 . 0/aasr/v 1/create
Thomas . ai . query-URL=https://AIP . Bai dubce . com/RPC/2 . 0/aasr/v 1/query此项目会将语音转换功能封装在SpeechService中
调用功能之前,必须根据上面的API密钥等获取access token并缓存token。
de>@Cacheable(value = "thomas-ai-token") public Optional<String> getAccessToken() { Map<String, String> params = new HashMap<>(2); ("client_id", API_KEY); ("client_secret", SECRET_KEY); //token请求URL String requestUrl = ACCESS_TOKEN_URL + "?grant_type=client_credentials" + "&client_id={client_id}" + "&client_secret={client_secret}"; String jsonStr = re(requestUrl, S, params); JSONObject jsonObject = JSON.parseObject(jsonStr); return O("access_token")); }为方便后续调用,封装了一个通用的doPost方法:
public Optional<ResponseEntity<String>> doPost(String url, boolean needToken, Map<String, Object> values) {
HttpHeaders headers = new HttpHeaders();
);
//将请求参数转换为json
String requestJson = JSON.toJSONString(values);
HttpEntity<String> request = new HttpEntity<>(requestJson, headers);
StringBuilder postUrl = new StringBuilder(url);
//需要追加token
if (needToken) {
Optional<String> opToken = getAccessToken();
if ()) {
//token存在则追加token
("?access_token=" + o());
} else {
log.error("没有获取到ACCESS TOKEN", opToken);
return O();
}
}
return O(), request, S));
}
基于录音文件URL,创建文本转写任务:
//调用模式参见
Map<String, Object> values = new HashMap<>(4);
values.put("speech_url", speechUrl);
values.put("format", "pcm");
values.put("pid", 1537);
values.put("rate", 16000);
return (CREATE_URL, true, values);
提交任务后,API返回的是taskId,该id必须保存,因为后续需要基于该id查询转写结果:
//解析返回结果中的taskid,能解析到即代表提交成功
String taskId = JSON.parseObjec().getBody()).getString("task_id");
将解析得到的id,保存到数据库中(本项目是基于JPA来进行数据库操作):
SpeechTaskInfo taskInfo = S()
.taskId(taskId)
.taskStatu)
.pcmKey())
.pcmUrl(url)
.build();
(taskInfo);
转录结果查询及存储
录音转写任务提交成功,最后一步就是等待离线任务运行完成,任务状态划分如下:
/** 转写中 */
Running,
/** 转写成功 */
Success,
/** 转写失败 */
Failure
在SpeechService中,封装了updateTaskResults方法,实现对任务的查询,并将转写成功的记录,记录到数据库中:
- 首先,遍历数据库中所有 Running状态的任务
- 其次,将所有任务taskId拼接后,调用任务运行结果批量查询API。
- 最后,判断API结果,并记录转写任务明细到数据库。
批量查询转录结果的调用非常简单:
// 技术文档
Map<String, Object> values = new HashMap<>(1);
values.put("task_ids", taskIds);
return (QUERY_URL, true, values);
处理API返回结果时,我们是采用的阿里巴巴的fastjson,实现将api返还的json对象,转换为java对象:
SpeechLogInfo logInfo = JSON.parseObjec().getBody(), S);
// 分析每个解析任务的运行状态
logIn()
.stream()
.filter(infoBean -> in().equal()))
.forEach(infoBean -> {
// 处理每个解析成功的任务
in().getDetailed_result().forEach(r -> {
// 遍历每个解析结果,并存储到数据库中
SpeechTaskResult result = S()
.taskId())
.beginTime() / 1000)
.endTime() / 1000)
.word("", r.getRes()))
.build();
(result);
});
// 更新任务为成功状态
Optional<SpeechTaskInfo> taskInfo = ());
if ()) {
SpeechTaskInfo info = ();
//设置为成功状态
in);
//保存到数据库
(info);
count.incrementAndGet();
}
});
补充说明下,推荐在idea中安装GsonFormat插件,实现基于json格式字符串,快速创建java对象SpeechLogInfo。
到此,我们将完成了将PCM文件上传到云端,并实现调用录音转写服务,解析得到文本内容,如果相关问题或疑问,欢迎给我留言。最后一篇,我们将实现读取数据库的转录结果,导出为一个完整的word文档,方便阅读和分享。