JavaCV录制视频时常遇到添加FFmpeg音视频滤镜的需求,FFmpeg内置很多常用的滤镜,如果添加多个滤镜的时候代码处理相对单个要复杂一点,使用滤镜的时候需要注意像素格式的转换,FFmpeg处理的时候隐含转换的细节以致于有时会遇到麻烦。
效果大概如下
String outputPath = "D:/opencv_test/ffmpeg/live.flv";
int width = 640, height = 480;
//Logo图片的路径
FFmpegFrameGrabber logoFrameGrabber = new FFmpegFrameGrabber("D:/opencv_test/ffmpeg/mylogo.jpg");
logoFrameGrabber.start();
Frame logoFrame = logoFrameGrabber.grab();
Assert.notNull(logoFrame, "can't find Logo picture");
//如果多个摄像头驱动请选择合适
VideoInputFrameGrabber grabber = VideoInputFrameGrabber.createDefault(1);
grabber.start();
// 流媒体输出地址,分辨率(长,高),是否录制音频(0:单声道/1:立体声)
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputPath, width, height, 1);
recorder.setInterleaved(true);
recorder.setVideoOption("tune", "zerolatency");
recorder.setVideoOption("preset", "ultrafast");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 28
recorder.setFormat("flv"); // rtmp的类型
int frameRate = 25;
recorder.setFrameRate(frameRate);
recorder.setGopSize(frameRate * 2);
recorder.setAudioOption("crf", "0");
recorder.setAudioQuality(0);// 最高质量
recorder.setAudioBitrate(192000);
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
recorder.setAudioChannels(1);
recorder.setSampleRate(44100);
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // yuv420p
recorder.start();
String textfilterDesc = "[0:v]drawtext=fontsize=30:fontcolor=white:fontfile=E\\\\:/java/ffmpeg-20200831/bin/arial.ttf:text='Victorkevin%{localtime\\:%y\\-%m\\-%d %H-%M-%S}':x=20:y=20";
String filterDesc = textfilterDesc
+ ",scale=640:480[main];[1:v]scale=60:60,format=pix_fmts=rgb24[logo];[main][logo]overlay=x=20:y=50,format=rgb24[v]";
FFmpegFrameFilter logoFrameFilter = new FFmpegFrameFilter(filterDesc, width, height);
logoFrameFilter.setVideoInputs(2);
logoFrameFilter.start();
CanvasFrame canvas = new CanvasFrame("Capture Preview", CanvasFrame.getDefaultGamma() / grabber.getGamma());
canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
int count = 0;
Frame frame = null;
while ((frame = grabber.grab()) != null) {
logoFrameFilter.push(0, frame, avutil.AV_PIX_FMT_RGB24);
logoFrameFilter.push(1, logoFrame, avutil.AV_PIX_FMT_RGB24);
frame = logoFrameFilter.pull();
if (canvas.isVisible()) {
canvas.showImage(frame);
}
recorder.record(frame, avutil.AV_PIX_FMT_BGR24);
if (count++ == 150) {
break;
}
}
logoFrameFilter.close();
canvas.dispose();
grabber.stop();
grabber.release();
recorder.stop();
recorder.release();