MP4Parser change video orientation

无人久伴 提交于 2019-12-18 06:49:49

问题


Im attempting to rotate a video that is in landscape into portrait using MP4Parser (or any other method if you know of one) currently playing with the TrackHeaderBox but unable to get the orientation to change at all, has anyone used this before that can spot the mistake I may of made? any help will go a long way thanks

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);

回答1:


Embedding Information about Rotation in the MP4

Are you really changing the orientation of the video track? If you change the orientation of the audio track you will not see any change.

From my experience it's easier to change the orientation of the whole file (1.0.4.2 API Version):

    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());

alternatively if you want to change the orientation directly without going via a Movie object:

    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());

The file result.mp4 is now rotated by 180 degrees as you can verify by playing back the file in a desktop player such as QuickTime or VLC.

Typical Problems on Android

When you playback the video on Android with the help of the VideoView you might notice that the matrix is not taken into account. I'm not entirely sure if this is done on purpose or not but the workaround is to use a TextureView that applies the transformation.

In order to do so you have to

  • extract the matrices from the MovieHeaderBox at /moov/mvhd and from MediaHeaderBox at /moov/trak[0, 1, 2, 3]/tkhd (depending on which trak contains the video).
  • Combine both matrices via matrix multiplication.
  • CallsetScaleX, setScaleY, setPivotX,setPivotY and setRotation with values according to the resulting matrix from the step before.



回答2:


The proposed solution by @Sebastian is only respected by a few media players. Secondly tools like Exiftool and MediaInfo does not correctly parse this.

The post here by a mp4Parser maintainer hints that one should use '/moov/trak/tkhd' instead of '/moov/mvhd'

The example below will make files with correct rotation.

        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);


来源:https://stackoverflow.com/questions/17177912/mp4parser-change-video-orientation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!