最近因为工作需要,需要将其它格式的视屏转码为MP4,因此完成了这个工具(支持多种格式互转)
该工具基于jave,但是由于jave太久没维护,里面所依赖的ffmpeg版本过低,还有一下bug,因此重写的内容如下:
1、重写自动生成ffmpeg文件,和ffmpeg指令构造部分,如果需要替换ffmpeg文件,只需要将resource下面的替换掉就可以
2、关于ffmpeg判断文件格式,本人看了晚上很多方法,大多数是这样的一个逻辑。
a、执行 ffmpeg -i demo.mp4 得到视屏信息
b、读取ffpmeg的标准输出,得到input输入信息,如下
得到mov,则认为该文件的文件格式为mov,实际上该文件是MP4
本工具中也提供这样的一种方式,参考本工具中 Encoder.java文件中
public MultimediaInfo getInfo(File source) throws InputFormatException,
EncoderException {
FFMPEGExecutor ffmpeg = locator.createExecutor();
ffmpeg.addArgument("-i");
ffmpeg.addArgument(source.getAbsolutePath());
try {
ffmpeg.execute();
} catch (IOException e) {
throw new EncoderException(e);
}
try {
RBufferedReader reader = null;
reader = new RBufferedReader(new InputStreamReader(ffmpeg
.getErrorStream()));
return parseMultimediaInfo(source, reader);
} finally {
ffmpeg.destroy();
}
}
如果运行这个方法,我刚才测试的1.MP4得到的文件格式是mov,但实际是MP4,这是两种不同的格式,为了佐证,我们打开看1.MP4的文件信息
查阅MP4和MOV文件的定义,得到如下结果,由下表可知,我们的这个1.MP4文件的文件格式是MP4而非mov,因此不建议使用上文提到的Encoder.getInfo()方法获取文件格式。但本工具依旧保留了该方法,但是使用@Deprecated标记
Hex Signature | File Extension | ASCII Signature | ASCII Signature |
---|---|---|---|
[4 byte offset] 66 74 79 70 4D 53 4E 56 | MP4 | [4 byte offset] ftypMSNV | MPEG-4 video file |
[4 byte offset] 66 74 79 70 69 73 6F 6D | MP4 | [4 byte offset] ftypisom | ISO Base Media file (MPEG-4) v1 |
[4 byte offset] 66 74 79 70 71 74 20 20 | mov | [4 byte offset] ftypqt | QuickTime movie file |
如果要获取视屏的文件格式,建议通过判断文件头中标识格式的二进制码来判断,本工具提供了该方法,位于FileInfoExecutor.java中,但是由于时间原因只实现了MP4和avi的判断
代码如下:
private static final byte[] MPG_4 = new byte[]{0x66, 0x74, 0x79, 0x70, 0x4D, 0x53, 0x4E, 0x56};
private static final byte[] MPG_4_V1 = new byte[]{0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D};
private static final byte[] AVI_HEAD = new byte[]{0x52, 0x49, 0x46, 0x46};
private static final byte[] AVI_TAIL = new byte[]{0x41, 0x56, 0x49, 0x20, 0x4C, 0x49, 0x53, 0x54};
public static boolean isMp4(String path) {
byte[] read = read(path, 4, 11);
return Arrays.equals(read, MPG_4) || Arrays.equals(read, MPG_4_V1);
}
public static boolean isAvi(String path) {
byte[] head = read(path, 0, 3);
if (Arrays.equals(head, AVI_HEAD)) {
byte[] tail = read(path, 8, 15);
return Arrays.equals(tail, AVI_TAIL);
}
return false;
}
private static byte[] read(String path, int from, int to) {
byte[] result = new byte[to - from + 1];
try {
FileInputStream fis = new FileInputStream(path);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.skip(from);
bis.read(result, 0, to - from + 1);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
最后仓库位于:https://gitee.com/ws410/javm
使用实例:https://gitee.com/ws410/javm/blob/master/src/main/java/cn/angs/Test.java
可以将代码拉到本地insatll ,然后引入使用
这里也提供了一个编译好的jar包,地址:https://download.csdn.net/download/wangshun_410/20601937