本文為大家分享了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