其实,在JavaCV中除了FFmpegFrameGrabber和FFmpegFrameRecorder之外,还有一个重要的类,那就是FFmpegFrameFilter。

FFmpegFrameFilter封装了ffmpeg滤镜相关操作,使得使用JavaCV进行滤镜操作变成简单,关于ffmpeg滤镜的使用文档可以查看ffmpeg的文档:http://www.ffmpeg.org/ffmpeg-filters.html

简单来说,如果熟悉ffmpeg的滤镜功能,那么使用FFmpegFrameFilter的难度不大,下面通过几个实例演示一下FFmpegFrameFilter的使用方式:

视频缩放

视频缩放使用的滤镜为scale,语法为:scale=width:height[:interl={1|-1}],这里需要注意的是,JavaCV对视频输入的滤镜命名是固定的:

  1. 如果是一路视频,那么输入为in,输出为out
  2. 如果是多路视频,那么输入为n:v,输出为v,这里的n就是第几路视频输入

了解了这一点之后,使用FFmpegFrameFilter就很简单了,下面以视频缩放为例,完整的代码如下:

public class Scale {

  public static void main(String[] args) throws IOException {

    String filterStr = "scale=320:240[out]";
//
FFmpegFrameGrabber stream0 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
stream0.start();
// width=640, height=352
System.out.println("width=" + stream0.getImageWidth() + ", height=" + stream0.getImageHeight());
//
FFmpegFrameFilter filter = new FFmpegFrameFilter(filterStr, stream0.getImageWidth(), stream0.getImageHeight());
filter.start();
//
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("stream0.mp4"), 320, 240);
recorder.setFormat("mp4");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.start(); int idx = 0;
Frame frame0, frame;
while ((frame0 = stream0.grabImage()) != null) {
filter.push(frame0);
frame = filter.pullImage();
if (frame != null && frame.image != null) {
recorder.record(frame);
}
if (idx++ > 100) {
break;
}
}
recorder.close();
filter.close();
stream0.close();
}
}

滤镜效果:

视频填充

视频填充效果使用的滤镜为pad,语法为:pad=width[:height[:x[:y[:color]]]], FFmpegFrameFilter使用实例跟视频缩放一样,不过滤镜要调整为下面这句:

String filterStr = "pad=700:412:30:30:pink[out]";

另外录制宽高改为原视频宽高:

FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("stream0.mp4"), stream0.getImageWidth(), stream0.getImageHeight());

滤镜效果:

LOGO、字幕

为视频添加LOGO和字幕(滚动)的滤镜相对于前面两个要复杂一点,不过Java代码实现是一样的,采用的滤镜如下:

movie='logo.png'[logo];[in]drawtext=text='我是滚动字幕--HiIT青年':fontfile=simhei.ttf:y=h-line_h-10:x=w-(t-4.5)*w/5.5:fontcolor=white:fontsize=40:shadowx=2:shadowy=2[text];[text][logo]overlay=15:15[out]

滤镜效果:

视频合成

前面提到的都是一路视频操作,对于多路视频的滤镜相对于单路视频有点区别,就是输入有in变成n:v,输出由out变成v, 下面是两路视频合成的完整源码:

public class Hstack {

  public static void main(String[] args) throws IOException {

    String filterStr = "[0:v][1:v]hstack=inputs=2[v]";
//
FFmpegFrameGrabber stream0 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream1 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
stream0.start();
stream1.start();
// width=640, height=352
System.out.println("width=" + stream0.getImageWidth() + ", height=" + stream0.getImageHeight());
//
FFmpegFrameFilter filter = new FFmpegFrameFilter(filterStr, stream0.getImageWidth(), stream0.getImageHeight());
filter.setVideoInputs(2);
filter.start();
//
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(new File("stream0.mp4"), stream0.getImageWidth(), stream0.getImageHeight());
recorder.setFormat("mp4");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.start(); int idx = 0;
Frame frame0, frame1, frame;
while ((frame0 = stream0.grabImage()) != null && (frame1 = stream1.grabImage()) != null) {
filter.push(0, frame0);
filter.push(1, frame1);
frame = filter.pullImage();
if (frame != null && frame.image != null) {
recorder.record(frame);
}
if (idx++ > 200) {
break;
}
}
recorder.close();
filter.close();
stream0.close();
stream1.close();
}
}

滤镜效果:

画中画

画中画滤镜其实跟两路视频合成差不多,不过用的是overlay,语法为:overlay[=x:y[[:rgb={0, 1}]]。下面一个画中画效果的滤镜例子:

String filterStr = "[0:v]scale=iw/2:ih/2[a];[1:v][a]overlay=30:30[v]";

滤镜效果:

NxN N宫格视频

其实不管是NxN,还是1xN,Nx1都可以使用padoverlay组合来实现,下面是2x2四宫格的滤镜:

String filterStr = "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h[v]";

四路视频输入:

FFmpegFrameGrabber stream0 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream1 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream2 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));
FFmpegFrameGrabber stream3 = new FFmpegFrameGrabber(new File("F:/Video/1.mp4"));

滤镜效果:

文章源码后续整理后将会在公众号发布!

=========================================================



关注公众号,阅读更多文章。

JavaCV 视频滤镜(LOGO、滚动字幕、画中画、NxN宫格)的更多相关文章

  1. FFmpeg中overlay滤镜用法-水印及画中画

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10434209.html 1. overlay技术简介 overlay技术又称视频叠加技术 ...

  2. HTML滚动字幕代码参数详解及Js间隔滚动代码

    html文字滚动代码 <marquee style="WIDTH: 388px; HEIGHT: 200px" scrollamount="2" dire ...

  3. UILabel滚动字幕的实现

    经常需要在应用中显示一段很长的文字,比如天气或者广告等,这时候使用滚动字幕的方式比较方便. 参考文献: [1] YouXianMing, 使用UILabel实现滚动字幕移动效果, 博客园 [2] ht ...

  4. js原生 + jQuery实现页面滚动字幕

    js原生/jQuery实现页面滚动字幕效果 17:45:49 在新闻列表或者文章列表信息等页面中很容易要求实现字幕滚动的效果,以下为简单的实现页面中滚动字幕的效果 1.jQuery实现页面滚动字幕效果 ...

  5. C#-循环滚动字幕,timer,从左至右,从右至左,暂停---ShinePans

    Lable的Left属性是能够更改的,可是 Right属性不能够更改,所以我们能够利用 这个特点做自加 自减运算 using System; using System.Collections.Gene ...

  6. DS控件库 DSLed控件呈现滚动字幕效果

    滚动字幕效果在DSled上可以使用偏移来实现,代码如下 运行效果

  7. 【Cocos2dx 3.3 Lua】滚动字幕

    参考资料:     http://blog.csdn.net/jackystudio/article/details/12991977   1.原理         通过调用update来更新位置达到 ...

  8. Flash和滚动字幕

    flash 1.插入flash     1)<object>             <embed src="路径"></embed>      ...

  9. 使用UILabel实现滚动字幕移动效果

    使用UILabel实现滚动字幕移动效果 这个链接中的代码也实现了这种效果 https://github.com/cbpowell/MarqueeLabel 最终效果如下: 原理如下: 1. 获取文本 ...

随机推荐

  1. 在vscode中用Git管理项目

    1.新建仓库-->填写仓库名称-->一定要将对钩去掉-->公开-->创建 Git全局设置: git config --global --add user.name " ...

  2. 资源授权?对OAuth2.0的一次重新认识的过程

    什么是OAuth? OAuth一个开放的授权标准,允许用户在不提供关键信息(如账号,密码)给第三方应用的前提下,让第三方应用去访问用户在某网站上的资源(如头像,用户昵称等). OAuth分为OAuth ...

  3. ADT基础(一)—— List,Stack,and Queue

    ADT基础(一)-- List,Stack,and Queue 1 List 表示 数组:易于search,难于insert和remove 链表:难于search,易于insert和remove // ...

  4. 8.Vue组件三---slot插槽

    主要内容:  1. 什么是插槽 2. 组件的插槽 3. 插槽的使用方法 4. 插槽的具名 5. 变量的作用域 6. slot的作用域 一. 什么是插槽呢? 1. 生活中的插槽有哪些呢? usb插槽, ...

  5. 解决appium点击软键盘上的搜索按钮

    在执行appium自动化测试的时候,需要点击软件盘上的搜索按钮. 具体操作步骤如下: 前提:需要事先安装搜狗输入法 1.唤醒软件盘,可以封装到一个类里,用到的时候随时调用. import os#调起s ...

  6. 2020年12月-第02阶段-前端基础-CSS Day07

    CSS Day07 CSS高级技巧 理解 能说出元素显示隐藏最常见的写法 能说出精灵图产生的目的 能说出去除图片底侧空白缝隙的方法 应用 能写出最常见的鼠标样式 能使用精灵图技术 能用滑动门做导航栏案 ...

  7. 浅谈.Net Core后端单元测试

    目录 1. 前言 2. 为什么需要单元测试 2.1 防止回归 2.2 减少代码耦合 3. 基本原则和规范 3.1 3A原则 3.2 尽量避免直接测试私有方法 3.3 重构原则 3.4 避免多个断言 3 ...

  8. 从零学脚手架(三)---webpack属性详解

    如果此篇对您有所帮助,在此求一个star.项目地址: OrcasTeam/my-cli 在上一篇中,介绍了webpack的entry.output.plugins属性. 在这一篇,接着介绍其它配置属性 ...

  9. 计算机二级Python学习笔记(一):温度转换

    今天通过一个温度转换的十行代码,理解了一些Python的基本元素. 所谓温度转换,就是摄氏度和华氏度的转换,要求输入摄氏度,可以输出华氏度,反之一样能实现.代码如下: #TempConvert.py ...

  10. vue 折线柱状图

    需求:折线柱状图实现,显示不同提示,颜色,标记等等. 图例: 实现: <template> <div class="transaction-barline"> ...