Andorid平台GB28181设备接入端如何生成黑帧并推送至国标平台

简介: 我们在做Android平台GB28181设备接入模块的时候,遇到这样的需求,做移动对讲的时候,是不需要视频数据的,但是国标平台侧,没有视频的话,大多平台又无法播纯音频打包的数据(网页端大多基于http-flv或webrtc实现),基于此,我们做了个简单的处理,通过Bitmap生成个32*32的黑帧,然后,确保上行的音视频数据都有,但是由于视频系黑帧数据,几乎不占用带宽。

我们在做Android平台GB28181设备接入模块的时候,遇到这样的需求,做移动对讲的时候,是不需要视频数据的,但是国标平台侧,没有视频的话,大多平台又无法播纯音频打包的数据(网页端大多基于http-flv或webrtc实现),基于此,我们做了个简单的处理,通过Bitmap生成个32*32的黑帧,然后,确保上行的音视频数据都有,但是由于视频系黑帧数据,几乎不占用带宽。

cd202541cee1430e89bf4f910087443e.jpg

废话不多说,上代码:

    class LayerPostThread extends Thread
    {
        private volatile boolean is_exit_ = false;
        private long handle_ = 0;
        ByteBuffer image_buffer_ = null;
        private int width_ = 32;
        private int height_ = 32;
        @Override
        public void run() {
            image_buffer_ = null;
            if (0 == handle_)
                return;
            generateImageBuffer(width_, height_);
            while(!is_exit_) {
                postImageLayer(0, 0, 0, width_, height_);
                waitSleep(40);
            }
            image_buffer_ = null;
        }
        private void generateImageBuffer(int width, int height)
        {
            Bitmap bitmap = android.graphics.Bitmap.createBitmap(width, height, android.graphics.Bitmap.Config.ARGB_8888);
            bitmap.eraseColor(android.graphics.Color.argb(255, 0, 0, 0));
            if (null == bitmap)
                return;
            if ( image_buffer_ != null) {
                image_buffer_.rewind();
                if ( image_buffer_.remaining() < bitmap.getByteCount())
                    image_buffer_ = null;
            }
            if (null == image_buffer_)
                image_buffer_ = ByteBuffer.allocateDirect(bitmap.getByteCount());
            bitmap.copyPixelsToBuffer(image_buffer_);
        }
        private int postImageLayer(int index, int left, int top, int video_w, int video_h) {
            if (video_w < 1 || video_h < 1)
                return  0;
            int scale_w = 0, scale_h = 0, scale_filter_mode = 0;
            libPublisher.PostLayerImageRGBA8888ByteBuffer(handle_, index, left, top, image_buffer_, 0,
                    4*video_w, video_w, video_h,
                    0, 0, scale_w, scale_h, scale_filter_mode,0);
            return 0;
        }
        public void startPost(long handle, int w, int h, boolean is_text, boolean is_pitcure) {
            this.is_exit_ = false;
            this.handle_ = handle;
            try {
                this.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        public void stopPost() {
            this.is_exit_ = true;
            try {
                this.join(1000);
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            handle_ = 0;
        }
    }

外部调用逻辑如下:

    private LayerPostThread layer_post_thread_ = null;
    private void startLayerPostThread() {
        if (null == layer_post_thread_) {
            layer_post_thread_ = new LayerPostThread();
            layer_post_thread_.startPost(publisherHandle, video_width_, video_height_, isHasTextWatermark(), isHasPictureWatermark());
        }
    }
    private void stopLayerPostThread() {
        if (layer_post_thread_ != null) {
            layer_post_thread_.stopPost();
            layer_post_thread_ = null;
        }
    }


简单来说,读取到的Bitmap数据,转bytebuffer,然后通过调用PostLayerImageRGBA8888ByteBuffer()接口投递到底层,PostLayerImageRGBA8888ByteBuffer()的接口设计如下:

    /*
     * SmartPublisherJniV2.java
     * Author: daniusdk.com
     */
  /**
   * 投递层RGBA8888图像,如果不需要Aplpha通道的话, 请使用RGBX8888接口, 效率高
   *
   * @param index: 层索引, 必须大于等于0, 注意:如果index是0的话,将忽略Alpha通道
   *
   * @param left: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param top: 层叠加的左上角坐标, 对于第0层的话传0
   *
   * @param rgba_plane: rgba 图像数据
   *
   * @param offset: 图像偏移, 这个主要目的是用来做clip的, 一般传0
   *
   * @param row_stride: stride information
   *
   * @param width: width, 必须大于1, 如果是奇数, 将减1
   *
   * @param height: height, 必须大于1, 如果是奇数, 将减1
   *
   * @param  is_vertical_flip: 是否垂直翻转, 0不翻转, 1翻转
   *
   * @param  is_horizontal_flip:是否水平翻转, 0不翻转, 1翻转
   *
   * @param  scale_width: 缩放宽,必须是偶数, 0或负数不缩放
   *
   * @param  scale_height: 缩放高, 必须是偶数, 0或负数不缩放
   *
   * @param  scale_filter_mode: 缩放质量, 传0使用默认速度,可选等级范围是:[1,3],值越大缩放质量越好, 但速度越慢
   *
   * @param  rotation_degree: 顺时针旋转, 必须是0, 90, 180, 270, 注意:旋转是在缩放, 垂直/水品反转之后再做, 请留意顺序
   *
   * @return {0} if successful
   */
  public native int PostLayerImageRGBA8888ByteBuffer(long handle, int index, int left, int top,
                       ByteBuffer rgba_plane, int offset, int row_stride, int width, int height,
                       int is_vertical_flip,  int is_horizontal_flip,
                       int scale_width,  int scale_height, int scale_filter_mode,
                       int rotation_degree);


这个接口非常强大,可以针对传下去的数据,进行裁剪、反转等各种操作,感兴趣的开发者可以尝试看看。

相关文章
|
编解码 监控 API
Android平台GB28181设备接入侧音频采集推送示例
GB/T28181是广泛应用于视频监控行业的标准协议规范,可以在不同设备之间实现互联互通。今天我们主要探讨Android平台的Audio采集部分。
128 1
|
存储 Android开发 开发者
Android平台GB28181设备接入端实现实时快照
Android平台GB28181设计开发的时候,有个功能必不可少的:实时快照,特别是用于执法记录仪等场景下,用于图像留底或分析等考量。
|
数据采集 前端开发 开发工具
Android平台GB28181设备接入端PTZ对接详解
上一篇blog“Android平台GB28181设备接入模块之球机/云台控制探究”谈到,Android平台做国标GB28181设备接入端的时候,PTZ控制要不要处理?如果处理,难度大不大?
182 0
|
Android开发 开发者
Android平台GB28181设备接入端如何实现本地录像?
实现Android平台GB28181设备接入的时候,有个功能点不可避免,那就是本地录像,实际上,在实现GB28181设备接入模块之前,我们前些年做RTMP推送和轻量级RTSP服务的时候,早已经实现了本地录像功能。
104 0
|
4月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
|
4月前
|
监控 Java 开发工具
如何快速对接Android平台GB28181接入模块(SmartGBD)
大牛直播SDK推出的Android平台GB28181接入SDK(SmartGBD),可实现不具备国标音视频能力的 Android终端,通过平台注册接入到现有的GB/T28181—2016服务,可用于如执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、生产运输、车载终端等场景,可能是业内为数不多功能齐全性能优异的商业级水准GB28181接入SDK。
|
编解码 网络协议 Android开发
Android平台GB28181设备接入端如何支持跨网段语音对讲
如果你是音视频开发者亦或寻求这块技术方案的公司,在探讨这个问题之前,你可能网上看了太多关于语音广播和语音对讲相关的资料,大多文章认为语音对讲和语音广播无本质区别,实现思路也大同小异。
130 0
|
Android开发
Android平台GB28181设备接入端如何实现多视频通道接入?
GB28181设备接入端如何实现多视频通道接入?
|
编解码 监控 开发工具
Android平台GB28181接入模块技术接入说明
今天,我们主要讲讲Android平台GB28181接入模块的技术对接,Android平台GB28181接入模块设计的目的,可实现不具备国标音视频能力的 Android终端,通过平台注册接入到现有的GB/T28181—2016服务,可用于如智能监控、智慧零售、智慧教育、远程办公、生产运输、智慧交通、车载或执法记录仪等场景。
155 1
|
编解码 Android开发 数据安全/隐私保护
Android平台GB28181设备接入端对接编码前后音视频源类型浅析
今天主要对Android平台GB28181设备接入模块支持的接入数据类型,做个简单的汇总: 1. 编码前数据(目前支持的有YV12/NV21/NV12/I420/RGB24/RGBA32/RGB565等数据类型),其中,Android平台前后摄像头数据,或者屏幕数据,或者Unity拿到的数据,均属编码前数据; 2. 编码后数据(如无人机等264/HEVC数据,或者本地解析的MP4音视频数据); 3. 拉取RTSP或RTMP流并接入至GB28181平台(比如其他IPC的RTSP流,可通过Android平台GB28181接入到国标平台)。