MP4解析器如何更改视频方向

4

我正在尝试使用MP4Parser(或其他方法,如果您知道的话)将横向视频旋转成纵向。目前在使用TrackHeaderBox进行尝试,但是无法改变方向。请问有没有人曾经使用过这个方法,并能够发现我可能犯的错误?任何帮助都将对我有所裨益,谢谢!

IsoFile out = new DefaultMp4Builder().build(result);

        // test

        double[] m = null;
        m = new double[] { 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };

        TrackBox tb = out.getMovieBox().getBoxes(TrackBox.class).get(0);
        TrackHeaderBox box = tb.getTrackHeaderBox();
        box.setMatrix(m);
2个回答

1

在MP4中嵌入旋转信息

您真的要改变视频轨道的方向吗?如果您更改音频轨道的方向,将不会看到任何变化。

根据我的经验,更改整个文件的方向会更容易(1.0.4.2 API版本):

    Movie result = MovieCreator.build("input.mp4");
    // do something with the file
    Container out = new DefaultMp4Builder().build(result);
    MovieHeaderBox mvhd = Path.getPath(out, "moov/mvhd");
    mvhd.setMatrix(Matrix.ROTATE_180);
    out.writeContainer(new FileOutputStream("result.mp4").getChannel());

如果您想直接更改方向而无需通过 Movie 对象:

    IsoFile isoFile = new IsoFile("video.mp4");
    MovieHeaderBox mvhd = Path.getPath(isoFile, "/moov/mvhd");
    mvhd.setMatrix(Matrix.ROTATE_180);
    isoFile.writeContainer(new FileOutputStream("result.mp4").getChannel());

文件result.mp4已经旋转了180度,您可以通过在桌面播放器(如QuickTime或VLC)中回放文件来验证。

Android上的典型问题

当您使用VideoView在Android上播放视频时,您可能会注意到矩阵没有被考虑在内。我不确定这是否是有意为之,但解决方法是使用一个应用了变换的TextureView

为了做到这一点,您需要:

  • 从/Moov/Mvhd中提取MovieHeaderBox中的矩阵,以及从/Moov/Trak[0、1、2、3]/Tkhd中提取MediaHeaderBox中的矩阵(取决于哪个轨道包含视频)。
  • 通过矩阵乘法组合两个矩阵。
  • 根据前一步的结果,调用setScaleXsetScaleYsetPivotXsetPivotYsetRotation

在许多情况下,音频或视频录制的长度并不相等。如果音频比视频短,则下一轨道的音频将提前开始。您可能希望在每个音频后附加静音:https://code.google.com/p/mp4parser/source/browse/trunk/examples/src/main/java/com/googlecode/mp4parser/SilencePrepender.java - Sebastian Annies
@Sebastian Annies的isoparser-1.0 RC-24 jar文件不可用。 - Ajay
请使用更新的版本。1.0.4.2 可在 Maven 中央获取。 - Sebastian Annies
当我使用较新版本时,这个方法track.getDecodingTimeEntries()出现了问题,它不可用。在我的应用程序中,修剪视频的概念非常重要。当我修剪横向视频时,效果非常好。但是,如果我修剪纵向视频,则视频的旋转会改变为90度,并且方向也会改变为横向。 - Ajay
for (int i = 0; i < track.getSampleDurations().size(); i++) { TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i); for (int j = 0; j < entry.getCount(); j++) { - Ajay
显示剩余11条评论

1
@Sebastian提出的解决方案只被少数媒体播放器所支持。其次,像Exiftool和MediaInfo这样的工具无法正确解析此类问题。
mp4Parser维护者在这里的帖子中暗示应该使用'/moov/trak/tkhd'而不是'/moov/mvhd'。
下面的示例将生成具有正确旋转的文件。
        IsoFile isoFile = new IsoFile(srcVideo.getAbsolutePath());
        FileOutputStream fileOutputStream = new FileOutputStream(destVideo.getAbsolutePath());
        FileChannel channel = fileOutputStream.getChannel()

        TrackHeaderBox thb = Path.getPath(isoFile, "/moov/trak/tkhd");
        thb.setMatrix(Matrix.ROTATE_90);
        isoFile.writeContainer(channel);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接