其實,在JavaCV中除了FFmpegFrameGrabber和FFmpegFrameRecorder之外,還有一個重要的類,那就是FFmpegFrameFilter。
FFmpegFrameFilter封裝了ffmpeg濾鏡相關操作,使得使用JavaCV進行濾鏡操作變成簡單,關於ffmpeg濾鏡的使用文檔可以查看ffmpeg的文檔:http://www.ffmpeg.org/ffmpeg-filters.html。
其他關於JavaCV的文章,可以通過下面的鏈接查看:
JavaCV-開發系列文章匯總篇(https://www.cnblogs.com/itqn/p/14696221.html)
簡單來說,如果熟悉ffmpeg的濾鏡功能,那么使用FFmpegFrameFilter的難度不大,下面通過幾個實例演示一下FFmpegFrameFilter的使用方式:
視頻縮放
視頻縮放使用的濾鏡為scale,語法為:scale=width:height[:interl={1|-1}],這里需要注意的是,JavaCV對視頻輸入的濾鏡命名是固定的:
- 如果是一路視頻,那么輸入為
in,輸出為out - 如果是多路視頻,那么輸入為
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, 下面是兩路視頻合成的濾鏡:
String filterStr = "[0:v][1:v]hstack=inputs=2[v]";
濾鏡效果:

畫中畫
畫中畫濾鏡其實跟兩路視頻合成差不多,不過用的是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都可以使用pad和overlay組合來實現,下面是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"));
濾鏡效果:

=========================================================
多路濾鏡實現源碼,可關注公眾號 “HiIT青年” 發送 “cv-filter” 查看。

關注公眾號,閱讀更多文章。
