2025年3月23日 星期日 甲辰(龙)年 月廿二 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Java

科大讯飞语音转文字开发(Java代码)

时间:03-10来源:作者:点击数:50
业务背景:公司要做一个语音转写的功能,自己开发的成本实在是有点大,直接调用科大讯飞的语音转写的接口,这是调用的具体步骤

科大讯飞的网址:

https://www.xfyun.cn/?ch=bdtg&b_scene_zt=1

当你注册成功以后,系统会把APPID和SecretKey给你,这两条数据你要记录一下,后面要用到

在这里插入图片描述

进入网址后,因为我用的是语音转写服务,所以,我先领取体验包

在这里插入图片描述

下面介绍一下用WebAPI的方式来进行的接口调用,首先可以先把接口的demo例子下载下来,集成到我们的项目中

在这里插入图片描述

下载完成后,是这几个类

在这里插入图片描述

主要介绍一下WebLfasrDemo这个类吧,咱们自己的业务逻辑代码是写在这里的

代码我已经粘贴出来了,上面注释都写的很详细,有一个地方没写,就是异常的处理,根据自己公司的规范自己处理一下就可以了

package com.atguigu.springboot.controller;

import java.io.BufferedWriter;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileWriter;

import java.io.IOException;

import java.security.SignatureException;

import java.util.Arrays;

import java.util.HashMap;

import java.util.Map;

import com.alibaba.fastjson.JSON;

import com.atguigu.springboot.ApiResultDto;

import com.atguigu.springboot.util.EncryptUtil;

import com.atguigu.springboot.util.HttpUtil;

import com.atguigu.springboot.util.SliceIdGenerator;

/**

  • 非实时转写webapi调用demo
  • 此demo只是一个简单的调用示例, 不适合用到实际生产环境中
  •  
  • @author white
  •  

/

public class WebLfasrDemo {

//这是调用的域名,建议加上https

public static final String LFASR_HOST = “http://raasr.xfyun.cn/api”;

/*

* 此处是设置你的sppid和sercet_key

* 需要在科大讯飞上申请

*/

public static final String APPID = “5e533011”;

public static final String SECRET_KEY = “f954b3f9121226a6c607dceb610b3c98”;

  • public static final String PREPARE = "/prepare";
  • public static final String UPLOAD = "/upload";
  • public static final String MERGE = "/merge";
  • public static final String GET_RESULT = "/getResult";
  • public static final String GET_PROGRESS = "/getProgress";
  • /**
  • * 文件分片大小,可根据实际情况调整
  • */
  • public static final int SLICE_SICE = 10485760;// 10M
  • public static void main(String[] args) {//D:\text.txt
  • /**
  • * 不用写成定时跑批,手动执行就可以,几天跑一次
  • */
  • //文件的总的目录
  • String basePath="D:\\aaa";
  • //先判断这个路径下的是文件还是文件夹
  • if(new File(basePath).isDirectory()) {
  • //获取文件夹下的所有的文件夹
  • String[] list=new File(basePath).list();
  • //遍历文件夹下的所有的文件
  • for (String wj : list) {
  • //测试用的输出,
  • System.out.println(wj);
  • //还得判断一下,是文件还是文件夹
  • if(new File(basePath+"\\"+wj).isDirectory()) {
  • String[] files=new File(basePath+"\\"+wj).list();
  • for (String file : files) {
  • //先判断一下,这个file是文件还是文件夹
  • System.out.println(file);
  • File audio = new File(basePath+"\\"+wj+"\\"+file);
  • //此处是这么拼接,第一层文件夹+第二层文件夹+文件名称
  • try (FileInputStream fis = new FileInputStream(audio)) {
  • // 预处理
  • String taskId = prepare(audio);
  • // 分片上传文件
  • int len = 0;
  • byte[] slice = new byte[SLICE_SICE];
  • SliceIdGenerator generator = new SliceIdGenerator();
  • while ((len =fis.read(slice)) > 0) {
  • // 上传分片
  • if (fis.available() == 0) {
  • slice = Arrays.copyOfRange(slice, 0, len);
  • }
  • uploadSlice(taskId, generator.getNextSliceId(), slice);
  • }
  • // 合并文件
  • merge(taskId);
  • // 轮询获取任务结果
  • while (true) {
  • try {
  • System.out.println("sleep a while Zzz" );
  • System.out.println("此处可以休眠一些时间");
  • Thread.sleep(20000);
  • } catch (InterruptedException e) {
  • e.printStackTrace();
  • }
  • ApiResultDto taskProgress = getProgress(taskId);
  • if (taskProgress.getOk() == 0) {
  • if (taskProgress.getErr_no() != 0) {
  • System.out.println("任务失败:" + JSON.toJSONString(taskProgress));
  • }
  • String taskStatus = taskProgress.getData();
  • if (JSON.parseObject(taskStatus).getInteger("status") == 9) {
  • System.out.println("任务完成!");
  • break;
  • }
  • System.out.println("任务处理中:" + taskStatus);
  • } else {
  • System.out.println("获取任务进度失败!");
  • }
  • }
  • //获取解析的结果
  • String result = getResult(taskId);
  • // 获取结果,测试解析的结果
  • System.out.println("\r\n\r\n转写结果: " + getResult(taskId));
  • //把解析的结果写入到文件中去
  • writeToText(wj,file, result);
  • /**
  • * 转写结果: [{"bg":"600","ed":"7530","onebest":"绿是阳春烟景,大块文章的底色,4月的林峦更是绿得鲜活!","speaker":"0"},{"bg":"7540","ed":"9150","onebest":"诶诗意盎然!","speaker":"0"}]
  • *
  • * 此处需要写业务逻辑
  • *
  • *
  • *
  • */
  • } catch (SignatureException e) {
  • e.printStackTrace();
  • } catch (FileNotFoundException e1) {
  • e1.printStackTrace();
  • } catch (IOException e1) {
  • e1.printStackTrace();
  • }
  • }
  • }
  • }
  • }
  • }
  • /**
  • * 获取每个接口都必须的鉴权参数
  • *
  • * @return
  • * @throws SignatureException
  • */
  • public static Map<String, String> getBaseAuthParam(String taskId) throws SignatureException {
  • Map<String, String> baseParam = new HashMap<String, String>();
  • String ts = String.valueOf(System.currentTimeMillis() / 1000L);
  • baseParam.put("app_id", APPID);
  • baseParam.put("ts", ts);
  • baseParam.put("signa", EncryptUtil.HmacSHA1Encrypt(EncryptUtil.MD5(APPID + ts), SECRET_KEY));
  • if (taskId != null) {
  • baseParam.put("task_id", taskId);
  • }
  • return baseParam;
  • }
  • /**
  • * 预处理
  • *
  • * @param audio 需要转写的音频
  • * @return
  • * @throws SignatureException
  • */
  • public static String prepare(File audio) throws SignatureException {
  • Map<String, String> prepareParam = getBaseAuthParam(null);
  • long fileLenth = audio.length();
  • prepareParam.put("file_len", fileLenth + "");
  • prepareParam.put("file_name", audio.getName());
  • prepareParam.put("slice_num", (fileLenth/SLICE_SICE) + (fileLenth % SLICE_SICE == 0 ? 0 : 1) + "");
  • /********************TODO 可配置参数********************/
  • // 转写类型

// prepareParam.put(“lfasr_type”, “0”);

// 开启分词

// prepareParam.put(“has_participle”, “true”);

// 说话人分离

// prepareParam.put(“has_seperate”, “true”);

// 设置多候选词个数

// prepareParam.put(“max_alternatives”, “2”);

// 是否进行敏感词检出

// prepareParam.put(“has_sensitive”, “true”);

// 敏感词类型

// prepareParam.put(“sensitive_type”, “1”);

// 关键词

// prepareParam.put(“keywords”, “科大讯飞,中国”);

/****************************************************/

  • String response = HttpUtil.post(LFASR_HOST + PREPARE, prepareParam);
  • if (response == null) {
  • throw new RuntimeException("预处理接口请求失败!");
  • }
  • ApiResultDto resultDto = JSON.parseObject(response, ApiResultDto.class);
  • String taskId = resultDto.getData();
  • if (resultDto.getOk() != 0 || taskId == null) {
  • throw new RuntimeException("预处理失败!" + response);
  • }
  • System.out.println("预处理成功, taskid:" + taskId);
  • return taskId;
  • }
  • /**
  • * 分片上传
  • *
  • * @param taskId 任务id
  • * @param slice 分片的byte数组
  • * @throws SignatureException
  • */
  • public static void uploadSlice(String taskId, String sliceId, byte[] slice) throws SignatureException {
  • Map<String, String> uploadParam = getBaseAuthParam(taskId);
  • uploadParam.put("slice_id", sliceId);
  • String response = HttpUtil.postMulti(LFASR_HOST + UPLOAD, uploadParam, slice);
  • if (response == null) {
  • throw new RuntimeException("分片上传接口请求失败!");
  • }
  • if (JSON.parseObject(response).getInteger("ok") == 0) {
  • System.out.println("分片上传成功, sliceId: " + sliceId + ", sliceLen: " + slice.length);
  • return;
  • }
  • System.out.println("params: " + JSON.toJSONString(uploadParam));
  • throw new RuntimeException("分片上传失败!" + response + "|" + taskId);
  • }
  • /**
  • * 文件合并
  • *
  • * @param taskId 任务id
  • * @throws SignatureException
  • */
  • public static void merge(String taskId) throws SignatureException {
  • String response = HttpUtil.post(LFASR_HOST + MERGE, getBaseAuthParam(taskId));
  • if (response == null) {
  • throw new RuntimeException("文件合并接口请求失败!");
  • }
  • if (JSON.parseObject(response).getInteger("ok") == 0) {
  • System.out.println("文件合并成功, taskId: " + taskId);
  • return;
  • }
  • throw new RuntimeException("文件合并失败!" + response);
  • }
  • /**
  • * 获取任务进度
  • *
  • * @param taskId 任务id
  • * @throws SignatureException
  • */
  • public static ApiResultDto getProgress(String taskId) throws SignatureException {
  • String response = HttpUtil.post(LFASR_HOST + GET_PROGRESS, getBaseAuthParam(taskId));
  • if (response == null) {
  • throw new RuntimeException("获取任务进度接口请求失败!");
  • }
  • return JSON.parseObject(response, ApiResultDto.class);
  • }
  • /**
  • * 获取转写结果
  • *
  • * @param taskId
  • * @return
  • * @throws SignatureException
  • */
  • public static String getResult(String taskId) throws SignatureException {
  • String responseStr = HttpUtil.post(LFASR_HOST + GET_RESULT, getBaseAuthParam(taskId));
  • if (responseStr == null) {
  • throw new RuntimeException("获取结果接口请求失败!");
  • }
  • ApiResultDto response = JSON.parseObject(responseStr, ApiResultDto.class);
  • if (response.getOk() != 0) {
  • throw new RuntimeException("获取结果失败!" + responseStr);
  • }
  • return response.getData();
  • }
  • /**
  • * @param OneDirectory 最外一层目录
  • * @param twoDirectory 第二层目录
  • * @param fileName 文件名称
  • * @param fileText 文件内容
  • */
  • public static void writeToText(String twoDirectory,String fileName,String fileText) {
  • //自己定义一个存放文件的目录,第二层目录就用解析的目录就可以了,话有文件的名称也用之前的就可以
  • String OneDirectory = "d:/writeToText";
  • if(fileName != null && !"".equals(fileName)) {
  • //处理一下文件名,只要前缀
  • String preFile = fileName.substring(0, fileName.lastIndexOf("."));
  • //先判断最外层的目录,如果没有就创建
  • File oneDir = new File(OneDirectory);
  • if(!oneDir.exists()) {
  • oneDir.mkdir();
  • }
  • //判断第二层目录是否存在,不存在则创建
  • File twoDir = new File(OneDirectory+"/"+twoDirectory);
  • if(!twoDir.exists()) {
  • twoDir.mkdirs();
  • }
  • //判断两层目录后,判断文件是否存在
  • File file = new File(OneDirectory+"/"+twoDirectory,preFile);
  • if(!file.exists()) {
  • try {
  • file.createNewFile();
  • } catch (IOException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • }
  • //向指定文件中写入文字
  • FileWriter fileWriter;
  • try {
  • fileWriter = new FileWriter(OneDirectory+"\\"+twoDirectory+"\\"+preFile);
  • //使用缓冲区比不使用缓冲区效果更好,因为每趟磁盘操作都比内存操作要花费更多时间。
  • //通过BufferedWriter和FileWriter的连接,BufferedWriter可以暂存一堆数据,然后到满时再实际写入磁盘
  • //这样就可以减少对磁盘操作的次数。如果想要强制把缓冲区立即写入,只要调用writer.flush();这个方法就可以要求缓冲区马上把内容写下去
  • BufferedWriter bufferedWriter=new BufferedWriter(fileWriter);
  • //向文件中写入数据
  • bufferedWriter.write(fileText);
  • bufferedWriter.close();
  • } catch (IOException e) {
  • // TODO Auto-generated catch block
  • e.printStackTrace();
  • }
  • }
  • }

}

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门