java使用Ffmpeg合成音频和视频

发布时间 2023-12-08 16:52:58作者: sowler

1、Maven依赖

<!-- 需要注意,javacv主要是一组API为主,还需要加入对应的实现 -->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.5.6</version>
        </dependency>
        <!-- 用到了 ffmpeg 需要把 ffmpeg 的平台实现依赖引入 -->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>4.4-1.5.6</version>
        </dependency>
        <!--所有平台实现,依赖非常大-->
        <!--<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.6</version>
        </dependency>-->

2、音音合并 和 音视合并

package com.xxx.util;

import com.google.common.collect.Lists;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: niusaibo
 * @date: 2023-12-08 15:29
 */
public class FfmpegUtils {


    public static void main(String[] args){
        //String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class); //打包太大 不用了 linux直接安装ffmpeg
        //System.out.println(ffmpeg);
        //String ffmpeg = "D:\\ffmpeg\\ffmpeg-6.1-essentials_build\\bin\\ffmpeg.exe";
        long start = System.currentTimeMillis();
        //String a = "D:/backGroundVideos/local_directory\\rec-3703991437697637-audio.opus";
        //String b = "D:/backGroundVideos/local_directory\\rec-7300304476129654-audio.opus";
        //String c = "D:/backGroundVideos/local_directory\\rec-3703991437697637-audio.opus-new.opus";
        //audioAudioMerge(ffmpeg,a,b,c);
        //String d = "D:/backGroundVideos/local_directory\\rec-3703991437697637-video.webm";
        //String e = "D:/backGroundVideos/local_directory\\rec-3703991437697637-video-new.webm";
        //audioVideoMerge(ffmpeg,c,d,e);
        long stop = System.currentTimeMillis();
        System.out.println("用时:" + (stop-start));

    }

    /**
     * 音音合并
     * ffmpeg -i  ./rec-6892714629334504-audio.opus  -i  ./rec-8061115439143880-audio.opus
     * -filter_complex amix=inputs=2:duration=first:dropout_transition=2
     * -f opus  rec-audio.opus)
     * @param ffmpegPath      ffmpeg程序文件路径
     * @param audioInputPath  音频文件路径(输入)
     * @param audioInputPath1 音频文件路径(输入)
     * @param videoOutputPath 转换完成的文件路径(输出)
     * @throws IOException
     */
    public static void audioAudioMerge(String ffmpegPath,
                                       String audioInputPath,
                                       String audioInputPath1,
                                       String videoOutputPath){
        List<String> command = new ArrayList<>();
        //获取JavaCV中的ffmpeg本地库的调用路径
        command.add(ffmpegPath);
        command.add("-i");
        command.add(audioInputPath);
        command.add("-i");
        command.add(audioInputPath1);
        command.add("-filter_complex");
        command.add("amix=inputs=2:duration=first:dropout_transition=2");
        command.add("-f");
        command.add("opus");
        //-shortest会取视频或音频两者短的一个为准,多余部分则去除不合并
        //command.add("-shortest");
        command.add(videoOutputPath);
        execute(command);
    }

    /**
     * 操作系统进程
     * @return
     */
    public static void execute(List<String> command){
        InputStream errorStream = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
//            String join = String.join("", command);
//            System.out.println(join);
//            ProcessBuilder process = new ProcessBuilder(command);
//            process.inheritIO().start().waitFor();

            ProcessBuilder builder = new ProcessBuilder(command);
            Process process = builder.start();
            errorStream = process.getErrorStream();
            isr = new InputStreamReader(errorStream);
            br = new BufferedReader(isr);
            String line = "";
            while ((line = br.readLine()) != null) {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (br != null){
                    br.close();
                }
                if (isr != null){
                    isr.close();
                }
                if (errorStream != null){
                    errorStream.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }



    /**
     * 音视频合并
     * ffmpeg -i ./audio.opus -i ./video.webm  -c:v copy -c:a opus -strict experimental test.webm)
     *
     * @param ffmpegPath      ffmpeg程序文件路径
     * @param audioInputPath  音频文件路径(输入)
     * @param videoInputPath  视频文件路径(输入)
     * @param videoOutputPath 转换完成的文件路径(输出)
     * @throws IOException
     */
    public static void audioVideoMerge(String ffmpegPath,
                                       String audioInputPath,
                                       String videoInputPath,
                                       String videoOutputPath){
        // 构建命令
        List<String> command = Lists.newArrayList();
        command.add(ffmpegPath);
        command.add("-i");
        command.add(audioInputPath);
        command.add("-i");
        command.add(videoInputPath);
        command.add("-c:v");
        command.add("copy");
        command.add("-c:a");
        command.add("opus");
        command.add("-strict");
        command.add("experimental");
        command.add(videoOutputPath);
        execute(command);
    }
}