[TOC]
小伙伴们知道,松哥平时录了蛮多视频课程,视频录完以后,就想整理一个视频文档出来,在整理视频文档的时候,就会遇到一个问题,就是怎么统计视频时长?
特别是有时候为了方便大家看到每一集视频的时长,我要把视频目录整理成下面这个样子:
这个逐集去查看就很麻烦,一套视频动辄几百集,挨个统计不现实,也不符合咱们程序员做事风格。
那么怎么办呢?
一开始我是使用 Python 去解决的,Python 做这样一个小工具其实特别方便,简简单单 30 行代码左右就能搞定了。之前的课程的这些时间统计我基本上都是用 Python 去完成的。
不过最近松哥发现 Java 里边其实也有一个视频处理的库,做这个事情也是非常方便,而且使用 Java 属于主场作战,就能够更加灵活的扩展功能了。
一 jave-all-deps
在 Java 开发中,处理音视频文件经常需要复杂的编解码操作,开发者通常需要依赖于外部库来实现这些功能,其中最著名的是 FFmpeg。然而,直接在 Java 中使用 FFmpeg 并不是一件容易的事,因为它需要处理本地库和复杂的命令行接口。
幸运的是,jave-all-deps 库提供了一个简洁而强大的解决方案,让 Java 开发者能够轻松地进行音视频文件的转码和处理。
jave-all-deps 是 JAVE2(Java Audio Video Encoder)项目的一部分,它是一个基于 ffmpeg 项目的 Java 封装库。JAVE2 通过提供一套简单易用的 API,允许 Java 开发者在不直接处理 ffmpeg 复杂命令的情况下,进行音视频文件的格式转换、转码、剪辑等操作。
jave-all-deps 库特别之处在于它集成了核心 Java 代码和所有支持平台的二进制可执行文件,使得开发者无需手动配置 ffmpeg 环境,即可在多个操作系统上无缝使用。
是不是非常方便?
整体上来说,jave-all-deps 帮我们解决了三大类问题:
- 跨平台兼容性问题:音视频处理往往涉及到不同的操作系统和硬件架构,jave-all-deps 库提供了针对不同平台的预编译 ffmpeg 二进制文件,使得开发者无需担心平台兼容性问题。
- 复杂的命令行操作:ffmpeg 虽然功能强大,但其命令行接口复杂且难以记忆。jave-all-deps 通过封装 ffmpeg 的命令行操作,提供了简洁易用的 Java API,降低了使用门槛。
- 依赖管理:在项目中集成音视频处理功能时,往往需要处理多个依赖项。jave-all-deps 库将核心代码和所有必要的二进制文件打包在一起,简化了依赖管理。
简单来说,就是你想在项目中使用 ffmpeg,但是又嫌麻烦,那么就可以使用 jave-all-deps 这个工具封装后的 ffmpeg,简单快捷!
二 具体用法
jave-all-deps 库提供了多种音视频处理功能,松哥这里来和大家演示几个常见的。
2.1 添加依赖
添加依赖有两种方式,一种就是添加所有的依赖库,如下:
1 2 3 4 5
| <dependency> <groupId>ws.schild</groupId> <artifactId>jave-all-deps</artifactId> <version>3.5.0</version> </dependency>
|
这个库中包含了不同平台所依赖的库的内容。
也可以根据自己平台选择不同的依赖库,这种方式需要首先添加 java-core:
1 2 3 4 5
| <dependency> <groupId>ws.schild</groupId> <artifactId>jave-core</artifactId> <version>3.5.0</version> </dependency>
|
然后再根据自己使用的不同平台,继续添加不同依赖库:
Linux 64 位 amd/intel:
1 2 3 4 5
| <dependency> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-linux64</artifactId> <version>3.5.0</version> </dependency>
|
Linux 64 位 arm:
1 2 3 4 5
| <dependency> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-linux-arm64</artifactId> <version>3.5.0</version> </dependency>
|
Linux 32 位 arm:
1 2 3 4 5
| <dependency> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-linux-arm32</artifactId> <version>3.5.0</version> </dependency>
|
Windows 64 位:
1 2 3 4 5
| <dependency> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-win64</artifactId> <version>3.5.0</version> </dependency>
|
MacOS 64 位:
1 2 3 4 5
| <dependency> <groupId>ws.schild</groupId> <artifactId>jave-nativebin-osx64</artifactId> <version>3.5.0</version> </dependency>
|
2.2 视频转音频
将视频文件从一种格式转换为另一种格式,例如将 AVI 文件转换为 MPEG 文件。
1 2 3 4 5 6 7 8 9 10 11 12
| File source = new File("D:\\AI智能体\\mp4\\01.大模型有什么缺陷.mp4"); File target = new File("D:\\AI智能体\\mp4\\01.大模型有什么缺陷.mp3"); AudioAttributes audio = new AudioAttributes(); audio.setCodec("libmp3lame"); audio.setBitRate(128000); audio.setChannels(2); audio.setSamplingRate(44100); EncodingAttributes attrs = new EncodingAttributes(); attrs.setOutputFormat("mp3"); attrs.setAudioAttributes(audio); Encoder encoder = new Encoder(); encoder.encode(new MultimediaObject(source), target, attrs);
|
2.3 视频格式转换
将一种视频格式转换为另外一种视频格式,例如将 mp4 转为 flv:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| File source = new File("D:\\AI智能体\\mp4\\01.大模型有什么缺陷.mp4"); File target = new File("D:\\AI智能体\\mp4\\01.大模型有什么缺陷.flv"); AudioAttributes audio = new AudioAttributes(); audio.setCodec("libmp3lame"); audio.setBitRate(64000); audio.setChannels(1); audio.setSamplingRate(22050); VideoAttributes video = new VideoAttributes(); video.setCodec("flv"); video.setBitRate(160000); video.setFrameRate(15); video.setSize(new VideoSize(400, 300)); EncodingAttributes attrs = new EncodingAttributes(); attrs.setOutputFormat("flv"); attrs.setAudioAttributes(audio); attrs.setVideoAttributes(video); Encoder encoder = new Encoder(); encoder.encode(new MultimediaObject(source), target, attrs);
|
2.4 获取视频时长
这个就是松哥的需求了,我这块举个简单例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class App { static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("mm:ss");
public static void main(String[] args) throws EncoderException { System.out.println("输入视频目录:"); String dir = new Scanner(System.in).next(); File folder = new File(dir); List<String> files = sort(folder); outputVideoTime(files); }
private static void outputVideoTime(List<String> files) throws EncoderException { for (String file : files) { File video = new File(file); if (video.isFile() && !video.getName().startsWith(".") && video.getName().endsWith(".mp4")) { MultimediaObject multimediaObject = new MultimediaObject(video); long duration = multimediaObject.getInfo().getDuration(); String s = "%s %s"; System.out.println(String.format(s, video.getName(), DATE_FORMAT.format(duration))); } else if (video.isDirectory()) { System.out.println(video.getName()); outputVideoTime(sort(video)); } } }
public static List<String> sort(File folder) { return Arrays.stream(folder.listFiles()).map(f -> f.getAbsolutePath()).sorted(String.CASE_INSENSITIVE_ORDER).collect(Collectors.toList()); } }
|
这段代码基本上都是 Java 基础语法,没啥难的,我也就不多说了。有不明白的地方欢迎加松哥微信讨论。
其实 Java 解决这个似乎也不难,也就是 20 行代码左右,似乎和 Python 不相上下。
三 总结
jave-all-deps 库是 Java 音视频处理领域的一个强大工具,它通过封装 ffmpeg 的复杂功能,为 Java 开发者提供了一个简单易用的音视频处理解决方案。该库解决了跨平台兼容性问题、简化了复杂的命令行操作,并简化了项目中的依赖管理。无论是进行格式转换、音频转码还是其他音视频处理任务,jave-all-deps 库都是一个值得考虑的选择。
通过本文的介绍,希望能够帮助读者更好地理解和使用 jave-all-deps 库。