Refactored to remove code duplication.
[meviz.git] / src / main / java / eu / svjatoslav / meviz / encoder / Encoder.java
1 /*
2  * Meviz - Various tools collection to work with multimedia.
3  * Copyright (C) 2012, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 2 of the GNU General Public License
7  * as published by the Free Software Foundation.
8  */
9
10 package eu.svjatoslav.meviz.encoder;
11
12 import java.io.File;
13 import java.util.List;
14
15 import eu.svjatoslav.commons.file.FilePathParser;
16 import eu.svjatoslav.commons.string.WildCardMatcher;
17 import eu.svjatoslav.meviz.Module;
18 import eu.svjatoslav.meviz.encoder.converters.AbstractConverter;
19
20 public class Encoder implements Module {
21
22         public FormatsRegistry encoderRegistry = new FormatsRegistry();
23
24         public EncodingOptions encodingOptions;
25
26         public EncodingPlan encodingPlan;
27
28         CommandlineHandler commandlineHandler = new CommandlineHandler();
29
30         /**
31          * Generate encoding plan
32          * 
33          * @param sourceFile
34          *            Source directory of file
35          */
36         public void compileEncodingPlan(final File sourceFile) {
37                 if (!sourceFile.exists()) {
38                         System.out.println("Error: file \"" + sourceFile.getAbsolutePath()
39                                         + "\" does not exist.");
40                         return;
41                 }
42
43                 if (sourceFile.isDirectory()) {
44                         // handle directory
45                         for (final File subFile : sourceFile.listFiles())
46                                 if (subFile.isDirectory()) {
47                                         if (encodingOptions.recursive)
48                                                 compileEncodingPlan(subFile);
49                                 } else
50                                         compileEncodingPlan(subFile);
51                 } else if (sourceFile.isFile())
52                         if (fileMatchesInputPattern(sourceFile)) {
53
54                                 // System.out.println("Processing file: " +
55                                 // file.getAbsolutePath());
56
57                                 final String sourceFileExtension = FilePathParser
58                                                 .getFileExtension(sourceFile);
59
60                                 // encode source file into every desired target format
61                                 for (final String targetFormat : encodingOptions.outputFormats) {
62
63                                         // construct target file
64                                         final File targetFile = getTargetFile(sourceFile,
65                                                         targetFormat);
66
67                                         // System.out.println("target path: " +
68                                         // targetFilePath.toString());
69
70                                         if (!targetFile.exists()) {
71
72                                                 final List<eu.svjatoslav.meviz.encoder.converters.AbstractConverter> formats = encoderRegistry
73                                                                 .getEncoders(sourceFileExtension, targetFormat);
74
75                                                 if (formats.size() == 0)
76                                                         System.out
77                                                                         .println("Error: no encoders found to convert file \""
78                                                                                         + sourceFile.getAbsolutePath()
79                                                                                         + "\" into "
80                                                                                         + targetFormat
81                                                                                         + " format.");
82                                                 else if (formats.size() > 1)
83                                                         System.out
84                                                                         .println("Error: Encoders piping not yet supported to convert file \""
85                                                                                         + sourceFile.getAbsolutePath()
86                                                                                         + "\" into "
87                                                                                         + targetFormat
88                                                                                         + " format.");
89                                                 else {
90                                                         final AbstractConverter chosenFormat = formats.get(0);
91                                                         final EncodingTask encodingTask = new EncodingTask(
92                                                                         sourceFile, targetFile, chosenFormat);
93
94                                                         if (chosenFormat.isTerminalMandatory())
95                                                                 encodingTask.setUseTerminal(true);
96                                                         encodingPlan.scheduleTask(encodingTask);
97                                                 }
98                                         }
99                                 }
100                         }
101
102         }
103
104         /**
105          * @param file
106          *            single file candidate to potentially be encoded
107          * 
108          * @return <code>true</code> if file shall be encoded.
109          */
110         public boolean fileMatchesInputPattern(final File file) {
111                 final String fileName = file.getName().toLowerCase();
112
113                 for (final String inputPattern : encodingOptions.inputPatterns)
114                         if (WildCardMatcher.match(fileName, inputPattern.toLowerCase()))
115                                 return true;
116
117                 return false;
118         }
119
120         @Override
121         public String getDescription() {
122                 return "Convert between various media formats.";
123         }
124
125         @Override
126         public String getModuleCommand() {
127                 return "encode";
128         }
129
130         private File getTargetFile(final File sourceFile, final String targetFormat) {
131                 final StringBuffer targetFilePath = new StringBuffer();
132                 targetFilePath.append(sourceFile.getParent());
133                 targetFilePath.append("/");
134                 targetFilePath.append(FilePathParser
135                                 .getFileNameWithoutExtension(sourceFile));
136                 targetFilePath.append(".");
137                 targetFilePath.append(targetFormat);
138
139                 return new File(targetFilePath.toString());
140         }
141
142         @Override
143         public void run(final String[] args) {
144
145                 // parse incoming commandline arguments
146                 encodingOptions = commandlineHandler.parseCommandlineArguments(args);
147
148                 if (encodingOptions == null) {
149                         showCommandlineHelp();
150                         return;
151                 }
152
153                 encodingPlan = new EncodingPlan();
154
155                 compileEncodingPlan(encodingOptions.workingDirectory);
156
157                 if (!encodingOptions.testOnly)
158                         try {
159                                 encodingPlan.execute(encodingOptions);
160                         } catch (final Exception exception) {
161                                 exception.printStackTrace();
162                         }
163
164         }
165
166         @Override
167         public void showCommandlineHelp() {
168                 commandlineHandler.parser.showHelp();
169                 System.out.println("Example commands:");
170                 System.out
171                                 .println("    Convert all MTS files in the current directory into MP4's.");
172                 System.out.println("        meviz encode -o mp4 -i *.MTS");
173         }
174
175 }