# GB28181-Helmet-Demo **Repository Path**: master_zhq/gb28181-helmet-demo ## Basic Information - **Project Name**: GB28181-Helmet-Demo - **Description**: 国标GB28181 demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-01-22 - **Last Updated**: 2026-01-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 该项目为超影国标GB28181音视频接入测试项目 # 1.该项目作为so库打包项目 # 2.该项目以library为开发主体 libbreakpad.so 继承以后初始化: File storageRootDir = Environment.getExternalStorageDirectory(); Logger.e("报错文件地址:" + storageRootDir.getAbsolutePath()); BreakPad.BreakPadInit(storageRootDir.getAbsolutePath()); 当ndk曾报错,会在“报错文件地址”生成一个类似:36d1cf33-a9dd-46a1-a91370b2-1c7096b0.dmp的文件 在Android Studiod的安装目录\bin\lldb\bin中存在一个minidump_stackwalk.exe的可执行文件,我们现在需要用这个工具对.dump文件进行解析,并将解析的结果写到crash.txt文件中 命令:minidump_stackwalk.exe f7ab957b-326b-4772-160d079e-1f44738d.dmp >crash.txt 打开crash.txt 获取到报错地址 如果是arm-64位的so,解析是需要使用aarch64-linux-android-4.9下的工具链。 如果是arm-32位的so,解析是需要使用arm-linux-androideabi-4.9下的工具链。 如果是x86-64位的so,解析是需要使用x86_64-4.9下的工具链。 如果是x86-32位的so,解析是需要使用x86-4.9下的工具链 因为CPU信息是armv7,所以选择arm-linux-androideabi-4.9下的工具链。我们将项目中build目录下的arm-v7a对应的libcrash-lib.so(app\build\intermediates\transforms\mergeJniLibs\debug\0\lib\armeabi-v7a\libcrash-lib.so) 拷贝到arm-linux-androideabi-4.9下的工具链目录(arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin)中,然后执行如下命令: arm-linux-androideabi-addr2line.exe -f -C -e libcrash-lib.so 0x7b2 addr2line调试命令: arm-linux-androideabi-addr2line -C -f -e H:\WorkSpace\NanGBD-Android-main\library\build\intermediates\cmake\debug\obj\armeabi-v7a 0x6c65682f302fa0 ndk-stack调试命令: adb shell logcat | androidsdk绝对路径/ndk-stack -sym so所在目录 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/nanguantong/NanGBD-Android/blob/main/LICENSE) [![JAVA](https://img.shields.io/badge/language-java%20|%20cpp-red.svg)](https://en.cppreference.com/) [![platform](https://img.shields.io/badge/platform-android%20-green.svg)](https://github.com/nanguantong/NanGBD-Android) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-yellow.svg)](https://github.com/nanguantong/NanGBD-Android/pulls) NanGBD-Android(即 Nanuns GB Device,国标设备端)是一套支持 GB/T 28181 和 GB 35114 [国标协议](https://github.com/nanguantong/GB-Doc)的安卓设备端应用。 NanGBD 和 [NanGBS](https://github.com/nanguantong/NanGBS)(即 Nanuns GB Server,国标平台端) 系列支持 Windows、Linux、Mac、Android、iOS、ARM 全平台。 # 应用场景 * 可用于安卓设备如智能穿戴设备(如安全帽)、门铃等终端。 * 可用于安卓设备的非标转国标需求,利旧改造。 * 可用于跨网互联互通、音视频推流、语音双向对讲等国标场景。 # 功能特性 - [X] 兼容国标 GB-T 28181-2011、GB-T 28181-2016、GB 35114 - [X] 设备支持公网/内网环境 - [X] 设备注册、注销、周期性保活 - [X] 设备信息设置与获取 - [X] 设备在线、离线状态维护与获取 - [X] 设备目录、移动位置、报警订阅与通知 - [X] 设备控制,包括云台控制、强制关键帧、远程启动、录像控制、报警复位、设备配置、签名控制、加密控制 - [X] 设备摄像头或屏幕、麦克风采集与推流 - [X] 设备视频参数配置,如帧率、码率、分辨率 - [X] 设备PS/H264/H265封装流、音频G711A编码 - [X] 支持 H264、H265 软硬编解码 - [X] 设备实时取流 - [X] 设备录制、取历史流 - [X] 设备公网/内网语音对讲 - [X] OSD 时间戳水印和自定义文字水印 - [X] GB 35114 A级 - [X] 设备授权认证(App key / secret) - [X] 代码加密与混淆 - [X] 可定制化功能(如 GB 35114 B/C 级 等) # TODO - [ ] 兼容国标 GB-T 28181-2022 - [ ] 兼容国标 GA-T 1400 - [ ] 支持 RTCP 码流传输控制 - [ ] 集成 WebRTC,并进行 UDP 传输改造 - [ ] 音频 3A 算法优化 - [ ] ... # 编译运行 整个核心代码分为 app 端(java 层)和 library 端(cpp 层)。 **注:cpp 编译库都位于 library/src/main/jniLibs/ 对应架构目录下。** 0. 准备环境 * 安装 Android Studio 工具 和 java8 + 环境。 * 修改 local.properties 中的 sdk.dir(安卓 sdk 路径)与 ndk.dir(安卓 ndk 路径),如: `sdk.dir=/Users/Nanuns/Library/Android/sdk` `ndk.dir=/Users/Nanuns/Library/Android/sdk/ndk-bundle` 1. 编译 osip 与 eXosip 安卓端交叉编译 osip 与 eXosip 相关这里就不展开,可自行摸索编译。注意 osip 和 eXosip 版本一定要对应,否则可能会出现不兼容的情况。我们这里选择 osip2-5.3.0 和 eXosip2-5.3.0。 可参考 [eXosip](https://github.com/xueqing/exosip) 和 [eXosip 交叉编译](https://blog.csdn.net/zhuyunier/article/details/79085345) 2. 编译 GmSSL 进入 library/src/main/sh/ 目录,运行 `bash ./build-gmssl4android.sh` 将生成全部架构的包,包括 armeabi-v7a、arm64-v8a、x86、x86_64。 也可以添加运行参数如:`bash ./build-gmssl4android.sh [arg1-arch] [arg1-abi] [arg2-api]`,其中: * [arg1-arch] 表示安卓架构,可选项为:arm、arm64、x86、x86_64、mips、mips64 * [arg1-abi] 表示安卓 ABI,可选项为:armeabi-v7a、arm64-v8a、x86、x86_64、mips、mips64 * [arg1-api] 表示支持安卓最低 SDK API 版本,可选项为:21、或者高于 21 的版本 3. 编译 FFmpeg 安卓端交叉编译 FFmpeg 相关这里就不展开,可自行摸索编译。注意我们这里使用版本 FFmpeg-v4.3.1,增加了 mediacodec 硬件编解码模块,且支持 H265。 4. 编译项目 根目录下运行 `./gradlew assembleRelease`,即可生成 Apk(位于 app/build/outputs/apk/release/ 目录下)和 Sdk(library/build/outputs/aar/ 目录下)包。 ### 依赖库 * [GmSSL](https://github.com/guanzhi/GmSSL) 用于 GB 35114 SIP 安全信令交互 * [osip](https://ftp.gnu.org/gnu/osip/) 用于 SIP 信令交互 * [eXosip](https://download.savannah.gnu.org/releases/exosip/) 用于 SIP 信令交互 * [libyuv](https://github.com/lemenkov/libyuv) 用于视频格式转换与处理 * [ffmpeg](https://ffmpeg.org/) 用于音视频处理 # 运行截图 ![1](doc/snapshot/1.jpg "1.jpg") ![2](doc/snapshot/2.jpg "2.jpg") ![3](doc/snapshot/3.jpg "3.jpg") # 联系我们 [上海南宙科技有限公司](https://www.nanuns.com) QQ 群:720153574 # 免责声明 请务必认真阅读和理解本《免责声明》中规定的使用权利和限制。 NanGBD-Android(以下简称“本软件”)规定的使用权利及限制如下: 1. 本软件供开发人员调试开发使用,严禁用于一切侵权、侵害他人利益、违法违禁等不当行为;使用本软件造成的一切后果由用户自行承担,请悉知! 2. 本软件其功能实现所依托的各项权限,需经由作者同意授权后才允许使用,用户需提前了解本软件的各项权限的作用以及利弊,并自行决定是否授予本软件权限。 3. 用户不得对本软件进行反向工程(Reverse engineer)、反向编译(Decompile)、反汇编(Disassemble)或二次打包发布,违者属于侵权行为,并承担由此产生的一切直接和间接后果。 4. 由于本软件使用了部分开源软件,本软件及本软件作者不承担由此引起的直接和间接损害责任。 源码需要修改的3个地方: 1.gb_muxer.cpp int GB28181Muxer::startMuxer() { if (is_running) { LOGI("[muxer]start mux is running"); return 0; } // 这里要注释掉,不然硬解码不能开启混合线程 // if (codec_ctx == NULL) { // return -1; // } LOGI("[muxer]starting mux, tid:%d", gettid()); is_running = STATE_RUNNING; if (args->v_encodec != VideoCodec::NONE) { // 将上面注释的内容放在这里 if (codec_ctx == NULL) { return -1; } pthread_create(&thread_encode, NULL, startEncode, this); pthread_create(&thread_mux, NULL, startMux, this); } else { pthread_create(&thread_mux, NULL, startMuxDirect, this); } LOGI("[muxer]started mux"); return 0; } 2.gb_muxer.cpp int GB28181Muxer::mux(uint8_t *data, int data_len, int64_t pts, bool keyframe) { .................. if (keyframe) { // 2 for I frame, add SYS_HEADER and PSM_HEADER h_len = gb_make_sys_header(header_buf + header_pos, args->enable_audio ? 1 : 0, 1, mux_rate); header_pos += h_len; // h_len = gb_make_psm_header(header_buf + header_pos, // codec_ctx->codec_id == AV_CODEC_ID_H264 ? ST_ID_H264 // : ST_ID_H265, // args->enable_audio ? ST_ID_G711A : -1); // 上面的header封装需要加上下面的逻辑:硬解码的情况下codec_ctx为null if (args->v_encodec != VideoCodec::NONE) { if (codec_ctx != nullptr) h_len = gb_make_psm_header(header_buf + header_pos, codec_ctx->codec_id == AV_CODEC_ID_H264 ? ST_ID_H264 : ST_ID_H265, args->enable_audio ? ST_ID_G711A : -1); } else { h_len = gb_make_psm_header(header_buf + header_pos, ST_ID_H264, args->enable_audio ? ST_ID_G711A : -1); } header_pos += h_len; } ..................... }