项目中需要对大音频文件做切割,特此记录
1、安装jave 1.0.2
maven仓库中没有这个jar,需要下载并手动install
下载完成后需手动install,各参数加上引号,没加引号之前报错
mvn install:install-file "-Dfile=E:\download\jave-1.0.2.jar" "-DgroupId=it.sauronsoftware" "-DartifactId=jave" "-Dversion=1.0.2" "-Dpackaging=jar"
安装完成后再pom文件引入即可
<dependency>
<groupId>it.sauronsoftware</groupId>
<artifactId>jave</artifactId>
<version>1.0.2</version>
</dependency>
2、实现
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.MultimediaInfo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
/**
* auth:v4aoy
* date: 2023/7/26 14:23
* desc:
*/
public class VideoUtil {
public static void main (String[] args) {
String source = "E:\\myproject\\yamnet\\20545__sirplus__snore.wav";
long time = getVideoLen(new File(source));
int internal = 10;
System.out.println("source file len:" + time);
for (int i = 0; i < time/internal + 1; i++) {
int begin = i * internal;
int end = begin + internal;
cutVideo(source, "E:\\video\\" + i + ".wav", begin, end);
}
}
public static void cutVideo(String sourceFile, String targetFile, int begin, int end) {
if (!sourceFile.toLowerCase().endsWith(".wav") || !targetFile.toLowerCase().endsWith(".wav"))
return ;
File source = new File(sourceFile);
if (!source.exists())
return ;
long sourceLen = getVideoLen(source);
if (begin < 0 || end < 0 || begin >= end || begin >= sourceLen)
return ;
if (end > sourceLen)
end = (int)sourceLen;
try {
System.out.println("cut video from:" + begin + " ;end:" + end);
FileInputStream inputStream = new FileInputStream(sourceFile);
long sourceSize = source.length() - 44; // 音频数据大小,44为头文件长度
int splitSize = (int) (sourceSize / sourceLen * (end - begin)); //需截取的音频大小
int skipSize = (int) (sourceSize / sourceLen * begin); //截取时需跳过的音频大小
System.out.println("sourceSize:"+sourceSize+";splitSize:"+splitSize+";skipSize:"+skipSize);
ByteBuffer fileBuf = ByteBuffer.allocate(4); // 存放文件大小
fileBuf.putInt(splitSize+36);
byte[] flen = fileBuf.array();
ByteBuffer dataBuf = ByteBuffer.allocate(4); //存放数据大小
dataBuf.putInt(splitSize);
byte[] dlen = dataBuf.array();
flen = reverse(flen); //数组反转
dlen = reverse(dlen);
byte[] head = new byte[44]; //定义wav头部信息数组
inputStream.read(head, 0, head.length); //读取源wav文件头部信息
for(int i=0; i<4; i++){ //4代表一个int占用字节数
head[i+4] = flen[i]; //替换原头部信息里的文件长度
head[i+40] = dlen[i]; //替换原头部信息里的数据长度
}
byte[] fbyte = new byte[splitSize+head.length]; //存放截取的音频数据
for (int i=0; i < head.length; i++){ //放入修改后的头部信息
fbyte[i] = head[i];
}
byte[] skipBytes = new byte[skipSize]; //存放截取时跳过的音频数据
inputStream.read(skipBytes, 0, skipBytes.length); //跳过不需要截取的数据
inputStream.read(fbyte, head.length, fbyte.length-head.length); //读取要截取的数据到目标数组
inputStream.close();
File target = new File(targetFile);
if(target.exists()){ //如果目标文件已存在,则删除目标文件
target.delete();
}
FileOutputStream outputStream = new FileOutputStream(target);
outputStream.write(fbyte);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static long getVideoLen (File source) {
if (source == null || !source.exists())
return 0;
Encoder encoder = new Encoder();
try {
MultimediaInfo info = encoder.getInfo(source);
return info.getDuration()/1000;
} catch (EncoderException e) {
e.printStackTrace();
}
return 0;
}
private 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;
}
}
执行结果: