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