pom文件引入

 <dependency><groupId>com.baidu.aip</groupId><artifactId>java-sdk</artifactId><version>4.12.0</version></dependency>

话不多说直接上代码

Constants

package net.hiyana.cogniz.litecheng.yuyin.constants;

/**

  • 语音系统参数配置
  • @Filename: Constants.java
  • @Version: 1.0
  • @Author: Dhjie
  • @Email: dhjievip@163.com

*/
public class Constants {

//获取授权的地址
//%d 表示匹配的参数
public static String TOKEN_URL = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s";//字符串转化为声音的url
/*** 文字变 语音参数* tex  必填  合成的文本,使用UTF-8编码,请注意文本长度必须小于1024字节* lan    必填  语言选择,填写zh* tok  必填  开放平台获取到的开发者 access_token* ctp   必填  客户端类型选择,web端填写1* cuid 必填     用户唯一标识,用来区分用户,填写机器 MAC 地址或 IMEI 码,长度为60以内* spd     选填  语速,取值0-9,默认为5中语速* pit     选填  音调,取值0-9,默认为5中语调* vol     选填  音量,取值0-9,默认为5中音量* per     选填  发音人选择,取值0-4, 0,1,4为女声,1,3为男声,默认为女声*/
public static String TEXT_AUDIO_URL = "http://tsn.baidu.com/text2audio";//默认语言
public static String DEFAULT_LAN = "zh";//客户端类型,默认为1
public static String DEFAULT_CTP = "1";//    选填  发音人选择,取值0-4, 0,1,4为女声,1,3为男声,默认为女声
public static String DEFAULT_PER = "4";//将音频转化为字符串
public static String AUDIO_TEXT_URL = "http://vop.baidu.com/server_api";

}

AudioClient

package net.hiyana.cogniz.litecheng.yuyin.client;import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.UUID;import javax.xml.bind.DatatypeConverter;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import lombok.extern.slf4j.Slf4j;
import net.hiyana.cogniz.litecheng.server.parse.server.ParseServerService;
import net.hiyana.cogniz.litecheng.util.AudioUtils;
import net.hiyana.cogniz.litecheng.util.Base64Utils;
import net.hiyana.cogniz.litecheng.util.HttpClientUtils;
import net.hiyana.cogniz.litecheng.util.JsonUtil;
import net.hiyana.cogniz.litecheng.util.TrustAnyTrustManager;
import net.hiyana.cogniz.litecheng.yuyin.constants.Constants;
import net.hiyana.cogniz.litecheng.yuyin.model.Audio2Text;
import net.hiyana.cogniz.litecheng.yuyin.model.Result;
import net.hiyana.cogniz.litecheng.yuyin.model.Text2Audio;/*** 语音转换*                       * @Filename: AudioClient.java* @Version: 1.0* @Author: Dhjie* @Email: dhjievip@163.com**/
@Slf4j
@Component
public class AudioClient {//"lhnN8uVsySG6SzdbEBSx2RwA";//id/*  private String appid ="17705048";// "V71cijc3Q9DZ5ZbFTd8sthFekDR3dTAC";//密钥private  String secret ="OCImtuS4VQEYZ2gq94Up1UxyK7cjrICW";*/@Value("${yuyin.baidu.user.apikey}")private String appid;@Value("${yuyin.baidu.user.secret}")private String secret;private String token;//用户的token
/*  private String token ;public AudioClient(String appid, String secret) {super();this.appid = appid;this.secret = secret;}public void setToken(String token) {this.token = token;}
*//*** 获取Token* @return token*/public  String getToken(){String token = null;try {
//          String url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id="+VoiceUtils.appid+"&client_secret="+VoiceUtils.secret;//获取TOKEN的地址String tokenUrl = String.format(Constants.TOKEN_URL, this.appid,this.secret);//发送请求String result = TrustAnyTrustManager.connect(tokenUrl);//获取tokentoken = JsonUtil.getMapper().readTree(result).get("access_token").asText();//设定类的tokenthis.token = token;} catch (Exception e) {e.printStackTrace();}return token;}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午5:01:36<br/>* 创建用户:Dhjie<br/>* 机能概要:将字符串转化为语音* @param word 需要转化为语音的文字* @return 返回数据流*/public InputStream text2Audio(String word){Text2Audio word2Voice = new Text2Audio();//设定转化为文件的字符串word2Voice.setTex(word);//调用return this.text2Audio(word2Voice);}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午5:50:24<br/>* 创建用户:Dhjie<br/>* 机能概要:将文本转转化为音频* @param word2Voice* @return*/public InputStream text2Audio(Text2Audio word2Voice){//当token不存在的情况if(this.isEmpty(this.token)){this.token= this.getToken();}//设定tokenword2Voice.setTok(this.token);//判断是否有cuidif(this.isEmpty(word2Voice.getCuid())){word2Voice.setCuid(UUID.randomUUID().toString());}if(this.isEmpty(word2Voice.getLan())){//默认的语言word2Voice.setLan(Constants.DEFAULT_LAN);}if(this.isEmpty(word2Voice.getCtp())){//访问类型  word2Voice.setCtp(Constants.DEFAULT_CTP);}if(this.isEmpty(word2Voice.getPer())){word2Voice.setPer(Constants.DEFAULT_PER);}//获取返回的参数String param = this.getParam(word2Voice);if(param == null || "".equals(param)){return null;}//获取连接诶地址String url = Constants.TEXT_AUDIO_URL+"?"+param;//获取语音数据InputStream in= HttpClientUtils.downLoad(url);return in;}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午10:46:02<br/>* 创建用户:Dhjie<br/>* 机能概要: 判断是否为空* @param str* @return*/private boolean isEmpty(String str){if(str == null || str.trim().equals("")){return true;}return false;}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午10:36:03<br/>* 创建用户:Dhjie<br/>* 机能概要:将声音转化为 文字* @param* @return*/public Result audio2Text(MultipartFile muFile){File audioFile=null;//转换Filetry {audioFile=File.createTempFile("tmp", ".mp3");muFile.transferTo(audioFile);} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}Audio2Text parm = new Audio2Text();//视屏格式parm.setFormat("pcm");//采样率, 8000 或者 16000, 推荐 16000 采用率parm.setRate(16000);//单通道parm.setChannel(1);parm.setCuid(UUID.randomUUID().toString());//当token不存在的情况if(this.token == null || "".equals(this.token)){this.token= this.getToken();}parm.setToken(this.getToken());File targertFile = audioFile;//当不是pcm文件的时候if(!audioFile.getName().endsWith("pcm")){AudioUtils audio = AudioUtils.getInstance();//将文件转化为 pcm文件File outPcmFile = new File(audioFile.getParentFile().getAbsolutePath()+File.pathSeparator+UUID.randomUUID().toString()+".pcm");if(!audio.convertMP32Pcm(audioFile.getAbsolutePath(), outPcmFile.getAbsolutePath())){return null;}targertFile = outPcmFile;}//加密音频文件Base64Utils utils = Base64Utils.getInstance();//读取文件basecode编码String mp3Base64Str = utils.file2Base64(targertFile);//读取文件大小int len = utils.getFileSize(targertFile);parm.setLen(len);parm.setSpeech(mp3Base64Str);String json = JsonUtil.object2Json(parm);//发送请求到服务器String jsonResult =null;try {jsonResult = HttpClientUtils.postJson(Constants.AUDIO_TEXT_URL, json);} catch (Exception e) {log.info("语音解析异常{}"+e);}//删除临时文件if(!targertFile.getAbsolutePath().equals(audioFile.getAbsolutePath())){targertFile.delete();}log.info("语音解析结果{}"+jsonResult);Result result = JsonUtil.json2Object(jsonResult, Result.class);return result;}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午5:43:24<br/>* 创建用户:Dhjie<br/>* 机能概要:获取请求的参数* @param* @return*/public String getParam(Text2Audio word2Voice) {String paramStr = null;try {Class<?> clazz = word2Voice.getClass();Field [] fields = word2Voice.getClass().getDeclaredFields();StringBuffer sb = new StringBuffer();for(Field field:fields){String fieldNm = field.getName();//获取方法名称String methodNm = this.getMethodName(field);//执行方法Object obj = clazz.getMethod(methodNm).invoke(word2Voice);//当参数数据为空的情况,直接if(obj != null && !"".equals(obj.toString())){sb.append(fieldNm+"="+obj.toString()+"&");}}if(sb.length() >0){paramStr = sb.substring(0, sb.length()-1);}} catch (Exception e) {e.printStackTrace();}return paramStr;}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午5:35:44<br/>* 创建用户:Dhjie<br/>* 机能概要:根据字段的名称来获取get方法的名称* @param field 字段* @return*/private String getMethodName(Field field){String fieldNm = field.getName();String methodNm = "get"+fieldNm.substring(0, 1).toUpperCase()+fieldNm.substring(1);return methodNm;}}

AudioUtils

package net.hiyana.cogniz.litecheng.util;import java.io.File;
import java.io.IOException;import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;/*** 创建日期:2018年1月14日* 创建时间:下午10:09:39* 创建者    :Dhjie* 机能概要:MP3转PCM Java方式实现* http://ai.baidu.com/forum/topic/show/496972*/
public class AudioUtils {private static AudioUtils audioUtils = null;private AudioUtils(){}//双判断,解决单利问题public static AudioUtils getInstance(){if(audioUtils == null){synchronized (AudioUtils.class) {if(audioUtils == null){audioUtils = new AudioUtils();}}}return audioUtils;}/*** MP3转换PCM文件方法* * @param mp3filepath 原始文件路径* @param pcmfilepath 转换文件的保存路径* @return * @throws Exception*/public boolean convertMP32Pcm(String mp3filepath, String pcmfilepath){try {//获取文件的音频流,pcm的格式AudioInputStream audioInputStream = getPcmAudioInputStream(mp3filepath);//将音频转化为  pcm的格式保存下来AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, new File(pcmfilepath));return true;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return false;}}/*** 播放MP3方法* * @param mp3filepath* @throws Exception*/public void playMP3(String mp3filepath) throws Exception {//获取音频为pcm的格式AudioInputStream audioInputStream = getPcmAudioInputStream(mp3filepath);// 播放if (audioInputStream == null){System.out.println("null audiostream");return;}//获取音频的格式AudioFormat targetFormat = audioInputStream.getFormat();DataLine.Info dinfo = new DataLine.Info(SourceDataLine.class, targetFormat, AudioSystem.NOT_SPECIFIED);//输出设备SourceDataLine line = null;try {line = (SourceDataLine) AudioSystem.getLine(dinfo);line.open(targetFormat);line.start();int len = -1;
//            byte[] buffer = new byte[8192];byte[] buffer = new byte[1024];//读取音频文件while ((len = audioInputStream.read(buffer)) > 0) {//输出音频文件line.write(buffer, 0, len);}// Block等待临时数据被输出为空line.drain();//关闭读取流audioInputStream.close();//停止播放line.stop();line.close();} catch (Exception ex) {ex.printStackTrace();System.out.println("audio problem " + ex);}}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午9:53:14<br/>* 创建用户:Dhjie<br/>* 机能概要:获取文件的音频流* @param mp3filepath* @return*/private AudioInputStream getPcmAudioInputStream(String mp3filepath) {File mp3 = new File(mp3filepath);AudioInputStream audioInputStream = null;AudioFormat targetFormat = null;try {AudioInputStream in = null;//读取音频文件的类MpegAudioFileReader mp = new MpegAudioFileReader();in = mp.getAudioInputStream(mp3);AudioFormat baseFormat = in.getFormat();//设定输出格式为pcm格式的音频文件targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);//输出到音频audioInputStream = AudioSystem.getAudioInputStream(targetFormat, in);} catch (Exception e) {e.printStackTrace();}return audioInputStream;}
}

Base64Utils

package net.hiyana.cogniz.litecheng.util;import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;import javax.xml.bind.DatatypeConverter;/*** 创建日期:2018年1月14日<br/>* 创建时间:下午6:50:53<br/>* 创建者 :yellowcong<br/>* 机能概要:用于Base64解码和编码*/
public class Base64Utils {private static Base64Utils utils = null;private Base64Utils(){}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午7:23:30<br/>* 创建用户:yellowcong<br/>* 机能概要:单利 ,懒汉模式* @return*/public static Base64Utils getInstance(){if(utils == null){synchronized (Base64Utils.class) {if(utils == null ){utils = new Base64Utils();}}}return utils;}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午7:47:12<br/>* 创建用户:yellowcong<br/>* 机能概要:获取文件的大小* @param inFile 文件* @return 文件的大小*/public int getFileSize(File inFile){InputStream in = null;try {in = new FileInputStream(inFile);//文件长度int len = in.available();return len;}catch (Exception e) {// TODO: handle exception}finally{try {in.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return -1;}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午6:57:53<br/>* 创建用户:yellowcong<br/>* 机能概要:将文件转化为base64* @return* @throws Exception */public String file2Base64(File inFile){//将文件转化为字节码byte [] bytes = copyFile2Byte(inFile);if(bytes == null){return null;}//base64,将字节码转化为base64的字符串return DatatypeConverter.printBase64Binary(bytes);
//      String result = Base64.getEncoder().encodeToString(bytes);
//      return result;}/*** * 创建日期:2018年1月14日<br/>* 创建时间:下午7:09:02<br/>* 创建用户:yellowcong<br/>* 机能概要:将文件转化为字节码* @param inFile * @return*/private byte [] copyFile2Byte(File inFile){InputStream in = null;try {in = new FileInputStream(inFile);//文件长度int len = in.available();//定义数组byte [] bytes = new byte[len];//读取到数组里面in.read(bytes);return bytes;} catch (Exception e) {e.printStackTrace();return null;}finally{try {if(in != null){in.close();}} catch (Exception e) {e.printStackTrace();}}}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午6:54:02<br/>* 创建用户:yellowcong<br/>* 机能概要:将字符串转化为文件* @param strBase64 base64 编码的文件* @param outFile 输出的目标文件地址* @return * @throws IOException*/public boolean base64ToFile(String strBase64,File outFile){try {// 解码,然后将字节转换为文件byte[] bytes = Base64.getDecoder().decode(strBase64); // 将字符串转换为byte数组return copyByte2File(bytes,outFile);} catch (Exception ioe) {ioe.printStackTrace();return false;}}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午7:01:59<br/>* 创建用户:yellowcong<br/>* 机能概要:将字节码转化为文件* @param bytes* @param file*/private boolean copyByte2File(byte [] bytes,File file){FileOutputStream  out = null;try {//转化为输入流ByteArrayInputStream in = new ByteArrayInputStream(bytes);//写出文件byte[] buffer = new byte[1024];out = new FileOutputStream(file);//写文件int len = 0;while ((len = in.read(buffer)) != -1) {out.write(buffer, 0, len); // 文件写操作}return true;} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(out != null){out.close();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return false;}
}

FileUtils

package net.hiyana.cogniz.litecheng.util;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;/*** *                       * @Filename: FileUtils.java* @Version: 1.0* @Author: Dhjie* @Email: dhjievip@163.com**/
public class FileUtils {//文件夹信息private static List<String> dirNames= null;//文件信息private static List<String> fileNames = null;//文件大小单位 ,我们可以通过添加SizeStr 来添加单位private static String [] sizeStr = {"B","KB","MB","GB","PB"}; private static int count =0;private static long fileSize = 0;private FileUtils(){}/*** 获取类路径下文件的路径* @param fileName* @return*/public static String getClassPathFilePath(String fileName){String path = FileUtils.class.getClassLoader().getResource(fileName).getPath().toString();if(path.contains("%20")){path = path.replace("%20", " ");}return path;}/*** 获取文件对象* @param fileName* @return*/public static File getClassPathFile(String fileName){return new File(FileUtils.getClassPathFilePath(fileName));}/*** 创建类路径下面的文件夹* @param directory*/public static String mkClassPathDir(String directory){String path = FileUtils.class.getClassLoader().getResource("").getPath();path += directory;File file = new File(path);if(!file.exists()){file.mkdir();}return path;}/*** 获取类文件的输入流* @param fileName* @return*/public static InputStream getClassPathFileInputStream(String fileName){return FileUtils.class.getResourceAsStream(fileName);}/*** 将File 文件转化为 字符串* @param filePath* @return*/public static String copyFileToString(String filePath){return FileUtils.getFileContent(filePath);}/*** 获取一个文本文件里面的内容* @param filePath* @return*/public static String getFileContent(String filePath){FileReader in  = null;BufferedReader reader = null;try {in  = new FileReader(new File(filePath));reader = new BufferedReader(in);String line = null;StringBuffer str = new StringBuffer();while((line = reader.readLine())!= null){str.append(line);str.append("\r\n");}return str.toString();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(in != null){in.close();}if(reader != null ){reader.close();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}return null;}/*** 通过 路径来创建文件* @param path*/public static void createDirectory(String path){File file = new File(path);if(!file.exists()){file.mkdirs();}}/*** 通过文件夹  获取文件夹 当前目录 和下面目录所有的文件 * @param path* @param isNowPath 目录级别  当前目录 数据 * @return*///获取所有文件public static List<String> getChildFiles(String path,boolean isNowPath){if(!new File(path).exists()){throw new RuntimeException(path+",文件夹不存在");}if(!new File(path).isDirectory()){throw new RuntimeException(path+",不是文件夹");}fileNames = new ArrayList<String>();listAllFile(path,isNowPath);return fileNames;}/*** 通过文件夹  获取文件夹 当前目录 和下面目录所有的文件 * @param path* @return*/public static List<String> getChildFiles(String path){return getChildFiles(path, false);}/*** 通过文件夹 获取* 所有的文件夹* @param path 目录名称* @param isNowPath 是否是当前目录* @return*/public static List<String> getChildDirs(String path,boolean isNowPath){if(!new File(path).exists()){throw new RuntimeException(path+",文件夹不存在");}if(!new File(path).isDirectory()){throw new RuntimeException(path+",不是文件夹");}dirNames = new ArrayList<String>();listAllDir(path,isNowPath);return dirNames;}/*** 通过文件夹 获取 我们的子 * 所有的文件夹  * @param path 目录名称* @return*/public static List<String> getChildDirs(String path){return getChildDirs(path, false);}/*** 获取某个文件夹下面的文件* 其中文件夹包含了第一个文件夹就是自己 重复调用* * @param path 文件夹路径名称*/private static void listAllFile(String path,boolean isNowPath){File file = new File(path);if(file.isDirectory()){for(File f:file.listFiles()){if(isNowPath){if(f.isFile()){fileNames.add(f.getPath());}}else{listAllFile(f.getPath(),isNowPath);}}}else{fileNames.add(path);}}/*** 获取某个文件夹下面的文件* 其中文件夹包含了第一个文件夹就是自己 重复调用* * @param path 文件夹路径名称* @param isNowPath 是否是当前目录 ,包含子目录*/private static void listAllDir(String path,boolean isNowPath){File file = new File(path);if(file.isDirectory()){dirNames.add(path);for(File f:file.listFiles()){if(isNowPath){dirNames.add(f.getPath());}else{listAllDir(f.getPath(),isNowPath);}}}}/*** 获取所有的文件,包括 文件夹的信息* @param path* @return*/public static List<String> listAllFiles(String path){List<String> strs = FileUtils.getChildDirs(path);strs.addAll(FileUtils.getChildFiles(path));FileUtils.getChildFiles(path);return strs;}/*** 将InputStream  转化为输出数据* @param in 输入流* @param file 输出的文件对象*/public static void copyInputStreamToFile(InputStream in ,File file){OutputStream out= null;try {out = new FileOutputStream(file);byte[] buff = new byte[1024];int len = 0;while ((len = in.read(buff)) > 0) {out.write(buff, 0, len);}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(in != null){in.close();}} catch (Exception e2) {// TODO: handle exception}finally{try {if(out != null){out.close();}} catch (Exception e3) {// TODO: handle exception}}}}/*** 将字符数据转化为我们的文件* @param data 字节数组* @param file 输出文件*/public static void copyByte2File(byte [] data,File file){if ((data == null) || (data.length <= 0))return;OutputStream out = null;InputStream in = null;try {out = new FileOutputStream(file);in = new ByteInputStream(data,data.length );byte [] buff = new byte[1024];int len =  0;while((len = in.read(buff))>0){out.write(buff, 0, len);}out.flush();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(in != null){in.close();}} catch (Exception e2) {// TODO: handle exception}finally{try {if(out != null){out.close();}} catch (Exception e3) {// TODO: handle exception}}}}/*** 将InputStream 转化为字节码文件* @return */public static byte[] copyFileToByteArray(File file){InputStream  in = null;try {in = new FileInputStream(file);//获取字节码的数量,将字节码装int len = in.available();byte [] result = new byte[len];in.read(result);return result;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(in != null){in.close();}} catch (Exception e2) {// TODO: handle exception}}return null;}/*** 将InputStream 转化为字节码文件* @return */public static byte[] copyInputStreamToByteArray(InputStream in){try {//获取字节码的数量,将字节码装int len = in.available();byte [] result = new byte[len];in.read(result);return result;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {if(in != null){in.close();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return null;}/*** xx "B","KB","MB","GB","PB"* * 计算文件大小* @param size*/private static void getFileSize(long size){long result  = size/1024;if(result >=1 && count <(sizeStr.length-2)){fileSize = size/1024;count = count +1;getFileSize(fileSize);}else{fileSize = size;}}/*** * xx "B","KB","MB","GB","PB"* * 计算文件大小* 我们用的时候,对于 静态的数据,需要清空 或者重新初始化,解决多次使用,导致数据堆积问题* @param fileSize* @return*/public static String getFileSizeStr(long filesize){if(filesize <0){throw new RuntimeException("文件大小有问题");}//多次使用的时候,这个 就会用问题了,一定要清空count = 0;fileSize= 0;getFileSize(filesize);return fileSize+sizeStr[count];}/*** 将InputStream转化为Str* @param in 输入流* @return  数据*/public static String copyInput2Str(InputStream in){String str = null;try {//写数据String line = null;BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuffer sb = new StringBuffer();while((line = reader.readLine())!= null){sb.append(line);}str = sb.toString();} catch (Exception e) {// TODO: handle exception}finally{try {if(in != null){in.close();}} catch (Exception e2) {// TODO: handle exception}}return str;}
}

HttpClientUtils

package net.hiyana.cogniz.litecheng.util;import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;/*** 这个工具包是用来 做代理服务 爬去数据的,结果好多代理数据没有 2015-10 爬取 推酷数据 来做服务 通过这个工具来来添加代理,来处理数据*                       * @Filename: HttpClientUtils.java* @Version: 1.0* @Author: Dhjie* @Email: dhjievip@163.com**/
public class HttpClientUtils {private static int timeout = 50000;/*** 通过url来获取我们的GetMethod* * @param url* @return*/public static GetMethod setGetMethod(String url) {// TODO Auto-generated method stub/* 2.生成 GetMethod 对象并设置参数 */GetMethod getMethod = null;try {// 可能会在查询的时候出现异常,我们简单的丢去getMethod = new GetMethod(url);// 设置 get 请求超时 5sgetMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, timeout);// 设置请求重试处理getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());// Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208// Firefox/3.0.1// Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070309// Firefox/2.0.0.3// Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070803// Firefox/1.5.0.12// Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; WOW64;// Trident/4.0; SLCC1)// Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; Trident/4.0;// .NET CLR 1.1.4322; .NET CLR 2.0.50727)// Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13// (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13// 设置USER_AGENTgetMethod.getParams().setParameter(HttpMethodParams.USER_AGENT,"Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070803 Firefox/1.5.0.12");} catch (Exception e) {throw new RuntimeException("-------------------------请求协议存在问题-----------------------");}return getMethod;}/*** 获取到我们的HttpClient* * @param url* @return*/private static HttpClient getHttpClient(String url) {HttpClient httpClient = new HttpClient();httpClient.getHostConfiguration().setHost(url);// 设定超时 5000 毫秒的时间httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(50000);return httpClient;}/*** 设定我们带有代理的HttpClieantProxy* * @param url* @param proxyIP* @param proxyPort* @return*/private static HttpClient setHttpClientProxy(String url, String proxyIP, int proxyPort) {HttpClient httpClient = getHttpClient(url);// 反悔return httpClient;}/*** 发送Get请求* * @param url* @return*/public static String sendGet(String url) {return sendGet(url, false);}/*** 发送get请求 待遇proxy* * @param url* @param isProxy* @return*/public static String sendGet(String url, boolean isProxy) {String content = null;HttpClient client = null;try {client = getHttpClient(url);GetMethod method = HttpClientUtils.setGetMethod(url);if (method != null) {content = dealHtml(client, method);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return content;}/*** 处理网页* * @param client* @param method* @return*/public static String dealHtml(HttpClient client, GetMethod method) {String content = null;try {int code = client.executeMethod(method);if (code == 200) {// 当数请求成功Header header = method.getResponseHeader("Content-Type");if (header != null) {String applicationType = header.getValue();if (applicationType != null) {// 当是网页的情况if (applicationType.indexOf("html") != -1) {content = getInput2Str(method.getResponseBodyAsStream());} else if (applicationType.indexOf("json") != -1) {content = getInput2Str(method.getResponseBodyAsStream());// 当是图片的问题// System.out.println(JsonUtils.object2Json(applicationType));}}}} else if ((code == HttpStatus.SC_MOVED_TEMPORARILY) || (code == HttpStatus.SC_MOVED_PERMANENTLY)|| (code == HttpStatus.SC_SEE_OTHER) || (code == HttpStatus.SC_TEMPORARY_REDIRECT)) {System.err.println("------------------------请求失败: " + method.getStatusLine());return null;// 当我们的ip被限制的情况} else if (code == HttpStatus.SC_FORBIDDEN) {}} catch (HttpException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return content;}/*** 发送json数据到服务器* * @param url* @param json* @return*/public static String postJson(String url, String json) {// 使用DefaultHttpClient 这个对象才可以获取到JsonString str = null;try {DefaultHttpClient client = new DefaultHttpClient();// 添加jsonHttpPost post = new HttpPost(url);StringEntity entity = new StringEntity(json, ContentType.create("application/json", "utf-8"));post.setEntity(entity);// 返回的数据HttpResponse response = client.execute(post);int code = response.getStatusLine().getStatusCode();if (code >= 200 && code < 300) {InputStream in = response.getEntity().getContent();str = HttpClientUtils.getInput2Str(in);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return str;}/*** 下载文件* * @param url*            下载的路径* @return*/public static InputStream downLoad(String url) {InputStream in = null;try {DefaultHttpClient client = new DefaultHttpClient();HttpGet get = new HttpGet(url);HttpResponse response = client.execute(get);int code = response.getStatusLine().getStatusCode();if (code >= 200 && code < 300) {in = response.getEntity().getContent();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return in;}/*** 下载文件* * @param url*            下载的路径* @return*/public static InputStream downLoadByPost(String url) {InputStream in = null;try {DefaultHttpClient client = new DefaultHttpClient();HttpPost post = new HttpPost(url);HttpResponse response = client.execute(post);int code = response.getStatusLine().getStatusCode();if (code >= 200 && code < 300) {in = response.getEntity().getContent();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return in;}/*** 传送文件到摸个地方* * @param url*            路径* @param field*            文件的字段* @param file*            文件对象* @return*/public static String upload(String url, String field, File file) {String result = null;try {DefaultHttpClient client = new DefaultHttpClient();HttpPost post = new HttpPost(url);MultipartEntity entity = new MultipartEntity();FileBody fileBody = new FileBody(file);entity.addPart(field, fileBody);post.setEntity(entity);HttpResponse response = client.execute(post);int code = response.getStatusLine().getStatusCode();if (code >= 200 && code < 300) {InputStream in = response.getEntity().getContent();result = HttpClientUtils.getInput2Str(in);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;}/*** 通过post来提交数据,没有带参数* * @param url*            请求的地址* @return*/public static String post(String url) {return HttpClientUtils.post(url, null);}/*** 通过post来提交数据,带参数的方法* * @param url*            请求地址* @param params*            参数* @return*/public static String post(String url, Map<String, String> params) {String str = null;try {HttpClient client = new HttpClient();PostMethod method = new PostMethod(url);// 设定请求头的样式method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");if (params != null && params.size() > 0) {for (Map.Entry<String, String> entry : params.entrySet()) {method.setParameter(entry.getKey(), entry.getValue());}}int code = client.executeMethod(method);if (code >= 200 && code < 300) {InputStream in = method.getResponseBodyAsStream();str = HttpClientUtils.getInput2Str(in);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return str;}/*** 将InputStream 转化为 字符串* * @param in* @return*/public static String getInput2Str(InputStream in) {String str = null;try {// 写数据String line = null;BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuffer sb = new StringBuffer();while ((line = reader.readLine()) != null) {sb.append(line);}str = sb.toString();} catch (Exception e) {// TODO: handle exception} finally {try {if (in != null) {in.close();}} catch (Exception e2) {// TODO: handle exception}}return str;}
}

TrustAnyTrustManager

package net.hiyana.cogniz.litecheng.util;import java.io.DataInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;/*** 创建日期:2018年1月14日<br/>* 创建时间:下午4:46:33<br/>* 创建者 :Dhjie<br/>* 机能概要:用来发送请求获取百度的token*/
public class TrustAnyTrustManager implements X509TrustManager {public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[] {};}static class TrustAnyHostnameVerifier implements HostnameVerifier {public boolean verify(String hostname, SSLSession session) {return true;}}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午4:52:51<br/>* 创建用户:Dhjie<br/>* 机能概要:* @param url 访问呢的目标地址* @return* @throws Exception*/public static String connect(String url) throws Exception {InputStream in = null;OutputStream out = null;byte[] buffer = new byte[4096];String str_return = "";try {// URL console = new URL(url);URL console = new URL(new String(url.getBytes("utf-8")));HttpURLConnection conn = (HttpURLConnection) console.openConnection();// 如果是httpsif (conn instanceof HttpsURLConnection) {SSLContext sc = SSLContext.getInstance("SSL");sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());((HttpsURLConnection) conn).setHostnameVerifier(new TrustAnyHostnameVerifier());}// conn.setRequestProperty("Content-type", "text/html");// conn.setRequestProperty("Accept-Charset", "GBK");// conn.setRequestProperty("contentType", "GBK");// conn.setRequestMethod("POST");// conn.setDoOutput(true);// conn.setRequestProperty("User-Agent", "directclient");// PrintWriter outdate = new PrintWriter(new// OutputStreamWriter(conn.getOutputStream(),"utf-8"));// outdate.println(url);// outdate.close();conn.connect();InputStream is = conn.getInputStream();DataInputStream indata = new DataInputStream(is);String ret = "";while (ret != null) {ret = indata.readLine();if (ret != null && !ret.trim().equals("")) {str_return = str_return + new String(ret.getBytes("ISO-8859-1"), "utf-8");}}conn.disconnect();} catch (Exception e) {throw e;} finally {try {in.close();} catch (Exception e) {}try {out.close();} catch (Exception e) {}}return str_return;}
}

Audio2Text

package net.hiyana.cogniz.litecheng.yuyin.model;/*** 语音变文字参数* 语音识别接口支持 POST 方式* 目前 API 仅支持整段语音识别的模式,即需要上传整段语音进行识别* 语音数据上传方式有两种:隐示发送和显示发送* 原始语音的录音格式目前只支持评测 8k/16k 采样率 16bit 位深的单声道语音* 压缩格式支持:pcm(不压缩)、wav、opus、speex、amr、x-flac* 系统支持语言种类:中文(zh)、粤语(ct)、英文(en)                     * @Filename: Audio2Text.java* @Version: 1.0* @Author: Dhjie* @Email: dhjievip@163.com**/
public class Audio2Text {/*** sting     必填  语音压缩的格式,请填写上述格式之一,不区分大小写*/private String format;  /***    int     必填  采样率,支持 8000 或者 16000*/private int rate; /*** int     必填  声道数,仅支持单声道,请填写 1*/private int channel;    /*** string     必填  用户唯一标识,用来区分用户,填写机器 MAC 地址或 IMEI 码,长度为60以内*/private String cuid;    /*** string     必填  开放平台获取到的开发者 access_token*/private String token;     /*** string     选填  语音下载地址*/private String url;     /*** 本地语音文件的的字节数,单位字节*/private int len;/*** 本地语音文件的的二进制语音数据 ,需要进行base64 编码。与len参数连一起使用。*/private String speech;/*** 用户服务器的识别结果回调地址,确保百度服务器可以访问*///private String callback;/*** 可下载的语音下载地址,与callback连一起使用,确保百度服务器可以访问。*///private String url ;public String getFormat() {return format;}public void setFormat(String format) {this.format = format;}public int getRate() {return rate;}public void setRate(int rate) {this.rate = rate;}public int getChannel() {return channel;}public void setChannel(int channel) {this.channel = channel;}public String getCuid() {return cuid;}public void setCuid(String cuid) {this.cuid = cuid;}public String getToken() {return token;}public void setToken(String token) {this.token = token;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public int getLen() {return len;}public void setLen(int len) {this.len = len;}public String getSpeech() {return speech;}public void setSpeech(String speech) {this.speech = speech;}
}

Result

package net.hiyana.cogniz.litecheng.yuyin.model;import org.codehaus.jackson.annotate.JsonProperty;/*** 返回结果的消息*                       * @Filename: Result.java* @Version: 1.0* @Author: Dhjie* @Email: dhjievip@163.com**/
public class Result {@JsonProperty("corpus_no")private String corpusNo;// 错误消息@JsonProperty("err_msg")private String errMsg;// 错误号@JsonProperty("err_no")private String errNo;// 结果private String [] result;private String sn;public String getCorpusNo() {return corpusNo;}public void setCorpusNo(String corpusNo) {this.corpusNo = corpusNo;}public String getErrMsg() {return errMsg;}public void setErrMsg(String errMsg) {this.errMsg = errMsg;}public String getErrNo() {return errNo;}public void setErrNo(String errNo) {this.errNo = errNo;}public String[] getResult() {return result;}public void setResult(String[] result) {this.result = result;}public String getSn() {return sn;}public void setSn(String sn) {this.sn = sn;}
}

Text2Audio

package net.hiyana.cogniz.litecheng.yuyin.model;
/*** * 创建日期:2018年1月14日<br/>* 创建时间:下午5:15:53<br/>* 创建者    :Dhjie<br/>* 机能概要:* 文字变 语音参数* tex    必填  合成的文本,使用UTF-8编码,请注意文本长度必须小于1024字节* lan    必填  语言选择,填写zh* tok  必填  开放平台获取到的开发者 access_token* ctp   必填  客户端类型选择,web端填写1* cuid 必填     用户唯一标识,用来区分用户,填写机器 MAC 地址或 IMEI 码,长度为60以内* spd     选填  语速,取值0-9,默认为5中语速* pit     选填  音调,取值0-9,默认为5中语调* vol     选填  音量,取值0-9,默认为5中音量* per     选填  发音人选择,取值0-3, 0、4为女声,1、3为男声,默认为女声* @author Dhjie* @date 2016年3月29日*TEXT_AUDIO*/
public class Text2Audio {//必填   合成的文本,使用UTF-8编码,请注意文本长度必须小于1024字节private String tex; //必填     语言选择,填写zhprivate String lan;    //必填    开放平台获取到的开发者 access_tokenprivate String tok ;    //必填    客户端类型选择,web端填写1private String ctp    ;//必填   用户唯一标识,用来区分用户,填写机器 MAC 地址或 IMEI 码,长度为60以内private String cuid ; //选填    语速,取值0-9,默认为5中语速private String spd    ;//选填   音调,取值0-9,默认为5中语调private String pit    ;//选填   音量,取值0-9,默认为5中音量private String vol    ;//选填   发音人选择,取值0-1, 0为女声,1为男声,默认为女声private String per     ;public String getTex() {return tex;}public void setTex(String tex) {this.tex = tex;}public String getLan() {return lan;}public void setLan(String lan) {this.lan = lan;}public String getTok() {return tok;}public void setTok(String tok) {this.tok = tok;}public String getCtp() {return ctp;}public void setCtp(String ctp) {this.ctp = ctp;}public String getCuid() {return cuid;}public void setCuid(String cuid) {this.cuid = cuid;}public String getSpd() {return spd;}public void setSpd(String spd) {this.spd = spd;}public String getPit() {return pit;}public void setPit(String pit) {this.pit = pit;}public String getVol() {return vol;}public void setVol(String vol) {this.vol = vol;}public String getPer() {return per;}public void setPer(String per) {this.per = per;}
}

TestDemo

/*** 创建日期:2018年1月14日<br/>* 创建时间:下午5:31:46<br/>* 创建者    :Dhjie<br/>* 机能概要:*/
public class Demo {private AudioClient client = null;@Beforepublic void setUp(){String appid = "jtKs8smVEnWLU5q2gQCxTWOj";String secret = "Y6HlBXsfF8q5wR1iFztXwTqqZKcDFeKB";client = new AudioClient(appid,secret);}@Testpublic void testText2Audio(){InputStream in = client.text2Audio("把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是把你挠吐露皮了是是是");FileUtils.copyInputStreamToFile(in, new File("D:/测试.mp3"));}@Testpublic void test2Text2Audio(){Text2Audio word = new Text2Audio();word.setTex("王贱狗,着急了吧");//语音 0-4word.setPer("4");InputStream in = client.text2Audio(word);FileUtils.copyInputStreamToFile(in, new File("D:/xx.mp3"));}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午10:52:00<br/>* 创建用户:Dhjie<br/>* 机能概要:将音频转文件* @throws Exception*/@Testpublic void testAduio2Text() throws Exception{Text2Audio word = new Text2Audio();word.setTex("你是逗逼");//InputStream in = client.text2Audio(word);//C:/Users/EDZ/Desktop/语音.txtfinal File outFile = new File("D:/xx.mp3");//FileUtils.copyInputStreamToFile(in, outFile);//开启线程 ,播放音乐new Thread() {@Overridepublic void run() {// TODO Auto-generated method stub//播放文件   try {AudioUtils.getInstance().playMP3(outFile.getAbsolutePath());} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}.start();//转义翻译结果Result result = client.audio2Text(outFile);//打印翻译的结果System.out.println("语音转换文字:{}"+result.getResult()[0]);}/*** 创建日期:2018年1月14日<br/>* 创建时间:下午6:07:47<br/>* 创建用户:Dhjie<br/>* 机能概要:测试token的获取* @throws Exception* @throws IllegalArgumentException* @throws InvocationTargetException* @throws NoSuchMethodException* @throws SecurityException*/@Testpublic void testGetToken() throws Exception, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{String token = client.getToken();Assert.assertNotNull(token);}

java 调用百度语音相关推荐

  1. QT调用百度语音REST API实现语音合成

    QT调用百度语音REST API实现语音合成 1.首先点击点击链接http://yuyin.baidu.com/docs/tts 点击access_token,获取access_token,里面有详细 ...

  2. java调用百度地图API依据地理位置中文获取经纬度

    百度地图api提供了非常多地图相关的免费接口,有利于地理位置相关的开发,百度地图api首页:http://developer.baidu.com/map/. 博主使用过依据地理依据地理位置中文获取经纬 ...

  3. html5d调用百度语音,易语言调用百度语音平台实现文字转换语音功能的代码

    调用百度语音平台实现文字转换语音功能 此功能需要加载精易模块5.6 .版本 2 .支持库 wmp9 .程序集 窗口程序集1 .子程序 _试听按钮_被单击 播放器1.地址 = "http:// ...

  4. java调用百度翻译_Java调用百度API实现翻译-Go语言中文社区

    下面是Java调用百度API实现翻译的具体步骤: 一.在写代码之前先在在百度翻译平台中,申请APP_ID 申请地址申请的详见点击打开链接 申请之后,会得到APP_ID和SECURITY_KEY 二.j ...

  5. Java调用百度AI实现人体属性分析

    Java调用百度AI实现人体属性分析 好久没有更新了...闲来无事发一下模仿百度AI的人体属性分析. 百度AI效果图如下: 本人开发效果图如下: 界面大家可以忽略........下面讲讲代码实现 1. ...

  6. Java调用百度OCR文字识别API实现图片文字识别软件

    java_baidu_ocr Java调用百度OCR文字识别API实现图片文字识别软件 这是一款小巧方便,强大的文字识别软件,由Java编写,配上了窗口界面 调用了百度ocr文字识别API 识别精度高 ...

  7. Java调用百度API实现图像识别

    Java调用百度API实现图像识别 最近在做一个关于识别的小功能,翻阅了一堆资料,也实践自己去实现这个功能,最后识别的结果不是那么理想.这里介绍一个完全可以商用以及识别率超高的百度ai接口 1.为什么 ...

  8. Java调用百度API生成短网址

    由于百度短网址旧API更新,故更新下原博客内容(仅供参考),希望小伙伴们以官方API为主,以防影响使用. 官方API:https://dwz.cn/console/apidoc package com ...

  9. Java调用百度API出现{status:211,message:APP SN校验失败}

    Java调用百度API出现{"status":211,"message":"APP SN校验失败"} {"status" ...

  10. Java调用百度OCR文字识别的接口

    调用百度OCR文字识别的接口,来自于百度官网,亲测可以使用 跳转链接 FileUtil的下载链接 Base64Util下载链接 HttpUtil下载链接 GsonUtils下载链接 Accurate. ...

最新文章

  1. java坐标点对称点的输出,编程java来确定一个对称的单词
  2. python中range 函数_pythonrange,range函数的用法
  3. linux查看内存_嵌入式操作系统的内存,你了解多少?
  4. 【剑指Offer】07变态跳台阶
  5. 神调侃!程序员必学推荐系统,我比女朋友更了解你!
  6. lcl手术和飞秒区别_全飞秒、半飞秒、ICL、TPRK...教你分清近视手术区别
  7. CC3200学习——blinky资料
  8. Java代码复用的三种常用方式:继承、组合和代理
  9. 2022-01-28 Android app 背景图首尾相接滚动效果,ImageView 滚动显示效果
  10. XML配置文件的读取
  11. 前端学习笔记之HTML body内常用标签
  12. java公路车为什么会被喷,最全指南
  13. 小米运动同步到Google Fit健身, 解决睡眠和体重不同步的情况
  14. 怎么查忘仙服务器信息,忘仙怎么跨服战斗 跨服玩法介绍[多图]
  15. for await of使用
  16. 高通 MSM8K GPT异常导致无法开机问题分析
  17. 在线快速将pdf转换成word
  18. JS 获取上周、本周、下周的开始日期或者结束日期
  19. goldwave混音功能—把两个音效文件合并在一起
  20. 为什么HashMap链表长度超过8会转成树结构

热门文章

  1. 韦东山ARM裸机学习笔记——S3C2440的串口驱动编程原理
  2. 纵横算法之二:社招如何面对算法面试
  3. 常见计算机硬件故障维修方法,电脑硬件有哪些常见问题 电脑硬件常见问题维修技巧【详解】...
  4. 小米电视显示服务器断开连接,小米电视投屏频繁断开的解决办法
  5. 我的世界java版如何加披风_我的世界披风怎么导入
  6. 编制现金流量表3个步骤!
  7. U盘容量变小了 -恢复U盘实际容量教程(亲试有效)
  8. 决策树算法--C4.5算法
  9. 如何将c语言程序变成应用,C语言代码转换为应用程序
  10. 如何阅读一本书?阅读的高效方法