java使用ffmpeg对视频进行转码和分辨率转换

最近做一个项目需要对视频进行处理,网上看了一写资料和教程,大部分都是使用ffmpeg对视频进行处理。话不多说直接上代码,很简单,一看就懂。参考博客,博主写的非常简单易懂,我自己根据业务做了一点简单的调整

首先是一个路径配置类代码如下:

public class Contants {

    /**
     * @Description:(3.工具类主类)设置转码工具的各个路径
     * @param:@param args
     * @return:void
     * @author:Zoutao
     * @date:2018-6-22
     * @version:V1.0
     */

    public static final String ffmpegpath = "D:/ffmpeg-20171225-be2da4c-win64-static/bin/ffmpeg.exe";		// ffmpeg工具安装位置
   
    public static final String videofolder = "d://file/"; // 需要被转换格式的视频目录
 
    public static final String targetfolder = "d://temp/"; // 转码后视频保存的目录
   


}
import com.tk.blogadmin.utils.DateUtils;

/**
 * @ClassName ConverVideoTest
 * @Desecription TODO
 * @Author tkk
 * @Date 2019/11/13 9:43
 **/
public class ConverVideoTest {

    /**
     * @Description:(1.转码功能调用)
     * @param:@param yuanPATH
     * @return:void
     * @author:Zoutao
     * @date:2018-6-23
     * @version:V1.0
     */

    /*本地测试专用--zoutao*/
    public static void main(String[] args) {
        System.out.println(DateUtils.getCurrentDateTime());
        ConverVideoTest c = new ConverVideoTest();
        String yuanPATH = "D:/file/IMG_4141.MP4";  //本地源视频
        c.run(yuanPATH);
        System.out.println(DateUtils.getCurrentDateTime());
    }

    //web调用
    public void run(String yuanPATH) {
        try {
            // 转码开始

            //String filePath = "D:/testfile/video/rmTest.rm";  //本地源视频测试

            String filePath = yuanPATH;				//web传入的源视频
            System.out.println("ConverVideoTest说:传入工具类的源视频为:"+filePath);

            ConverVideoUtils zout = new ConverVideoUtils(filePath);  //传入path
            String targetExtension = ".mp4";  				//设置转换的格式
            boolean isDelSourseFile = true; //删除源文件

            boolean beginConver = zout.beginConver(targetExtension,isDelSourseFile);
            System.out.println(beginConver);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
mport java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @Title: ConverVideoUtils.java
 * @Package:com.resource.mytools
 * @Description:(2.转码和截图功能)
 * @see:接收Contants实体的路径
 * @author:Zoutao
 * @date:2018-7-15
 * @version:V1.0
 */

public class ConverVideoUtils {
    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的目录
    public ConverVideoUtils() {
    }

    //重构构造方法,传入源视频
    public ConverVideoUtils(String path) {
        sourceVideoPath = path;
    }

    //set和get方法传递path
    public String getPATH() {
        return sourceVideoPath;
    }

    public void setPATH(String path) {
        sourceVideoPath = path;
    }

    /**
     * 转换视频格式
     * @param String targetExtension 目标视频后缀名 .xxx
     * @param boolean 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;
		}*/

        System.out.println("----开始转文件(" + sourceVideoPath + ")-------------------------- ");

        //执行转码机制
        if (process(targetExtension,isDelSourseFile)) {

            System.out.println("视频转码结束================= ");

           
            //删除原视频+临时视频
			/*if (isDelSourseFile) {
				deleteFile(sourceVideoPath);
			}*/

			/*File file1 = new File(sourceVideoPath);
	         if (file1.exists()){
	        	 System.out.println("删除原文件-可用:"+sourceVideoPath);
	             file1.delete();
	          }*/

            String temppath=videofolder + filerealname + ".avi";
            File file2 = new File(temppath);
            if (file2.exists()){
                System.out.println("删除临时文件:"+temppath);
                file2.delete();
            }

            sourceVideoPath = null;
            return true;
        } else {
            sourceVideoPath = null;
            return false;
        }
    }


    /**
     * 检查文件是否存在-多处都有判断
     * @param path
     * @return
     */

	/*private boolean checkfile(String path) {
		path = sourceVideoPath;
		File file = new File(path);
		try {
			if (file.exists()) {
				System.out.println("视频文件不存在============="+path);
				return true;
			} else {
				System.out.println("视频文件存在"+path);
				return false;
			}
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("拒绝对文件进行读访问");
		}
		return false;
	}*/

    /**
     * 实际转换视频格式的方法
     * @param targetExtension 目标视频后缀名
     * @param isDelSourseFile 转换完成后是否删除源文件
     * @return
     */
    private boolean process(String targetExtension, boolean isDelSourseFile) {

        //先判断视频的类型-返回状态码
        int type = checkContentType();
        boolean status = false;

        //根据状态码处理
        if (type == 0) {
            System.out.println("ffmpeg可以转换,统一转为mp4文件");

            status = processVideoFormat(sourceVideoPath,targetExtension,isDelSourseFile);//可以指定转换为什么格式的视频

        } else if (type == 1) {
            //如果type为1,将其他文件先转换为avi,然后在用ffmpeg转换为指定格式
            System.out.println("ffmpeg不可以转换,先调用mencoder转码avi");
            String avifilepath = processAVI(type);

            if (avifilepath == null){
                // 转码失败--avi文件没有得到
                System.out.println("mencoder转码失败,未生成AVI文件");
                return false;
            }else {
                System.out.println("生成AVI文件成功,ffmpeg开始转码:");
                status = processVideoFormat(avifilepath,targetExtension,isDelSourseFile);
            }
        }
        return status;   //执行完成返回布尔类型true
    }

    /**
     * 检查文件类型
     * @return
     */
    private int checkContentType() {

        //取得视频后缀-
        String type = sourceVideoPath.substring(sourceVideoPath.lastIndexOf(".") + 1, sourceVideoPath.length()).toLowerCase();
        System.out.println("源视频类型为:"+type);

        // 如果是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;
        }else if (type.equals("mkv")) {
            return 0;
        }

        System.out.println("上传视频格式异常");
        return 9;
    }


    /**
     * 转换为指定格式--zoutao
     * 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) {

        System.out.println("调用了ffmpeg.exe工具");

        //先确保保存转码后的视频的文件夹存在
        File TempFile = new File(targetfolder);
        if (TempFile.exists()) {
            if (TempFile.isDirectory()) {
                System.out.println("该文件夹存在。");
            }else {
                System.out.println("同名的文件存在,不能创建文件夹。");
            }
        }else {
            System.out.println("文件夹不存在,创建该文件夹。");
            TempFile.mkdir();
        }

        List<String> commend = new ArrayList<String>();

        commend.add(ffmpegpath);		 //ffmpeg.exe工具地址
        commend.add("-i");
        commend.add(oldfilepath);			//源视频路径

        commend.add("-vf");             //视频分辨率处理
        commend.add("scale=180:320");   //9:16

        commend.add("-vcodec");
        commend.add("h263");  //
        commend.add("-ab");		//新增4条
        commend.add("64");      //高品质:128 低品质:64
        commend.add("-acodec");
        commend.add("mp3");      //音频编码器:原libmp3lame
        commend.add("-ac");
        commend.add("2");       //原1
        commend.add("-ar");
        commend.add("22050");   //音频采样率22.05kHz
        commend.add("-r");
        commend.add("15");  //高品质:29.97 低品质:15
        commend.add("-c:v");
        commend.add("libx264");	//视频编码器:视频是h.264编码格式
        commend.add("-strict");
        commend.add("-2");
        commend.add(targetfolder + filerealname + targetExtension);  // //转码后的路径+名称,是指定后缀的视频

        //打印命令--zoutao
        StringBuffer test = new StringBuffer();
        for (int i = 0; i < commend.size(); i++) {
            test.append(commend.get(i) + " ");
        }
        System.out.println("ffmpeg输入的命令:"+test);

        try {
            //多线程处理加快速度-解决rmvb数据丢失builder名称要相同
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commend);
            Process p = builder.start();   //多线程处理加快速度-解决数据丢失

            final InputStream is1 = p.getInputStream();
            final InputStream is2 = p.getErrorStream();
            new Thread() {
                public void run() {
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(is1));
                    try {
                        String lineB = null;
                        while ((lineB = br.readLine()) != null) {
                            if (lineB != null)
                                System.out.println(lineB);    //打印mencoder转换过程代码
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            new Thread() {
                public void run() {
                    BufferedReader br2 = new BufferedReader(
                            new InputStreamReader(is2));
                    try {
                        String lineC = null;
                        while ((lineC = br2.readLine()) != null) {
                            if (lineC != null)
                                System.out.println(lineC);    //打印mencoder转换过程代码
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();

            p.waitFor();		//进程等待机制,必须要有,否则不生成mp4!!!
            System.out.println("生成mp4视频为:"+videofolder + filerealname + ".mp4");
            return true;
        }
        catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值