其实,在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. 开启算法之路,还原题目,用debug调试搞懂每一道题

    文章简述 大家好,本篇是个人的第 3 篇文章. 承接第一篇文章<手写单链表基础之增,删,查!附赠一道链表题>,在第一篇文章中提过,在刷算法题之前先将基础知识过一遍,这样对后面的做算法题是很 ...

  2. MySQL 常用命令手册 增删改查大法

    一.数据库操作 创建数据库 语法: CREATE DATABASE database_name; 删除数据库 删除数据库务必谨慎!因为执行删除命令后,所有数据将消失. 语法: DROP DATABAS ...

  3. C#实现JWT无状态验证的实战应用

    前言 本文主要介绍JWT的实战运用. 准备工作 首先我们创建一个Asp.Net的,包含MVC和WebApi的Web项目. 然后使用Nuget搜索JWT,安装JWT类库,如下图. 设计思路 这里我们简单 ...

  4. 10. vue之webpack打包详解

    一.什么是webpack webpack官网给出的定义是 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler).当 webpack 处理应 ...

  5. FakeTaobaoDeepLink - 复制淘宝deeplink来拦截淘宝广告的自动拉起

    Fake Taobao Deeplink 复制 ** com.taobao.tao.welcome.Welcome ** 的intent-filter来拦截误触广告后自动拉起淘宝app 完整工程 Gi ...

  6. kubernets资源预留

    一.  Kubelet Node Allocatable Kubelet Node Allocatable用来为Kube组件和System进程预留资源,从而保证当节点出现满负荷时也能保证Kube和Sy ...

  7. 剑指 Offer 50. 第一个只出现一次的字符 + 哈希表 + 有序哈希表

    剑指 Offer 50. 第一个只出现一次的字符 Offer_50 题目详情 方法一:使用无序哈希表 package com.walegarrett.offer; /** * @Author Wale ...

  8. Java 哈希表(google 公司的上机题)

    1 哈希表(散列)-Google 上机题 1) 看一个实际需求,google 公司的一个上机题: 2) 有一个公司,当有新的员工来报道时,要求将该员工的信息加入(id,性别,年龄,住址..),当输入该 ...

  9. 常见 git 需求整理(持续更新中)

    首发于 语雀文档 突然感觉自己对 git 还是挺熟悉的,因为团队里新来的七八号应届生来问我 git 问题,基本没有答不上的情况,但为了能更好地对知识进行整理,还是记录一下为好. (希望能)持续更新.. ...

  10. centos系统mysql忘记密码

    安装 mysql 之后,注意添加软连接 mysql 忘记密码操作, vim /etc/my.cnf 在 [mysqld] 的段中加上一句:skip-grant-tables 重启 mysql 服务, ...