背景
场景
设想一个场景,我们在会议中,现场录制了下来了会议音频。随后整理会议纪要时,需要重新人工听一遍,然后写成文字。
但是这个重复枯燥的事情能否由自动完成呢?
通过 录音文件识别
功能,即可以实现。
方案
之前使用过 讯飞听见
来完成这个功能。我们在上面上传一段语音,即可以自动识别成为文字。
但是讯飞听见只有 2 小时免费转写时长。在讯飞的免费时长使用完后,开始调研了一下别的产品。
阿里云录音文件识别
阿里云的录音文件识别功能,也可以完成相应的事情。
目前只支持 API 方式的调用,但是对于我们工程师来说,这都不是困难。API 调用可能还更方便一些。
注册阿里云账号
注册阿里云账号后,可以得到 AccessKey ID 和 AccessKey Secret。
之后就可以开通试用了。
pom 依赖
从官方文档中直接拿过来
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>3.5.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.49</version> </dependency>
Java 调用
依赖从官方文档中拿过来。
import com.alibaba.fastjson.JSONObject; import com.aliyuncs.CommonRequest; import com.aliyuncs.CommonResponse; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.http.MethodType; import com.aliyuncs.profile.DefaultProfile; public class FileTransJavaDemo { /** * 地域ID 常量内容,请勿改变 */ public static final String REGIONID = "cn-shanghai"; public static final String ENDPOINTNAME = "cn-shanghai"; public static final String PRODUCT = "nls-filetrans"; public static final String DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"; public static final String API_VERSION = "2018-08-17"; public static final String POST_REQUEST_ACTION = "SubmitTask"; public static final String GET_REQUEST_ACTION = "GetTaskResult"; /** * 参数设置Key 常量内容,请勿改变 */ public static final String KEY_APP_KEY = "app_key"; public static final String KEY_FILE_LINK = "file_link"; public static final String KEY_TASK = "Task"; public static final String KEY_TASK_ID = "TaskId"; public static final String KEY_STATUS_TEXT = "StatusText"; public static void main(String args[]) throws Exception { if (args.length < 3) { System.err.println("FileTransJavaDemo need params: <AccessKey Id> <AccessKey Secret> <app-key>"); } final String accessKeyId = args[0]; final String accessKeySecret = args[1]; final String appKey = args[2]; /** * 阿里云鉴权client */ IAcsClient client; // 设置endpoint DefaultProfile.addEndpoint(ENDPOINTNAME, REGIONID, PRODUCT, DOMAIN); // 创建DefaultAcsClient实例并初始化 DefaultProfile profile = DefaultProfile.getProfile(REGIONID, accessKeyId, accessKeySecret); client = new DefaultAcsClient(profile); /** * 创建CommonRequest 设置请求参数 */ CommonRequest postRequest = new CommonRequest(); // 设置域名 postRequest.setDomain(DOMAIN); // 设置API的版本号,格式为YYYY-MM-DD postRequest.setVersion(API_VERSION); // 设置action postRequest.setAction(POST_REQUEST_ACTION); // 设置产品名称 postRequest.setProduct(PRODUCT); /** * 设置录音文件识别请求参数,以JSON字符串的格式设置到请求的Body中 */ JSONObject taskObject = new JSONObject(); // 设置app_key taskObject.put(KEY_APP_KEY, appKey); // 设置音频文件访问链接 taskObject.put(KEY_FILE_LINK, "http://aliyun-nls.oss.aliyuncs.com/asr/fileASR/examples/nls-sample.wav"); String task = taskObject.toJSONString(); // 设置以上JOSN字符串为Body参数 postRequest.putBodyParameter(KEY_TASK, task); // 设置为POST方式的请求 postRequest.setMethod(MethodType.POST); /** * 提交录音文件识别请求 */ // 获取录音文件识别请求任务的ID,以供识别结果查询使用 String taskId = ""; CommonResponse postResponse = client.getCommonResponse(postRequest); if (postResponse.getHttpStatus() == 200) { JSONObject result = JSONObject.parseObject(postResponse.getData()); String statusText = result.getString(KEY_STATUS_TEXT); if (statusText.equals("SUCCESS")) { System.out.println("录音文件识别请求成功响应: " + result.toJSONString()); taskId = result.getString(KEY_TASK_ID); } else { System.err.println("录音文件识别请求失败: " + postResponse.getData()); return; } } else { System.err.println("录音文件识别请求失败,Http错误码:" + postResponse.getHttpStatus()); System.err.println("录音文件识别请求失败响应:" + postResponse.getData()); return; } /** * 创建CommonRequest 设置任务ID */ CommonRequest getRequest = new CommonRequest(); // 设置域名 getRequest.setDomain(DOMAIN); // 设置API版本 getRequest.setVersion(API_VERSION); // 设置action getRequest.setAction(GET_REQUEST_ACTION); // 设置产品名称 getRequest.setProduct(PRODUCT); // 设置任务ID为查询参数 getRequest.putQueryParameter(KEY_TASK_ID, taskId); // 设置为GET方式的请求 getRequest.setMethod(MethodType.GET); /** * 提交录音文件识别结果查询请求 * 以轮询的方式进行识别结果的查询,直到服务端返回的状态描述为“SUCCESS”、“SUCCESS_WITH_NO_VALID_FRAGMENT”,或者为错误描述,则结束轮询。 */ String statusText = ""; while (true) { CommonResponse getResponse = client.getCommonResponse(getRequest); if (getResponse.getHttpStatus() != 200) { System.err.println("识别结果查询请求失败,Http错误码:" + getResponse.getHttpStatus()); System.err.println("识别结果查询请求失败:" + getResponse.getData()); break; } JSONObject result = JSONObject.parseObject(getResponse.getData()); System.out.println("识别查询结果:" + result.toJSONString()); statusText = result.getString(KEY_STATUS_TEXT); if (statusText.equals("RUNNING") || statusText.equals("QUEUEING")) { // 继续轮询 Thread.sleep(3000); } else { break; } } if (statusText.equals("SUCCESS") || statusText.equals("SUCCESS_WITH_NO_VALID_FRAGMENT")) { System.out.println("录音文件识别成功!"); } else { System.err.println("录音文件识别失败!"); } } }
实际调用
录音文件识别请求成功响应:
{ "TaskId": "64d8d379cd4c11e8b422f1057c7axxxx", "RequestId": "EBBFC8E8-16BC-4220-84D3-C2DB1B7Dxxxx", "StatusText": "SUCCESS", "StatusCode": 21050000 }
识别查询结果:
{ "TaskId": "64d8d379cd4c11e8b422f1057c7axxxx", "RequestId": "A378A43D-97AD-4314-BD52-D3865CD1xxxx", "StatusText": "RUNNING", "BizDuration": 0, "StatusCode": 21050001 }
识别查询结果:
{ "TaskId": "64d8d379cd4c11e8b422f1057c7axxxx", "RequestId": "ECB8FB0E-2503-45CD-BF17-FF76BB98xxxx", "StatusText": "SUCCESS", "BizDuration": 3574, "SolveTime": 1539258996543, "StatusCode": 21050000, "Result": { "Sentences": [{ "EndTime": 3574, "SilenceDuration": 0, "BeginTime": 470, "Text": "明天是周一天气挺好的", "ChannelId": 0, "SpeechRate": 193, "EmotionValue": 6.0 }, { "EndTime": 3574, "SilenceDuration": 0, "BeginTime": 470, "Text": "明天是周一天气挺好的", "ChannelId": 1, "SpeechRate": 193, "EmotionValue": 6.0 }] } }
录音文件识别成功!
注意,结果中的两句话,并不是识别重复了,而是两个不同的 ChannelId 的结果是一样的而已。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于