使用FFmpeg粗加工处理视频转码、截封面图 (1)

561 阅读2分钟

java通过FFmpeg粗加工处理视频转码、截封面图

这是我参与更文挑战的第11天,活动详情查看: 更文挑战

业务场景:

通过java对上传的视频进行转码,截封面图,然后将视频上传到文件存储服务器

使用工具

(jave包是一个处理ffmpeg的一个开源框架,比较老旧,功能也相对欠缺,本文只用它来做一个视频格式转换的功能)

pom.xml配置

<!--FFmpeg集成jar包-->
<dependency>   
  <groupId>joinery</groupId>   
  <artifactId>jave</artifactId>   
  <version>1.0.2</version> 
</dependency>        

实现原理

将传过来的视频先写入在本地test1,然后调用本地安装的视频处理工具ffmpeg进行处理,把处理好的文件放在本地test2,调用相关API把test2里的文件上传到文件存储服务器,上传完毕后删除掉本地test1和test2里的文件

clipboard

代码实现

视频转码部分的处理直接使用了jave包封装好的方法处理,视频截封面图的功能jave并没有封装好,此处直接是在代码里把处理截图的命令拼接好,然后通过调用系统的命令行去让ffmpeg执行该命令

视频处理相关方法

private static void dealStreamCommon(BufferedReader buff) {
         String line = null;
         try {
             while ((line = buff.readLine()) != null) {
                 logger.warn("output: " + line);
             }
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             try {
                 buff.close();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }
 /**
      * 删除文件
      *
      * @param file
      */
     public static void deleteFile(File file) {
         if (file.exists()) {
             file.delete();
         }
     }

开启线程处理Ffmpeg处理流

/**
      *
      * @param process
      */
     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()));
                 dealStreamCommon(in);
             }
         }.start();
         // 处理ErrorStream的线程
         new Thread() {
             @Override
             public void run() {
                 BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                 dealStreamCommon(err);
             }
         }.start();
     }

截取视频中的一帧作为封面图片

    /**
     * 
     *
     * @param fileName
     *            ffmpeg -i /Users/jinx/Downloads/test.mp4 -y -f image2 -ss
     *            00:00:01 -vframes 1 /Users/jinx/Downloads/test.jpeg
     * @return
     */
    public static boolean covPic(String fileName, String time, String outName, String size) {
        List<String> command = new ArrayList<String>();
        command.add(FFMPEG_PATH);
        command.add("-i");
        //文件输入源路径
        command.add(fileName);
        command.add("-y");
        command.add("-f");
        command.add("image2");
        command.add("-ss");
        //截取的时间点格式为 00:00:01
        command.add(time);
        command.add("-vframes");
        command.add("1");
        command.add("-s");
        //截取的图片大小,格式为:1920x1080
        command.add(size);
        //文件输出路径,格式为 11.jpg
        command.add(outName);

        try {
            Process videoProcess = new ProcessBuilder(command).start();
            dealStream(videoProcess);
            videoProcess.waitFor();
            return true;
        } catch (Exception e) {
        }
        return false;
    }