由于大多數(shù)情況下溃论,我們的電腦性能是有限的,所以在使用憾徊康攝像頭等RTSP抓幀讀流的時候钥勋,應(yīng)首先將主碼流和輔碼流的分辨率降低并且將視頻的幀率也降低(這是本人經(jīng)過無數(shù)血的教訓(xùn)實(shí)驗(yàn)得出的結(jié)論)炬转,如下圖所示
讀流抓幀是肯定需要開一個專門的線程去讀的,在關(guān)閉線程的時候通用辦法就是開一個while(true或false)的方式來結(jié)束一個線程
以下是我的抓幀邏輯(這也是我經(jīng)過無數(shù)個黑夜得出來的幾行關(guān)鍵代碼):
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacv.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class CameraSnatch {
public static void main(String[] args) throws IOException {
//String file = "rtsp://admin:admin123@192.168.18.253/h264/sub/av_stream";
String file = "rtsp://admin:Admin123@192.168.0.105/h264/sub/av_stream";
FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(file);
grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式算灸,不然會丟包很嚴(yán)重
grabber.setImageWidth(1280);
grabber.setImageHeight(720);
System.out.println("grabber start");
grabber.start();
//1.播放視頻
CanvasFrame canvasFrame = new CanvasFrame("攝像機(jī)");
canvasFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvasFrame.setAlwaysOnTop(true);
OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
while (true){
Frame frame = grabber.grabImage();
opencv_core.Mat mat = converter.convertToMat(frame);
canvasFrame.showImage(frame);
}
//2.幀截圖
/* File outPut = new File("E:\\convert\\" + 123 + ".jpeg");
while (true) {
Frame frame = grabber.grabImage();
if (frame != null) {
ImageIO.write(FrameToBufferedImage(frame), "jpeg", outPut);
//grabber.stop();
//grabber.release();
System.out.println("圖片已保存");
//break;
}
}*/
}
/**
* 創(chuàng)建BufferedImage對象
*/
public static BufferedImage FrameToBufferedImage(Frame frame) {
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.getBufferedImage(frame);
// bufferedImage=rotateClockwise90(bufferedImage);
return bufferedImage;
}
/**
* 處理圖片扼劈,將圖片旋轉(zhuǎn)90度。
*/
public static BufferedImage rotateClockwise90(BufferedImage bi) {
int width = bi.getWidth();
int height = bi.getHeight();
BufferedImage bufferedImage = new BufferedImage(height, width, bi.getType());
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
bufferedImage.setRGB(j, i, bi.getRGB(i, j));
return bufferedImage;
}
}