一、mp4parser 介绍
mp4parser
是用于读取,写入和创建 MP4 容器的 Java API。操作容器不同于编码和解码视频和音频。
二、mp4parser 使用
2.1 Gradle
implementation 'com.googlecode.mp4parser:isoparser:1.1.22'
2.2 Maven:
<dependency>
<groupId>org.mp4parser</groupId>
<artifactId>isoparser</artifactId>
<version>1.9.27</version>
</dependency>
对于不使用依赖管理工具的项目,可以在发布页面上下载每个版本的 artifacts(jar,javadoc-jar,source-jar)
。请注意,该项目需要 aspectj-rt.jar
库。
三、mp4parser 功能
混合音频或视频到 MP4 文件中
合并相同编码设置的 MP4 文件
增加或者改变 MP4 文件的
metadata
通过省略帧的方式缩短 MP4 文件
官方例子采用的编解码格式是 H264
和 AAC
,因为这两种格式对于 MP4 文件非常常见。还有 AC-3
格式也很常见,它常用于 DVD。至于 H263 / MPEG-2
视频轨道,它们已经很少在 Android 手机上使用了。
3.1 混合音频和视频
3.1.1 将每个原始格式文件包装到对应的 Track 对象中。
H264TrackImpl h264Track = new H264TrackImpl(new FileDataSourceImpl("video.h264"));
AACTrackImpl aacTrack = new AACTrackImpl(new FileDataSourceImpl("audio.aac"));
3.1.2 然后将这些 Track 对象添加到 Movie 对象
Movie movie = new Movie();
movie.addTrack(h264Track);
movie.addTrack(aacTrack);
3.1.3 将 Movie 对象传入 MP4Builder 以创建容器。
Container mp4file = new DefaultMp4Builder().build(movie);
3.1.4 将容器写入适当的文件通道。
FileChannel fc = new FileOutputStream(new File("output.mp4")).getChannel();
mp4file.writeContainer(fc);
fc.close();
There are cases where the frame rate is signalled out of band or is known in advance so that the H264 doesn't contain it literally. In this case you will have to supply it to the constructor.(这段笔者不知道该怎么翻译才正确。)
有以下格式的 Track 实现:
H264
AAC
AC3
EC3
另外还有两种不直接包装原始格式的字幕轨道,但它们在概念上是相似的。
四、常见问题
音频和视频不同步。
4.1 音频在视频之前开始
In AAC there are always samplerate / 1024 sample/s so each sample's duration is 1000 * 1024 / samplerate milliseconds.(这段笔者真的不知道该怎么翻译。)
48KHz => ~21.3ms
44.1KHz => ~23.2ms
通过移除样本,你可以轻松缩短音轨。我们应该尽可能多地移除。因为你无法将音频和视频完全匹配,但人类对于 early audio
比对 late audio
更敏感。
请记住:如果有人距离仅 10 米,音频和视频之间的延迟时间即使 > 30 毫秒,大脑也不会感知出差异。
AACTrackImpl aacTrackOriginal = new AACTrackImpl(new FileDataSourceImpl("audio.aac"));
// removes the first sample and shortens the AAC track by ~22ms
CroppedTrack aacTrackShort = new CroppedTrack(aacTrackOriginal, 1, aacTrack.getSamples().size());
五、合并具有相同编码设置的视频
需要提醒的是,你不能合并符合以下情况的两个视频:
Different resolutions
(不同的分辨率)Different frame-rates
(不同的帧速率)
六、mp4parser 不能做什么?
从电影中创建 JPEG
格式的图像文件。这是做不到的,mp4parser
不是解码器。