Java集成SOX开发
项目痛点
- 1、项目需要做“提取双声道录音中的右声道”的功能,故需要用到sox。但是sox需要安装,不能直接像依赖一个jar包一样简单。
- 2、网上能找到安装了sox的docker镜像,但是里面没有java环境,或者是有java环境却没有sox,两者不能兼得。
- 3、如果直接在sox docker中安装java,或者是在java docker中安装sox,可能都会导致docker镜像过大;故本文提供了一种思路:就是把sox二进制文件直接拷贝到java的docker镜像中(这种方法制作的sox镜像只比之前多了2M !!)。
编写Dockerfile
- 1、建一个空文件夹,在里面放如下几个文件(sox是sox安装的二进制文件;lib开头的两个文件sox依赖的库)
PS:下载地址:免安装sox二进制文件下载
- 2、其中的基础镜像是我这边,大家可以把其换成任意一个jdk镜像(例如:mcr.microsoft.com/java/jdk)
FROM registry:5000/jdk8:base
COPY lib* /usr/local/lib/
COPY sox /usr/local/bin/
代码开发
- 下面是Sox开发的示例:
其实思路就是:先在系统中安装好sox环境,然后执行shell命令
import java.io.*;
public class SoxUtil {
public static final String WORK_PATH_SOX = "/home/sox-img/";
private void execute(String command) throws Exception {
boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
System.out.println("isWindows=" + isWindows);
ProcessBuilder pb = new ProcessBuilder();
if (isWindows) {//其实可以不考虑windows环境,不过是为了本地调试用
pb.command("cmd.exe", "/c", command);
} else {
pb.command("sh", "-c", command);
}
pb.directory(new File(WORK_PATH_SOX));
Process process = pb.start();
String result = convertStreamToStr(process.getInputStream());
System.out.println(result);
}
/**
* 把inputStream变为字符串
*
* @param is
* @return
* @throws IOException
*/
private String convertStreamToStr(InputStream is) throws IOException {
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
}catch (Exception e) {
e.printStackTrace();
} finally {
is.close();
}
return writer.toString();
} else {
return "";
}
}
public static void main(String[] args) throws Exception {
SoxUtil sox = new SoxUtil();
sox.execute(args[0]);
}
}
效果演示(例如:提取双声道录音中的右声道)
windows系统
- windows演示需要写sox安装的绝对路径,例如:
D://sox-14-4-2/sox.exe E://sox/t1.wav E://sox/t1_r.wav remix 2
- 执行 java SoxUtil “D://sox-14-4-2/sox.exe E://sox/t1.wav E://sox/t1_r.wav remix 2” 即可(这里是命令行执行,也可以程序调用)
linux系统
先执行javac SoxUtil.java编译,再执行下面的代码(他会取提取t2.wav中的单声道,并生成aaa.wav文件)