grpc-spring 通信(监控视频传输)

先看效果

这是微软相机,22ms延迟 (不走网络存粹寄存器和内存的通信)在这里插入图片描述这是程序抓取摄像头然后传给client,client的java窗口展示的,延时也是22ms(对了localhost好像也不走网络吧)在这里插入图片描述

几个点
1.opencv如何引用
2. .proto
3. stub选择

opencv引用

opencv是平台相关的,毕竟他要访问硬件,借助操作系统。所以maven gradle这种东西就不太支持这样的组件,windows下的直接用opencv开发的例子可以找很多
下面是一个

https://blog.youkuaiyun.com/qq_37131111/article/details/126588443

但我找到了一个更好用的。可以更轻松的平台迁移(只需要把.dll 或者.so 放到javahome/bin下就可以)。

https://github.com/openpnp/opencv

gradle引用

dependencies {
	//不知道为什么在最外层的build.gradle里加就不可以
	implementation('org.openpnp:opencv:4.5.1-2')  (90MB下很长时间 ,连英国很快)
}

下载dll

org.openpnp:opencv:4.5.1-2,需要的是opencv_java451.dll ,即opencv 4.5.1版本。
https://opencv.org/releases/page/2/
在这里插入图片描述
.dll放到 javahome/bin下

代码里使用

server里
启动的时候加载

@SpringBootApplication
public class LocalGrpcServerApplication {

    static {
        System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
        //add opencv_java451.dll to C:\Program Files\Java\jdk-17.0.2\bin
    }

    public static void main(String[] args) {
        SpringApplication.run(LocalGrpcServerApplication.class, args);
    }
}
int camId = request.getCameraId();
        VideoCapture cap = null;
        try {
            System.out.println("-----z--1----" + camId);
            cap = new VideoCapture(camId);
            //} catch (Exception e) {
        } catch (Throwable e) {
            System.out.println("-----------");
//            e.printStackTrace();
            e.getMessage();
        }

        Mat frame = new Mat();
        MatOfByte buf = new MatOfByte();

        while (cap.grab()) {
            Date date = new Date();
            cap.read(frame);
            Imgcodecs.imencode(".png", frame, buf);
            CameraStreamResponse response =
                    CameraStreamResponse.newBuilder()
                            .setFrame(ByteString.copyFrom(buf.toArray()))
                            //.setFrame(buf.toArray())
                            .setTimestamp(date.getTime())
                            .build();

            responseObserver.onNext(response);

        }

        cap.release();
        responseObserver.onCompleted();

client

@SpringBootApplication
public class LocalGrpcClientApplication {

    public static void main(String[] args) {

//        SpringApplication.run(LocalGrpcClientApplication.class, args);

// 用有头模式启动, 才可以有java窗口
        SpringApplicationBuilder builder = new SpringApplicationBuilder(LocalGrpcClientApplication.class);
        builder.headless(false).run(args);
    }

}
 public void cameraStream(int  camId)  {
        CameraStreamRequest cameraStreamRequest = CameraStreamRequest.newBuilder().setCameraId(camId).build();
        Iterator<CameraStreamResponse> cameraStreamResponses = cameraStreamBlockingStub.cameraStream(cameraStreamRequest);

        JFrame window = null;
        try {
            window = new JFrame();
        } catch (HeadlessException e) {
            e.printStackTrace();
        }
        JLabel screen = new JLabel();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
        ImageIcon ic = null;
        try {
            ic = new ImageIcon(ImageIO.read(new File("C:\\Users\\king\\IdeaProjects\\grpc-spring\\examples\\local-grpc-client\\src\\main\\java\\net\\devh\\boot\\grpc\\examples\\local\\client\\loadImage.png")));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        screen.setIcon(ic);
        window.setContentPane(screen);
        window.pack();
        int i = 99;

        while(cameraStreamResponses.hasNext()) {
            i++;
            CameraStreamResponse response = cameraStreamResponses.next();
            ic = new ImageIcon(response.getFrame().toByteArray());
            screen.setIcon(ic);
            window.setContentPane(screen);
            window.pack();
            if (i % 100 == 0) {
                System.out.println(response.getTimestamp() );
            }
        }
        window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSED));

    }

这里注意
使用的是cameraStreamBlockingStub
也可以使用 cameraStreamStub
一个同步一个异步。后者是操作见上个文章里的server steaming里的client端

用哪个以后看效果。

哦 .proto

// Camera stream service definition
service CameraStream {
    // Method to connect and start receiving camera frames
    rpc CameraStream(CameraStreamRequest) returns (stream CameraStreamResponse) {}
}

// camera id
message CameraStreamRequest {
    int32 cameraId = 1;
}

// Camera frame message
// 帧编码压缩, client 缓冲接收 //也许可以不压缩 (现在是1.5G的光纤,配上超六类网线也许可以不压缩) //使用模拟摄像头软件(不,有摄像头)
message CameraStreamResponse {
    bytes frame = 1;
    int64 timestamp = 2;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值