OSDN Git Service

dc657d0ca48474ccd277caeb14d3d16a122bcb34
[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     public Boolean call() throws Exception {
52         boolean result = false;
53         try {
54             result = runConvert();
55         } finally {
56             getStopFlag().finished();
57         }
58         return Boolean.valueOf(result);
59     }
60
61     public void run() {
62         try {
63             call();
64         } catch (Exception ex) {
65             String text = (ex.getMessage() != null) ? ex.getMessage() : "予期しないエラー発生のため中断しました。";
66             sendText(text);
67             ex.printStackTrace();
68         }
69     }
70
71     private boolean runConvert() throws IOException, InterruptedException {
72         if (!Setting.shouldRun()) {
73             sendText("何もすることがありません");
74             return true;
75         }
76
77         validSetting();
78         final FfmpegOption ov = Setting.getFfmpeg().getFfmpegOption();
79
80         sendText("ログイン中");
81
82         final FileInstanciator fi = createInstanciator();
83
84         stopFlagReturn();
85
86         final File videoFile = fi.getVideoFile(getListener());
87
88         stopFlagReturn();
89
90         File commentFile = fi.getCommentFile(getListener());
91
92         stopFlagReturn();
93
94         File tcommFile = fi.getTcommFile(getListener());
95
96         if (!Setting.needsConvert()) {
97             sendText("動画・コメントを保存し、変換は行いませんでした。");
98             return true;
99         }
100
101         if (!videoFile.isFile()) {
102             throw new IOException("入力動画ファイルが存在しません:" + videoFile.getPath());
103         }
104
105         if (Setting.getOutputFileSetting().isAddComment()) {
106             if (!commentFile.isFile()) {
107                 throw new IOException("入力コメントファイルが存在しません:" + commentFile.getPath());
108             }
109         } else {
110             commentFile = null;
111         }
112
113         if (Setting.getOutputFileSetting().isAddTcomment()) {
114             if (!tcommFile.isFile()) {
115                 throw new IOException("入力投稿者コメントファイルが存在しません" + tcommFile.getPath());
116             }
117         } else {
118             tcommFile = null;
119         }
120
121         /*ビデオ名の確定*/
122         File convertedVideoFile;
123         if (!Setting.getOutputFileSetting().getFile().isFile()) {
124             String conv_name = fi.getVideoTitle();
125             if (Setting.getOutputFileSetting().isAppendPrefixVideoId()) {
126                 conv_name = getVideoIDWithBracket() + conv_name;
127             }
128             convertedVideoFile = new File(Setting.getOutputFileSetting().getFile().getFile(),
129                     conv_name + ov.getExtOption());
130         } else {
131             String filename = Setting.getOutputFileSetting().getFile().getFile().getPath();
132             if (!filename.endsWith(ov.getExtOption())) {
133                 filename = filename.substring(0, filename.lastIndexOf('.')) + ov.getExtOption();
134                 convertedVideoFile = new File(filename);
135             } else {
136                 convertedVideoFile = Setting.getOutputFileSetting().getFile().getFile();
137             }
138         }
139
140         boolean res = new FfmpegCommand(getListener(), getStopFlag(), commentFile, tcommFile, videoFile,
141                 convertedVideoFile, Setting.getFfmpeg(), Setting.getGeneralSetting()).execute();
142         if (res) {
143             if (Setting.getCommentSetting().isDelete()) {
144                 commentFile.delete();
145             }
146             if (Setting.getVideoSetting().isDelete()) {
147                 videoFile.delete();
148             }
149             if (Setting.getTcommentSetting().isDelete()) {
150                 tcommFile.delete();
151             }
152         }
153         return res;
154     }
155
156     private FileInstanciator createInstanciator() throws IOException {
157         FileInstanciator fi;
158
159         FileInstanciator.InstanciationType videoType = new FileInstanciator.InstanciationType(Setting.getVideoSetting());
160
161         FileInstanciator.CommentInstanciationType commentType = new FileInstanciator.CommentInstanciationType(Setting.
162                 getCommentSetting(), Setting.getCommentGetInfo().isSelfAdjustCommentNum(), Setting.getCommentGetInfo().
163                 getBackComment(), Setting.getCommentGetInfo().isReduceComment());
164
165         FileInstanciator.InstanciationType tcommType = new FileInstanciator.InstanciationType(
166                 Setting.getTcommentSetting());
167
168         fi = FileInstanciator.create(getStopFlag(), videoType, commentType, tcommType, Setting.getLoginInfo(), Tag, Time);
169         return fi;
170     }
171
172     /**
173      * (ネットワーク設定以外の)設定を検証する.
174      * @throws IllegalArgumentException 設定に不備がある場合.
175      */
176     private void validSetting() {
177         if (Setting.needsConvert()) {
178             File a = Setting.getFfmpeg().getFfmpeg();
179             if (!a.canRead()) {
180                 throw new IllegalArgumentException("FFmpegが見つかりません。");
181             }
182             if (Setting.getFfmpeg().getVhook().getPath().indexOf(' ') >= 0) {
183                 throw new IllegalArgumentException("すいません。現在vhookライブラリには半角空白は使えません。");
184             }
185             a = Setting.getFfmpeg().getVhook();
186             if (!a.canRead()) {
187                 throw new IllegalArgumentException("Vhookライブラリが見つかりません。");
188             }
189             a = Setting.getFfmpeg().getFont();
190             if (!a.canRead()) {
191                 throw new IllegalArgumentException("フォントが見つかりません。");
192             }
193         } else {
194             if (Setting.getVideoSetting().isDelete()) {
195                 throw new IllegalArgumentException("変換しないのに、動画削除しちゃって良いんですか?");
196             }
197             if (Setting.getCommentSetting().isDelete()) {
198                 throw new IllegalArgumentException("変換しないのに、コメント削除しちゃって良いんですか?");
199             }
200             if (Setting.getTcommentSetting().isDelete()) {
201                 throw new IllegalArgumentException("変換しないのに、投稿者コメント削除しちゃって良いんですか?");
202             }
203         }
204     }
205
206     private String getVideoIDWithBracket() {
207         return "[" + Tag + "]";
208     }
209
210     public boolean isConverted() {
211         return getStopFlag().isFinished();
212     }
213
214     @Override
215     public ConvertStopFlag getStopFlag() {
216         return super.getStopFlag();
217     }
218 }