软编解码 cpu 速度慢 耗费性能
硬编解码 gpu 速度快
把如AVI 其他格式视频转换成 MP4(可配置参数如分辨率1080p,声道 赫兹 编码264 265等.....)
视频转码 分两种
一种是依靠CPU的 。 由CPU 单个硬件处理 。速度相对较慢,主要看CPU性能。CPU转码的效果最好
第二种 是依靠CPU + GPU 两者协同工作 。主要依靠GPU 速度很快 。效果 相对CPU 要差些。
jave http://www.sauronsoftware.it/projects/jave/manual.php(感觉实用性不大)
安装ffmpeg windows https://blog.csdn.net/qq_43803367/article/details/110308401
安装mencoder https://www.cnblogs.com/nosnowwolf/archive/2011/11/18/2254191.html
ffmpeg 参数 https://www.cnblogs.com/tyqing/p/6040267.html
mencoder 参数https://blog.csdn.net/gaohuanjie/article/details/19069563
gpu转码 https://www.jianshu.com/p/59da3d350488
demo
package com.zhuhai;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 1.ffmpeg是mplayer和mencoder的库类之一,并且mencoder是mplayer的一部分。
*
* 2.mplayer是一个播放器,mencoder是一个编码器。
*
* 3.mencoder更易于操作,并且能转换更多音频/视频文件,但是它不能用于截图。
*
* 4、转换速度比较:总体上ffmpeg转换的速度快于Mencoder
*
* 5、转换格式要求:rm、rmvb、rt格式的文件只能用Mencoder转换。
*
* 6.纯音频格式只能用Mencoder进行转换。如何判断是否是纯音频格式可以通过使用命令 FFmpeg -i "文件的完整路径" 获得输出后就可以分析出来。
*/
public class TransferUtil {
//自定义线程池 最好手动创建
static ExecutorServiceexecutor = Executors.newFixedThreadPool(3);
//FFMPEG 安装路径
private static final StringFFMPEGPATH ="E:\\zhuhai\\ffmpeg\\ffmpeg-4.4-essentials_build\\bin\\ffmpeg.exe";
//MENCODER 安装路径
private static final StringMENCODERPATH ="E:\\zhuhai\\ffmpeg\\mplayer\\mencoder.exe";
public static void main(String[] args)throws FFmpegException {
getTransCommandToExec("C:\\Users\\zhuhai8\\Desktop\\videotest\\old\\source.mp4",
"C:\\Users\\zhuhai8\\Desktop\\videotest\\new\\2.mp4", "1920", "1080", 2, 30);
}
public static boolean getTransCommandToExec(String oldFilePath, String newFilePath,
String resolutionWidth, String resolutionHight, Integer voice,
Integer fps)throws FFmpegException {
System.out.println("开始执行任务========================" + oldFilePath);
List command =new ArrayList<>();
String oldFileType = oldFilePath.substring(oldFilePath.lastIndexOf(".") +1, oldFilePath.length());
if (CollUtil.newArrayList("wmv9", "rmvb", "rm").contains(oldFilePath)) {
//对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等)用mencoder格式
command =getMencoderCommand(MENCODERPATH, oldFilePath, newFilePath, resolutionWidth, resolutionHight, voice, fps);
}else {
//其他格式用ffmpeg转换 速度快
command =getFfmpegCommand(FFMPEGPATH, oldFilePath, newFilePath, resolutionWidth, resolutionHight, voice, fps);
}
//执行cmd
if (CollUtil.isNotEmpty(command)) {
return process(command);
}
return false;
}
private static ListgetMencoderCommand(String toolPath, String oldFilePath, String newFilePath,
String resolutionWidth, String resolutionHight, Integer voice,
Integer fps) {
List commend =new java.util.ArrayList<>();
commend.add(toolPath);// 添加转换工具路径
commend.add(oldFilePath);// 添加要转换格式的视频文件的路径
commend.add("-oac");
commend.add("mp3lame");
commend.add("-lameopts");
commend.add("abr:br=56");
commend.add("-ac"); //设置声道数
commend.add("" + voice); //1单声道 2立体声
commend.add("-ovc"); //目标文件的编码器
commend.add("x264");//todo 编码器
commend.add("-ofps"); //帧率
commend.add("" + fps);
commend.add("-vf-add"); //分辨率
commend.add("scale=" + resolutionWidth +":" + resolutionHight);
commend.add("-o"); //输出文件
commend.add(newFilePath);
return commend;
}
private static ListgetFfmpegCommand(String toolPath, String oldFilePath, String newFilePath,
String resolutionWidth, String resolutionHight, Integer voice,
Integer fps)throws FFmpegException {
List command =new ArrayList();
command.add(toolPath); // 添加转换工具路径
command.add("-i"); // 添加参数"-i",该参数指定要转换的文件
command.add(oldFilePath); // 添加要转换格式的视频文件的路径
command.add("-qscale"); // 指定转换的质量 取值0.01-255,约小质量越好
command.add("4");
// command.add("-ab"); //设置音频码率
// command.add("64"); //高品质128 低品质64
// command.add("-ar"); //设置声音的采样频率 单位Hz
// command.add("22050");
command.add("-ac"); //设置声道数
command.add("" + voice); //1单声道 2立体声
command.add("-vcodec"); //目标文件的编码器
command.add("h264"); //todo 编码器
command.add("-r"); // 设置帧率
command.add("" + fps);
command.add("-s"); // 设置分辨率
command.add(resolutionWidth +"x" + resolutionHight);
// command.add("-threads"); //具体要不要在ffmpeg再多线程 windows测试擦别不大
// command.add("8");
command.add("-y"); // 添加参数"-y",该参数指定将覆盖已存在的文件
command.add(newFilePath);
return command;
}
/**
* 执行cmd
* @param command
* @return
* @throws FFmpegException
*/
private static boolean process(List command)throws FFmpegException {
try {
if (null == command || command.size() ==0)
return false;
Process p =new ProcessBuilder(command).redirectErrorStream(true).start();
p.getInputStream().close();
int exitcode = p.waitFor();
if (exitcode ==1) {
return false;
}
return true;
}catch (Exception e) {
throw new FFmpegException("file transfer failed", e);
}
}
}
class VideoTranextends Thread{
private StringoldFilePath;
private StringnewFilePath;
private StringresolutionWidth;
private StringresolutionHight;
private Integervoice;
private Integerfps;
public VideoTran(String oldFilePath, String newFilePath, String resolutionWidth, String resolutionHight, Integer voice, Integer fps) {
this.oldFilePath = oldFilePath;
this.newFilePath = newFilePath;
this.resolutionWidth = resolutionWidth;
this.resolutionHight = resolutionHight;
this.voice = voice;
this.fps = fps;
}
@Override
public void run() {
try {
long l = System.currentTimeMillis();
TransferUtil.getTransCommandToExec(oldFilePath, newFilePath, resolutionWidth, resolutionHight, voice, fps);
System.out.println(oldFilePath +"================================任务转码完成");
System.out.println(oldFilePath +"转码耗时" + (System.currentTimeMillis() - l));
}catch (FFmpegException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
File[] sourcesFiles = FileUtil.ls("C:\\Users\\zhuhai8\\Desktop\\videotest\\old");
String newpath ="C:\\Users\\zhuhai8\\Desktop\\videotest\\new\\";
for (File sourcesFile : sourcesFiles) {
TransferUtil.executor.execute(new VideoTran(sourcesFile.getAbsolutePath(),newpath+sourcesFile.getName(),
"1920","1080",1,30));
}
}
}
class FFmpegExceptionextends Exception {
private static final long serialVersionUID =1L;
public FFmpegException() {
super();
}
public FFmpegException(String message) {
super(message);
}
public FFmpegException(Throwable cause) {
super(cause);
}
public FFmpegException(String message, Throwable cause) {
super(message, cause);
}
}