<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.tang</groupId><artifactId>media-converter</artifactId><version>1.0.0</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency><dependency><groupId>ws.schild</groupId><artifactId>jave-all-deps</artifactId><version>2.7.3</version></dependency></dependencies><build><finalName>media-converter</finalName><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-clean-plugin</artifactId><version>2.5</version></plugin><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><appendAssemblyId>false</appendAssemblyId><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs><archive><manifest><mainClass>com.tang.MediaConverter</mainClass></manifest></archive></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>assembly</goal></goals></execution></executions></plugin></plugins></build></project>
FileUtil
package com.tang;import lombok.extern.slf4j.Slf4j;import java.io.*;import java.nio.charset.Charset;import java.nio.file.Files;import java.nio.file.StandardCopyOption;import java.nio.file.StandardOpenOption;import java.util.ArrayList;import java.util.Arrays;import java.util.List;/** * 文件工具 * @author tang */@Slf4jpublic class FileUtil {public static boolean checkFileSize(File file, int size_MB) {long size = size_MB * 1024 * 1024;return file.length() > size ? false : true;}public static String resetPostfix(String sourcePath,String newPostfix) {String targetPath;int point_index = sourcePath.lastIndexOf(".");if (point_index != -1) {targetPath = sourcePath.substring(0, point_index) + "."+newPostfix;} else {targetPath = sourcePath + "."+newPostfix;}return targetPath;}public static String getFilePath(String absolutePath) {int lastIndexOf = absolutePath.lastIndexOf("/");if (lastIndexOf >= 0) {return absolutePath.substring(0, lastIndexOf + 1);}lastIndexOf = absolutePath.lastIndexOf("\\");if (lastIndexOf >= 0) {return absolutePath.substring(0, lastIndexOf + 1);}return absolutePath;}public static String getFilePostfix(File file) {String absolutePath = file.getAbsolutePath();int lastIndexOf = absolutePath.lastIndexOf(".");if (lastIndexOf >= 0) {return absolutePath.substring(lastIndexOf + 1);}return "";}public static String getFilePostfix(String path) {int lastIndexOf = path.lastIndexOf(".");if (lastIndexOf >= 0) {return path.substring(lastIndexOf + 1);}return "";}public static String getFileNameNotPostfix(File file) {String name = file.getName();int lastIndexOf = name.lastIndexOf(".");if (lastIndexOf >= 0) {return name.substring(0, lastIndexOf);}return "";}public static boolean exists(File file) {return file != null && file.exists();}public static boolean isCanWrite(File targetFile) {if (targetFile == null) {return false;}if (targetFile.isDirectory()) {return false;}if (!targetFile.exists()) {return true;}try (FileOutputStream fos = new FileOutputStream(targetFile, true)) {return true;} catch (Exception e) {return false;}}public static String readTextFile(File file) {return readTextFile(file, "UTF-8");}public static String readTextFile(File file, String code) {try {return new String(Files.readAllBytes(file.toPath()), code);} catch (Exception e) {log.error("error",e);}return null;}public static File createFile(String filePath) {File file = new File(filePath);if (file.exists()) {return file;}if (file.isDirectory()) {file.mkdirs();return file;}if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}try {file.createNewFile();} catch (Exception e) {log.error("error",e);}return file;}public static void saveTextFile(String filePath, String str) {saveTextFile(createFile(filePath), str);}public static void saveTextFile(File file, String str) {saveTextFile(file, str, "UTF-8");}public static void saveTextFile(File file, String str, String code) {try {Files.write(file.toPath(), str.getBytes(code), StandardOpenOption.CREATE);} catch (Exception e) {log.error("error",e);}}public static void deleteFile(File file) {if (!exists(file)) {return;}if (file.isDirectory()) {File[] listFiles = file.listFiles();for (int i = 0; i < listFiles.length; i++) {deleteFile(listFiles[i]);}// Files.delete(file.toPath());file.delete();} else {file.delete();}}public static void moveFile(File sourceFile, File targetFile) {if (!exists(sourceFile)) {return;}if (sourceFile.isDirectory()) {if (!targetFile.exists()) {targetFile.mkdirs();}File[] listFiles = sourceFile.listFiles();for (int i = 0; i < listFiles.length; i++) {File childTargetFile = new File(targetFile.getPath() + File.separator + listFiles[i].getName());moveFile(listFiles[i], childTargetFile);}sourceFile.delete();} else {try {if (!targetFile.getParentFile().exists()) {targetFile.getParentFile().mkdirs();}Files.move(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);} catch (Exception e) {log.error("error",e);}}}public static void copyFile(File sourceFile, File targetFile) {if (!exists(sourceFile)) {return;}if (sourceFile.isDirectory()) {if (!targetFile.exists()) {targetFile.mkdirs();}File[] listFiles = sourceFile.listFiles();for (int i = 0; i < listFiles.length; i++) {File childTargetFile = new File(targetFile.getPath() + File.separator + listFiles[i].getName());copyFile(listFiles[i], childTargetFile);}} else {try {if (!targetFile.getParentFile().exists()) {targetFile.getParentFile().mkdirs();}Files.copy(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);} catch (Exception e) {log.error("error",e);}}}public static Object copyOfDeep(Object obj) throws IOException, ClassNotFoundException{ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);oos.writeObject(obj);oos.close();ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);Object obj2 = ois.readObject();ois.close();return obj2;}public static byte[] readAllBytes(InputStream in, int initialSize) throws IOException {try (InputStream _in = in) {int capacity = initialSize;byte[] buf = new byte[capacity];int nread = 0;int rem = buf.length;for (int n = _in.read(buf, nread, rem); n > 0; n = _in.read(buf, nread, rem)) {nread += n;rem -= n;assert rem >= 0;if (rem == 0) {int newCapacity = capacity << 1;if (newCapacity < 0) {if (capacity == Integer.MAX_VALUE)throw new OutOfMemoryError("Required array size too large");newCapacity = Integer.MAX_VALUE;}rem = newCapacity - capacity;buf = Arrays.copyOf(buf, newCapacity);capacity = newCapacity;}}return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);} catch (IOException e) {throw e;}}public static String readAllString(InputStream in) throws IOException {return readAllString(in, Charset.forName("UTF-8"));}public static String readAllString(InputStream in, Charset code) throws IOException {if (code==null) {code=Charset.forName("UTF-8");}try (BufferedInputStream bis = new BufferedInputStream(in);InputStreamReader isr=new InputStreamReader(bis,code.newDecoder());BufferedReader reader = new BufferedReader (isr)) {StringBuffer sb = new StringBuffer();for (String line = reader.readLine();line != null;line = reader.readLine()) {sb.append(line);}return sb.toString();}}public static String readAllString(Reader r, int initialSize) throws IOException {try (BufferedReader br = new BufferedReader(r)) {StringBuffer sb = new StringBuffer();char[] b = new char[initialSize];for (int i = br.read(b); i > 0; i = br.read(b)) {sb.append(new String(b, 0, i));}return sb.toString();}}public static List<String> readAllLines(InputStream in, String code) throws IOException {try (Reader r = code == null ? new InputStreamReader(in) : new InputStreamReader(in, code)) {return readAllLines(r);}}public static List<String> readAllLines(Reader r) throws IOException {try (BufferedReader br = new BufferedReader(r)) {List<String> result = new ArrayList<>();for (String line = br.readLine(); line != null; line = br.readLine()) {result.add(line);}return result;}}}
MediaUtil
package com.tang;import lombok.extern.slf4j.Slf4j;import ws.schild.jave.*;import java.io.File;/** * 视频转换工具 * @author tang */@Slf4jpublic class MediaUtil {public static MultimediaInfo getInfo(String sourcePath) {try {return new MultimediaObject(new File(sourcePath)).getInfo();} catch (Exception e) {log.error("获取多媒体信息报错:",e);return null;}}public static String saveOneImage(String sourcePath) {String imagePath = FileUtil.resetPostfix(sourcePath, "png");return saveOneImage(sourcePath, imagePath);}/** * 截取视频的一针作为封面图并保存到指定文件 * * @param sourcePath 视频文件路径 * @param imagePath截取图片保存路径 */public static String saveOneImage(String sourcePath, String imagePath) {try {MultimediaObject multimediaObject = new MultimediaObject(new File(sourcePath));VideoInfo videoInfo = multimediaObject.getInfo().getVideo();if (videoInfo != null) {// 第一个参数 视频源文件信息类// 第二个参数 截取的宽度// 第三个参数 截取的高度// 第四个参数 截取的是那一帧// 第五个参数是 截取的图片质量 1-31 数字越小质量越高new ScreenExtractor().renderOneImage(multimediaObject, videoInfo.getSize().getWidth(), videoInfo.getSize().getHeight(), 0, new File(imagePath), 31);log.info("获取视频封面图成功!");return "";} else {log.info("获取视频封面图失败:没有视频信息!");return "没有视频信息";}} catch (Exception e) {log.error("获取视频封面图失败:", e);return e.getMessage();}}public static String convertMediaToMp4(String sourcePath) {String targetPath = FileUtil.resetPostfix(sourcePath, "mp4");return convertMediaToMp4(sourcePath, targetPath);}public static String convertMediaToMp4(String sourcePath, String targetPath) {return convertMediaFormat(sourcePath, targetPath, "libmp3lame", "libx264", "mp4");}public static String convertMediaFormat(String sourcePath, String targetPath, String audioEncoder, String videoEncoder, String targetFormat) {try {File source = new File(sourcePath);File target = new File(targetPath);MultimediaObject multimediaObject = new MultimediaObject(source);MultimediaInfo info = multimediaObject.getInfo();logVideoInfo(info);VideoAttributes video = new VideoAttributes();video.setCodec(videoEncoder);video.setSize(info.getVideo().getSize());video.setBitRate(info.getVideo().getBitRate());video.setFrameRate((int) info.getVideo().getFrameRate());EncodingAttributes attrs = new EncodingAttributes();attrs.setFormat(targetFormat);attrs.setVideoAttributes(video);if(info.getAudio()!=null){AudioAttributes audio = new AudioAttributes();audio.setCodec(audioEncoder);audio.setChannels(info.getAudio().getChannels());audio.setBitRate(info.getAudio().getBitRate());audio.setSamplingRate(info.getAudio().getSamplingRate());attrs.setAudioAttributes(audio);}else{attrs.setAudioAttributes(null);}Encoder encoder = new Encoder();encoder.encode(multimediaObject, target, attrs);log.info("转换视频格式成功!");return "";} catch (Exception e) {log.error("转换视频格式发生错误:", e);return e.getMessage();}}private static void logVideoInfo(MultimediaInfo info) {log.info("原文件格式:" + info.getFormat());log.info("原播放时长:" + (info.getDuration() / 1000L / 60L) + "分钟");if(info.getAudio()!=null){log.info("原音频编码:" + info.getAudio().getDecoder());log.info("原音频频道:" + info.getAudio().getChannels());log.info("原音频比特率:" + (info.getAudio().getBitRate() / 1000) + "每秒");// 越大越清晰log.info("原音频帧率:" + info.getAudio().getSamplingRate());}else{log.info("无音频......");}log.info("原视频编码:" + info.getVideo().getDecoder());log.info("原视频宽高:" + info.getVideo().getSize().getWidth() + "," + info.getVideo().getSize().getHeight());log.info("原视频比特率:" + (info.getVideo().getBitRate() / 1000) + "每秒");// 越大越清晰log.info("原视频帧率:" + (info.getVideo().getFrameRate()));// 越高越连贯}public static void main(String[] args) {//convertMediaToMp4("D:\\desktop\\Video_2024-03-12_212432.wmv",true);saveOneImage("D:\\desktop\\Video_2024-03-12_212432.wmv");}}
MediaConverter
package com.tang;import lombok.extern.slf4j.Slf4j;import javax.swing.*;import java.awt.*;import java.io.File;/** * 视频转换工具 * @author tang */@Slf4jpublic class MediaConverterextends JFrame {JTextField sourcePathField;private MediaConverter() {setTitle("视频转换工具(by tzc)");setSize(600, 200);setLocationRelativeTo(null);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel root = new JPanel();setContentPane(root);root.setLayout(new BorderLayout());JPanel gridPanel = new JPanel();gridPanel.setLayout(new GridLayout(2,1));root.add(gridPanel, BorderLayout.CENTER);JPanel infoPanel1 = new JPanel();gridPanel.add(infoPanel1);infoPanel1.setLayout(new FlowLayout(FlowLayout.CENTER));infoPanel1.setBackground(Color.gray);infoPanel1.add(new JLabel("原视频:"));sourcePathField = new JTextField(40);sourcePathField.setText("");infoPanel1.add(sourcePathField);JButton selectFileBtn = new JButton("选择");selectFileBtn.addActionListener(e -> {JFileChooser fileChooser = new JFileChooser();int option = fileChooser.showDialog(MediaConverter.this, "选择要转换的视频文件");if(option==JFileChooser.APPROVE_OPTION){File file = fileChooser.getSelectedFile();String fileName = file.getAbsolutePath();sourcePathField.setText(fileName);}else{sourcePathField.setText("");}});infoPanel1.add(selectFileBtn);JPanel infoPanel2 = new JPanel();gridPanel.add(infoPanel2);infoPanel2.setLayout(new FlowLayout(FlowLayout.CENTER));infoPanel2.setBackground(Color.gray);JButton startBtn = new JButton("转换成MP4");startBtn.addActionListener(e -> {if(sourcePathField.getText().isEmpty()){JOptionPane.showMessageDialog(MediaConverter.this, "请选择视频文件!");return;}String err = MediaUtil.convertMediaToMp4(sourcePathField.getText());if(err.isEmpty()){JOptionPane.showMessageDialog(MediaConverter.this, "转换成功!");}else{JOptionPane.showMessageDialog(MediaConverter.this, "转换失败!");}});infoPanel2.add(startBtn);JButton cutImageBtn = new JButton("截取封面");cutImageBtn.addActionListener(e -> {if(sourcePathField.getText().isEmpty()){JOptionPane.showMessageDialog(MediaConverter.this, "请选择视频文件!");return;}String err = MediaUtil.saveOneImage(sourcePathField.getText());if(err.isEmpty()){JOptionPane.showMessageDialog(MediaConverter.this, "截取成功!");}else{JOptionPane.showMessageDialog(MediaConverter.this, "截取失败!");}});infoPanel2.add(cutImageBtn);}public static void main(String[] args) throws Exception {UIManager.setLookAndFeel(com.sun.java.swing.plaf.windows.WindowsLookAndFeel.class.getName());MediaConverter jFrame = new MediaConverter();jFrame.setVisible(true);}}