Как записать метаданные ротации в видео в xuggler? - PullRequest
0 голосов
/ 09 июля 2019

Я создал класс для изменения размера видео.Я проверил это с видео, снятым на моем мобильном телефоне в портретном режиме.Видео корректно отображается в портретном режиме в любой кабине медиаплеера на телефоне и компьютере.Однако при использовании моей программы для изменения размера видео корректно изменяется размер, но метаданные поворота теряются.

Запрос метаданных моего входного видео через mediainfo дает следующий вывод:

General
Complete name                            : /home/sneese/Downloads/20190708_095754.mp4
Format                                   : MPEG-4
Format profile                           : Base Media / Version 2
Codec ID                                 : mp42 (isom/mp42)
File size                                : 22.7 MiB
Duration                                 : 6s 741ms
Overall bit rate                         : 28.3 Mbps
Encoded date                             : UTC 2019-07-08 07:58:02
Tagged date                              : UTC 2019-07-08 07:58:02
com.android.version                      : 8.0.0

Video
ID                                       : 1
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : High@L4.2
Format settings, CABAC                   : Yes
Format settings, ReFrames                : 1 frame
Format settings, GOP                     : M=1, N=60
Codec ID                                 : avc1
Codec ID/Info                            : Advanced Video Coding
Duration                                 : 6s 732ms
Bit rate                                 : 28.0 Mbps
Width                                    : 1 920 pixels
Height                                   : 1 080 pixels
Display aspect ratio                     : 16:9
Rotation                                 : 90°
Frame rate mode                          : Variable
Frame rate                               : 60.000 fps
Minimum frame rate                       : 59.094 fps
Maximum frame rate                       : 60.934 fps
Color space                              : YUV
Chroma subsampling                       : 4:2:0
Bit depth                                : 8 bits
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 0.225
Stream size                              : 22.5 MiB (99%)
Title                                    : VideoHandle
Language                                 : English
Encoded date                             : UTC 2019-07-08 07:58:02
Tagged date                              : UTC 2019-07-08 07:58:02
mdhd_Duration                            : 6732

Audio
ID                                       : 2
Format                                   : AAC
Format/Info                              : Advanced Audio Codec
Format profile                           : LC
Codec ID                                 : 40
Duration                                 : 6s 741ms
Source duration                          : 6s 745ms
Source_Duration_FirstFrame               : 3ms
Bit rate mode                            : Constant
Bit rate                                 : 256 Kbps
Channel(s)                               : 2 channels
Channel positions                        : Front: L R
Sampling rate                            : 48.0 KHz
Frame rate                               : 46.875 fps (1024 spf)
Compression mode                         : Lossy
Stream size                              : 211 KiB (1%)
Source stream size                       : 211 KiB (1%)
Title                                    : SoundHandle
Language                                 : English
Encoded date                             : UTC 2019-07-08 07:58:02
Tagged date                              : UTC 2019-07-08 07:58:02
mdhd_Duration                            : 6741

По мере того как выможно видеть, что поворот установлен на 90 градусов.

Это мой код:

Основной класс: пакет test.video;

import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IMetaData;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;

public class MediaConverter {

      private static final String INPUT_FILE = "/home/user/input_video.mp4";
      private static final String OUTPUT_FILE = "/home/user/output_video.mp4";

      public static void main(String[] args) throws IOException {
          convertVideo(INPUT_FILE, OUTPUT_FILE, 640, 360);
      }

    private static void convertVideo(String inputFile, String outputFile, int width, int height){ 
            // reader
            IMediaReader reader = ToolFactory.makeReader(inputFile);
            Resizer resizer = new Resizer(width, height);
            reader.addListener(resizer);

            // writer
            IMediaWriter writer = ToolFactory.makeWriter(outputFile, reader);
            resizer.addListener(writer); 
            while (reader.readPacket() == null) { 
                // no need to do anything here just let him read
            }
        writer.flush();
    }
}

MediaToolAdapter: пакет test.video;

import com.xuggle.mediatool.MediaToolAdapter;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.mediatool.event.IWriteHeaderEvent;
import com.xuggle.mediatool.event.VideoPictureEvent;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IMetaData;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.IVideoResampler;
import java.util.Collection;

public class Resizer extends MediaToolAdapter {
      private Integer width;
      private Integer height;

      private IVideoResampler videoResampler = null;

      public Resizer(Integer aWidth, Integer aHeight) {
            this.width = aWidth;
            this.height = aHeight;
      }

      @Override
      public void onAddStream(IAddStreamEvent event) {
            int streamIndex = event.getStreamIndex();
            IStreamCoder streamCoder = event.getSource().getContainer().getStream(streamIndex).getStreamCoder();
            if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
            IStream stream = event.getSource().getContainer().getStream(streamIndex);
                  streamCoder.setWidth(width);
                  streamCoder.setHeight(height);
            // checked if this writes the metadata - but does not
            streamCoder.setProperty(stream.getMetaData(), null);
            event.getSource().getContainer().setMetaData(stream.getMetaData());
            }
            super.onAddStream(event);
      }

      @Override
      public void onVideoPicture(IVideoPictureEvent event) {
            IVideoPicture pic = event.getPicture();
            if (videoResampler == null) {
                videoResampler = IVideoResampler.make(width, height, pic.getPixelType(), pic.getWidth(), pic
                        .getHeight(), pic.getPixelType());
            }
            IVideoPicture out = IVideoPicture.make(pic.getPixelType(), width, height);
            videoResampler.resample(out, pic);

            IVideoPictureEvent asc = new VideoPictureEvent(event.getSource(), out, event.getStreamIndex());
            super.onVideoPicture(asc);
            out.delete();
      }
}

Ожидаемым результатом будет то, что видео будет отображаться в портретном режиме после преобразования, если оно было таким же до преобразования, в противном случае альбомный режим.Спасибо

...