超大文件调用讯飞语音听写解决方案
生活随笔
收集整理的這篇文章主要介紹了
超大文件调用讯飞语音听写解决方案
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
需求
2019年6月20日 1,案場銷售和客服的談話錄音,需要將其翻譯成文字,入庫,后臺審核。需求分析
技術(shù)選型
訊飛接口語音有方言
1,因?yàn)榉窖缘拇嬖?#xff0c;只能使用語音聽寫接口。拿到的是語音文件
1,所以只能使用WebAPI方式調(diào)用訊飛接口。訊飛語音聽寫有音頻格式限制
1,所以只能使用ffmpeg進(jìn)行格式轉(zhuǎn)換 2,[下載地址](http://www.ffmpeg.org/download.html) 3,[基本使用](https://doc.xfyun.cn/rest_api/%E9%9F%B3%E9%A2%91%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E.html)接口對語音時(shí)長限制60秒內(nèi)
1,將轉(zhuǎn)換格式后的文件根據(jù)時(shí)長進(jìn)行分片。 2,采用多線程將分割后的文件交由訊飛處理,等待返回結(jié)果(語音聽寫沒有異步接口)。 3,根據(jù)分片計(jì)算每個(gè)線程需要處理的分片數(shù)量,采用分頁思路,決定開啟多少線程。 4,將處理結(jié)果放入一個(gè)并發(fā)集合中(生產(chǎn)環(huán)境在redis中) 5,如果當(dāng)期分片失敗,或者異常,使用補(bǔ)償機(jī)制,默認(rèn)5次,如果還失敗手動(dòng)補(bǔ)償。 6,將結(jié)果集進(jìn)行拼接格式化。實(shí)現(xiàn)思路
1,用戶分片上傳文件到服務(wù)器,服務(wù)器進(jìn)行合并。 2,文件合并完成后生成一條數(shù)據(jù),將id放入MQ中。 3,消費(fèi)者接收到MQ中的消息,將服務(wù)器文件下載到當(dāng)前機(jī)器,進(jìn)行格式化,分片操作。 4,分片完成后進(jìn)行任務(wù)分配。 5,獲取執(zhí)行結(jié)果,進(jìn)行合并,并將其更新到數(shù)據(jù)庫中。總結(jié)
1,典型的生產(chǎn)-消費(fèi)模式 2,使用MQ原因,因?yàn)椴⒉皇侵骶€業(yè)務(wù),不能讓其占用了太多內(nèi)存和帶寬,所以采用單線程處理。 3,對大文件進(jìn)行先分后合中間采用多線程提高效率。 4,采用補(bǔ)償機(jī)制,提高結(jié)果的可靠性,最后提供手動(dòng)補(bǔ)償,也是防止程序補(bǔ)償失敗問題。實(shí)現(xiàn)代碼
1,文件轉(zhuǎn)換工具類
package com.itpengwei.util;import java.io.File; import java.io.InputStreamReader; import java.io.LineNumberReader;/*** @author 彭偉* @Date 2019/6/21 15:50* 文件格式轉(zhuǎn)換工具類*/ public class Video2Voice {// private static Logger logger = Logger.getLogger(Video2Voice.class);/*** 將音頻文件轉(zhuǎn)16k的pcm文件** @param fileName* @return 音頻文件名* @throws Exception*/public static String transform(String fileName) throws Exception {File file = new File(fileName);if (!file.exists()) {System.out.println("文件不存在:" + fileName);throw new RuntimeException("文件不存在:" + fileName);}// 訊飛現(xiàn)在支持pcm,wav的語音流文件String name = fileName.substring(0, fileName.lastIndexOf(".")) + ".pcm";System.out.println("獲取到的音頻文件:" + name);// 提取視頻中的音頻文件。 根據(jù)訊飛要求設(shè)置采樣率, 位數(shù),File ffmpegPath = new File("D:\\軟件\\ffmpeg-20190620-86f04b9-win64-static\\bin\\ffmpeg.exe");String cmd = ffmpegPath + " -y -i " + fileName + " -acodec pcm_s16le -f s16le -ac 1 -ar 16000 " + name;System.out.println("命令===》" + cmd);File tagret = new File(name);if (tagret.exists()) {System.out.println("文件存在,刪除文件,進(jìn)行覆蓋操作");tagret.delete();}Process process = Runtime.getRuntime().exec(cmd);// 執(zhí)行命令I(lǐng)nputStreamReader ir = new InputStreamReader(process.getInputStream());LineNumberReader input = new LineNumberReader(ir);String line;// 輸出結(jié)果,需要有這部分代碼, 否則不能生產(chǎn)抽取的音頻文件while ((line = input.readLine()) != null) {System.out.println(line);}process.destroy();return name;}public static void main(String[] args) {try {String transform = transform("C:\\Users\\彭偉\\Desktop\\temp\\java.mp3");} catch (Exception e) {e.printStackTrace();}} }2,文件分片工具類
package com.itpengwei.xunfei;import com.itpengwei.util.Video2Voice; import it.sauronsoftware.jave.Encoder; import it.sauronsoftware.jave.MultimediaInfo;import java.io.*; import java.net.URL; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.List;/*** @author 彭偉* @Date 2019/6/21 15:50* 文件操作工具類*/ public class FileUtil {/*** 讀取文件內(nèi)容為二進(jìn)制數(shù)組** @param filePath* @return* @throws IOException*/public static byte[] read(String filePath) throws IOException {InputStream in = new FileInputStream(filePath);byte[] data = inputStream2ByteArray(in);in.close();return data;}/*** 流轉(zhuǎn)二進(jìn)制數(shù)組** @param in* @return* @throws IOException*/private static byte[] inputStream2ByteArray(InputStream in) throws IOException {ByteArrayOutputStream out = new ByteArrayOutputStream();byte[] buffer = new byte[1024 * 4];int n = 0;while ((n = in.read(buffer)) != -1) {out.write(buffer, 0, n);}return out.toByteArray();}/*** 保存文件** @param filePath* @param fileName* @param content*/public static void save(String filePath, String fileName, byte[] content) {try {File filedir = new File(filePath);if (!filedir.exists()) {filedir.mkdirs();}File file = new File(filedir, fileName);OutputStream os = new FileOutputStream(file);os.write(content, 0, content.length);os.flush();os.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}/*** @param sourcefile 源文件路徑* @param targetfile 目標(biāo)文件路徑* @param start 開始時(shí)間* @param end 結(jié)束時(shí)間* @param postname 文件后綴名* @return*/public static boolean cut(String sourcefile, String targetfile, int start, int end, String postname) {try {if (!sourcefile.toLowerCase().endsWith(postname) || !targetfile.toLowerCase().endsWith(postname)) {return false;}File wav = new File(sourcefile);if (!wav.exists()) {return false;}long t1 = getTimeLen(wav); //總時(shí)長(秒)if (start < 0 || end <= 0 || start >= t1 || end > t1 || start >= end) {return false;}FileInputStream fis = new FileInputStream(wav);long wavSize = wav.length() - 44; //音頻數(shù)據(jù)大小(44為128kbps比特率wav文件頭長度)long splitSize = (wavSize / t1) * (end - start); //截取的音頻數(shù)據(jù)大小long skipSize = (wavSize / t1) * start; //截取時(shí)跳過的音頻數(shù)據(jù)大小int splitSizeInt = Integer.parseInt(String.valueOf(splitSize));int skipSizeInt = Integer.parseInt(String.valueOf(skipSize));ByteBuffer buf1 = ByteBuffer.allocate(4); //存放文件大小,4代表一個(gè)int占用字節(jié)數(shù)buf1.putInt(splitSizeInt + 36); //放入文件長度信息byte[] flen = buf1.array(); //代表文件長度ByteBuffer buf2 = ByteBuffer.allocate(4); //存放音頻數(shù)據(jù)大小,4代表一個(gè)int占用字節(jié)數(shù)buf2.putInt(splitSizeInt); //放入數(shù)據(jù)長度信息byte[] dlen = buf2.array(); //代表數(shù)據(jù)長度flen = reverse(flen); //數(shù)組反轉(zhuǎn)dlen = reverse(dlen);byte[] head = new byte[44]; //定義wav頭部信息數(shù)組fis.read(head, 0, head.length); //讀取源wav文件頭部信息for (int i = 0; i < 4; i++) { //4代表一個(gè)int占用字節(jié)數(shù)head[i + 4] = flen[i]; //替換原頭部信息里的文件長度head[i + 40] = dlen[i]; //替換原頭部信息里的數(shù)據(jù)長度}byte[] fbyte = new byte[splitSizeInt + head.length]; //存放截取的音頻數(shù)據(jù)for (int i = 0; i < head.length; i++) { //放入修改后的頭部信息fbyte[i] = head[i];}byte[] skipBytes = new byte[skipSizeInt]; //存放截取時(shí)跳過的音頻數(shù)據(jù)fis.read(skipBytes, 0, skipBytes.length); //跳過不需要截取的數(shù)據(jù)fis.read(fbyte, head.length, fbyte.length - head.length); //讀取要截取的數(shù)據(jù)到目標(biāo)數(shù)組fis.close();File target = new File(targetfile);FileOutputStream fos = new FileOutputStream(target);fos.write(fbyte);fos.flush();fos.close();} catch (IOException e) {e.printStackTrace();return false;}return true;}/*** @param file 目標(biāo)文件* @return 獲取文件時(shí)長*/public static long getTimeLen(File file) {long tlen = 0;if (file != null && file.exists()) {Encoder encoder = new Encoder();try {MultimediaInfo m = encoder.getInfo(file);long ls = m.getDuration();tlen = ls / 1000;} catch (Exception e) {e.printStackTrace();}}return tlen;}public static byte[] reverse(byte[] array) {byte temp;int len = array.length;for (int i = 0; i < len / 2; i++) {temp = array[i];array[i] = array[len - 1 - i];array[len - 1 - i] = temp;}return array;}/*** @param sourcePath 源文件全路徑* @param tagretPath 臨時(shí)操作目錄路徑* @param suffixName 文件后綴名* @param filesize 切片時(shí)長* 將文件根據(jù)時(shí)長進(jìn)行切片*/public static void sectionFile(String sourcePath, String tagretPath, String suffixName, int filesize) {File sourcefile = new File(sourcePath);File tagretfile = new File(tagretPath);if (!sourcefile.exists()) {throw new RuntimeException("源文件不存在,請檢查文件路徑");}//刪除臨時(shí)操作目錄下所有文件delAllFile(tagretPath);if (!tagretfile.exists()) {tagretfile.mkdir();}//獲取文件時(shí)長long timeLen = getTimeLen(sourcefile);//計(jì)算切片數(shù)int count = (int) (timeLen / filesize) + 1;for (int i = 0; i < count; i++) {int start = i * filesize;int end = start + filesize;if ((timeLen - start) < filesize) {end = (int) timeLen;}StringBuilder tagretpath = new StringBuilder(tagretPath);tagretpath.append(i).append(suffixName);//切片開始boolean result = cut(sourcePath, tagretpath.toString(), start, end, suffixName);//切片結(jié)束System.out.println(result);}}public static void main(String[] args) throws Exception {String fileName = "C:\\Users\\彭偉\\Desktop\\temp\\java.mp3";String transform = Video2Voice.transform(fileName);System.out.println("格式化后的文件名稱=====>" + transform);String targetName = "C:\\Users\\彭偉\\Desktop\\temp\\qie\\";sectionFile(transform, targetName, ".pcm", 60);}/*** @param path 文件夾路徑* @return 刪除一個(gè)文件夾下面所有的文件以及文件夾(不刪除自己)*/public static boolean delAllFile(String path) {boolean flag = false;File file = new File(path);if (!file.exists()) {return flag;}if (!file.isDirectory()) {return flag;}String[] tempList = file.list();File temp = null;for (int i = 0; i < tempList.length; i++) {if (path.endsWith(File.separator)) {temp = new File(path + tempList[i]);} else {temp = new File(path + File.separator + tempList[i]);}if (temp.isFile()) {temp.delete();}if (temp.isDirectory()) {delAllFile(path + "/" + tempList[i]);//遞歸刪除文件夾flag = true;}}file.delete();return flag;} }3,線程實(shí)現(xiàn)類
package com.itpengwei.util;import com.alibaba.fastjson.JSON; import com.itpengwei.po.Message; import com.itpengwei.xunfei.FileUtil; import com.itpengwei.xunfei.HttpUtil; import com.itpengwei.xunfei.WebIAT; import org.apache.commons.codec.binary.Base64;import java.net.URLEncoder; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap;/*** @author 彭偉* @Date 2019/6/24 11:41* 訊飛語音聽寫線程池任務(wù)處理類*/ public class ThreadTask implements Runnable {private Map<String, String> header;//請求頭private String path;//目標(biāo)文件夾private List<String> fileList;//文件名稱集合private int flag;//當(dāng)前開啟的線程private int totalsize;//分片總數(shù)private ConcurrentHashMap<String, Object> rs;private int compensateTatol = 5;//失敗,補(bǔ)償總數(shù)public ThreadTask() {}public ThreadTask(Map<String, String> header, String path, List<String> fileList, int flag, int totalsize, ConcurrentHashMap<String, Object> rs) {this.header = header;this.path = path;this.fileList = fileList;this.flag = flag;this.totalsize = totalsize;this.rs = rs;}public void run() {Thread.currentThread().setName("處理訊飛語音分片線程----序號----》" + flag);System.out.println(Thread.currentThread().getName() + "--線程處理文件-----》" + fileList);for (int i = 0; i < fileList.size(); i++) {int compensateCount = 0;//失敗,補(bǔ)償計(jì)數(shù)器Message result = getResult(i, compensateCount);rs.put(fileList.get(i), result);}if (rs.size() == totalsize) {formatResult(rs);}}/*** @param i 當(dāng)前處理文件角標(biāo)* @param compensateCount 失敗補(bǔ)償計(jì)數(shù)器* @return 處理返回結(jié)果并添加重試機(jī)制*/public Message getResult(int i, int compensateCount) {Message message = null;try {byte[] audioByteArray = FileUtil.read(path + "\\" + fileList.get(i));String audioBase64 = new String(Base64.encodeBase64(audioByteArray), "UTF-8");String result = HttpUtil.doPost1(WebIAT.WEBIAT_URL, header, "audio=" + URLEncoder.encode(audioBase64, "UTF-8"));message = JSON.parseObject(result, Message.class);if (!message.getCode().equals("0")) {System.out.println(fileList.get(i) + "----文件處理失敗,異常碼" + message.getCode() + ",重試===>" + compensateCount + "次");compensateCount++;//記錄失敗次數(shù)if (compensateCount <= compensateTatol) {//在失敗補(bǔ)償次數(shù)內(nèi)進(jìn)行補(bǔ)償getResult(i, compensateCount);}}} catch (Exception e) {e.printStackTrace();System.out.println(fileList.get(i) + "----文件處理異常,重試第====》" + compensateCount + "次");compensateCount++;//記錄失敗次數(shù)if (compensateCount <= compensateTatol) {//在失敗補(bǔ)償次數(shù)內(nèi)進(jìn)行補(bǔ)償getResult(i, compensateCount);}}return message;}/*** @param result 未格式化結(jié)果,將結(jié)果格式化*/public void formatResult(Map<String, Object> result) {StringBuilder rs = new StringBuilder();for (int i = 0; i < result.size(); i++) {Message message = (Message) result.get(i + ".pcm");if (!message.getCode().equals("0")) {System.out.println("當(dāng)前分片轉(zhuǎn)換失敗,分片名稱====>" + i + ".pcm");}rs.append(message.getData());}System.out.println("最后結(jié)果為====》" + rs);} }4,程序測試主類
package com.itpengwei.xunfei; /*** 語音聽寫 WebAPI 接口調(diào)用示例* 運(yùn)行方法:直接運(yùn)行 main() 即可* 結(jié)果: 控制臺輸出語音聽寫結(jié)果信息** @author iflytek*/import com.itpengwei.util.ThreadTask; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.digest.DigestUtils;import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** 語音聽寫 WebAPI 接口調(diào)用示例 接口文檔(必看):https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E5%90%AC%E5%86%99.html* webapi 聽寫服務(wù)參考帖子(必看):http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=38947&extra=* 語音聽寫WebAPI 服務(wù),熱詞使用方式:登陸開放平臺https://www.xfyun.cn/后,找到控制臺--我的應(yīng)用---語音聽寫---服務(wù)管理--上傳熱詞* (Very Important)創(chuàng)建完webapi應(yīng)用添加聽寫服務(wù)之后一定要設(shè)置ip白名單,找到控制臺--我的應(yīng)用--設(shè)置ip白名單,如何設(shè)置參考:http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=41891* 注意:熱詞只能在識別的時(shí)候會增加熱詞的識別權(quán)重,需要注意的是增加相應(yīng)詞條的識別率,但并不是絕對的,具體效果以您測試為準(zhǔn)。* 錯(cuò)誤碼鏈接:https://www.xfyun.cn/document/error-code (code返回錯(cuò)誤碼時(shí)必看)** @author iflytek*/public class WebIAT {public static final int ThreadPooSize = 5;public static ExecutorService executorService = Executors.newFixedThreadPool(ThreadPooSize);// 聽寫webapi接口地址public static final String WEBIAT_URL = "http://api.xfyun.cn/v1/service/v1/iat";// 應(yīng)用APPID(必須為webapi類型應(yīng)用,并開通語音聽寫服務(wù),參考帖子如何創(chuàng)建一個(gè)webapi應(yīng)用:http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=36481)private static final String APPID = "";// 接口密鑰(webapi類型應(yīng)用開通聽寫服務(wù)后,控制臺--我的應(yīng)用---語音聽寫---相應(yīng)服務(wù)的apikey)private static final String API_KEY = "";// 音頻編碼private static final String AUE = "raw";// 引擎類型//(聽寫服務(wù):engine_type為識別引擎類型,開通webapi聽寫服務(wù)后默認(rèn)識別普通話與英文:示例音頻請?jiān)诼爩懡涌谖臋n底部下載// sms16k(16k采樣率、16bit普通話音頻、單聲道、pcm或者wav)// sms8k(8k采樣率、16bit普通話音頻、單聲道、pcm或者wav)// sms-en16k(16k采樣率,16bit英語音頻,單聲道,pcm或者wav)// sms-en8k(8k采樣率,16bit英語音頻,單聲道,pcm或者wav)// 請使用cool edit Pro軟件查看音頻格式是否滿足相應(yīng)的識別引擎類型,不滿足則識別為空(即返回的data為空,code為0),或者識別為錯(cuò)誤文本)// 音頻格式轉(zhuǎn)換可參考(訊飛開放平臺語音識別音頻文件格式說明):https://doc.xfyun.cn/rest_api/%E9%9F%B3%E9%A2%91%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E.htmlprivate static final String ENGINE_TYPE = "sms16k";// 后端點(diǎn)(取值范圍0-10000ms)private static final String VAD_EOS = "10000";// 音頻文件地址,示例音頻請?jiān)诼爩懡涌谖臋n底部下載private static final String AUDIO_PATH = "C:\\Users\\彭偉\\Desktop\\temp\\qie";/*** 組裝http請求頭*/private static Map<String, String> buildHttpHeader() throws UnsupportedEncodingException {String curTime = System.currentTimeMillis() / 1000L + "";String param = "{\"aue\":\"" + AUE + "\"" + ",\"engine_type\":\"" + ENGINE_TYPE + "\"" + ",\"vad_eos\":\"" + VAD_EOS + "\"}";String paramBase64 = new String(Base64.encodeBase64(param.getBytes("UTF-8")));String checkSum = DigestUtils.md5Hex(API_KEY + curTime + paramBase64);Map<String, String> header = new HashMap<String, String>();header.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");header.put("X-Param", paramBase64);header.put("X-CurTime", curTime);header.put("X-CheckSum", checkSum);header.put("X-Appid", APPID);return header;}/*** 聽寫 WebAPI 調(diào)用示例程序** @param args* @throws IOException*/public static void main(String[] args) throws Exception {testThreadPool();}/*** @throws Exception 測試使用線程池進(jìn)行處理并合并結(jié)果*/public static void testThreadPool() throws Exception {//1,構(gòu)建請求頭Map<String, String> header = buildHttpHeader();String path = "C:\\Users\\彭偉\\Desktop\\temp\\qie";File file = new File(path);String[] list = file.list();//開始計(jì)算每條線程執(zhí)行多少分片int taskSize = list.length / ThreadPooSize;//任務(wù)分片結(jié)束int count = ThreadPooSize;if (taskSize <=0) {count = taskSize == 0 ? 0 : taskSize;}ConcurrentHashMap<String, Object> rs = new ConcurrentHashMap<String, Object>();//收集結(jié)果集for (int i = 0; i < count; i++) {//計(jì)算每條線程處理的任務(wù),設(shè)置界限隔離int start = i * taskSize, end = taskSize * i + taskSize - 1;if (end < 0) {//第一次end = 0;}if (i == (count - 1)) {//最后一次end = list.length - 1;}List<String> fileList = new ArrayList<String>();for (int j = start; j <= end; j++) {fileList.add(list[j]);}executorService.execute(new ThreadTask(header, path, fileList, i, list.length, rs));}executorService.shutdown();//關(guān)閉線程池}}5,http工具類
package com.itpengwei.xunfei;import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.Map;/*** Http Client 工具類** @author 彭偉*/ public class HttpUtil {/*** 發(fā)送post請求,根據(jù) Content-Type 返回不同的返回值** @param url* @param header* @param body* @return*/public static Map<String, Object> doPost2(String url, Map<String, String> header, String body) {Map<String, Object> resultMap = new HashMap<String, Object>();PrintWriter out = null;try {// 設(shè)置 urlURL realUrl = new URL(url);URLConnection connection = realUrl.openConnection();HttpURLConnection httpURLConnection = (HttpURLConnection) connection;// 設(shè)置 headerfor (String key : header.keySet()) {httpURLConnection.setRequestProperty(key, header.get(key));}// 設(shè)置請求 bodyhttpURLConnection.setDoOutput(true);httpURLConnection.setDoInput(true);out = new PrintWriter(httpURLConnection.getOutputStream());// 保存bodyout.print(body);// 發(fā)送bodyout.flush();if (HttpURLConnection.HTTP_OK != httpURLConnection.getResponseCode()) {System.out.println("Http 請求失敗,狀態(tài)碼:" + httpURLConnection.getResponseCode());return null;}// 獲取響應(yīng)headerString responseContentType = httpURLConnection.getHeaderField("Content-Type");if ("audio/mpeg".equals(responseContentType)) {// 獲取響應(yīng)bodybyte[] bytes = toByteArray(httpURLConnection.getInputStream());resultMap.put("Content-Type", "audio/mpeg");resultMap.put("sid", httpURLConnection.getHeaderField("sid"));resultMap.put("body", bytes);return resultMap;} else {// 設(shè)置請求 bodyBufferedReader in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));String line;String result = "";while ((line = in.readLine()) != null) {result += line;}resultMap.put("Content-Type", "text/plain");resultMap.put("body", result);return resultMap;}} catch (Exception e) {return null;}}/*** 發(fā)送post請求** @param url* @param header* @param body* @return*/public static String doPost1(String url, Map<String, String> header, String body) {String result = "";BufferedReader in = null;PrintWriter out = null;try {// 設(shè)置 urlURL realUrl = new URL(url);URLConnection connection = realUrl.openConnection();HttpURLConnection httpURLConnection = (HttpURLConnection) connection;// 設(shè)置 headerfor (String key : header.keySet()) {httpURLConnection.setRequestProperty(key, header.get(key));}// 設(shè)置請求 bodyhttpURLConnection.setDoOutput(true);httpURLConnection.setDoInput(true);out = new PrintWriter(httpURLConnection.getOutputStream());// 保存bodyout.print(body);// 發(fā)送bodyout.flush();if (HttpURLConnection.HTTP_OK != httpURLConnection.getResponseCode()) {System.out.println("Http 請求失敗,狀態(tài)碼:" + httpURLConnection.getResponseCode());return null;}// 獲取響應(yīng)bodyin = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {return null;}return result;}/*** 流轉(zhuǎn)二進(jìn)制數(shù)組** @param in* @return* @throws IOException*/private static byte[] toByteArray(InputStream in) throws IOException {ByteArrayOutputStream out = new ByteArrayOutputStream();byte[] buffer = new byte[1024 * 4];int n = 0;while ((n = in.read(buffer)) != -1) {out.write(buffer, 0, n);}return out.toByteArray();} }pom文件
<dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.4</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.9</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.1.37</version></dependency></dependencies>maven中沒有的jar,自己添加到lib下去的包
jave-1.0.2.jar
下載地址
總結(jié)
以上是生活随笔為你收集整理的超大文件调用讯飞语音听写解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jax指标的用法_股票指标参数用法.do
- 下一篇: ADC0804工作原理及过程