OSDN Git Service

merge.
[coroid/inqubus.git] / frontend / src / saccubus / converter / Converter.java
1 package saccubus.converter;
2
3 import saccubus.converter.filegetter.LoginInfo;
4 import saccubus.converter.filegetter.FileInstanciator;
5 import java.io.BufferedReader;
6 import java.io.File;
7 import java.io.FileInputStream;
8 import java.io.IOException;
9 import java.io.InputStreamReader;
10 import java.io.UnsupportedEncodingException;
11 import java.net.URLEncoder;
12 import java.util.Properties;
13 import saccubus.ConvertStopFlag;
14 import saccubus.conv.ConvertToVideoHook;
15 import saccubus.net.TextProgressListener;
16 import yukihane.swf.Cws2Fws;
17
18 /**
19  * <p>\83^\83C\83g\83\8b\82³\82«\82ã\82Î\82·</p>
20  *
21  * <p>\90à\96¾: \83j\83R\83j\83R\93®\89æ\82Ì\93®\89æ\82ð\83R\83\81\83\93\83g\82Â\82«\82Å\95Û\91¶</p>
22  *
23  * <p>\92\98\8dì\8c : Copyright (c) 2007 PSI</p>
24  *
25  * <p>\89ï\8eÐ\96¼: </p>
26  *
27  * @author \96¢\93ü\97Í
28  * @version 1.0
29  */
30 public class Converter extends Thread {
31
32     private static final String VIDEO_URL_PARSER = "http://www.nicovideo.jp/watch/";
33     private static final String TMP_CWS = "fws_tmp.swf";
34     private final Profile Setting;
35     private final String Tag;
36     private final String Time;
37     private final TextProgressListener listener;
38     private final ConvertStopFlag StopFlag;
39     private final File commentMiddleFile = new File("./vhook.tmp");
40     private final File tcommMiddleFile = new File("./tcomment.tmp");
41
42     public Converter(String url, String time, Profile setting,
43             TextProgressListener listener, ConvertStopFlag flag) {
44         url = url.trim();
45         if (url.startsWith(VIDEO_URL_PARSER)) {
46             int index = url.indexOf('?', VIDEO_URL_PARSER.length());
47             if (index >= 0) {
48                 Tag = url.substring(VIDEO_URL_PARSER.length(), index);
49             } else {
50                 Tag = url.substring(VIDEO_URL_PARSER.length());
51             }
52         } else {
53             Tag = url;
54         }
55         Time = time;
56         Setting = setting;
57         this.listener = listener;
58         StopFlag = flag;
59     }
60
61     @Override
62     public void run() {
63         try {
64             runConvert();
65         } catch (Exception ex) {
66             sendText(ex.getMessage());
67             ex.printStackTrace();
68         } finally {
69             if (commentMiddleFile.exists()) {
70                 commentMiddleFile.delete();
71             }
72             if (tcommMiddleFile.exists()) {
73                 tcommMiddleFile.delete();
74             }
75             StopFlag.finished();
76         }
77     }
78
79     private void runConvert() throws IOException, InterruptedException {
80         if (!Setting.shouldRun()) {
81             sendText("\89½\82à\82·\82é\82±\82Æ\82ª\82 \82è\82Ü\82¹\82ñ");
82             return;
83         }
84
85         validSetting();
86         final FfmpegOption ov = Setting.getFfmpegOption();
87
88         sendText("\83\8d\83O\83C\83\93\92\86");
89
90         final FileInstanciator fi = createInstanciator();
91
92         stopFlagReturn();
93
94         final File videoFile = fi.getVideoFile(listener);
95
96         stopFlagReturn();
97
98         final File commentFile = fi.getCommentFile(listener);
99
100         stopFlagReturn();
101
102         final File tcommFile = fi.getTcommFile(listener);
103
104         if (!Setting.needsConvert()) {
105             sendText("\93®\89æ\81E\83R\83\81\83\93\83g\82ð\95Û\91\82µ\81A\95Ï\8a·\82Í\8ds\82¢\82Ü\82¹\82ñ\82Å\82µ\82½\81B");
106             return;
107         }
108
109         if (Setting.getAddComment()) {
110             sendText("\83R\83\81\83\93\83g\82Ì\92\86\8aÔ\83t\83@\83C\83\8b\82Ö\82Ì\95Ï\8a·\92\86");
111
112             boolean conv = ConvertToVideoHook.convert(commentFile, commentMiddleFile,
113                     Setting.getNgId(), Setting.getNgWord());
114             if (!conv) {
115                 sendText("\83R\83\81\83\93\83g\95Ï\8a·\82É\8e¸\94s\81B\82¨\82»\82ç\82­\90³\8bK\95\\8c»\82Ì\8aÔ\88á\82¢\81H");
116                 return;
117             }
118         }
119
120         stopFlagReturn();
121
122         if (Setting.getAddTcomment()) {
123             sendText("\93\8a\8de\8eÒ\83R\83\81\83\93\83g\82Ì\92\86\8aÔ\83t\83@\83C\83\8b\82Ö\82Ì\95Ï\8a·\92\86");
124
125             boolean conv = ConvertToVideoHook.convert(tcommFile, tcommMiddleFile,
126                     Setting.getNgId(), Setting.getNgWord());
127             if (!conv) {
128                 sendText("\83R\83\81\83\93\83g\95Ï\8a·\82É\8e¸\94s\81B\82¨\82»\82ç\82­\90³\8bK\95\\8c»\82Ì\8aÔ\88á\82¢\81H");
129                 return;
130             }
131         }
132
133         stopFlagReturn();
134
135         sendText("\93®\89æ\82Ì\95Ï\8a·\82ð\8aJ\8en");
136         /*\83r\83f\83I\96¼\82Ì\8am\92è*/
137         File convertedVideoFile;
138         if (!Setting.getConvertFile().isFile()) {
139             if (fi.getVideoTitle() == null) {
140                 sendText("\95Ï\8a·\8cã\82Ì\83r\83f\83I\83t\83@\83C\83\8b\96¼\82ª\8am\92è\82Å\82«\82Ü\82¹\82ñ\81B");
141                 return;
142             }
143             String conv_name = fi.getVideoTitle();
144             if (Setting.needsAppendPrefixVideoId()) {
145                 conv_name = getVideoIDWithBracket() + conv_name;
146             }
147             convertedVideoFile = new File(Setting.getConvertFile().getFile(), conv_name + ov.getExtOption());
148         } else {
149             String filename = Setting.getConvertFile().getFile().getPath();
150             if (!filename.endsWith(ov.getExtOption())) {
151                 filename = filename.substring(0, filename.lastIndexOf('.'))
152                         + ov.getExtOption();
153                 convertedVideoFile = new File(filename);
154             } else {
155                 convertedVideoFile = Setting.getConvertFile().getFile();
156             }
157         }
158         int code;
159         if ((code = converting_video(videoFile, convertedVideoFile, Setting.getAddComment(), commentMiddleFile.getPath(),
160                 Setting.getAddTcomment(), tcommMiddleFile.getPath(), ov)) == 0) {
161             sendText("\95Ï\8a·\82ª\90³\8fí\82É\8fI\97¹\82µ\82Ü\82µ\82½\81B");
162             if (Setting.getCommentSetting().isDelete()) {
163                 commentFile.delete();
164             }
165             if (Setting.getVideoSetting().isDelete()) {
166                 videoFile.delete();
167             }
168             if (Setting.getTcommentSetting().isDelete()) {
169                 tcommFile.delete();
170             }
171         } else {
172             sendText("\95Ï\8a·\83G\83\89\81[:" + convertedVideoFile.getPath());
173         }
174     }
175
176     private FileInstanciator createInstanciator() throws IOException {
177         FileInstanciator fi;
178         LoginInfo li = new LoginInfo(Setting.getMailAddress(), Setting.getPassword(), Setting.getProxy());
179
180         FileInstanciator.InstanciationType videoType = new FileInstanciator.InstanciationType(Setting.getVideoSetting());
181
182         FileInstanciator.CommentInstanciationType commentType = new FileInstanciator.CommentInstanciationType(Setting.
183                 getCommentSetting(), Setting.isselfAdjustCommentNum(), Setting.getBackComment());
184
185         FileInstanciator.InstanciationType tcommType = new FileInstanciator.InstanciationType(
186                 Setting.getTcommentSetting());
187
188         fi = FileInstanciator.create(StopFlag, videoType, commentType, tcommType, li, Tag, Time);
189         return fi;
190     }
191
192     /**
193      * (\83l\83b\83g\83\8f\81[\83N\90Ý\92è\88È\8aO\82Ì)\90Ý\92è\82ð\8c\9f\8fØ\82·\82é.
194      * @throws IllegalArgumentException \90Ý\92è\82É\95s\94õ\82ª\82 \82é\8fê\8d\87.
195      */
196     private void validSetting() {
197         if (Setting.needsConvert()) {
198             File a = new File(Setting.getFfmpegPath());
199             if (!a.canRead()) {
200                 throw new IllegalArgumentException("FFmpeg\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ\81B");
201             }
202             if (Setting.getVhookPath().indexOf(' ') >= 0) {
203                 throw new IllegalArgumentException("\82·\82¢\82Ü\82¹\82ñ\81B\8c»\8dÝvhook\83\89\83C\83u\83\89\83\8a\82É\82Í\94¼\8ap\8bó\94\92\82Í\8eg\82¦\82Ü\82¹\82ñ\81B");
204             }
205             a = new File(Setting.getVhookPath());
206             if (!a.canRead()) {
207                 throw new IllegalArgumentException("Vhook\83\89\83C\83u\83\89\83\8a\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ\81B");
208             }
209             a = new File(Setting.getFontPath());
210             if (!a.canRead()) {
211                 throw new IllegalArgumentException("\83t\83H\83\93\83g\82ª\8c©\82Â\82©\82è\82Ü\82¹\82ñ\81B");
212             }
213         } else {
214             if (Setting.getVideoSetting().isDelete()) {
215                 throw new IllegalArgumentException("\95Ï\8a·\82µ\82È\82¢\82Ì\82É\81A\93®\89æ\8dí\8f\9c\82µ\82¿\82á\82Á\82Ä\97Ç\82¢\82ñ\82Å\82·\82©\81H");
216             }
217             if (Setting.getCommentSetting().isDelete()) {
218                 throw new IllegalArgumentException("\95Ï\8a·\82µ\82È\82¢\82Ì\82É\81A\83R\83\81\83\93\83g\8dí\8f\9c\82µ\82¿\82á\82Á\82Ä\97Ç\82¢\82ñ\82Å\82·\82©\81H");
219             }
220             if (Setting.getTcommentSetting().isDelete()) {
221                 throw new IllegalArgumentException("\95Ï\8a·\82µ\82È\82¢\82Ì\82É\81A\93\8a\8de\8eÒ\83R\83\81\83\93\83g\8dí\8f\9c\82µ\82¿\82á\82Á\82Ä\97Ç\82¢\82ñ\82Å\82·\82©\81H");
222             }
223         }
224     }
225
226     private void sendText(String text) {
227         listener.setText(text);
228     }
229
230     private int converting_video(File videoFile, File convertedVideoFile, boolean addComment, String vhook_path,
231             boolean addTcomment, String tcommPath, FfmpegOption ov) throws InterruptedException, IOException {
232         File fwsFile = Cws2Fws.createFws(videoFile, new File(TMP_CWS));
233
234         StringBuffer sb = new StringBuffer();
235         sb.append("\"");
236         sb.append(Setting.getFfmpegPath().replace("\\", "\\\\"));
237         sb.append("\"");
238         sb.append(" -y ");
239         sb.append(ov.getMainOption());
240         sb.append(" ");
241         sb.append(ov.getInOption());
242         sb.append(" -i ");
243         if (fwsFile == null) {
244             sb.append("\"");
245             sb.append(videoFile.getPath().replace("\\", "\\\\"));
246             sb.append("\"");
247         } else {
248             sb.append(fwsFile.getPath().replace("\\", "\\\\"));
249         }
250         sb.append(" ");
251         sb.append(ov.getOutOption());
252         sb.append(" \"");
253         sb.append(convertedVideoFile.getPath().replace("\\", "\\\\"));
254         sb.append("\"");
255         if (!Setting.isVhookDisabled()) {
256             if (!addVhookSetting(sb, addComment, vhook_path, addTcomment, tcommPath)) {
257                 return -1;
258             }
259         }
260         String cmd = sb.substring(0);
261         System.out.println("arg:" + cmd);
262         try {
263             System.out.println("\n\n----\nProcessing FFmpeg...\n----\n\n");
264             Process process = Runtime.getRuntime().exec(cmd);
265             BufferedReader ebr = new BufferedReader(new InputStreamReader(
266                     process.getErrorStream()));
267             String e;
268             while ((e = ebr.readLine()) != null) {
269                 String state = e;
270                 if (state.startsWith("frame=")) {
271                     sendText(state);
272                 } else if (!state.endsWith("No accelerated colorspace conversion found")) {
273                     System.out.println(e);
274                 }
275
276                 try {
277                     stopFlagReturn();
278                 } catch (InterruptedException ex) {
279                     process.destroy();
280                     throw ex;
281                 }
282
283             }
284             process.waitFor();
285             return process.exitValue();
286         } finally {
287             if (fwsFile != null) {
288                 fwsFile.delete();
289             }
290         }
291     }
292
293     private boolean addVhookSetting(StringBuffer sb, boolean addComment, String vhook_path, boolean addTcomment,
294             String tcommPath) {
295         try {
296             sb.append(" -vfilters \"vhext=");
297             sb.append(Setting.getVhookPath().replace("\\", "/"));
298             if (addComment) {
299                 sb.append("|");
300                 sb.append("--data-user:");
301                 sb.append(URLEncoder.encode(vhook_path.replace("\\", "/"), "Shift_JIS"));
302             }
303             if (addTcomment) {
304                 sb.append("|");
305                 sb.append("--data-owner:");
306                 sb.append(URLEncoder.encode(tcommPath.replace("\\", "/"), "Shift_JIS"));
307             }
308             sb.append("|");
309             sb.append("--font:");
310             sb.append(URLEncoder.encode(
311                     Setting.getFontPath().replace("\\", "/"), "Shift_JIS"));
312             sb.append("|");
313             sb.append("--font-index:");
314             sb.append(Setting.getFontIndex());
315             sb.append("|");
316             sb.append("--show-user:");
317             sb.append(Setting.getVideoShowNum());
318             sb.append("|");
319             sb.append("--shadow:");
320             sb.append(Setting.getShadowIndex());
321             sb.append("|");
322             if (Setting.isShowConvertingVideo()) {
323                 sb.append("--enable-show-video");
324                 sb.append("|");
325             }
326             if (Setting.isSelfAdjustFontSize()) {
327                 sb.append("--enable-fix-font-size");
328                 sb.append("|");
329             }
330             if (Setting.isOpaqueComment()) {
331                 sb.append("--enable-opaque-comment");
332             }
333             sb.append("\"");
334             return true;
335         } catch (UnsupportedEncodingException e) {
336             e.printStackTrace();
337             return false;
338         }
339     }
340
341     public boolean isConverted() {
342         return StopFlag.isFinished();
343     }
344
345     private void stopFlagReturn() throws InterruptedException {
346         if (StopFlag.needStop()) {
347             throw new InterruptedException("\92\86\8e~\82µ\82Ü\82µ\82½\81B");
348         }
349     }
350
351     public ConvertStopFlag getStopFlag() {
352         return this.StopFlag;
353     }
354
355     private String getVideoIDWithBracket() {
356         return "[" + Tag + "]";
357     }
358 }