Android平台GB28181设备接入侧如何实现GB28181-2022实时快照

本文涉及的产品
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,视频资源包5000点
视觉智能开放平台,图像资源包5000点
简介: GB/T28181-2022标准中明确了快照的具体要求,包括图像抓拍配置命令的发送与接收流程。源设备需向目标设备发送包含传输路径和会话ID等信息的命令,目标设备完成图像传输后,通过IETF RFC 3428中的MESSAGE方法发送图像抓拍传输完成的通知。图像格式推荐使用JPEG,且分辨率应与主码流相同。技术实现上,如使用大牛直播SDK在Android平台上,可通过创建`SnapShotImpl`类并调用`capture()`方法实现快照功能,之后将JPEG格式的快照文件上传至国标平台。

规范解读

GB/T28181-2022相对2016版,除了对H.265、AAC有了明确的说明外,快照也有了具体的要求。源设备向目标设备发送图像抓拍配置命令,携带传输路径、会话ID等信息。目标设备完成图像传输后,发送图像抓拍传输完成通知命令,采用IETF RFC 3428中的MESSAGE方法实现,图像格式宜使用JPEG,图像分辨率宜采用与主码流相同的分辨率。

具体流程如下图:

image.gif

需要注意的是,MESSAGE消息头Content-type头域要求Content-type:Application/MANSCDP+xml。图像传输方式宜采用http,图像抓拍传输完成通知命令采用MANSCDP协议格式定义。

技术实现

本文以大牛直播SDK实现的Android平台GB28181设备接入模块为例,介绍下快照实现逻辑,需要注意的是,哪怕设备侧不回传,也需要具备快照能力,并保存为jpeg格式,然后按照gb28181规范要求,把采集到的图片,上传到国标平台侧。

image.gif 编辑

先说外部驱动快照:

/*
     * MainActivity.java
     * Author: daniusdk.com
     */
    class ButtonCaptureImageListener implements View.OnClickListener {
        public void onClick(View v) {
            if (null == snap_shot_impl_) {
                snap_shot_impl_ = new SnapShotImpl(image_path_, context_, handler_, libPublisher, snap_shot_publisher_);
                snap_shot_impl_.start();
            }
            startLayerPostThread();
            snap_shot_impl_.set_layer_post_thread(layer_post_thread_);
            snap_shot_impl_.capture();
        }
    }

image.gif

SnapShotImpl实现如下:

public SnapShotImpl(String dir, Context context, android.os.Handler handler,
                        SmartPublisherJniV2 lib_sdk, LibPublisherWrapper publisher) {
        this.dir_ = dir;
        if (context != null)
            this.context_ = new WeakReference<>(context);
        if (handler != null)
            this.os_handler_ = new WeakReference<>(handler);
        this.lib_sdk_ = lib_sdk;
        this.publisher_ = publisher;
    }

image.gif

调用capture()的时候,处理逻辑如下:

protected boolean capture(String file_name, boolean is_update_layers, String user_data) {
        if (is_null_or_empty(file_name)) {
            Log.e(TAG, "capture file name is null");
            return false;
        }
        if (publisher_.empty()) {
            if (!init_sdk_instance()) {
                Log.e(TAG, "init_sdk_instance failed");
                return false;
            }
        }
        if (is_update_layers && layer_post_thread_ != null)
            layer_post_thread_.update_layers();
        boolean ret = publisher_.CaptureImage(0, 100, file_name, user_data);
        if (ret)
            update_sdk_instance_release_time();
        return ret;
    }

image.gif

其中init_sdk_instance()实现如下:

protected boolean init_sdk_instance() {
        if (!publisher_.empty())
            return true;
        Context context = application_context();
        if (null == context)
            return false;
        if (null == lib_sdk_)
            return false;
        long handle = lib_sdk_.SmartPublisherOpen(context, 0, 3, 1920, 1080);
        if (0 == handle) {
            Log.e(TAG, "init_sdk_instance sdk open failed!");
            return false;
        }
        lib_sdk_.SetSmartPublisherEventCallbackV2(handle, new SDKEventHandler(this));
        lib_sdk_.SmartPublisherSetFPS(handle, 4);
        publisher_.set(lib_sdk_, handle);
        update_sdk_instance_release_time();
        Log.i(TAG, "init_sdk_instance ok handle:" + handle);
        return true;
    }

image.gif

对接gb28181平台部分,快照状态定义:

public final static int INITIALIZATION_STATUS = 0; // 初始状态
        public final static int CAPTURING_STATUS = 1; // 抓拍中
        public final static int CAPTURE_COMPLETION_STATUS = 2; // 抓拍完成状态
        public final static int UPLOADING_STATUS = 3; // 图像上传中状态
        public final static int UPLOAD_COMPLETION_STATUS = 4; // 图像上传完成状态
        public final static int ERROR_STATUS = 5; // 错误状态

image.gif

快照完成后,告知国标平台:

public void notify_server(List<String> notified_files) {
            ArrayList<String> snap_shot_list = new ArrayList(items_.size());
            for (SnapItem i : items_) {
                if (SnapItem.UPLOAD_COMPLETION_STATUS == i.status())
                    snap_shot_list.add(i.gb_snap_shot_file_id());
                if (notified_files != null)
                    notified_files.add(i.file_name());
            }
            if (null == agent_)
                return;
            GBSIPAgent agent = agent_.get();
            if (null == agent)
                return;
            agent.notifyUploadSnapShotFinished(from_user_name_, from_user_name_at_domain_, device_id_, this.session_id(), snap_shot_list);
        }

image.gif

技术总结

GB28181-2022快照实现,最好是单独开个实例,帧率根据实际快照间隔或者要求,不需要全帧率投递,在不录像不实时回传的时候,也能实现快照逻辑,然后按照规范要求和国标平台侧的客制化诉求,把快照后的文件上传到国标平台。

相关文章
|
2月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
121 1
|
3月前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
14天前
|
IDE 开发工具 Android开发
移动应用开发之旅:探索Android和iOS平台
在这篇文章中,我们将深入探讨移动应用开发的两个主要平台——Android和iOS。我们将了解它们的操作系统、开发环境和工具,并通过代码示例展示如何在这两个平台上创建一个简单的“Hello World”应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧,帮助你更好地理解和掌握移动应用开发。
40 17
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
110 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
3月前
|
监控 Android开发 iOS开发
深入探索安卓与iOS的系统架构差异:理解两大移动平台的技术根基在移动技术日新月异的今天,安卓和iOS作为市场上最为流行的两个操作系统,各自拥有独特的技术特性和庞大的用户基础。本文将深入探讨这两个平台的系统架构差异,揭示它们如何支撑起各自的生态系统,并影响着全球数亿用户的使用体验。
本文通过对比分析安卓和iOS的系统架构,揭示了这两个平台在设计理念、安全性、用户体验和技术生态上的根本区别。不同于常规的技术综述,本文以深入浅出的方式,带领读者理解这些差异是如何影响应用开发、用户选择和市场趋势的。通过梳理历史脉络和未来展望,本文旨在为开发者、用户以及行业分析师提供有价值的见解,帮助大家更好地把握移动技术发展的脉络。
112 6
|
3月前
|
开发工具 Android开发 iOS开发
安卓与iOS开发环境对比:选择适合你的平台
【9月更文挑战第26天】在移动应用开发的广阔天地中,安卓和iOS是两大巨头。它们各自拥有独特的优势和挑战,影响着开发者的选择和决策。本文将深入探讨这两个平台的开发环境,帮助你理解它们的核心差异,并指导你根据个人或项目需求做出明智的选择。无论你是初学者还是资深开发者,了解这些平台的异同都至关重要。让我们一起探索,找到最适合你的那片开发天地。
|
3月前
|
Android开发 开发者
Android平台无纸化同屏如何实现实时录像功能
Android平台无纸化同屏,如果需要本地录像的话,实现难度不大,只要复用之前开发的录像模块的就可以,对我们来说,同屏采集这块,只是数据源不同而已,如果是自采集的其他数据,我们一样可以编码录像。
|
3月前
|
安全 API 开发工具
Android平台RTMP推送|轻量级RTSP服务如何实现麦克风|扬声器声音采集切换
Android平台扬声器播放声音的采集,在无纸化同屏等场景下,意义很大,早期低版本的Android设备,是没法直接采集扬声器audio的(从Android 10开始支持),所以,如果需要采集扬声器audio,需要先做系统版本判断,添加相应的权限。
|
3月前
|
编解码 开发工具 Android开发
Android平台实现屏幕录制(屏幕投影)|音频播放采集|麦克风采集并推送RTMP或轻量级RTSP服务
Android平台屏幕采集、音频播放声音采集、麦克风采集编码打包推送到RTMP和轻量级RTSP服务的相关技术实现,做成高稳定低延迟的同屏系统,还需要有配套好的RTMP、RTSP直播播放器
|
3月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
85 0

热门文章

最新文章