2021-06-11 java视频转码

软编解码 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);

    }

}


it.sauronsoftware

jave

1.0.2

你可能感兴趣的:(2021-06-11 java视频转码)