ffmpeg视屏合成

明天你是否会想起 坐在你旁边的小弟 明天你是否还惦记 内存溢出的虚拟机
回想起粉笔的点点滴滴 我永远都难以忘记
是否能再给契机 让你我再相遇
致 chalk 、 我亲爱的豪哥
我转过我的脸 看不到你的眼 之前的消息你都没发现

方式一

package com.gluoh.file.ffmpeg;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class MergeFile {

    /**
     * 明天你是否会想起 坐在你旁边的小弟 明天你是否还惦记  内存溢出的虚拟机
     * 回想起粉笔的点点滴滴 我永远都难以忘记
     * 是否能再给契机  让你我再相遇
     *
     * 致 chalk 、 我亲爱的豪哥
     *
     * 我转过我的脸 看不到你的眼  之前的消息你都没发现
     *
     * **List<String> fromVideoFileList 需要合并的多视频url地址以List存放**
     * **String ffmpeg 此处是ffmpeg 配置地址,可写死如“E:/ffmpeg/bin/ffmpeg.exe”**
     * **String NewfilePath 合并后的视频存放地址,如:E:/mergevideo.mp4***
     */
    public static void convetor(List<String> fromVideoFileList, String ffmpeg,
                                String NewfilePath) throws IOException {
        new Thread(
                () -> {
                    try {
                        List<String> voidTS = new ArrayList<>();
                        Process process = null;
                        ProcessBuilder builder = null;
                        List<String> command = null;
                        for (int i = 0; i < fromVideoFileList.size(); i++) {
                            String fromVideoFile = fromVideoFileList.get(i);
                            command = new ArrayList<String>();
                            command.add(ffmpeg);
                            command.add("-y");
                            command.add("-i");
                            command.add(fromVideoFile);
                            command.add("-vcodec");
                            command.add("copy");
                            command.add("-bsf:v");
                            command.add("h264_mp4toannexb");
                            command.add("-f");
                            command.add("mpegts");
                            command.add(fromVideoFile.substring(0,
                                    fromVideoFile.lastIndexOf(".")) + ".ts");
                            builder = new ProcessBuilder(command);
                            voidTS.add(fromVideoFile.substring(0,
                                    fromVideoFile.lastIndexOf("."))
                                    + ".ts");
                            try {
                                process = builder.start();
                                InputStream errorStream = process
                                        .getErrorStream();
                                InputStreamReader inputStreamReader = new InputStreamReader(
                                        errorStream);
                                BufferedReader br = new BufferedReader(
                                        inputStreamReader);
                                String line = "";
                                StringBuffer sb = new StringBuffer();
                                while ((line = br.readLine()) != null) {
                                    sb.append(line);
                                }
                                String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
                                Pattern pattern = Pattern
                                        .compile(regexDuration);
                                Matcher m = pattern.matcher(sb.toString());
                                /*                     */
                                System.out.println(sb.toString());
                                br.close();
                                inputStreamReader.close();
                                errorStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                        List<String> dos = new ArrayList<>();
                        StringBuffer tsPath = new StringBuffer();
                        tsPath.append(ffmpeg);
                        tsPath.append(" -i ");
                        tsPath.append("concat:");
                        for (int t = 0; t < voidTS.size(); t++) {
                            if (t != voidTS.size() - 1) {
                                tsPath.append(voidTS.get(t) + "|");
                            } else {
                                tsPath.append(voidTS.get(t));
                            }
                        }
                        tsPath.append(" -vcodec ");
                        tsPath.append(" copy ");
                        tsPath.append(" -bsf:a ");
                        tsPath.append(" aac_adtstoasc ");
                        tsPath.append(" -movflags ");
                        tsPath.append(" +faststart ");
                        tsPath.append(NewfilePath);
                        Process pr = Runtime.getRuntime().exec(
                                tsPath.toString());
                        process.getInputStream();
                        pr.getOutputStream().close();
                        pr.getInputStream().close();
                        pr.getErrorStream().close();
                        try {
                            pr.waitFor();
                            Thread.sleep(1000);
                            pr.destroy();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        //删除生成的ts文件
                        for (String filePath : voidTS) {
                            File file = new File(filePath);
                            file.delete();
                            pr.destroy();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).start();
    }

    public static void main(String[] args) throws IOException {
        String ffmpeg = "E:\\dev-env\\ffmpeg\\bin\\ffmpeg.exe";
        String NewfilePath = "E:\\mergevideo.mp4";
        List fromVideoFileList = new ArrayList();
        fromVideoFileList.add("E:\\01.mp4");
        fromVideoFileList.add("E:\\02.mp4");
        convetor(fromVideoFileList, ffmpeg, NewfilePath);
    }

}

方式二-使用concat分离器合成视屏

   @ApiOperation(value = "视频合并", notes = "视频合并", response = Result.class)
    @PostMapping("/concatVideo")
    public Result concatVideo(
            @ApiParam(name = "files", value = "文件", required = true)
            @RequestParam("files") MultipartFile[] files) {
        List<Map<Integer, Object>> fileDatas = new ArrayList<>();
        Map<Integer, String> map = new HashMap<>();
        try {
            if (files != null && files.length > 0) {
                boolean b = false;
                for (int i=0;i<files.length;i++) {
                    /* 上传文件 */
                    String fileUrl = fastDFSClient.uploadFile(files[i]);
                    map.put(i,fileUrl);
                    /*视屏绝对路径*/
                    String veidoPath =temporaryPic+ fileUrl.replace("group1/M00/","");
                    /*视屏路径写入file.txt文件中*/
                    saveAsFileWriter("file '"+veidoPath+"'",b);
                    b =true;
                }
                /*文件输出路径*/
                String out = temporaryPic+ map.get(0).replace("group1/M00/","");
                /*视屏合并*/
                FirstFrameUtil.video(out);
                /*删除源文件*/
                for(Integer key:map.keySet()){
                    if(key != 0){
                        fastDFSClient.deleteFile(map.get(key));
                    }
                }
                return Result.success(map.get(0));
            }
        } catch (IOException e) {
            logger.error("上传文件异常:{}", ExceptionUtils.getStackTrace(e));
            return Result.error(ExceptionUtils.getMessage(e));
        }
        return Result.fail();
    }



//    private static String filePath = "/home/ffmpeg/file.txt";
    private static String filePath = "G:\\WeChat Files\\123.txt";

    private static void saveAsFileWriter(String content,boolean b) {
        System.out.println("文件路径--------"+content);
        FileWriter fwriter = null;
        try {
            // true表示不覆盖原来的内容,而是加到文件的后面。若要覆盖原来的内容,直接省略这个参数就好
            if(b){
                fwriter = new FileWriter(filePath, true);

            }else{
                fwriter = new FileWriter(filePath);
            }
            fwriter.write(content);
            fwriter.write("\n");

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                fwriter.flush();
                fwriter.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

import java.io.File;
import java.util.List;

/**
 * @author xiaoqiang
 * @Description 视频第一帧处理工具
 * @date 2019/5/29 10:21
 */
public class FirstFrameUtil {
    //windows
    //private static  String FFMPEG_PATH = "D:/soft/ffmpeg/bin/ffmpeg.exe";
    //centos
    private static  String FFMPEG_PATH = "/usr/local/bin/ffmpeg";
    /**
     * FFmpeg
     * @param veidoPath
     * @return
     */
    public static boolean processImg(String veidoPath) {
        File file = new File(veidoPath);
        if (!file.exists()) {
            System.err.println("路径[" + veidoPath + "]对应的视频文件不存在!");
            return false;
        }
        List<String> commands = new java.util.ArrayList<String>();
        commands.add(FFMPEG_PATH);
        commands.add("-i");
        commands.add(veidoPath);
        commands.add("-y");
        commands.add("-f");
        commands.add("image2");
        commands.add("-ss");
        // 这个参数是设置截取视频多少秒时的画面
        commands.add("1");
        // commands.add("-t");
        // commands.add("0.001");
        commands.add("-s");
        commands.add("700x525");
        commands.add(veidoPath.substring(0, veidoPath.lastIndexOf("."))
                .replaceFirst("vedio", "file") + ".jpg");
        try {
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commands);
            builder.start();
            System.out.println("截取成功");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean video(String outPath) {
        File file = new File("/home/ffmpeg/file.txt");
        if (!file.exists()) {
            System.err.println("文件不存在!");
            return false;
        }
        List<String> commands = new java.util.ArrayList<String>();
        commands.add(FFMPEG_PATH);
        commands.add("-y");//覆盖元视屏
        commands.add("-f");
        commands.add("concat");
        commands.add("-safe");
        commands.add("0");
        commands.add("-i");
        commands.add("/home/ffmpeg/file.txt");
        commands.add("-c");
        commands.add("copy");
        commands.add(outPath);
        try {
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commands);
            builder.start();
            System.out.println("合成功");
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,113评论 0 4
  • 公元:2019年11月28日19时42分农历:二零一九年 十一月 初三日 戌时干支:己亥乙亥己巳甲戌当月节气:立冬...
    石放阅读 6,926评论 0 2