예제 #1
0
  /**
   * Converts UTF-16 inputFile to UTF-8 outputFile. Does not overwrite existing outputFile file.
   *
   * @param inputFile UTF-16 file
   * @param outputFile UTF-8 file after conversion
   * @throws IOException
   */
  public static void convertFileFromUtf16ToUtf8(File inputFile, File outputFile)
      throws IOException {
    String charset;
    if (inputFile == null || !inputFile.canRead()) {
      throw new FileNotFoundException("Can't read inputFile.");
    }

    try {
      charset = getFileCharset(inputFile);
    } catch (IOException ex) {
      LOGGER.debug("Exception during charset detection.", ex);
      throw new IllegalArgumentException("Can't confirm inputFile is UTF-16.");
    }

    if (isCharsetUTF16(charset)) {
      if (!outputFile.exists()) {
        BufferedReader reader = null;

        try {
          if (equalsIgnoreCase(charset, CHARSET_UTF_16LE)) {
            reader =
                new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF-16"));
          } else {
            reader =
                new BufferedReader(
                    new InputStreamReader(new FileInputStream(inputFile), "UTF-16BE"));
          }
        } catch (UnsupportedEncodingException ex) {
          LOGGER.warn("Unsupported exception.", ex);
          throw ex;
        }

        BufferedWriter writer =
            new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"));
        int c;

        while ((c = reader.read()) != -1) {
          writer.write(c);
        }

        writer.close();
        reader.close();
      }
    } else {
      throw new IllegalArgumentException("File is not UTF-16");
    }
  }
  /**
   * Shift timing of subtitles in SSA/ASS or SRT format and converts charset to UTF8 if necessary
   *
   * @param inputSubtitles Subtitles file in SSA/ASS or SRT format
   * @param timeShift Time stamp value
   * @return Converted subtitles file
   * @throws IOException
   */
  public static DLNAMediaSubtitle shiftSubtitlesTimingWithUtfConversion(
      final DLNAMediaSubtitle inputSubtitles, double timeShift) throws IOException {
    if (inputSubtitles == null) {
      throw new NullPointerException("inputSubtitles should not be null.");
    }
    if (!inputSubtitles.isExternal()) {
      throw new IllegalArgumentException("inputSubtitles should be external.");
    }
    if (isBlank(inputSubtitles.getExternalFile().getName())) {
      throw new IllegalArgumentException(
          "inputSubtitles' external file should not have blank name.");
    }
    if (inputSubtitles.getType() == null) {
      throw new NullPointerException("inputSubtitles.getType() should not be null.");
    }
    if (!isSupportsTimeShifting(inputSubtitles.getType())) {
      throw new IllegalArgumentException(
          "inputSubtitles.getType() " + inputSubtitles.getType() + " is not supported.");
    }

    final File convertedSubtitlesFile =
        new File(
            configuration.getTempFolder(),
            getBaseName(inputSubtitles.getExternalFile().getName())
                + System.currentTimeMillis()
                + ".tmp");
    FileUtils.forceDeleteOnExit(convertedSubtitlesFile);
    BufferedReader input;

    final boolean isSubtitlesCodepageForcedInConfigurationAndSupportedByJVM =
        isNotBlank(configuration.getSubtitlesCodepage())
            && Charset.isSupported(configuration.getSubtitlesCodepage());
    final boolean isSubtitlesCodepageAutoDetectedAndSupportedByJVM =
        isNotBlank(inputSubtitles.getExternalFileCharacterSet())
            && Charset.isSupported(inputSubtitles.getExternalFileCharacterSet());
    if (isSubtitlesCodepageForcedInConfigurationAndSupportedByJVM) {
      input =
          new BufferedReader(
              new InputStreamReader(
                  new FileInputStream(inputSubtitles.getExternalFile()),
                  Charset.forName(configuration.getSubtitlesCodepage())));
    } else if (isSubtitlesCodepageAutoDetectedAndSupportedByJVM) {
      input =
          new BufferedReader(
              new InputStreamReader(
                  new FileInputStream(inputSubtitles.getExternalFile()),
                  Charset.forName(inputSubtitles.getExternalFileCharacterSet())));
    } else {
      input =
          new BufferedReader(
              new InputStreamReader(new FileInputStream(inputSubtitles.getExternalFile())));
    }
    final BufferedWriter output =
        new BufferedWriter(
            new OutputStreamWriter(
                new FileOutputStream(convertedSubtitlesFile), Charset.forName("UTF-8")));
    String line;
    double startTime;
    double endTime;

    try {
      if (SubtitleType.ASS.equals(inputSubtitles.getType())) {
        while ((line = input.readLine()) != null) {
          if (startsWith(line, "Dialogue:")) {
            String[] timings = splitPreserveAllTokens(line, ",");
            if (timings.length >= 3 && isNotBlank(timings[1]) && isNotBlank(timings[1])) {
              startTime = convertSubtitleTimingStringToTime(timings[1]);
              endTime = convertSubtitleTimingStringToTime(timings[2]);
              if (startTime >= timeShift) {
                timings[1] =
                    convertTimeToSubtitleTimingString(
                        startTime - timeShift, TimingFormat.ASS_TIMING);
                timings[2] =
                    convertTimeToSubtitleTimingString(endTime - timeShift, TimingFormat.ASS_TIMING);
                output.write(join(timings, ",") + "\n");
              } else {
                continue;
              }
            } else {
              output.write(line + "\n");
            }
          } else {
            output.write(line + "\n");
          }
        }
      } else if (SubtitleType.SUBRIP.equals(inputSubtitles.getType())) {
        int n = 1;
        while ((line = input.readLine()) != null) {
          if (contains(line, ("-->"))) {
            startTime =
                convertSubtitleTimingStringToTime(line.substring(0, line.indexOf("-->") - 1));
            endTime = convertSubtitleTimingStringToTime(line.substring(line.indexOf("-->") + 4));
            if (startTime >= timeShift) {
              output.write("" + (n++) + "\n");
              output.write(
                  convertTimeToSubtitleTimingString(
                      startTime - timeShift, TimingFormat.SRT_TIMING));
              output.write(" --> ");
              output.write(
                  convertTimeToSubtitleTimingString(endTime - timeShift, TimingFormat.SRT_TIMING)
                      + "\n");

              while (isNotBlank(line = input.readLine())) { // Read all following subs lines
                output.write(line + "\n");
              }
              output.write("" + "\n");
            }
          }
        }
      }
    } finally {
      if (output != null) {
        output.flush();
        output.close();
      }
      if (input != null) {
        input.close();
      }
    }

    final DLNAMediaSubtitle convertedSubtitles = new DLNAMediaSubtitle();
    convertedSubtitles.setExternalFile(convertedSubtitlesFile);
    convertedSubtitles.setType(inputSubtitles.getType());
    convertedSubtitles.setLang(inputSubtitles.getLang());
    convertedSubtitles.setFlavor(inputSubtitles.getFlavor());
    convertedSubtitles.setId(inputSubtitles.getId());
    return convertedSubtitles;
  }