a2aeb81581abe5d4f91d1d9178de9d0411095095
[meviz.git] / src / main / java / eu / svjatoslav / meviz / encoder / converters / FFMpegVideo.java
1 /*
2  * Meviz - Various tools collection to work with multimedia. Author: Svjatoslav Agejenko.
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5
6
7 package eu.svjatoslav.meviz.encoder.converters;
8
9 import eu.svjatoslav.meviz.encoder.BitrateParameter.Bitrate;
10 import eu.svjatoslav.meviz.encoder.EncodingOptions;
11
12 import java.io.File;
13 import java.util.List;
14
15 public class FFMpegVideo extends AbstractConverter {
16
17     private String constructCodecParamsString(final EncodingOptions options,
18                                               final int videoBitrate, final int audioBitrate,
19                                               final String videoCodec, final String audioCodec) {
20
21         final StringBuilder codecParams = new StringBuilder();
22
23         if (audioCodec == null)
24             codecParams.append("-an ");
25         else
26             codecParams.append("-acodec " + audioCodec + " ");
27
28         codecParams.append("-vcodec " + videoCodec + " ");
29
30         if (videoBitrate != -1)
31             codecParams.append("-b " + videoBitrate + "k ");
32
33         if (audioBitrate != -1)
34             codecParams.append("-b:a " + audioBitrate + "k ");
35
36         if (options.isDeinterlace())
37             codecParams.append("-filter:v yadif ");
38
39         if (options.getTargetFps() != null)
40             codecParams.append("-r " + options.getTargetFps() + " ");
41
42         return codecParams.toString();
43     }
44
45     private int getAudioBitrateValue(final Bitrate bitRate) {
46         switch (bitRate) {
47             case LOW:
48                 return 128;
49
50             case MEDIUM:
51                 return 160;
52
53             case HIGH:
54                 return 320;
55
56             case COPY:
57                 return -1;
58
59             case NONE:
60                 return -1;
61
62             case LOSSLESS:
63                 return -1;
64
65             default:
66                 throw new RuntimeException("Audio bitrate: " + bitRate
67                         + " is not supported.");
68         }
69     }
70
71     @Override
72     public String getCommand(final File inputFile, final File targetFile,
73                              final EncodingOptions options, final String targetFormat) {
74
75         int videoBitrate = getVideoBitrateValue(options.getVideoBitrate());
76         int audioBitrate = getAudioBitrateValue(options.getAudioBitrate());
77
78         // convert
79         final StringBuilder codecParams = new StringBuilder();
80
81         String videoCodec = "libx264";
82         String audioCodec = "libmp3lame";
83
84         if (targetFormat.equals("webm")) {
85             videoCodec = "vp8";
86             audioCodec = "opus";
87             codecParams.append("-s 800x450 ");
88         }
89
90         if (options.getVideoBitrate() == Bitrate.COPY)
91             videoCodec = "copy";
92
93         if (options.getAudioBitrate() == Bitrate.COPY)
94             audioCodec = "copy";
95
96         if (options.getAudioBitrate() == Bitrate.LOSSLESS){
97             audioCodec = "flac";
98             codecParams.append("-strict -2 ");
99         }
100
101         if (options.getAudioBitrate() == Bitrate.NONE)
102             audioCodec = null;
103
104         if (options.isForPortablePlayer()) {
105             videoBitrate = 1000;
106             audioBitrate = 128;
107             videoCodec = "libxvid";
108
109             // reduce resolution
110             codecParams.append("-s 640x480 ");
111
112             // enforce maximum keyframe interval
113             codecParams.append("-g 150 ");
114         }
115
116         codecParams.append(constructCodecParamsString(options, videoBitrate,
117                 audioBitrate, videoCodec, audioCodec));
118
119         return "ffmpeg -i \"" + inputFile.getAbsolutePath() + "\" "
120                 + codecParams.toString() + "\"" + targetFile.getAbsolutePath()
121                 + "\"";
122     }
123
124     @Override
125     public List<String> getSourceFileExtensions() {
126         return getSupportedExtensions();
127     }
128
129     private List<String> getSupportedExtensions() {
130         return toList("mkv", "mts", "mp4", "avi", "mpg", "mpeg", "vob", "m4v",
131                 "webm", "mov", "asf", "3gp");
132     }
133
134     @Override
135     public List<String> getTargetFileExtensions() {
136         return getSupportedExtensions();
137     }
138
139     private int getVideoBitrateValue(final Bitrate bitRate) {
140         switch (bitRate) {
141             case LOW:
142                 return 1000;
143
144             case MEDIUM:
145                 return 4000;
146
147             case HIGH:
148                 return 16000;
149
150             case COPY:
151                 return -1;
152
153             default:
154                 throw new RuntimeException("Video bitrate: " + bitRate
155                         + " is not supported.");
156         }
157     }
158
159     @Override
160     public boolean isTerminalMandatory() {
161         return true;
162     }
163
164 }