Java使用ffmpeg和mencoder实现视频转码

时间:2021-12-22 14:03:27

本文为大家分享了java使用ffmpeg和mencoder实现视频转码的具体代码,供大家参考,具体内容如下

准备:

需要下载ffmpeg和mencoder,百度一搜就有了,请自行下载。

不墨迹,上代码:

1)首先需要定义几个量:contants.java

?
1
2
3
4
5
6
7
8
9
10
public class contants {
 public static final string ffmpegpath = "d:\\devtools\\ffmpeg\\bin\\ffmpeg.exe";//ffmpeg的安装位置
 public static final string mencoderpath = "d:\\devtools\\mencoder\\"; // mencoder的目录
 
 public static final string videofolder = "d:\\tools\\video\\"; // 需要被转换格式的视频目录
 public static final string targetfolder = "d:\\tools\\target\\"; // 转换后视频的目录
 
 public static final string videorealpath = "d:\\tools\\target\\"; // 需要被截图的视频目录;
 public static final string imagerealpath = "d:\\tools\\imgs\\"; // 截图的存放目录
}

2)其次,就是utils类了,具体里面有注释:convervideoutils.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
import java.io.file;
import java.io.ioexception;
import java.io.inputstream;
import java.util.date;
import java.util.list;
 
import com.wdy.common.contants;
 
public class convervideoutils {
 private date dt;
 private long begintime;
 private string sourcevideopath;//源视频路径
 private string filerealname; // 文件名 不包括扩展名
 private string filename; // 包括扩展名
 private string videofolder = contants.videofolder; // 别的格式视频的目录
 private string targetfolder = contants.targetfolder; // flv视频的目录
 private string ffmpegpath = contants.ffmpegpath; // ffmpeg.exe的目录
 private string mencoderpath = contants.mencoderpath; // mencoder的目录
 private string imagerealpath = contants.imagerealpath; // 截图的存放目录
 
 public convervideoutils() {
 }
 
 public convervideoutils(string path) {
 sourcevideopath = path;
 }
 
 public string getpath() {
 return sourcevideopath;
 }
 
 public void setpath(string path) {
 sourcevideopath = path;
 }
 
 /**
 * 转换视频格式
 * @param string targetextension 目标视频扩展名 .xxx
 * @param isdelsoursefile 转换完成后是否删除源文件
 * @return
 */
 public boolean beginconver(string targetextension, boolean isdelsoursefile) {
 file fi = new file(sourcevideopath);
 filename = fi.getname();
 filerealname = filename.substring(0, filename.lastindexof(".")).tolowercase();
 system.out.println("----接收到文件(" + sourcevideopath + ")需要转换-------------------------- ");
 if (!checkfile(sourcevideopath)) {
 system.out.println(sourcevideopath + "文件不存在" + " ");
 return false;
 }
 dt = new date();
 begintime = dt.gettime();
 system.out.println("----开始转文件(" + sourcevideopath + ")-------------------------- ");
 if (process(targetextension,isdelsoursefile)) {
 date dt2 = new date();
 system.out.println("转换成功 ");
 long endtime = dt2.gettime();
 long timecha = (endtime - begintime);
 string totaltime = sumtime(timecha);
 system.out.println("转换视频格式共用了:" + totaltime + " ");
 if (processimg(sourcevideopath)) {
 system.out.println("截图成功了! ");
 } else {
 system.out.println("截图失败了! ");
 }
 if (isdelsoursefile) {
 deletefile(sourcevideopath);
 }
 sourcevideopath = null;
 return true;
 } else {
 sourcevideopath = null;
 return false;
 }
 }
 
 /**
 * 对视频进行截图
 * @param sourcevideopath 需要被截图的视频路径(包含文件名和扩展名)
 * @return
 */
 public boolean processimg(string sourcevideopath) {
 if (!checkfile(sourcevideopath)) {
 system.out.println(sourcevideopath + " is not file");
 return false;
 }
 file fi = new file(sourcevideopath);
 filename = fi.getname();
 filerealname = filename.substring(0, filename.lastindexof(".")).tolowercase();
 list<string> commend = new java.util.arraylist<string>();
 //第一帧: 00:00:01
 //time ffmpeg -ss 00:00:01 -i test1.flv -f image2 -y test1.jpg
 commend.add(ffmpegpath);
// commend.add("-i");
// commend.add(videorealpath + filerealname + ".flv");
// commend.add("-y");
// commend.add("-f");
// commend.add("image2");
// commend.add("-ss");
// commend.add("38");
// commend.add("-t");
// commend.add("0.001");
// commend.add("-s");
// commend.add("320x240");
 commend.add("-ss");
 commend.add("00:00:01");
 commend.add("-i");
 commend.add(sourcevideopath);
 commend.add("-f");
 commend.add("image2");
 commend.add("-y");
 commend.add(imagerealpath + filerealname + ".jpg");
 try {
 processbuilder builder = new processbuilder();
 builder.command(commend);
 builder.start();
 return true;
 } catch (exception e) {
 e.printstacktrace();
 return false;
 }
 }
 
 /**
 * 实际转换视频格式的方法
 * @param targetextension 目标视频扩展名
 * @param isdelsoursefile 转换完成后是否删除源文件
 * @return
 */
 private boolean process(string targetextension, boolean isdelsoursefile) {
 int type = checkcontenttype();
 boolean status = false;
 if (type == 0) {
 //如果type为0用ffmpeg直接转换
 status = processvideoformat(sourcevideopath,targetextension, isdelsoursefile);
 } else if (type == 1) {
 //如果type为1,将其他文件先转换为avi,然后在用ffmpeg转换为指定格式
 string avifilepath = processavi(type);
 if (avifilepath == null){
 // avi文件没有得到
 return false;
 }else {
 system.out.println("开始转换:");
 status = processvideoformat(avifilepath,targetextension, isdelsoursefile);
 }
 }
 return status;
 }
 
 /**
 * 检查文件类型
 * @return
 */
 private int checkcontenttype() {
 string type = sourcevideopath.substring(sourcevideopath.lastindexof(".") + 1, sourcevideopath.length()).tolowercase();
 // ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
 if (type.equals("avi")) {
 return 0;
 } else if (type.equals("mpg")) {
 return 0;
 } else if (type.equals("wmv")) {
 return 0;
 } else if (type.equals("3gp")) {
 return 0;
 } else if (type.equals("mov")) {
 return 0;
 } else if (type.equals("mp4")) {
 return 0;
 } else if (type.equals("asf")) {
 return 0;
 } else if (type.equals("asx")) {
 return 0;
 } else if (type.equals("flv")) {
 return 0;
 }
 // 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),
 // 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
 else if (type.equals("wmv9")) {
 return 1;
 } else if (type.equals("rm")) {
 return 1;
 } else if (type.equals("rmvb")) {
 return 1;
 }
 return 9;
 }
 
 /**
 * 检查文件是否存在
 * @param path
 * @return
 */
 private boolean checkfile(string path) {
 file file = new file(path);
 if (!file.isfile()) {
 return false;
 } else {
 return true;
 }
 }
 
 /**
 * 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
 * @param type
 * @return
 */
 private string processavi(int type) {
 list<string> commend = new java.util.arraylist<string>();
 commend.add(mencoderpath);
 commend.add(sourcevideopath);
 commend.add("-oac");
 commend.add("mp3lame");
 commend.add("-lameopts");
 commend.add("preset=64");
 commend.add("-ovc");
 commend.add("xvid");
 commend.add("-xvidencopts");
 commend.add("bitrate=600");
 commend.add("-of");
 commend.add("avi");
 commend.add("-o");
 commend.add(videofolder + filerealname + ".avi");
 // 命令类型:mencoder 1.rmvb -oac mp3lame -lameopts preset=64 -ovc xvid
 // -xvidencopts bitrate=600 -of avi -o rmvb.avi
 try {
 processbuilder builder = new processbuilder();
 builder.command(commend);
 process p = builder.start();
 dowaitfor(p);
 return videofolder + filerealname + ".avi";
 } catch (exception e) {
 e.printstacktrace();
 return null;
 }
 }
 
 /**
 * 转换为指定格式
 * ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
 * @param oldfilepath
 * @param targetextension 目标格式扩展名 .xxx
 * @param isdelsoursefile 转换完成后是否删除源文件
 * @return
 */
 private boolean processvideoformat(string oldfilepath, string targetextension, boolean isdelsourcefile) {
 if (!checkfile(sourcevideopath)) {
 system.out.println(oldfilepath + " is not file");
 return false;
 }
 //ffmpeg -i file_name.flv -ar 22050 new_file_name.mp4
 list<string> commend = new java.util.arraylist<>();
 commend.add(ffmpegpath);
 commend.add("-i");
 commend.add(oldfilepath);
 commend.add("-ar");
 commend.add("22050");
 commend.add(targetfolder + filerealname + targetextension);
 try {
 processbuilder builder = new processbuilder();
 string cmd = commend.tostring();
 builder.command(commend);
 process p = builder.start();
 dowaitfor(p);
 p.destroy();
 //转换完成后删除源文件
// if (isdelsourcefile) {
// deletefile(sourcevideopath);
// }
 return true;
 } catch (exception e) {
 e.printstacktrace();
 return false;
 }
 }
 
 /**
 * ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
 * @param oldfilepath
 * @return
 */
 private boolean processflv(string oldfilepath) {
 if (!checkfile(sourcevideopath)) {
 system.out.println(oldfilepath + " is not file");
 return false;
 }
 list<string> commend = new java.util.arraylist<>();
 commend.add(ffmpegpath);
 commend.add("-i");
 commend.add(oldfilepath);
 commend.add("-ab");
 commend.add("64");
 commend.add("-acodec");
 commend.add("mp3");
 commend.add("-ac");
 commend.add("2");
 commend.add("-ar");
 commend.add("22050");
 commend.add("-b");
 commend.add("230");
 commend.add("-r");
 commend.add("24");
 commend.add("-y");
 commend.add(targetfolder + filerealname + ".flv");
 try {
 processbuilder builder = new processbuilder();
 string cmd = commend.tostring();
 builder.command(commend);
 process p = builder.start();
 dowaitfor(p);
 p.destroy();
 deletefile(oldfilepath);
 return true;
 } catch (exception e) {
 e.printstacktrace();
 return false;
 }
 }
 
 public int dowaitfor(process p) {
 inputstream in = null;
 inputstream err = null;
 int exitvalue = -1; // returned to caller when p is finished
 try {
 system.out.println("comeing");
 in = p.getinputstream();
 err = p.geterrorstream();
 boolean finished = false; // set to true when p is finished
 
 while (!finished) {
 try {
  while (in.available() > 0) {
  character c = new character((char) in.read());
  system.out.print(c);
  }
  while (err.available() > 0) {
  character c = new character((char) err.read());
  system.out.print(c);
  }
 
  exitvalue = p.exitvalue();
  finished = true;
 
 } catch (illegalthreadstateexception e) {
  thread.currentthread().sleep(500);
 }
 }
 } catch (exception e) {
 system.err.println("dowaitfor();: unexpected exception - " + e.getmessage());
 } finally {
 try {
 if (in != null) {
  in.close();
 }
 
 } catch (ioexception e) {
 system.out.println(e.getmessage());
 }
 if (err != null) {
 try {
  err.close();
 } catch (ioexception e) {
  system.out.println(e.getmessage());
 }
 }
 }
 return exitvalue;
 }

3)最后,编写测试类:convervideotest.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class convervideotest {
 public void run() {
  try {
   // 转换并截图
   string filepath = "c:\\users\\wangdy\\desktop\\pics\\05.尚硅谷_svn_启动服务器.wmv";
   convervideoutils cv = new convervideoutils(filepath);
   string targetextension = ".mp4";
   boolean isdelsoursefile = true;
   boolean beginconver = cv.beginconver(targetextension,isdelsoursefile);
   system.out.println(beginconver);
  } catch (exception e) {
   e.printstacktrace();
  }
 }
 
 public static void main(string args[]) {
  convervideotest c = new convervideotest();
  c.run();
 }
}

这样就完成了整个视频格式的转换,在定义的目标视频文件夹和截图存放文件夹就可以看到转换后的视频和视频第一帧的截图了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/wdy_2099/article/details/71453602