有需求将VCD中的VOB文件转换成MP4的朋友们可以一试, 需要安装ffmpeg,再把bin目录加入到系统路径中,着实方便好用 感谢作者。附源码及原文地址
pacpathkage com.octopus;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* 利用FFmpeg实现视频格式批量转化的工具
*
* @author hw
*
*/
public class FfmpegConvertUtil {
private String lastMessage = "";// 当前最后一条消息
private String currentFile = "";// 当前操作的文件
//转换过程中的消息
private StringBuffer sbMessages = new StringBuffer();
//ffmpeg的实际路径,请在path中配置对应的bin
private String ffmpegPath = null;
private boolean isRunning = false;
public static void main(String[] args) {
FfmpegConvertUtil util = new FfmpegConvertUtil();
util.new MainFrame(util);
}
/**
* 处理某个文件夹
*/
public void startProcess(String basepath) {
if (ffmpegPath == null) {
//在path环境变量中搜索ffmpeg程序的路径
String path = System.getenv("path");
String[] paths = path.split(";");
for (String p : paths) {
File file = new File(p);
File[] files = file.listFiles();
if (files != null && files.length > 0) {
for (File f : files) {
if (f.getAbsolutePath().toLowerCase().endsWith("ffmpeg.exe")) {
ffmpegPath = f.getAbsolutePath();
break;
}
}
}
if(ffmpegPath!=null) {
//无需再找
break;
}
}
if (ffmpegPath == null) {
JOptionPane.showMessageDialog(null, "找不到转换程序,请设置ffmpeg到path环境变量");
}
}
//使用timer作为多线程的使用方式
Timer timer = new Timer();
ConvertTask task = new ConvertTask();
task.basePath = basepath;
timer.schedule(task, 1000, 10000);
}
public class ConvertTask extends TimerTask {
public FfmpegConvertUtil util;
public String basePath;
@Override
public void run() {
isRunning = true;
int count = 0;
List<String> autoGenerateMp4 = findFilesToConvert(basePath);
for (String path : autoGenerateMp4) {
currentFile = path + "(一共有文件:" + autoGenerateMp4.size() + "剩余文件数:" + (autoGenerateMp4.size() - count)+")";
convertAllOthersToMp4(path);
count++;
currentFile = "";
}
sbMessages.append(basePath + "当前文件夹下面内容已经处理完成\r\n");
isRunning = false;
}
}
/**
* 得到需要转换的文件的列表
*
* @param base 起始路径
*/
public List<String> findFilesToConvert(String base) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sbMessages.append(sdf.format(new Date()) + ":" + base + "文件搜索开始\r\n");
List<File> files = new ArrayList<File>();
List<String> filesToConvert = new ArrayList<String>();
listAllVideoFile(new File(base), files);
for (File f : files) {
filesToConvert.add(f.getAbsolutePath());
sbMessages.append(sdf.format(new Date()) + ":" + f.getAbsolutePath() + "加入清单\r\n");
}
sbMessages.append(sdf.format(new Date()) + ":" + base + "文件搜索结束,共找到需要转换文件" + filesToConvert.size() + "个\r\n");
return filesToConvert;
}
/**
* 将一个视频文件转化为对应的mp4格式
* @param filepath 要转的文件的绝对路径
*/
public void convertAllOthersToMp4(String filepath) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (filepath == null) {
return;
}
if (filepath.toLowerCase().endsWith(".mp4")) {
sbMessages.append("************" + sdf.format(new Date()) + ":" + filepath + "是mp4文件,跳过转换。\r\n");
return;
}
sbMessages.append("************" + sdf.format(new Date()) + ":" + filepath + "转换开始\r\n");
String path = filepath.substring(0, filepath.lastIndexOf('.')) + ".mp4";
byte[] buff = new byte[4096];
try {
String cmd = ffmpegPath + " -y -i \"" + filepath + "\" \"" + path + "\"";
Process process = Runtime.getRuntime().exec(cmd);
InputStream inputStream = process.getInputStream();
InputStream errorStream = process.getErrorStream();
while (process.isAlive()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
int len = inputStream.available() > 0 ? inputStream.read(buff) : 0;
if (len > 0) {
lastMessage = new String(buff, 0, len);
}
len = errorStream.available() > 0 ? errorStream.read(buff) : 0;
if (len > 0) {
lastMessage = new String(buff, 0, len);
}
}
} catch (IOException e) {
sbMessages.append("************" + "转换文件:" + path + "执行失败:" + e.getMessage() + "\r\n");
}
sbMessages.append("************" + sdf.format(new Date()) + ":" + filepath + "转换开始" + "\r\n");
}
/**
* 根据后缀名判断是不是视频文件
* @param fileName 要判断的文件名
* @return 是否为视频文件
*/
public boolean isVideoFile(String fileName) {
String[] videoExts = new String[] { "vob", "wmv", "avi", "rmvb", "mov", "rm" };
for (String ext : videoExts) {
if (fileName.endsWith(ext)) {
return true;
}
}
return false;
}
/**
* 获取指定文件夹下指定文件类型的所有文件的完整路径
*
* @param parent 起始文件夹
* @param files 存放数据的集合
*/
public void listAllVideoFile(File parent, List<File> files) {
File[] listFiles = parent.listFiles();
if (listFiles != null) {
for (File f : listFiles) {
if (f.isFile() && isVideoFile(f.getName().toLowerCase())) {
files.add(f);
} else {
listAllVideoFile(f, files);
}
}
}
}
/**
* 窗体
* @author Administrator
*
*/
public class MainFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JButton btnChooseRootDir;
private JTextArea txtMessages;
private JLabel lblMessage;
private JTextField txtCurrentFile;
private JLabel lblCurrentFile;
private JTextField txtChoosenDir;
private JLabel lblChoosenDir;
private JButton btnOpenDir;
private javax.swing.Timer timerDisplay;
public MainFrame(FfmpegConvertUtil util) {
//使用代码构建界面
this.getRootPane().setLayout(new FlowLayout(FlowLayout.LEFT, 10, 5));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
btnChooseRootDir = new JButton(" 选择转换文件夹 ");
btnChooseRootDir.setSize(200, 30);
btnChooseRootDir.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = chooser.showOpenDialog(MainFrame.this);
if (result == JFileChooser.APPROVE_OPTION) {
txtChoosenDir.setText(chooser.getSelectedFile().getAbsolutePath());
util.startProcess(txtChoosenDir.getText());
}
}
});
btnOpenDir = new JButton(" 打开文件夹 ");
btnOpenDir.setSize(200, 30);
btnOpenDir.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Runtime.getRuntime().exec("explorer \"" + txtChoosenDir.getText() + "\"");
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
txtCurrentFile = new JTextField();
txtCurrentFile.setColumns(80);
txtCurrentFile.setFont(new Font("微软雅黑", Font.PLAIN, 16));
JLabel lblTemp = new JLabel(" "
+ " ");
lblTemp.setFont(new Font("微软雅黑", Font.PLAIN, 16));
lblCurrentFile = new JLabel("当前处理中文件");
lblCurrentFile.setFont(new Font("微软雅黑", Font.PLAIN, 16));
txtChoosenDir = new JTextField();
txtChoosenDir.setColumns(80);
txtChoosenDir.setFont(new Font("微软雅黑", Font.PLAIN, 16));
lblChoosenDir = new JLabel("当前处理的文件夹");
lblChoosenDir.setFont(new Font("微软雅黑", Font.PLAIN, 16));
lblMessage = new JLabel("处理消息显示");
lblMessage.setFont(new Font("微软雅黑", Font.PLAIN, 16));
txtMessages = new JTextArea(30, 105);
JScrollPane pane = new JScrollPane(txtMessages, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
timerDisplay = new javax.swing.Timer(5000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isRunning) {
if (sbMessages.length() > 8096) {
sbMessages.delete(0, lastMessage.length());
}
if (lastMessage != null) {
sbMessages.append(lastMessage + "\r\n");
lastMessage = null;
}
txtCurrentFile.setText(currentFile);
txtMessages.setText(sbMessages.toString());
} else {
}
}
});
timerDisplay.start();
this.getRootPane().add(btnChooseRootDir);
this.getRootPane().add(btnOpenDir);
this.getRootPane().add(lblTemp);
this.getRootPane().add(lblChoosenDir);
this.getRootPane().add(txtChoosenDir);
this.getRootPane().add(lblCurrentFile);
this.getRootPane().add(txtCurrentFile);
this.getRootPane().add(lblMessage);
this.getRootPane().add(pane);
this.setSize(1200, 800);
this.setResizable(false);
this.setVisible(true);
}
}
}
原地址https://www.cnblogs.com/huangwu1/p/12354459.html