JAVA调用FFmpeg实现音视频转码加水印功能

Posted 赵侠客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA调用FFmpeg实现音视频转码加水印功能相关的知识,希望对你有一定的参考价值。

目录

目录

写在前面

MAVEN引用

获取音视频基本信息

音频转码成Mp3格式

视频转码成Mp4格式

视频转码成Mp4并添加文字水印

视频转码成Mp4并添加图片水印

测试代码

 


写在前面

如今各大云厂商都提供完整的音频处理服务,这些服务可以一站式完成音频/视频的存储/转码/分发等工作,我们完全不需要去研究其底层的实现原理。不过实际项目需求总是千奇百怪,有的客户可能有自己的硬编,只需要使用云场商的储存服务,而有的客户可能有自己的储存,但是想使用云厂商的音视频处理服务就比较麻烦了,那么使用本地FFmpeg完成音视频的转码就可以很好的解决这部分客户的需求了。使用JAVA调用FFmpeg可以先下载安装FFmpeg软件(下载地址https://ffmpeg.org/download.html),然后使用JAVA的 runtime.exec(ffmpeg命令)来完成所有的操作,不过这样有点麻烦。这么麻烦肯定有人会造轮子,然后找到了 JAVE (Java Audio Video Encoder) http://www.sauronsoftware.it/projects/jave/index.php ,这个框架封装了java操作ffmpeg音视频转码,使用起来方便多了,不过2009年后就没有更新了,使用的FFmpeg也是比较老的版本。然后又在GitHub找到了JAVE2 (Java Audio Video Encoder) https://github.com/a-schild/jave2,这套框架也是封装了FFmpeg,不需要Window/Linux/Mac分别去装对应的ffmpeg软件,使用的版本比较新,开箱即用,感觉比较香。接下来就简单介绍 JAVA2的基本使用。

MAVEN引用

    <properties>
        <java.version>1.8</java.version>
        <schild.version>3.0.1</schild.version>
    </properties>

   <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-all-deps</artifactId>
            <version>$schild.version</version>
        </dependency>
        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-core</artifactId>
            <version>$schild.version</version>
        </dependency>

        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-nativebin-win64</artifactId>
            <version>$schild.version</version>
        </dependency>
        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-nativebin-linux64</artifactId>
            <version>$schild.version</version>
    </dependency>

获取音视频基本信息

 

    /**
     * 获取音频基本信息
     *
     * @param path 文件路径|URL
     * @throws EncoderException
     */
    public static MultimediaInfo testMediaInfo(String path) throws EncoderException, MalformedURLException 
        MultimediaObject instance;
        if (path.startsWith("http")) 
            instance = new MultimediaObject(new URL(path));
         else 
            instance = new MultimediaObject(new File(path));
        
        return instance.getInfo();
    
    /**
     * 原生调用ffmpeg获取音频基本信息
     *
     * @param urlPath
     */
    public static void testFFmpeg(String urlPath) 
        ProcessLocator processLocator = new DefaultFFMPEGLocator();
        ProcessWrapper ffmpeg = processLocator.createExecutor();
        ffmpeg.addArgument("-i");
        ffmpeg.addArgument(urlPath);
        try 
            ffmpeg.execute();
            String res = IOUtils.toString(ffmpeg.getErrorStream(), "UTF-8");
            System.out.println(res);
         catch (Exception e) 
            e.printStackTrace();
         finally 
            ffmpeg.destroy();
        
    

音频转码成Mp3格式

    /**
     * 转成Mp3
     *
     * @param sourceFile
     * @param distFile
     * @param pListener
     * @throws EncoderException
     */
    public static void codecToMp3(String sourceFile, String distFile, EncoderProgressListener pListener) throws EncoderException 
        System.out.println("testEncodeAudio1");
        File source = new File(sourceFile);
        File target = new File(distFile);
        if (target.exists()) 
            target.delete();
        
        AudioAttributes audio = new AudioAttributes();
        audio.setCodec("libmp3lame");
        audio.setBitRate(128000);
        audio.setChannels(2);
        audio.setSamplingRate(44100);
        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setOutputFormat("mp3");
        attrs.setAudioAttributes(audio);
        Encoder encoder = new Encoder();
        encoder.encode(new MultimediaObject(source), target, attrs, pListener);
    

视频转码成Mp4格式

  /**
     * 转成Mp4
     *
     * @param sourceFile
     * @param distFile
     * @param pListener
     * @throws EncoderException
     */
    public static void codecToMp4(String sourceFile, String distFile, EncoderProgressListener pListener) throws EncoderException 
        File source = new File(sourceFile);
        File target = new File(distFile);
        if (target.exists()) 
            target.delete();
        
        AudioAttributes audioAttr = new AudioAttributes();
        VideoAttributes videoAttr = new VideoAttributes();
        EncodingAttributes encodingAttr = new EncodingAttributes();
        audioAttr.setChannels(2);
        audioAttr.setCodec("aac");
        audioAttr.setBitRate(128000);
        audioAttr.setSamplingRate(44100);
        videoAttr.setCodec("libx264");
        videoAttr.setBitRate(2 * 1024 * 1024);
        videoAttr.setSize(new VideoSize(1080, 720));
        videoAttr.setFaststart(true);
        videoAttr.setFrameRate(29);
        encodingAttr.setAudioAttributes(audioAttr);
        encodingAttr.setVideoAttributes(videoAttr);
        encodingAttr.setOutputFormat("mp4");
        Encoder encoder = new Encoder();
        encoder.encode(new MultimediaObject(source), target, encodingAttr, pListener);
    

视频转码成Mp4并添加文字水印

 

    /**
     * 添加文字水印
     *
     * @param sourceFile
     * @param distFile
     * @param textWaterMark
     * @param pListener
     * @throws EncoderException
     */
    public static void codecToMp4WithText(String sourceFile, String distFile, String textWaterMark, EncoderProgressListener pListener) throws EncoderException 
        File sourceVideo = new File(sourceFile);
        File target = new File(distFile);
        if (target.exists()) 
            target.delete();
        
        DrawtextFilter vf = new DrawtextFilter(textWaterMark, "(w-text_w)/2", "(h-text_h)/2", "宋体", 30.0, new Color("ffffff", "44"));
        vf.setShadow(new Color("000000", "44"), 2, 2);
        VideoAttributes videoAttributes = new VideoAttributes();
        videoAttributes.addFilter(vf);
        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setVideoAttributes(videoAttributes);
        Encoder encoder = new Encoder();
        encoder.encode(new MultimediaObject(sourceVideo), target, attrs, pListener);
    

视频转码成Mp4并添加图片水印

    /**
     * 视频加图片水印
     *
     * @param sourceFile
     * @param distFile
     * @param waterMark
     * @param pListener
     * @throws EncoderException
     */
    public static void codecToMp4WithWaterMark(String sourceFile, String distFile, String waterMark, EncoderProgressListener pListener) throws EncoderException 
        File sourceVideo = new File(sourceFile);
        File watermark = new File(waterMark);
        VideoAttributes vidAttr = new VideoAttributes();
        vidAttr.addFilter(new OverlayWatermark(watermark, OverlayLocation.BOTTOM_RIGHT, -10, -10));
        EncodingAttributes encAttr = new EncodingAttributes().setVideoAttributes(vidAttr);
        File target = new File(distFile);
        new Encoder().encode(new MultimediaObject(sourceVideo), target, encAttr, pListener);
    

测试代码

    public static void main(String[] args) throws EncoderException, MalformedURLException 
        String videoPath = "C:\\\\Users\\\\Administrator\\\\Videos\\\\258440.mp4";
        String wavPath = "C:\\\\Users\\\\Administrator\\\\Music\\\\3344927998404.wav";
        String mp3Path = "C:\\\\Users\\\\Administrator\\\\Music\\\\3344927998404.mp3";
        //测试获取视频信息
        MultimediaInfo info = testMediaInfo(videoPath);
        System.out.println(JSON.toJSONString(info));
        //测试音频转码
        codecToMp3(wavPath, mp3Path, new EncoderProgressListener() 
            @Override
            public void sourceInfo(MultimediaInfo info) 
                System.out.println(JSON.toJSONString(info));
            
            @Override
            public void progress(int permil) 
                System.out.println(permil);
            
            @Override
            public void message(String message) 
                System.out.println(message);
            
        );
    

 

以上是关于JAVA调用FFmpeg实现音视频转码加水印功能的主要内容,如果未能解决你的问题,请参考以下文章

Android NDK开发之FFmpeg视频添加水印

200分求:使用ffmpeg给视频加水印

使用ffmpeg给视频添加图片及文字水印

linux 上java调用ffmpeg转码只有几秒长

FFMpeg SDK使用7调用FFmpeg SDK实现视频水印

FFmpeg滤镜使用