OSDN Git Service

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