https://www.xfyun.cn/?ch=bdtg&b_scene_zt=1
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;
/**
/
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();
- }
- }
- }
-
}