OSDN Git Service

デバッグ出力を追加
[coroid/inqubus.git] / frontend / src / saccubus / converter / Converter.java
1 package saccubus.converter;
2
3 import java.util.regex.Matcher;
4 import saccubus.converter.profile.Profile;
5 import saccubus.converter.profile.FfmpegOption;
6 import saccubus.converter.filegetter.FileInstanciator;
7 import java.io.File;
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;
13
14 /**
15  * <p>タイトル: さきゅばす</p>
16  *
17  * <p>説明: ニコニコ動画の動画をコメントつきで保存</p>
18  *
19  * <p>著作権: Copyright (c) 2007 PSI</p>
20  *
21  * <p>会社名: </p>
22  *
23  * @author 未入力
24  * @version 1.0
25  */
26 public class Converter extends AbstractCommand implements Runnable, Callable<Boolean> {
27
28     private final Profile Setting;
29     private final String Tag;
30     private final String Time;
31
32     public Converter(String url, String time, Profile setting,
33             TextProgressListener listener, ConvertStopFlag flag) {
34         super(listener, flag);
35
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);
43         } else {
44             throw new IllegalArgumentException("URL/IDの指定が不正です: " + url);
45         }
46
47         Time = time;
48         Setting = setting;
49     }
50
51     @Override
52     public Boolean call() throws Exception {
53         System.out.println("Convert Thread Start");
54         boolean result = false;
55         try {
56             result = runConvert();
57         } finally {
58             getStopFlag().finished();
59         }
60         return Boolean.valueOf(result);
61     }
62
63     @Override
64     public void run() {
65         try {
66             call();
67         } catch (Exception ex) {
68             String text = (ex.getMessage() != null) ? ex.getMessage() : "予期しないエラー発生のため中断しました。";
69             sendText(text);
70             ex.printStackTrace();
71         }
72     }
73
74     private boolean runConvert() throws IOException, InterruptedException {
75         if (!Setting.shouldRun()) {
76             sendText("何もすることがありません");
77             return true;
78         }
79
80         validSetting();
81         final FfmpegOption ov = Setting.getFfmpeg().getFfmpegOption();
82
83         sendText("ログイン中");
84
85         final FileInstanciator fi = createInstanciator();
86
87         stopFlagReturn();
88
89         final File videoFile = fi.getVideoFile(getListener());
90
91         stopFlagReturn();
92
93         File commentFile = fi.getCommentFile(getListener());
94
95         stopFlagReturn();
96
97         File tcommFile = fi.getTcommFile(getListener());
98
99         if (!Setting.needsConvert()) {
100             sendText("動画・コメントを保存し、変換は行いませんでした。");
101             return true;
102         }
103
104         if (!videoFile.isFile()) {
105             throw new IOException("入力動画ファイルが存在しません:" + videoFile.getPath());
106         }
107
108         if (Setting.getOutputFileSetting().isAddComment()) {
109             if (!commentFile.isFile()) {
110                 throw new IOException("入力コメントファイルが存在しません:" + commentFile.getPath());
111             }
112         } else {
113             commentFile = null;
114         }
115
116         if (Setting.getOutputFileSetting().isAddTcomment()) {
117             if (!tcommFile.isFile()) {
118                 throw new IOException("入力投稿者コメントファイルが存在しません" + tcommFile.getPath());
119             }
120         } else {
121             tcommFile = null;
122         }
123
124         /*ビデオ名の確定*/
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;
130             }
131             convertedVideoFile = new File(Setting.getOutputFileSetting().getFile().getFile(),
132                     conv_name + ov.getExtOption());
133         } else {
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);
138             } else {
139                 convertedVideoFile = Setting.getOutputFileSetting().getFile().getFile();
140             }
141         }
142
143         boolean res = new FfmpegCommand(getListener(), getStopFlag(), commentFile, tcommFile, videoFile,
144                 convertedVideoFile, Setting.getFfmpeg(), Setting.getGeneralSetting()).execute();
145         if (res) {
146             if (Setting.getCommentSetting().isDelete()) {
147                 commentFile.delete();
148             }
149             if (Setting.getVideoSetting().isDelete()) {
150                 videoFile.delete();
151             }
152             if (Setting.getTcommentSetting().isDelete()) {
153                 tcommFile.delete();
154             }
155         }
156         return res;
157     }
158
159     private FileInstanciator createInstanciator() throws IOException {
160         FileInstanciator fi;
161
162         FileInstanciator.InstanciationType videoType = new FileInstanciator.InstanciationType(Setting.getVideoSetting());
163
164         FileInstanciator.CommentInstanciationType commentType = new FileInstanciator.CommentInstanciationType(Setting.
165                 getCommentSetting(), Setting.getCommentGetInfo().isSelfAdjustCommentNum(), Setting.getCommentGetInfo().
166                 getBackComment(), Setting.getCommentGetInfo().isReduceComment());
167
168         FileInstanciator.InstanciationType tcommType = new FileInstanciator.InstanciationType(
169                 Setting.getTcommentSetting());
170
171         fi = FileInstanciator.create(getStopFlag(), videoType, commentType, tcommType, Setting.getLoginInfo(), Tag, Time);
172         return fi;
173     }
174
175     /**
176      * (ネットワーク設定以外の)設定を検証する.
177      * @throws IllegalArgumentException 設定に不備がある場合.
178      */
179     private void validSetting() {
180         if (Setting.needsConvert()) {
181             File a = Setting.getFfmpeg().getFfmpeg();
182             if (!a.canRead()) {
183                 throw new IllegalArgumentException("FFmpegが見つかりません。");
184             }
185             if (Setting.getFfmpeg().getVhook().getPath().indexOf(' ') >= 0) {
186                 throw new IllegalArgumentException("すいません。現在vhookライブラリには半角空白は使えません。");
187             }
188             a = Setting.getFfmpeg().getVhook();
189             if (!a.canRead()) {
190                 throw new IllegalArgumentException("Vhookライブラリが見つかりません。");
191             }
192             a = Setting.getFfmpeg().getFont();
193             if (!a.canRead()) {
194                 throw new IllegalArgumentException("フォントが見つかりません。");
195             }
196         } else {
197             if (Setting.getVideoSetting().isDelete()) {
198                 throw new IllegalArgumentException("変換しないのに、動画削除しちゃって良いんですか?");
199             }
200             if (Setting.getCommentSetting().isDelete()) {
201                 throw new IllegalArgumentException("変換しないのに、コメント削除しちゃって良いんですか?");
202             }
203             if (Setting.getTcommentSetting().isDelete()) {
204                 throw new IllegalArgumentException("変換しないのに、投稿者コメント削除しちゃって良いんですか?");
205             }
206         }
207     }
208
209     private String getVideoIDWithBracket() {
210         return "[" + Tag + "]";
211     }
212
213     public boolean isConverted() {
214         return getStopFlag().isFinished();
215     }
216
217     @Override
218     public ConvertStopFlag getStopFlag() {
219         return super.getStopFlag();
220     }
221 }