private long getVideoBitrateBasedOnFileBitrate() {
    // file bitrate
    String fileBitrate = conversionSetting.getFfProbe().getFormat().getBit_rate();
    long fbr;
    if (fileBitrate == null || fileBitrate.trim().length() == 0) {
      return 0l;
    } else {
      try {
        fbr = Long.parseLong(fileBitrate);
      } catch (Exception e) {
        // number format exception
        return 0l;
      }
    }

    // audio bitrate
    long abr;
    Stream audioStream = getStream(CODEC_TYPE_AUDIO);
    String audioBitrate = audioStream.getBit_rate();
    try {
      abr = Long.parseLong(audioBitrate);
    } catch (Exception e) {
      // number format exception
      abr = Settings.getDefaultPerChannelAudioBitRate() * audioStream.getChannels();
    }

    return fbr - abr;
  }
  //
  // general information about this file
  // =================================================================================================================
  private int internalGetType() {

    Stream videoStream = getStream(CODEC_TYPE_VIDEO);
    if (videoStream == null) return TYPE_NO_GOOD;

    Stream audioStream = getStream(CODEC_TYPE_AUDIO);
    if (audioStream == null) return TYPE_NO_GOOD;

    // good video codec and profile
    if (VIDEO_CODEC.equals(videoStream.getCodec_name())
        && VIDEO_PROFILE.equals(videoStream.getProfile())) {

      // good audio codec
      if (AUDIO_CODEC_1.equals(audioStream.getCodec_name())
          || AUDIO_CODEC_2.equals(audioStream.getCodec_name())) {

        // good container
        String ext =
            FilenameUtils.getExtension(conversionSetting.getOriginalVideoFile().getAbsolutePath());
        if (MP4.equals(ext)
            && conversionSetting.getFfProbe().getFormat().getFormat_name().contains(MP4)) {
          return TYPE_NO_CHANGE;
        }

        return TYPE_JUST_CHANGE_CONTAINER;
      }

      return TYPE_CONVERT_ONLY_AUDIO;
    }

    // same file size uses 2 pass, other qualities uses CRF
    return conversionSetting.getQuality() == Settings.QUALITY_SAME_FILE_SIZE
        ? TYPE_TWO_PASS
        : TYPE_CRF;
  }
  private String[] internalGetSubtitle(int position) {

    Stream subtitle = null;

    int subtitleIndex = 0;

    for (int streamIndex = 0;
        streamIndex < conversionSetting.getFfProbe().getStreams().size();
        streamIndex++) {
      Stream s = conversionSetting.getFfProbe().getStreams().get(streamIndex);
      if (CODEC_TYPE_SUBTITLE.equals(s.getCodec_type())
          && !INVALID_SUBTITLE.equals(s.getCodec_name())) {

        if (position == subtitleIndex) {
          subtitle = s;
        }

        subtitleIndex++; // increment for all valid subtitles
      }
    }

    if (subtitle == null) return null;

    // get the language code for the filename
    String language = null;
    Tags t = subtitle.getTags();
    if (t != null) {
      language = t.getLanguage();
    }

    if (language == null) language = "DEFAULT";

    File fileName = conversionSetting.getSubtitleFileName(language);

    ArrayList<String> cmd = new ArrayList<String>();
    cmd.add("ffmpeg");
    cmd.add("-i");
    cmd.add(conversionSetting.getOriginalVideoFile().getAbsolutePath());
    cmd.add("-vn");
    cmd.add("-an");
    cmd.add("-map");
    cmd.add("0:s:" + position);
    cmd.add(fileName.getAbsolutePath());

    return getArray(cmd);
  }
 private int internalGetNumberOfSubtitles() {
   int numberOfSubtitles = 0;
   for (Stream s : conversionSetting.getFfProbe().getStreams()) {
     if (CODEC_TYPE_SUBTITLE.equals(s.getCodec_type())
         && !INVALID_SUBTITLE.equals(s.getCodec_name())) {
       numberOfSubtitles++;
     }
   }
   return numberOfSubtitles;
 }
 private Stream getStream(String name) {
   for (int i = 0; i < conversionSetting.getFfProbe().getStreams().size(); i++)
     if (name.equals(conversionSetting.getFfProbe().getStreams().get(i).getCodec_type()))
       return conversionSetting.getFfProbe().getStreams().get(i);
   return null;
 }