1 package saccubus.converter;
3 import java.util.regex.Matcher;
4 import saccubus.converter.profile.Profile;
5 import saccubus.converter.profile.FfmpegOption;
6 import saccubus.converter.filegetter.FileInstanciator;
8 import java.io.IOException;
9 import java.util.concurrent.Callable;
10 import java.util.regex.Pattern;
11 import saccubus.ConvertStopFlag;
12 import saccubus.net.TextProgressListener;
17 * <p>説明: ニコニコ動画の動画をコメントつきで保存</p>
19 * <p>著作権: Copyright (c) 2007 PSI</p>
26 public class Converter extends AbstractCommand implements Runnable, Callable<Boolean> {
28 private final Profile Setting;
29 private final String Tag;
30 private final String Time;
32 public Converter(String url, String time, Profile setting,
33 TextProgressListener listener, ConvertStopFlag flag) {
34 super(listener, flag);
36 // TODO 入力欄の値から動画IDの切り出しはGUI側でやるべきだろう
37 final int startIdIdx = url.lastIndexOf("/") + 1;
38 final String altId = url.substring(startIdIdx);
39 final Pattern idPattern = Pattern.compile("([a-z]*\\d+)");
40 final Matcher idMatcher = idPattern.matcher(altId);
41 if (idMatcher.find()) {
42 Tag = idMatcher.group(1);
44 throw new IllegalArgumentException("URL/IDの指定が不正です: " + url);
52 public Boolean call() throws Exception {
53 System.out.println("Convert Thread Start");
54 boolean result = false;
56 result = runConvert();
58 getStopFlag().finished();
60 return Boolean.valueOf(result);
67 } catch (Exception ex) {
68 String text = (ex.getMessage() != null) ? ex.getMessage() : "予期しないエラー発生のため中断しました。";
74 private boolean runConvert() throws IOException, InterruptedException {
75 if (!Setting.shouldRun()) {
76 sendText("何もすることがありません");
81 final FfmpegOption ov = Setting.getFfmpeg().getFfmpegOption();
85 final FileInstanciator fi = createInstanciator();
89 final File videoFile = fi.getVideoFile(getListener());
93 File commentFile = fi.getCommentFile(getListener());
97 File tcommFile = fi.getTcommFile(getListener());
99 if (!Setting.needsConvert()) {
100 sendText("動画・コメントを保存し、変換は行いませんでした。");
104 if (!videoFile.isFile()) {
105 throw new IOException("入力動画ファイルが存在しません:" + videoFile.getPath());
108 if (Setting.getOutputFileSetting().isAddComment()) {
109 if (!commentFile.isFile()) {
110 throw new IOException("入力コメントファイルが存在しません:" + commentFile.getPath());
116 if (Setting.getOutputFileSetting().isAddTcomment()) {
117 if (!tcommFile.isFile()) {
118 throw new IOException("入力投稿者コメントファイルが存在しません" + tcommFile.getPath());
125 File convertedVideoFile;
126 if (!Setting.getOutputFileSetting().getFile().isFile()) {
127 String conv_name = fi.getVideoTitle();
128 if (Setting.getOutputFileSetting().isAppendPrefixVideoId()) {
129 conv_name = getVideoIDWithBracket() + conv_name;
131 convertedVideoFile = new File(Setting.getOutputFileSetting().getFile().getFile(),
132 conv_name + ov.getExtOption());
134 String filename = Setting.getOutputFileSetting().getFile().getFile().getPath();
135 if (!filename.endsWith(ov.getExtOption())) {
136 filename = filename.substring(0, filename.lastIndexOf('.')) + ov.getExtOption();
137 convertedVideoFile = new File(filename);
139 convertedVideoFile = Setting.getOutputFileSetting().getFile().getFile();
143 boolean res = new FfmpegCommand(getListener(), getStopFlag(), commentFile, tcommFile, videoFile,
144 convertedVideoFile, Setting.getFfmpeg(), Setting.getGeneralSetting()).execute();
146 if (Setting.getCommentSetting().isDelete()) {
147 commentFile.delete();
149 if (Setting.getVideoSetting().isDelete()) {
152 if (Setting.getTcommentSetting().isDelete()) {
159 private FileInstanciator createInstanciator() throws IOException {
162 FileInstanciator.InstanciationType videoType = new FileInstanciator.InstanciationType(Setting.getVideoSetting());
164 FileInstanciator.CommentInstanciationType commentType = new FileInstanciator.CommentInstanciationType(Setting.
165 getCommentSetting(), Setting.getCommentGetInfo().isSelfAdjustCommentNum(), Setting.getCommentGetInfo().
166 getBackComment(), Setting.getCommentGetInfo().isReduceComment());
168 FileInstanciator.InstanciationType tcommType = new FileInstanciator.InstanciationType(
169 Setting.getTcommentSetting());
171 fi = FileInstanciator.create(getStopFlag(), videoType, commentType, tcommType, Setting.getLoginInfo(), Tag, Time);
176 * (ネットワーク設定以外の)設定を検証する.
177 * @throws IllegalArgumentException 設定に不備がある場合.
179 private void validSetting() {
180 if (Setting.needsConvert()) {
181 File a = Setting.getFfmpeg().getFfmpeg();
183 throw new IllegalArgumentException("FFmpegが見つかりません。");
185 if (Setting.getFfmpeg().getVhook().getPath().indexOf(' ') >= 0) {
186 throw new IllegalArgumentException("すいません。現在vhookライブラリには半角空白は使えません。");
188 a = Setting.getFfmpeg().getVhook();
190 throw new IllegalArgumentException("Vhookライブラリが見つかりません。");
192 a = Setting.getFfmpeg().getFont();
194 throw new IllegalArgumentException("フォントが見つかりません。");
197 if (Setting.getVideoSetting().isDelete()) {
198 throw new IllegalArgumentException("変換しないのに、動画削除しちゃって良いんですか?");
200 if (Setting.getCommentSetting().isDelete()) {
201 throw new IllegalArgumentException("変換しないのに、コメント削除しちゃって良いんですか?");
203 if (Setting.getTcommentSetting().isDelete()) {
204 throw new IllegalArgumentException("変換しないのに、投稿者コメント削除しちゃって良いんですか?");
209 private String getVideoIDWithBracket() {
210 return "[" + Tag + "]";
213 public boolean isConverted() {
214 return getStopFlag().isFinished();
218 public ConvertStopFlag getStopFlag() {
219 return super.getStopFlag();