JAVA调用FFmpeg实现音视频转码加水印功能
Posted 赵侠客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA调用FFmpeg实现音视频转码加水印功能相关的知识,希望对你有一定的参考价值。
目录
目录
写在前面
如今各大云厂商都提供完整的音频处理服务,这些服务可以一站式完成音频/视频的存储/转码/分发等工作,我们完全不需要去研究其底层的实现原理。不过实际项目需求总是千奇百怪,有的客户可能有自己的硬编,只需要使用云场商的储存服务,而有的客户可能有自己的储存,但是想使用云厂商的音视频处理服务就比较麻烦了,那么使用本地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实现音视频转码加水印功能的主要内容,如果未能解决你的问题,请参考以下文章