java-ffmpeg笔记

下载ffmpeg:

https://download.csdn.net/download/qq_22071421/87254287?spm=1001.2014.3001.5503

shell工具类

@Slf4j
@Component
public class ShellUtil {
    /**
     * 运行shell脚本
     * @param shell 需要运行的shell脚本
     */
    public static void execShell(String shell){
        try {
            Runtime.getRuntime().exec(shell);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 运行shell脚本 new String[]方式
     * @param shell 需要运行的shell脚本
     */
    public static void execShellBin(String shell){
        try {
            Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",shell},null,null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 运行shell并获得结果,注意:如果sh中含有awk,一定要按new String[]{"/bin/sh","-c",shStr}写,才可以获得流
     *
     * @param shStr
     *            需要执行的shell
     * @return
     */
    public static List<String> runShell(String shStr) {
        List<String> strList = new ArrayList<String>();
        if(StringUtils.isBlank(shStr)){
            return strList;
        }
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",shStr},null,null);
            InputStreamReader ir = new InputStreamReader(process.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);
            String line;
//            process.waitFor();
            while ((line = input.readLine()) != null){
                strList.add(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strList;
    }

    public static void playStream(String exec){
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",exec},null,null);
//            new Thread(new DealProcessStream(process.getInputStream())).start();
//            new Thread(new DealProcessStream(process.getErrorStream())).start();
            dealStream(process);
            //等待
            process.waitFor();
        } catch (Exception e) {
            log.info("结束了"+e.getLocalizedMessage());
        }
    }

    private static void dealStream(Process process) {
        if (process == null) {
            return;
        }
        // 处理InputStream的线程
        new Thread() {
            @Override
            public void run() {
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = null;
                try {
                    while ((line = in.readLine()) != null) {
                        // logger.info("output: " + line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        // 处理ErrorStream的线程
        new Thread() {
            @Override
            public void run() {
                BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String line = null;
                try {
                    while ((line = err.readLine()) != null) {
                        //  logger.info("err: " + line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        err.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
}
使用ShellUtil.playStream(shell)运行

hls分片大小,hlsTime:时间,单位:秒

    public String splitTimeByHls(){
        return " -force_key_frames \"expr:gte(t,n_forced*"+hlsTime+")\" -c:v libx264 -hls_time "+hlsTime+" -hls_list_size 0 -c:a aac -strict -2 -f hls ";
    }

将网络m3u8流保存到本地:

url:m3u8网络地址,path:保存路径(/结尾),name:文件名

//直接使用copy的m3u8文件不准
//ffmpeg -i "http://127.0.0.1/opt/videoTmp/test/test.m3u8" -c copy /opt/videoTmp/test/output.mp4

    public String m3u8NetToDisk(String url,String path,String name){
        String shell= ffmpegPath+" -i \""+url+"\""+splitTimeByHls()+path+name+" &";
        log.info(shell);
        return shell;
    }

将网络m3u8流存储到本地mp4:

    public String m3u8ToMp4(String url,String path,String name){
        String shell= ffmpegPath+" -i "+"\""+url+"\"" +" -vcodec copy -acodec copy -absf aac_adtstoasc "+path+name+" &";
        log.info(shell);
        return shell;
    }

合并多个m3u8到一个m3u8

    public String mergeM3u8(List<String> ms,String out){
        String orgStr="";
        for(String m:ms){
            orgStr+=orgStr+" -i "+m+".m3u8 ";
        }
        String shell=ffmpegPath+orgStr+" -filter_complex concat=n="+ms.size()+":v=1:a=1 "+splitTimeByHls()+out+".m3u8 &";
        log.info(shell);
        return shell;
    }

合并多个MP4到一个mp4

             String filePath="all.txt";
            FileWriter fileWriter = new FileWriter(filePath);
            BufferedWriter writer= new BufferedWriter(fileWriter);

            for(String str:orgList){
                writer.write("file '"+str+"'");
                writer.newLine();
            }

          String ins=  ffmpegPath+" -f concat -i "+filePath+" -c copy  out.mp4  &";

mp4转m3u8

//ffmpeg.exe -i   "D:\uav_hrgig0p3ahcl.mp4"  -force_key_frames expr:gte(t,n_forced*10) -c:v libx264 -hls_time 10 -hls_list_size 0 -c:a aac -strict -2 -f hls   "D:\uav_hrgig0p3ahcl\uav_hrgig0p3ahcl.m3u8"    
public String getMp4ToM3u8(String org,String out){
             String shell= ffmpegPath+" -i "+org+".mp4 "+splitTimeByHls()
                +out+".m3u8 &";
        return shell;
    }

 根据code获取进程的pid

    public List<String> getRunPort(String code){
        String exe="ps -ef|grep "+code+" |grep -v 'grep' |awk '{print $2}'";
        log.info("shell:"+exe);
        return ShellUtil.runShell(exe);
    }

rtsp流转m3u8,code:视频流名称标识,playUrl:rtsp地址,out:存储位置(到.m3u8)

    public void rtspPlay(String code,String playUrl,String out){
        List<String> runPort = getRunPort(code);
        if(CollUtil.isNotEmpty(runPort)){
            return;
        }
        String exe="";
        exe = ffmpegPath + " -rtsp_transport tcp -i \"" + playUrl + "\" -fflags flush_packets -max_delay 1 -an -flags -global_header -hls_time 1 -hls_list_size 3  -vcodec libx264 -s 1920x1080 -b 1024k -y " + out +" &";
        log.info("shell:"+exe);
        ShellUtil.playStream(exe);
    }

rtmp转m3u8

    public void rtmpPlay(String code,String playUrl,String out){
        List<String> runPort = getRunPort(code);
        if(CollUtil.isNotEmpty(runPort)){
            return;
        }
        String exe=ffmpegPath+ " -f flv -i \""+playUrl+"\" -vcodec copy -acodec copy -f flv -y "+out;
        log.info("shell:"+exe);
        ShellUtil.playStream(exe);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮雪...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值