OSDN Git Service

FFMPEG関連のオプションをインタフェース化
[coroid/inqubus.git] / frontend / src / saccubus / converter / FfmpegCommand.java
1 /* $Id$ */
2 package saccubus.converter;
3
4 import java.io.BufferedReader;
5 import java.io.File;
6 import java.io.IOException;
7 import java.io.InputStreamReader;
8 import java.io.UnsupportedEncodingException;
9 import java.net.URLEncoder;
10 import java.util.ArrayList;
11 import java.util.List;
12 import org.apache.commons.lang.StringUtils;
13 import saccubus.ConvertStopFlag;
14 import saccubus.conv.ConvertToVideoHook;
15 import saccubus.converter.profile.NgSetting;
16 import saccubus.converter.profile.Ffmpeg;
17 import saccubus.converter.profile.FfmpegOption;
18 import saccubus.converter.profile.GeneralSetting;
19 import saccubus.net.TextProgressListener;
20 import yukihane.swf.Cws2Fws;
21
22 /**
23  *
24  * @author yuki
25  */
26 public class FfmpegCommand extends AbstractCommand {
27
28     private final File commentMiddleFile;
29     private final File tcommMiddleFile;
30     private final File TMP_CWS;
31     private final File commentFile;
32     private final File tcommFile;
33     private final File videoFile;
34     private final File convertedVideoFile;
35     private final Ffmpeg ffmpeg;
36
37     FfmpegCommand(TextProgressListener listener, ConvertStopFlag flag, File commentFile, File tcommFile,
38             File videoFile, File convertedVideoFile, Ffmpeg ffmpeg, GeneralSetting general) throws IOException {
39         super(listener, flag);
40         this.commentFile = commentFile;
41         this.tcommFile = tcommFile;
42         this.videoFile = videoFile;
43         this.convertedVideoFile = convertedVideoFile;
44         this.ffmpeg = ffmpeg;
45
46         File tmpDir = general.getTempDir();
47         commentMiddleFile = File.createTempFile("vhk", ".tmp", tmpDir);
48         tcommMiddleFile = File.createTempFile("tcom", ".tmp", tmpDir);
49         TMP_CWS = File.createTempFile("cws", ".swf", tmpDir);
50     }
51
52     public boolean execute() throws InterruptedException, IOException {
53         try {
54             return exec();
55         } finally {
56             if (commentMiddleFile.exists()) {
57                 commentMiddleFile.delete();
58             }
59             if (tcommMiddleFile.exists()) {
60                 tcommMiddleFile.delete();
61             }
62             if (TMP_CWS.exists()) {
63                 TMP_CWS.delete();
64             }
65         }
66     }
67
68     private boolean exec() throws InterruptedException, IOException {
69         final NgSetting ngSetting = getFfmpeg().getNgSetting();
70         if (commentFile != null) {
71             sendText("コメントの中間ファイルへの変換中");
72             boolean conv = ConvertToVideoHook.convert(commentFile, commentMiddleFile, ngSetting.getId(), ngSetting.
73                     getWord());
74             if (!conv) {
75                 sendText("コメント変換に失敗。ファイル名に使用できない文字が含まれているか正規表現の間違い?");
76                 return false;
77             }
78         }
79         stopFlagReturn();
80         if (tcommFile != null) {
81             sendText("投稿者コメントの中間ファイルへの変換中");
82             boolean conv = ConvertToVideoHook.convert(tcommFile, tcommMiddleFile, ngSetting.getId(), ngSetting.getWord());
83             if (!conv) {
84                 sendText("コメント変換に失敗。ファイル名に使用できない文字が含まれているか正規表現の間違い?");
85                 return false;
86             }
87         }
88         stopFlagReturn();
89         sendText("動画の変換を開始");
90         int code;
91         if ((code = converting_video(videoFile, convertedVideoFile, (commentFile != null), commentMiddleFile.getPath(), (tcommFile
92                 != null), tcommMiddleFile.getPath(), getFfmpeg().getFfmpegOption())) == 0) {
93             sendText("変換が正常に終了しました。");
94             return true;
95         } else {
96             sendText("変換エラー:" + convertedVideoFile.getPath());
97         }
98         return false;
99     }
100
101     private int converting_video(File videoFile, File convertedVideoFile, boolean addComment, String vhook_path,
102             boolean addTcomment, String tcommPath, FfmpegOption ov) throws InterruptedException, IOException {
103         File fwsFile = Cws2Fws.createFws(videoFile, TMP_CWS);
104
105         List<String> cmdList = new ArrayList<String>();
106         cmdList.add(getFfmpeg().getFfmpeg().getPath());
107         cmdList.add("-y");
108         String[] mainOptions = ov.getMainOption().split(" +");
109         for (String opt : mainOptions) {
110             if (StringUtils.isNotBlank(opt)) {
111                 cmdList.add(opt);
112             }
113         }
114         String[] inOptions = ov.getInOption().split(" +");
115         for (String opt : inOptions) {
116             if (StringUtils.isNotBlank(opt)) {
117                 cmdList.add(opt);
118             }
119         }
120         cmdList.add("-i");
121
122         if (fwsFile == null) {
123             cmdList.add(videoFile.getPath());
124         } else {
125             cmdList.add(fwsFile.getPath());
126         }
127         String[] outOptions = ov.getOutOption().split(" +");
128         for (String opt : outOptions) {
129             if (StringUtils.isNotBlank(opt)) {
130                 cmdList.add(opt);
131             }
132         }
133         if (!getFfmpeg().isVhookDisabled()) {
134             if (!addVhookSetting(cmdList, addComment, vhook_path, addTcomment, tcommPath)) {
135                 return -1;
136             }
137         }
138         cmdList.add(convertedVideoFile.getPath());
139
140         System.out.print("arg:");
141         for (String s : cmdList) {
142             System.out.print(" " + s);
143         }
144         System.out.println();
145
146         try {
147             System.out.println("\n\n----\nProcessing FFmpeg...\n----\n\n");
148             Process process = Runtime.getRuntime().exec(cmdList.toArray(new String[0]));
149             BufferedReader ebr = new BufferedReader(new InputStreamReader(
150                     process.getErrorStream()));
151             String e;
152             while ((e = ebr.readLine()) != null) {
153                 String state = e;
154                 if (state.startsWith("frame=")) {
155                     sendText(state);
156                 } else if (!state.endsWith("No accelerated colorspace conversion found")) {
157                     System.out.println(e);
158                 }
159
160                 try {
161                     stopFlagReturn();
162                 } catch (InterruptedException ex) {
163                     process.destroy();
164                     throw ex;
165                 }
166
167             }
168             process.waitFor();
169             return process.exitValue();
170         } finally {
171             if (fwsFile != null) {
172                 fwsFile.delete();
173             }
174         }
175     }
176
177     private boolean addVhookSetting(List cmdList, boolean addComment, String vhook_path, boolean addTcomment,
178             String tcommPath) {
179         try {
180             cmdList.add("-vfilters");
181             StringBuffer sb = new StringBuffer();
182             sb.append("vhext=");
183             sb.append(getFfmpeg().getVhook().getPath().replace("\\", "/"));
184             if (addComment) {
185                 sb.append("|");
186                 sb.append("--data-user:");
187                 sb.append(URLEncoder.encode(vhook_path.replace("\\", "/"), "Shift_JIS"));
188             }
189             if (addTcomment) {
190                 sb.append("|");
191                 sb.append("--data-owner:");
192                 sb.append(URLEncoder.encode(tcommPath.replace("\\", "/"), "Shift_JIS"));
193             }
194             sb.append("|");
195             sb.append("--font:");
196             sb.append(URLEncoder.encode(
197                     getFfmpeg().getFont().getPath().replace("\\", "/"), "Shift_JIS"));
198             sb.append("|");
199             sb.append("--font-index:");
200             sb.append(getFfmpeg().getFontIndex());
201             sb.append("|");
202             sb.append("--show-user:");
203             sb.append(getFfmpeg().getMaxNumOfComment());
204             sb.append("|");
205             sb.append("--shadow:");
206             sb.append(getFfmpeg().getShadowIndex());
207             sb.append("|");
208             if (getFfmpeg().isShowConverting()) {
209                 sb.append("--enable-show-video");
210                 sb.append("|");
211             }
212             if (getFfmpeg().isSelfAdjustFontSize()) {
213                 sb.append("--enable-fix-font-size");
214                 sb.append("|");
215             }
216             if (getFfmpeg().isCommentOpaque()) {
217                 sb.append("--enable-opaque-comment");
218             }
219             cmdList.add(sb.toString());
220             return true;
221         } catch (UnsupportedEncodingException e) {
222             e.printStackTrace();
223             return false;
224         }
225     }
226
227     private Ffmpeg getFfmpeg() {
228         return ffmpeg;
229     }
230 }