import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- *
+ * ffmpegから動画情報を取得するためのユーティリティクラス.
+ * マルチスレッドで使用されることは想定していません.
* @author yuki
*/
public final class FfmpegUtil {
+ private static final Logger logger = Logger.getLogger(FfmpegUtil.class.getName());
private static final Pattern PATTERN_DURATION = Pattern.compile("Duration: (\\d+):(\\d+):(\\d+)");
+ private static final Pattern PATTERN_SIZE = Pattern.compile("Video: .+?(\\d+)x(\\d+)");
private final File ffmpegPath;
private final File targetPath;
private String execResultCache;
}
}
+ /**
+ * 動画ファイルのサイズを取得します.
+ * ただし, ffmpegのバージョンに依存するため正常に動作しない場合があります.
+ * @return 動画サイズ.
+ * @throws IOException 取得失敗.
+ */
+ public saccubus.util.Size getSize() throws IOException {
+ // TODO ffmpegのバージョンによってはうまく動かない.
+ final String res = getExecResult();
+ final Matcher m = PATTERN_SIZE.matcher(res);
+ if (m.find()) {
+ final int width = Integer.parseInt(m.group(1));
+ final int height = Integer.parseInt(m.group(2));
+ final Size size = new Size(width, height);
+ logger.log(Level.FINER, size.toString());
+ return size;
+ } else {
+ throw new IOException("Can Not Get Size");
+ }
+ }
+
+ public saccubus.util.Size adjustSize(int maxWidth, int maxHeight) throws IOException {
+ final saccubus.util.Size nowSize = getSize();
+
+ if (nowSize.getWidth() <= maxWidth && nowSize.getHeight() <= maxHeight) {
+ return nowSize;
+ }
+
+ double widthRatio = calcRatio(nowSize.getWidth(), maxWidth);
+ double heightRatio = calcRatio(nowSize.getHeight(), maxHeight);
+
+ if (widthRatio >= heightRatio) {
+ int adjustedWidth = adjust(nowSize.getWidth(), widthRatio);
+ int adjustedHeight = adjust(nowSize.getHeight(), widthRatio);
+ return new Size(adjustedWidth, adjustedHeight);
+ } else {
+ int adjustedWidth = adjust(nowSize.getWidth(), heightRatio);
+ int adjustedHeight = adjust(nowSize.getHeight(), heightRatio);
+ return new Size(adjustedWidth, adjustedHeight);
+ }
+ }
+
+ private static double calcRatio(int now, int max) {
+ return (double) now / (double) max;
+ }
+
+ private static int adjust(int size, double ratio) {
+ return (int) (size / ratio);
+ }
+
private String getExecResult() throws IOException {
if (execResultCache != null) {
return execResultCache;
return res;
}
}
+
+ private static class Size implements saccubus.util.Size {
+
+ private final int width;
+ private final int height;
+
+ public Size(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ @Override
+ public int getHeight() {
+ return height;
+ }
+
+ @Override
+ public int getWidth() {
+ return width;
+ }
+
+ @Override
+ public String toString() {
+ return "Width:" + width + ", Height:" + height;
+ }
+ }
}