首页 » Java » java 微信小程序 语音识别成文字 音频格式转换 silk pcm wav

java 微信小程序 语音识别成文字 音频格式转换 silk pcm wav

原文 http://blog.csdn.net/haiyang4988/article/details/75168602

2017-07-15 17:20:05阅读(667)

最近有需求要把微信小程序里面的语音进行语音识别,然后搜搜,微信小程序的语音格式是silk

1、上传silk文件

2、下载silk-v3-decoder,通过名称把silk转换成讯飞可识别的wav文件

3、获取讯飞转换后的文字信息

	/**
	 * 获取wav文件 并返回路径
	 * @param wavFileName
	 * @return
	 * @throws Exception
	 */
	public String getWav(String wavFileName) throws Exception {//之前别人写的代码,可以改为java直接执行shell脚本的方式
		StringBuilder command = new StringBuilder(Constant.FFMPEG);
		command.append(Constant.CONVERTER);
		command.append(Constant.OXM_VOICE_UPLOAD_BASE_PTAH);
		command.append(wavFileName);
		command.append(" wav ");
		Session session = jschSessionService.getSession();
		jschSessionService.getChannelAndExec(session, command.toString());
		Thread.sleep(2000);
		String name = wavFileName.replace("silk", "wav");
		return name;
	}


public static final String FFMPEG = " export PATH=/usr/local/ffmpeg/bin/:$PATH; source /etc/profile;";
public static final String CONVERTER = " sh /home/deployer/silk-v3-decoder-master/converter.sh ";
public static final String OXM_VOICE_UPLOAD_BASE_PTAH = "/home/deployer/tomcat7/webapps/xxxx/";

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Properties;
import org.springframework.stereotype.Service;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.shanjin.oxm.common.util.Constant;
/**
 *  java  ssh 服务
 *
 */
@Service("JschSessionService")
public class JschSessionService {
	public Session getSession() throws JSchException {
		Properties sshConfig = new Properties();
		sshConfig.put("StrictHostKeyChecking", "no");
		JSch jsch = new JSch();
		Session session = jsch.getSession(Constant.SSH_USER,Constant.SSH_IP,Constant.SSH_PORT);
		session.setPassword(Constant.SSH_PASSWORD);
		session.setConfig(sshConfig);
		session.connect();
		return session;
	}
	public void closeSession(Session session) {
		if (session.isConnected()) {
			session.disconnect();
		}
	}
	
	public String getChannelAndExec(Session session, String command) throws JSchException, IOException {
		Channel channel = session.openChannel("exec");
		((ChannelExec) channel).setCommand(command);
		channel.setInputStream(null);
		((ChannelExec) channel).setErrStream(System.err);
		channel.connect();
		int state = channel.getExitStatus();
		/*if (state != 0) {
			return "exec is error ,exit code is :" + state;
		}*/
		((ChannelExec) channel).setErrStream(System.err);
		//String msg = getExitMessage(channel);
		closeChannel(channel);
		closeSession(session);
		return state + "";
	}
	public void closeChannel(Channel channel){
		if(channel.isConnected()){
			channel.disconnect();
		}
	}
	
	
	public String getExitMessage(Channel channel) throws IOException {
		StringBuilder message = new StringBuilder("exit message is : ");
		InputStream in = channel.getInputStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(in,
				Charset.forName("utf-8")));
		String buf = null;
		while ((buf = reader.readLine()) != null) {
			message.append(buf);
		}
		return message.toString();
	}
	
}

	/**
	 * 获取语音信息
	 */
	public String getVoiceText(String filePath,String wavName) throws Exception {
		IflyTekServiceImpl iflytekService = new IflyTekServiceImpl();//TODO 注解方式,会产生缓存,一直都是第一次识别的语音
        	File ff = null;
		String text = null;
		File file = new File(filePath+wavName);
		InputStream in = new FileInputStream(file);
		byte[] bb = VoiceSplitUtil.getbytes(in);
		System.out.println(bb);
		text = iflytekService.RecognizePcmfileByte(bb);
//		text = this.getText(fly);
		in.close();
		return text;
	}
	public String getText(IflyTekServiceImpl fly) {
		StringBuilder text = new StringBuilder();
		JSONObject json = null;
		JSONArray wss = null;
		JSONObject ws = null;
		JSONArray cw = null;
		JSONObject c = null;
        long begin = System.currentTimeMillis();
		while (true) {
			 long end = System.currentTimeMillis();
			 if((end - begin) >3000){
				 break;
				
			 }
			if (fly.recognizer.isListening() && fly.mIsEndOfSpeech == true) {
System.out.println(fly.sn);
				json = JSONObject.fromObject(fly.sn.toString());
				wss = json.getJSONArray("ws");
				text = new StringBuilder();
				for (int i = 0; i < wss.size(); i++) {
					ws = wss.getJSONObject(i);
					cw = ws.getJSONArray("cw");
					c = cw.getJSONObject(0);
					text.append(c.getString("w"));
				}
				break;
			}
		}
		
		if(text.length() <= 0){
			text.append("对不起,我没听清您在说什么");
		}
		return text.toString();
	}


用到了讯飞的jar:json-jena-1.0-1.0.jar、Msc-1.0.jar

讯飞的插件:libmsc32.so、libmsc64.so、msc32.dll、msc64.dll,插件我全部放在了工程的根目录下


后来又要求文字需要转换成,一个痛苦的过程啊,各种文件格式转换

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.Properties;
public class ShellExec {
	public static void execShell(String command) {
		InputStreamReader stdISR = null;
		InputStreamReader errISR = null;
		Process process = null;
//		String command = "/home/Lance/workspace/someTest/testbash.sh";
		long timeout = 10 * 1000;
		try {
			process = Runtime.getRuntime().exec(command);
//			CommandStreamGobbler errorGobbler = new CommandStreamGobbler(
//					process.getErrorStream(), command, "ERR");
//			CommandStreamGobbler outputGobbler = new CommandStreamGobbler(
//					process.getInputStream(), command, "STD");
//			errorGobbler.start();
			// 必须先等待错误输出ready再建立标准输出
//			while (!errorGobbler.isReady()) {
//				Thread.sleep(10);
//			}
//			outputGobbler.start();
//			while (!outputGobbler.isReady()) {
//				Thread.sleep(10);
//			}
			CommandWaitForThread commandThread = new CommandWaitForThread(
					process);
			commandThread.start();
			long commandTime = new Date().getTime();
			long nowTime = new Date().getTime();
			boolean timeoutFlag = false;
			while (!commandThread.isFinish()) {
				if (nowTime - commandTime > timeout) {
					timeoutFlag = true;
					break;
				} else {
					Thread.sleep(1000);
					nowTime = new Date().getTime();
				}
			}
			if (timeoutFlag) {
				// 命令超时
//				errorGobbler.setTimeout(1);
//				outputGobbler.setTimeout(1);
				System.out.println("正式执行命令:" + command + "超时");
			}
//			while (true) {
//				if (errorGobbler.isReadFinish() && outputGobbler.isReadFinish()) {
//					break;
//				}
//				Thread.sleep(10);
//			}
		} catch (IOException | InterruptedException e) {
			e.printStackTrace();
		} finally {
			if (process != null) {
				process.destroy();
			}
		}
	}
	
	public static void convertAudio(String sourcePath,int sourceHZ,String targetPath,int targetHZ){//ffmpeg参数设置的坑好大啊
		Properties props=System.getProperties(); //获得系统属性集    
		String osName = props.getProperty("os.name"); //操作系统名称
		String command = null;
		if(osName.contains("Windows")){
//			ffmpeg -y -f s16le -ar 24000 -ac 1 -i "$1.pcm" -f wav -ar 16000 -b:a 16 -ac 1 "${1%.*}.$2"
			command = "C:\\ffmpeg.exe -y -f s16le -ar "+sourceHZ+" -i "+sourcePath+" -f wav -ar "+targetHZ+" -b:a 8 -ac 1 "+targetPath;			
		}else{
			command = "/usr/local/ffmpeg/bin/ffmpeg -y -f s16le -ar "+sourceHZ+" -ac 1 -i "+sourcePath+" -f wav -ar "+targetHZ+" -b:a 8 -ac 1 "+targetPath;
		}
		System.out.println("格式转换:"+command);
		ShellExec.execShell(command);
	}
	
	public static void pcmToSilk(String pcmPath,String silkPath) throws InterruptedException{
		//首先 pcm转换成8000的wav,然后wav转成silk
//		ShellExec.convertAudio(pcmPath, 16000, pcmPath+".wav", 16000);
//		Thread.sleep(1000);
//		ShellExec.convertAudio(pcmPath+".wav", 16000, silkPath, 8000);
		
		ShellExec.convertAudio(pcmPath, 16000, silkPath, 8000);
	}
	
	public static void pcmToWav(String pcmPath,String wavPath){
		Properties props=System.getProperties(); //获得系统属性集    
		String osName = props.getProperty("os.name"); //操作系统名称
		String command = null;
		if(osName.contains("Windows")){
			command = "C:\\ffmpeg.exe -f s16le -ar 16000 -i "+pcmPath+" -f wav -ar 16000 -b:a 8 -ac 1 "+wavPath;			
		}else{
			command = "/usr/local/ffmpeg/bin/ffmpeg -f s16le -ar 16000 -i "+pcmPath+" -f wav -ar 16000 -b:a 16 -ac 1 "+wavPath;
		}
		System.out.println("格式转换:"+command);
		ShellExec.execShell(command);
	}
	
	public static void silkToWav(String silkPath,String wavPath){
		Properties props=System.getProperties(); //获得系统属性集    
		String osName = props.getProperty("os.name"); //操作系统名称
		String command = null;
		if(osName.contains("Windows")){
//			ffmpeg -y -f s16le -ar 24000 -ac 1 -i "$1.pcm" -f wav -ar 16000 -b:a 16 -ac 1 "${1%.*}.$2"
			command = "C:\\ffmpeg.exe -y -f s16le -ar 8000 -ac 1 -i "+silkPath+" -f wav -ar 16000 -b:a 16 -ac 1 "+wavPath;			
		}else{
			command = "/usr/local/ffmpeg/bin/ffmpeg -y -f s16le -ar 8000 -ac 1 -i "+silkPath+" -f wav -ar 16000 -b:a 16 -ac 1 "+wavPath;
		}
		System.out.println("格式转换:"+command);
		ShellExec.execShell(command);
	
	}
	
	public static void main(String[] args) throws Exception{
		ShellExec.pcmToSilk("/home/deployer/tomcat7/webapps/omoFile/gc3e72fbe-1a27-479f-ae4f-d3aacc6276ed.pcm", "/home/deployer/tomcat7/webapps/omoFile/gc3e72fbe-1a27-479f-ae4f-d3aacc6276ed.pcm.silk");
//		ShellExec.pcmToWav("/home/deployer/tomcat7/webapps/omoFile/gdd68fe07-35b3-46f1-af08-97100caba179.pcm", "/home/deployer/tomcat7/webapps/omoFile/gdd68fe07-35b3-46f1-af08-97100caba179.pcm.wav");
	}

public class CommandWaitForThread extends Thread {
	private Process process;
	private boolean finish = false;
	private int exitValue = -1;
	public CommandWaitForThread(Process process) {
		this.process = process;
	}
	public void run() {
		try {
			this.exitValue = process.waitFor();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			finish = true;
		}
	}
	public boolean isFinish() {
		return finish;
	}
	public void setFinish(boolean finish) {
		this.finish = finish;
	}
	public int getExitValue() {
		return exitValue;
	}

最终得到了微信小程序需要的silk格式,然而,他喵的我不知道微信小程序需要什么频率什么规格的silk文件,电脑能够播放我转换了的silk,但是小程序并不能播放,好蛋疼啊。继续蛋疼中........


附两份资料

linux安装ffmpeg

http://blog.csdn.net/wh8_2011/article/details/50666745

ffmpeg命令及案例

http://blog.csdn.net/c910511/article/details/54849048 案例

http://www.cuplayer.com/player/PlayerCode/FFmpeg/2014/0706/1399.html 命令

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹