Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

336
LINES

< > BotCompany Repo | #1006719 // class Transcode (from JCodec 0.2.0)

JavaX fragment (include)

import static org.jcodec.common.Tuple._2;
import static org.jcodec.common.Tuple._3;

import org.jcodec.common.Codec;
import org.jcodec.common.Demuxer;
import org.jcodec.common.DemuxerTrack;
import org.jcodec.common.DemuxerTrackMeta;
import org.jcodec.common.Format;
import org.jcodec.common.JCodecUtil;
import org.jcodec.common.TrackType;
import org.jcodec.common.logging.Logger;
import org.jcodec.common.model.Packet;
import org.jcodec.common.tools.MainUtils;
import org.jcodec.common.tools.MainUtils.Cmd;
import org.jcodec.common.tools.MathUtil;
import org.jcodec.samples.transcode.Transcoder.Filter;
import org.jcodec.samples.transcode.filters.DumpMvFilter;

/**
 * This class is part of JCodec ( www.jcodec.org ) This software is distributed
 * under FreeBSD License
 * 
 * Transcoder command line.
 * 
 * @author The JCodec project
 * 
 */
sclass TranscodeMain {
  private static final String FLAG_SEEK_FRAMES = "seek-frames";
  private static final String FLAG_MAX_FRAMES = "max-frames";

  private static final String FLAG_OUTPUT_AUDIO_CODEC = "o:ac";
  private static final String FLAG_INPUT_AUDIO_CODEC = "i:ac";
  private static final String FLAG_OUTPUT_VIDEO_CODEC = "o:vc";
  private static final String FLAG_INPUT_VIDEO_CODEC = "i:vc";
  private static final String FLAG_OUTPUT_FORMAT = "o:f";
  private static final String FLAG_INPUT_FORMAT = "i:f";

  private static final String FLAG_PROFILE = "profile";
  private static final String FLAG_INTERLACED = "interlaced";

  private static final String FLAG_DUMPMV = "dumpMv";
  private static final String FLAG_DUMPMVJS = "dumpMvJs";

  private static final String FLAG_DOWNSCALE = "downscale";

  private static Map<String, Format> extensionToF = new HashMap<String, Format>();
  private static Map<String, Codec> extensionToC = new HashMap<String, Codec>();
  private static Map<Format, Codec> videoCodecsForF = new HashMap<Format, Codec>();
  private static Map<Format, Codec> audioCodecsForF = new HashMap<Format, Codec>();
  private static Set<Codec> supportedDecoders = new HashSet<Codec>();

  static {
      extensionToF.put("mpg", Format.MPEG_PS);
      extensionToF.put("mpeg", Format.MPEG_PS);
      extensionToF.put("m2p", Format.MPEG_PS);
      extensionToF.put("ps", Format.MPEG_PS);
      extensionToF.put("vob", Format.MPEG_PS);
      extensionToF.put("evo", Format.MPEG_PS);
      extensionToF.put("mod", Format.MPEG_PS);
      extensionToF.put("tod", Format.MPEG_PS);

      extensionToF.put("ts", Format.MPEG_TS);
      extensionToF.put("m2t", Format.MPEG_TS);

      extensionToF.put("mp4", Format.MOV);
      extensionToF.put("m4a", Format.MOV);
      extensionToF.put("m4v", Format.MOV);
      extensionToF.put("mov", Format.MOV);
      extensionToF.put("3gp", Format.MOV);

      extensionToF.put("mkv", Format.MKV);
      extensionToF.put("webm", Format.MKV);

      extensionToF.put("264", Format.H264);
      extensionToF.put("raw", Format.RAW);
      extensionToF.put("", Format.RAW);
      extensionToF.put("flv", Format.FLV);
      extensionToF.put("avi", Format.AVI);
      extensionToF.put("jpg", Format.IMG);
      extensionToF.put("jpeg", Format.IMG);
      extensionToF.put("png", Format.IMG);

      extensionToF.put("mjp", Format.MJPEG);

      extensionToF.put("ivf", Format.IVF);
      extensionToF.put("y4m", Format.Y4M);
      extensionToF.put("wav", Format.WAV);

      extensionToC.put("mpg", Codec.MPEG2);
      extensionToC.put("mpeg", Codec.MPEG2);
      extensionToC.put("m2p", Codec.MPEG2);
      extensionToC.put("ps", Codec.MPEG2);
      extensionToC.put("vob", Codec.MPEG2);
      extensionToC.put("evo", Codec.MPEG2);
      extensionToC.put("mod", Codec.MPEG2);
      extensionToC.put("tod", Codec.MPEG2);
      extensionToC.put("ts", Codec.MPEG2);
      extensionToC.put("m2t", Codec.MPEG2);
      extensionToC.put("m4a", Codec.AAC);
      extensionToC.put("mkv", Codec.H264);
      extensionToC.put("webm", Codec.VP8);
      extensionToC.put("264", Codec.H264);
      extensionToC.put("raw", Codec.RAW);
      extensionToC.put("jpg", Codec.JPEG);
      extensionToC.put("jpeg", Codec.JPEG);
      extensionToC.put("png", Codec.PNG);
      extensionToC.put("mjp", Codec.JPEG);
      extensionToC.put("y4m", Codec.RAW);

      videoCodecsForF.put(Format.MPEG_PS, Codec.MPEG2);
      audioCodecsForF.put(Format.MPEG_PS, Codec.MP2);
      videoCodecsForF.put(Format.MOV, Codec.H264);
      audioCodecsForF.put(Format.MOV, Codec.AAC);
      videoCodecsForF.put(Format.MKV, Codec.VP8);
      audioCodecsForF.put(Format.MKV, Codec.VORBIS);
      audioCodecsForF.put(Format.WAV, Codec.PCM);
      videoCodecsForF.put(Format.H264, Codec.H264);
      videoCodecsForF.put(Format.RAW, Codec.RAW);
      videoCodecsForF.put(Format.FLV, Codec.H264);
      videoCodecsForF.put(Format.AVI, Codec.MPEG4);
      videoCodecsForF.put(Format.IMG, Codec.PNG);
      videoCodecsForF.put(Format.MJPEG, Codec.JPEG);
      videoCodecsForF.put(Format.IVF, Codec.VP8);
      videoCodecsForF.put(Format.Y4M, Codec.RAW);

      supportedDecoders.add(Codec.AAC);
      supportedDecoders.add(Codec.H264);
      supportedDecoders.add(Codec.JPEG);
      supportedDecoders.add(Codec.MPEG2);
      supportedDecoders.add(Codec.PCM);
      supportedDecoders.add(Codec.PNG);
      supportedDecoders.add(Codec.PRORES);
      supportedDecoders.add(Codec.RAW);
      supportedDecoders.add(Codec.VP8);
  }

  public static void main(String[] args) throws Exception {
      Cmd cmd = MainUtils.parseArguments(args);
      if (args.length < 2) {
          MainUtils.printHelpVarArgs(new HashMap<String, String>() {
              {

                  put(FLAG_INPUT_FORMAT, "Input format [default=auto].");
                  put(FLAG_OUTPUT_FORMAT, "Output format [default=auto].");
                  put(FLAG_INPUT_VIDEO_CODEC, "Input video codec [default=auto].");
                  put(FLAG_OUTPUT_VIDEO_CODEC, "Output video codec [default=auto].");
                  put(FLAG_INPUT_AUDIO_CODEC, "Input audio codec [default=auto].");
                  put(FLAG_OUTPUT_AUDIO_CODEC, "Output audio codec [default=auto].");
                  put(FLAG_SEEK_FRAMES, "Seek frames");
                  put(FLAG_MAX_FRAMES, "Max frames");
                  put(FLAG_PROFILE, "Profile to use (supported by some encoders).");
                  put(FLAG_INTERLACED, "Encode output as interlaced (supported by Prores encoder).");
                  put(FLAG_DUMPMV, "Dump motion vectors (supported by h.264 decoder).");
                  put(FLAG_DUMPMVJS, "Dump motion vectors in form of JASON file (supported by h.264 decoder).");
                  put(FLAG_DOWNSCALE, "Decode frames in downscale (supported by MPEG, Prores and Jpeg decoders).");
              }
          }, "input", "output");
          return;
      }

      String input = cmd.getArg(0);
      String output = cmd.getArg(1);

      String inputFormatRaw = cmd.getStringFlag(FLAG_INPUT_FORMAT);
      Format inputFormat;
      if (inputFormatRaw == null) {
          inputFormat = getFormatFromExtension(input);
          if (inputFormat != Format.IMG) {
              Format detectFormat = JCodecUtil.detectFormat(new File(input));
              if (detectFormat != null)
                  inputFormat = detectFormat;
          }
      } else {
          inputFormat = Format.valueOf(inputFormatRaw.toUpperCase());
      }
      if (inputFormat == null) {
          Logger.error("Input format could not be detected");
          return;
      }

      String outputFormatRaw = cmd.getStringFlag(FLAG_OUTPUT_FORMAT);
      Format outputFormat;
      if (outputFormatRaw == null) {
          outputFormat = getFormatFromExtension(output);
      } else {
          outputFormat = Format.valueOf(outputFormatRaw.toUpperCase());
      }

      int videoTrackNo = -1;
      String inputCodecVideoRaw = cmd.getStringFlag(FLAG_INPUT_VIDEO_CODEC);
      _3<Integer, Integer, Codec> inputCodecVideo = null;
      if (inputCodecVideoRaw == null) {
          if (inputFormat == Format.IMG) {
              inputCodecVideo = _3(0, 0, getCodecFromExtension(input));
          } else if (inputFormat.isVideo()) {
              inputCodecVideo = selectSuitableTrack(input, inputFormat, TrackType.VIDEO);
          }
      } else {
          inputCodecVideo = _3(0, 0, Codec.valueOf(inputCodecVideoRaw.toUpperCase()));
      }

      String outputCodecVideoRaw = cmd.getStringFlag(FLAG_OUTPUT_VIDEO_CODEC);
      Codec outputCodecVideo = null;
      boolean videoCopy = false;
      if (outputCodecVideoRaw == null) {
          outputCodecVideo = getCodecFromExtension(output);
          if (outputCodecVideo == null)
              outputCodecVideo = getFirstVideoCodecForFormat(outputFormat);
      } else {
          if ("copy".equalsIgnoreCase(outputCodecVideoRaw)) {
              videoCopy = true;
              outputCodecVideo = inputCodecVideo.v2;
          } else if("none".equalsIgnoreCase(outputCodecVideoRaw)) {
              outputCodecVideo = null;
              inputCodecVideo = null;
          } else {
              outputCodecVideo = Codec.valueOf(outputCodecVideoRaw.toUpperCase());
          }
      }

      String inputCodecAudioRaw = cmd.getStringFlag(FLAG_INPUT_AUDIO_CODEC);
      _3<Integer, Integer, Codec> inputCodecAudio = null;
      if (inputCodecAudioRaw == null) {
          if (inputFormat.isAudio()) {
              inputCodecAudio = selectSuitableTrack(input, inputFormat, TrackType.AUDIO);
          }
      } else {
          inputCodecAudio = _3(0, 0, Codec.valueOf(inputCodecAudioRaw.toUpperCase()));
      }

      String outputCodecAudioRaw = cmd.getStringFlag(FLAG_OUTPUT_AUDIO_CODEC);
      Codec outputCodecAudio = null;
      boolean audioCopy = false;
      if (outputCodecAudioRaw == null) {
          if (outputFormat.isAudio())
              outputCodecAudio = getFirstAudioCodecForFormat(outputFormat);
      } else {
          if ("copy".equalsIgnoreCase(outputCodecAudioRaw)) {
              audioCopy = true;
              outputCodecAudio = inputCodecAudio.v2;
          } else if("none".equalsIgnoreCase(outputCodecVideoRaw)) {
              outputCodecAudio = null;
              inputCodecAudio = null;
          } else {
              outputCodecAudio = Codec.valueOf(outputCodecAudioRaw.toUpperCase());
          }
      }
      if (inputCodecAudio == null)
          outputCodecAudio = null;

      List<Filter> filters = new ArrayList<Filter>();
      if (cmd.getBooleanFlag(FLAG_DUMPMV))
          filters.add(new DumpMvFilter(false));
      else if (cmd.getBooleanFlag(FLAG_DUMPMVJS))
          filters.add(new DumpMvFilter(true));

      Transcoder transcoder = new Transcoder(cmd.getArg(0), cmd.getArg(1), inputFormat, outputFormat, inputCodecVideo,
              outputCodecVideo, inputCodecAudio, outputCodecAudio, videoCopy, audioCopy, filters);
      transcoder.setSeekFrames(cmd.getIntegerFlagD(FLAG_SEEK_FRAMES, 0));
      transcoder.setMaxFrames(cmd.getIntegerFlagD(FLAG_MAX_FRAMES, Integer.MAX_VALUE));
      transcoder.setProfile(cmd.getStringFlag(FLAG_PROFILE));
      transcoder.setInterlaced(cmd.getBooleanFlagD(FLAG_INTERLACED, false));
      Integer downscale = cmd.getIntegerFlagD(FLAG_DOWNSCALE, 1);
      if (downscale != null && (1 << MathUtil.log2(downscale)) != downscale) {
          Logger.error(
                  "Only values [2, 4, 8] are supported for " + FLAG_DOWNSCALE + ", the option will have no effect.");
      } else {
          transcoder.setDownscale(downscale);
      }
      transcoder.transcode();
  }

  private static Codec getFirstAudioCodecForFormat(Format inputFormat) {
      return audioCodecsForF.get(inputFormat);
  }

  private static Codec getFirstVideoCodecForFormat(Format inputFormat) {
      return videoCodecsForF.get(inputFormat);
  }

  private static Codec detectVideoDecoder(DemuxerTrack track) throws IOException {
      DemuxerTrackMeta meta = track.getMeta();
      if (meta != null) {
          Codec codec = meta.getCodec();
          if (codec != null)
              return codec;
      }
      Packet packet = track.nextFrame();
      if (packet == null)
          return null;

      return JCodecUtil.detectDecoder(packet.getData());
  }

  private static _3<Integer, Integer, Codec> selectSuitableTrack(String input, Format format, TrackType targetType)
          throws IOException {
      _2<Integer, Demuxer> demuxerPid;
      if (format == Format.MPEG_TS) {
          demuxerPid = JCodecUtil.createM2TSDemuxer(new File(input), targetType);
      } else {
          demuxerPid = _2(0, JCodecUtil.createDemuxer(format, new File(input)));
      }
      if(demuxerPid == null || demuxerPid.v1 == null)
          return null;
      int trackNo = 0;
      List<? extends DemuxerTrack> tracks = targetType == TrackType.VIDEO ? demuxerPid.v1.getVideoTracks()
              : demuxerPid.v1.getAudioTracks();
      for (DemuxerTrack demuxerTrack : tracks) {
          Codec codec = detectVideoDecoder(demuxerTrack);
          if (supportedDecoders.contains(codec)) {
              return _3(demuxerPid.v0, trackNo, codec);
          }
          trackNo++;
      }
      return null;
  }

  private static Format getFormatFromExtension(String output) {
      String extension = output.replaceFirst(".*\\.([^\\.]+$)", "$1");
      return extensionToF.get(extension);
  }

  private static Codec getCodecFromExtension(String output) {
      String extension = output.replaceFirst(".*\\.([^\\.]+$)", "$1");
      return extensionToC.get(extension);
  }

  public static Set<Format> formats(Format... formats) {
      return new HashSet<Format>(Arrays.asList(formats));
  }

  public static Set<Codec> codecs(Codec... codecs) {
      return new HashSet<Codec>(Arrays.asList(codecs));
  }
}

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1006719
Snippet name: class Transcode (from JCodec 0.2.0)
Eternal ID of this version: #1006719/1
Text MD5: 6dc867e73742a9f883255c045cc1e4d7
Author: stefan
Category: javax video
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-02-02 23:49:20
Source code size: 14061 bytes / 336 lines
Pitched / IR pitched: No / No
Views / Downloads: 603 / 604
Referenced in: [show references]