=======结尾重要绿色链接,不看悔恨,和上面关联==========
JAVA无需本地下载Ffmpeg,实现FfmpegCMD

本文不须要本地下载Ffmpeg,只需引入maven依赖即可

1、增加maven依赖

<!--m3u8视频转码须要FFmpeg依赖-->        <dependency>            <groupId>ws.schild</groupId>            <artifactId>jave-all-deps</artifactId>            <version>3.3.1</version>        </dependency>        <dependency>            <groupId>ws.schild</groupId>            <artifactId>jave-core</artifactId>            <version>3.3.1</version>        </dependency>        <dependency>            <groupId>ws.schild</groupId>            <artifactId>jave-nativebin-win64</artifactId>            <version>3.3.1</version>        </dependency>

2、编写代码

package com.gxw.util;import com.alibaba.fastjson.JSON;import ws.schild.jave.MultimediaObject;import ws.schild.jave.info.MultimediaInfo;import java.io.*;import java.math.BigDecimal;import java.math.RoundingMode;import java.nio.channels.FileChannel;import java.util.HashMap;import java.util.Map;import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * @Description:(MP4 转码 HLS m3u8 AES128 加密) * @author: GuoXiangWen * @date:   2022年04月16日 上午08:08:08 */public class EncodeVideoUtils {    private static String PREIX = "gxwAwdlpgyn";    //加密文件门路,如:enc.key、enc.keyinfo、m3u8文件、ts文件等    private static String ENC_DIRECTORY = "D:/test-ffmpeg/"+PREIX;    //enc.key地址    private static String ENC_KEY_FILE_PATH = null;    //enc.keyinfo地址    private static String ENC_KEY_INFO_FILE_PATH = null;    //密钥http地址    private static String ENC_HTTP_PATH = "http://127.0.0.1:8848/Student";    //执行胜利0,失败1    private static int CODE_SUCCESS = 0;    private static int CODE_FAIL = 1;    //$encInfoPath、$encPath是须要替换的ENC_DIRECTORY文件门路    private static String cmd_enc = " -y -i {videoPath} -hls_time 12 -hls_key_info_file $encInfoPath -hls_playlist_type vod -hls_segment_filename $encPath\\{tsName}_%3d.ts $encPath\\{saveM3u8Name} ";    public static void main(String[] args) {        //视频门路        String videoPath = "D:/test-ffmpeg/test.mp4";        System.out.println(JSON.toJSONString(encodeVideo(videoPath, "test", "1")));    }    /**     * 第一步:创立enc.keyinfo文件     *      * 第二步:HLS m3u8 AES128 加密     * @param videoPath 视频门路     * @param videoType 视频所属类型,     * @param index 视频角标,传来递增的     * @return     */    public synchronized static Map<String, String> encodeVideo(String videoPath, String videoType, String index) {        String videoTypeBP = videoType;        String mp4Name = videoPath.substring(videoPath.lastIndexOf('/') + 1, videoPath.lastIndexOf(".mp4"));        String saveM3u8Name = PREIX + RandomUtils.generateRandomString(32);        //设置tsName        cmd_enc = cmd_enc.replace("{tsName}", saveM3u8Name);        //设置视频地址        cmd_enc = cmd_enc.replace("{videoPath}", videoPath);        //设置视频保留名称地址        cmd_enc = cmd_enc.replace("{saveM3u8Name}", saveM3u8Name + ".m3u8");        if(videoType.equals("") || videoType == null){            videoType = "";        }else {            videoType = "/" + Md5Utils.md5Password(videoType, 8);        }        ENC_DIRECTORY = ENC_DIRECTORY + videoType + "/" + index;        ENC_KEY_FILE_PATH = ENC_DIRECTORY + "/" + saveM3u8Name + ".key";        ENC_KEY_INFO_FILE_PATH = ENC_DIRECTORY + "/" + saveM3u8Name + ".keyinfo";        ENC_HTTP_PATH = ENC_HTTP_PATH + "/" + PREIX + videoType + "/" + index + "/" + saveM3u8Name + ".key";        // 先创立两个流动线程的线程池        ExecutorService executor = Executors.newFixedThreadPool(10);        //异步执行        //第一步:创立enc.keyinfo文件等        CompletableFuture<String> completableFutureTask = CompletableFuture.supplyAsync(() ->{            //保留加密视频目录enc            File encFilePathDir = new File(ENC_DIRECTORY);            if (!encFilePathDir.exists()) {// 判断目录是否存在                encFilePathDir.mkdirs();            }            //写入文件内容enc.key            BufferedWriter bwkey = null;            //写入文件内容enc.keyinfo            BufferedWriter bwkeyInfo = null;            try{//文件                File fileKey = new File(ENC_KEY_FILE_PATH);                File fileKeyInfo = new File(ENC_KEY_INFO_FILE_PATH);                //初始化存在删除                if(fileKey.exists()) {                    fileKey.delete();                }                if(fileKeyInfo.exists()) {                    fileKeyInfo.delete();                }                bwkey = new BufferedWriter(new FileWriter(fileKey));                bwkeyInfo = new BufferedWriter(new FileWriter(fileKeyInfo));                //写入key--自定义的AES128加密的密匙                bwkey.write("********换成本人加密钥匙即可*******");                //写入keyInfo                //密匙URL地址,能够对该URL鉴权                bwkeyInfo.write(ENC_HTTP_PATH);                bwkeyInfo.newLine();                //全门路,绝对路径                bwkeyInfo.write(ENC_KEY_FILE_PATH);                bwkey.flush();                bwkeyInfo.flush();            }catch(IOException e){                e.printStackTrace();                //复原默认                ENC_KEY_INFO_FILE_PATH = null;            } finally{                try {                    //肯定要敞开文件                    bwkey.close();                    bwkeyInfo.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            return ENC_KEY_INFO_FILE_PATH;        }, executor).exceptionally(e -> {            System.out.println(e);            return "false";        });        //异步执行        //第二步:HLS m3u8 AES128 加密        CompletableFuture<Integer> completableFutureTaskHls = completableFutureTask.thenApplyAsync((String encKeyInfoFilePath)->{            if(encKeyInfoFilePath == null || encKeyInfoFilePath.length() == 0) {return CODE_FAIL;}            Integer codeTmp =  cmdExecut(cmd_enc.replace("$encInfoPath", encKeyInfoFilePath).replace("$encPath", ENC_DIRECTORY));            if(CODE_SUCCESS != codeTmp) {return CODE_FAIL;}            System.out.println("类型:"+videoTypeBP+" 视频:" + mp4Name + " 加密,胜利!");            return codeTmp;        }, executor).exceptionally(e -> {            System.out.println(e);            return null;        });        //获取执行后果        //code=0示意失常        try {            System.out.println(String.format("获取最终执行后果:%s", completableFutureTaskHls.get() == CODE_SUCCESS ? "胜利!" : "失败!"));        } catch (InterruptedException e) {            Thread.currentThread().interrupt();            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }        //返回后果        Map<String, String> resultMap = new HashMap<>();        //视频名称        resultMap.put("videoName", mp4Name);        //视频大小        resultMap.put("videoSize", getVideoSize(new File(videoPath)));        //视频时长        resultMap.put("videoTime", getVideoTime(videoPath));        //保留m3u8加密地址        resultMap.put("saveM3u8Path", ENC_DIRECTORY + "/" + saveM3u8Name + ".m3u8");        return resultMap;    }    /**     *     * @Description: (执行ffmpeg自定义命令)     * @param: @param cmdStr     * @param: @return     * @return: Integer     * @throws     */    public static Integer cmdExecut(String cmdStr) {        //code=0示意失常        Integer code  = null;        FfmpegCmd ffmpegCmd = new FfmpegCmd();        /**         * 谬误流         */        InputStream errorStream = null;        try {            ffmpegCmd.execute(false, true, cmdStr);            errorStream = ffmpegCmd.getErrorStream();            //打印过程            int len = 0;            while ((len=errorStream.read())!=-1){                System.out.print((char)len);            }            //code=0示意失常            code = ffmpegCmd.getProcessExitCode();        } catch (IOException e) {            e.printStackTrace();        } finally {            //敞开资源            ffmpegCmd.close();        }        //返回        return code;    }    /**     * 获取视频时长     *     * @param FileUrl     * @return     */    public static String getVideoTime(String FileUrl) {        File source = new File(FileUrl);        String length = "";        try {            MultimediaObject instance = new MultimediaObject(source);            MultimediaInfo result = instance.getInfo();            long ls = result.getDuration() / 1000;            Integer hour = (int) (ls / 3600);            Integer minute = (int) (ls % 3600) / 60;            Integer second = (int) (ls - hour * 3600 - minute * 60);            String hr = hour.toString();            String mi = minute.toString();            String se = second.toString();            if (hr.length() < 2) {                hr = "0" + hr;            }            if (mi.length() < 2) {                mi = "0" + mi;            }            if (se.length() < 2) {                se = "0" + se;            }            length = hr + ":" + mi + ":" + se;        } catch (Exception e) {            e.printStackTrace();        }        return length;    }    /**     * 获取视频大小     *     * @param source     * @return     */    public static String getVideoSize(File source) {        FileChannel fc = null;        String size = "";        try {            FileInputStream fis = new FileInputStream(source);            fc = fis.getChannel();            BigDecimal fileSize = new BigDecimal(fc.size());            size = fileSize.divide(new BigDecimal(1024 * 1024), 2, RoundingMode.HALF_UP) + "MB";        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {            if (null != fc) {                try {                    fc.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }        return size;    }}

3、运行测试

取得以下后果,即胜利: