使用Java将微信speex转成wav格式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/scropio0zry/article/details/84929451

背景:

工作中,遇到了需要从微信中获取录音文件,然而高音质的音频文件不能直接使用,需要转成wav才能正常使用,这里记录下调研后的结果

通过微信录音获取音频文件的方式的有两种

一种是amr 低质量音频 通过https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID获取

一种是speex 高质量音频 通过https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token=ACCESS_TOKEN&media_id=MEDIA_ID获取

然而高质量speex音频文件 往往无法直接使用,需要还换成其他的格式才能够使用

 

方法:

第一步,我们需要安装speex环境
根据微信提示,我们从https://www.speex.org/downloads/ 下载speex-1.2.0.tar.gz
  1. 通过tar –xzvf speex-1.2.0.tar.gz解压包
  2. 执行sudo make install
这里需要注意的是
安装的speex生成的可执行文件默认在/usr/local/lib/下 但是默认的path依赖是usr/lib/下,所以需要配置etc/bashrc文件最后一行加一行:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
第二步:从https://github.com/ppninja/wechat-speex-declib下载speex_decode转码工具
  1. 通过 unzip wechat-speex-declib-master.zip 命令解压zip包
  2. 到 wechat-speex-declib-master 文件夹中执行make命令
到bin目录下 可以看到生成的speex_decode可执行文件 如果不存在,很有可能是因为上面的path路径问题
转码只需要到bin目录下 执行./speex_decode 音频.speex 音频.wav即可

如何使用Java进行转换

以下附上代码,具体说明请看代码注释,涉及到一些其他工具类不影响主要逻辑,可以删除改成固定值测试

import java.text.MessageFormat;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.stereotype.Service;

import com.common.utils.logback.LogUtil;
import com.common.utils.uuid.GuidUtil;
import com.common.FileUtil;
import com.common.PropertiesDef;

@Service
public class SpeexToWavService {

	private ExecutorService pool = Executors.newCachedThreadPool();

	public byte[] speexToWav(byte[] data) {
		byte[] body = null;
		String speexName = GuidUtil.getUUID() + ".speex";
		String wavName = GuidUtil.getUUID() + ".wav";
		try {
			if (FileUtil.save(PropertiesDef.ORIGIN_PATH, speexName, data)) {
				// SPEEX_DECODE_PATH : speex_decode所在路径
				// ORIGIN_PATH : 微信录音音频文件下拉位置
				String command = MessageFormat.format("{0}speex_decode {1} {2}", PropertiesDef.SPEEX_DECODE_PATH,
						PropertiesDef.ORIGIN_PATH + speexName, PropertiesDef.ORIGIN_PATH + wavName);
				
				
				int n = execCommand(command, 10000);

				// 获取文件流
				if (n == 0) {
					body = FileUtil.getFile(PropertiesDef.ORIGIN_PATH, wavName);
				}

			}
		} catch (Exception e) {
			LogUtil.logError("speex转wav失败", ExceptionUtils.getStackTrace(e));

		} finally {
			// 执行完毕,删除下拉音频文件
			 FileUtil.deleteFile(PropertiesDef.ORIGIN_PATH + speexName);
			 FileUtil.deleteFile(PropertiesDef.ORIGIN_PATH + wavName);
		}

		return body;
	}

	public int execCommand(String command, long timeout) {
		Process process = null;
		Future<Integer> executeFuture = null;
		try {
			process = Runtime.getRuntime().exec(command);
			final Process p = process;
			Callable<Integer> call = new Callable<Integer>() {
				@Override
				public Integer call() throws Exception {
					p.waitFor();
					return p.exitValue();
				}
			};
			
			//使用线程池防止Process阻塞
			executeFuture = pool.submit(call);
			return executeFuture.get(timeout, TimeUnit.MILLISECONDS);
			
		} catch (Exception e) {
			LogUtil.logError("speex转wav:execCommand 执行命令失败,command:{},错误原因:{}", command,
					ExceptionUtils.getStackTrace(e));
			return 1;
		}finally {
			if (executeFuture != null) {
				try {
					executeFuture.cancel(true);
				} catch (Exception ignore) {
				}
			}
			if (process != null) {
				process.destroy();
			}
		}


	}

}

FileUtil 工具类

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.lang.exception.ExceptionUtils;

import com.common.utils.logback.LogUtil;


public class FileUtil {
	
	public static boolean 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) {
			LogUtil.logError(
					"保存文件流异常,函数名称:save,fileName:{},filePath:{},异常原因:{}",
					fileName, filePath, ExceptionUtils.getStackTrace(e));
			return false;
		} catch (IOException e) {
			LogUtil.logError(
					"保存文件流异常,函数名称:save,fileName:{},filePath:{},异常原因:{}",
					fileName, filePath, ExceptionUtils.getStackTrace(e));
			return false;
		}
		return true;
	}
	
	public static byte[] getFile(String filePath, String fileName){
		 byte[] buffer = null;  
		    try {  
		        File file = new File(filePath,fileName);  
		        FileInputStream fis = new FileInputStream(file);  
		        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
		        byte[] b = new byte[1024 * 4];  
		        int n;  
		        while ((n = fis.read(b)) != -1) {  
		            bos.write(b, 0, n);  
		        }  
		        buffer = bos.toByteArray();  
		        fis.close();  
		        bos.close();  
		    } catch (Exception e) {  
		    	LogUtil.logError(
						"获取文件流异常,函数名称:getFile,fileName:{},filePath:{},异常原因:{}",
						fileName, filePath, ExceptionUtils.getStackTrace(e)); 
		    }
		 return buffer;  
	}
	
}
 

猜你喜欢

转载自blog.csdn.net/scropio0zry/article/details/84929451
今日推荐