GB28181 PTZCmd 完整指令对照表(8 位 16 进制)+ 详细注释 + 使用说明

GB28181 PTZCmd 完整指令对照表(8 位 16 进制)+ 详细注释 + 使用说明

前置规则(必看)

  1. PTZCmd 固定 8 位十六进制字符串 ,格式:A5 + 指令 + 速度 + 预留
  2. 协议标准帧结构:

plaintext

复制代码
字节1: A5  固定起始码
字节2: 命令码 上下左右、变焦、聚焦、光圈
字节3: 速度码 01~FF,数值越大转速越快
字节4: 预留位 固定 00
  1. 停止规则:任意动作发一次对应停止码,云台立即停
  2. 所有指令直接放到 <PTZCmd>xxxxxxx</PTZCmd> 即可用

一、云台上下左右控制

表格

动作 PTZCmd 指令 注释说明
向上转动 A5010800 01 = 向上,08 = 中等速度
向下转动 A5020800 02 = 向下,08 = 中等速度
向左转动 A5030800 03 = 向左,08 = 中等速度
向右转动 A5040800 04 = 向右,08 = 中等速度
上下左右停止 A5000000 00 = 停止所有云台转动

速度调节说明

  • 速度取值:01 ~ FF
  • 示例:
    • 慢速:A5010200 上转慢速
    • 快速:A5012000 上转快速

二、变焦控制(变倍)

表格

动作 PTZCmd 指令 注释说明
变焦放大(拉近) A5050800 5 = 变焦 +
变焦缩小(拉远) A5060800 6 = 变焦 -
变焦停止 A5000000 统一停止码

三、聚焦控制

表格

动作 PTZCmd 指令 注释说明
聚焦近 A5070800 7 = 聚焦 +
聚焦远 A5080800 8 = 聚焦 -
聚焦停止 A5000000 统一停止

四、光圈控制

表格

动作 PTZCmd 指令 注释说明
光圈开大 A5090800 9 = 光圈 +
光圈关小 A50A0800 A = 光圈 -
光圈停止 A5000000 统一停止

五、预置位 设置 / 调用 / 删除

规则

预置位编号 1~127,指令格式:

  • 设置预置位:A50BXX00
  • 调用预置位:A50CXX00
  • 删除预置位:A50DXX00XX = 预置位编号十六进制

表格

功能 预置位 PTZCmd 注释
设置预置位 1 1 A50B0100 把当前画面保存为预置位 1
调用预置位 1 1 A50C0100 摄像头自动转到预置位 1
删除预置位 1 1 A50D0100 删除预置位 1
设置预置位 2 2 A50B0200
调用预置位 2 2 A50C0200

举例:预置位 10 十进制 = 十六进制 0A设置预置位 10:A50B0A00


六、巡航控制(巡逻)

表格

动作 PTZCmd 说明
开始巡航 A50E0100 启动预置位巡航
停止巡航 A50E0000 停止巡航

七、完整可直接下发的 XML 示例(带注释)

xml

复制代码
<?xml version="1.0" encoding="GB2312"?>
<Control>
  <CmdType>Control</CmdType>
  <!-- 命令类型:设备控制 -->
  <SN>202604300030</SN>
  <!-- 消息序列号,自增即可 -->
  <DeviceID>34010000001320000001</DeviceID>
  <!-- 目标摄像头20位国标ID -->
  <PTZCmd>A5010800</PTZCmd>
  <!-- 这里填上面任意8位指令:A5010800=向上转 -->
</Control>

八、开发 & 调试必记要点

  1. 所有动作必须发停止码 按住云台向上,松开必须发 A5000000,否则摄像头一直转。
  2. 速度字节可自定义中间第三位改 01~FF,控制云台转速。
  3. 编码固定大写PTZCmd 用大写十六进制,部分设备小写不兼容。
  4. 放在 GB28181 的 MESSAGE 消息体里,搭配 Application/MANSCDP+xml 头才能生效。

GB28181 PTZ 控制 Java 枚举工具类(可直接拷贝使用)

包含:

  1. PTZ 枚举
  2. 国标 SIP-MESSAGE 报文组装工具类
  3. 可直接生成完整 SIP 头 + XML 体,复制就能发 Socket
  4. 纯 JDK 原生、无依赖、带超详细注释

一、先保留:PTZ 指令枚举类

直接复用,不用改:

java

运行

复制代码
/**
 * GB28181 PTZ 云台控制指令枚举
 * 格式:A5 + 命令码 + 速度码 + 00
 */
public enum PtzCommandEnum {

    PTZ_UP("A5%s%s00", "向上转动"),
    PTZ_DOWN("A5%s%s00", "向下转动"),
    PTZ_LEFT("A5%s%s00", "向左转动"),
    PTZ_RIGHT("A5%s%s00", "向右转动"),

    ZOOM_IN("A5%s%s00", "变焦拉近"),
    ZOOM_OUT("A5%s%s00", "变焦拉远"),

    FOCUS_NEAR("A5%s%s00", "聚焦近"),
    FOCUS_FAR("A5%s%s00", "聚焦远"),

    IRIS_OPEN("A5%s%s00", "光圈开大"),
    IRIS_CLOSE("A5%s%s00", "光圈关小"),

    PRESET_SET("A5%s%s00", "设置预置位"),
    PRESET_CALL("A5%s%s00", "调用预置位"),
    PRESET_DEL("A5%s%s00", "删除预置位"),

    STOP("A5000000", "停止所有动作");

    private final String cmdFormat;
    private final String desc;

    PtzCommandEnum(String cmdFormat, String desc) {
        this.cmdFormat = cmdFormat;
        this.desc = desc;
    }

    public String getCommandCode() {
        return switch (this) {
            case PTZ_UP -> "01";
            case PTZ_DOWN -> "02";
            case PTZ_LEFT -> "03";
            case PTZ_RIGHT -> "04";
            case ZOOM_IN -> "05";
            case ZOOM_OUT -> "06";
            case FOCUS_NEAR -> "07";
            case FOCUS_FAR -> "08";
            case IRIS_OPEN -> "09";
            case IRIS_CLOSE -> "0A";
            case PRESET_SET -> "0B";
            case PRESET_CALL -> "0C";
            case PRESET_DEL -> "0D";
            case STOP -> "00";
        };
    }

    public String build(String speed) {
        if (this == STOP) {
            return STOP.cmdFormat;
        }
        return String.format(cmdFormat, getCommandCode(), speed);
    }

    public String buildPreset(int presetNo) {
        if (presetNo < 1 || presetNo > 127) {
            throw new IllegalArgumentException("预置位范围1~127");
        }
        String hex = String.format("%02X", presetNo);
        return String.format(cmdFormat, getCommandCode(), hex);
    }

    // 快捷默认中速 08
    public static String up() { return PTZ_UP.build("08"); }
    public static String down() { return PTZ_DOWN.build("08"); }
    public static String left() { return PTZ_LEFT.build("08"); }
    public static String right() { return PTZ_RIGHT.build("08"); }
    public static String stop() { return STOP.build("00"); }
}

二、GB28181 XML 生成工具类

生成:云台控制、心跳、目录查询 标准 XML

java

运行

复制代码
/**
 * GB28181 业务XML构造工具
 * 心跳、目录查询、PTZ云台控制
 */
public class Gb28181XmlUtil {

    /**
     * 构造 PTZ 云台控制 XML
     * @param deviceId 设备20位国标ID
     * @param ptzCmd 8位PTZ指令
     * @param sn 消息序列号 自增字符串
     * @return 标准MANSCDP+xml
     */
    public static String buildPtzControlXml(String deviceId, String ptzCmd, String sn) {
        return """
                <?xml version="1.0" encoding="GB2312"?>
                <Control>
                  <CmdType>Control</CmdType>
                  <SN>%s</SN>
                  <DeviceID>%s</DeviceID>
                  <PTZCmd>%s</PTZCmd>
                </Control>
                """.formatted(sn, deviceId, ptzCmd);
    }

    /**
     * 构造 心跳保活 XML
     */
    public static String buildKeepAliveXml(String deviceId, String sn) {
        return """
                <?xml version="1.0" encoding="GB2312"?>
                <Notify>
                  <CmdType>Keepalive</CmdType>
                  <SN>%s</SN>
                  <DeviceID>%s</DeviceID>
                  <Status>Online</Status>
                </Notify>
                """.formatted(sn, deviceId);
    }

    /**
     * 构造 目录查询 XML
     */
    public static String buildCatalogQueryXml(String deviceId, String sn) {
        return """
                <?xml version="1.0" encoding="GB2312"?>
                <Query>
                  <CmdType>Catalog</CmdType>
                  <SN>%s</SN>
                  <DeviceID>%s</DeviceID>
                </Query>
                """.formatted(sn, deviceId);
    }
}

三、核心:SIP MESSAGE 报文组装工具类

直接拼接完整可发送的 SIP 报文,带详细注释

java

运行

复制代码
import java.util.UUID;

/**
 * GB28181 SIP MESSAGE 完整报文构造工具
 * 可生成:标准SIP头 + MANSCDP+xml体
 * 直接通过UDP Socket发送即可
 */
public class Gb28181SipMessageUtil {

    /**
     * 生成完整 GB28181 SIP MESSAGE 报文
     * @param platformId 平台国标ID
     * @param platformIp 平台IP
     * @param deviceId   设备国标ID
     * @param deviceIp   设备IP
     * @param xmlBody    业务XML报文
     * @return 组装好的完整SIP字符串
     */
    public static String buildSipMessage(String platformId, String platformIp,
                                        String deviceId, String deviceIp,
                                        String xmlBody) {
        // 1. 生成随机分支、CallID
        String branch = "z9hG4bK" + UUID.randomUUID().toString().replace("-", "");
        String callId = UUID.randomUUID().toString().replace("-", "") + "@" + platformIp;
        int cseq = 1;
        int maxForwards = 70;

        // 2. 计算XML体长度
        int contentLen = xmlBody.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;

        // 3. 拼接完整SIP报文
        String sipTemplate = """
                MESSAGE sip:%s@%s:5060 SIP/2.0
                Via: SIP/2.0/UDP %s:5060;branch=%s
                From: <sip:%s@%s>;tag=Plat%s
                To: <sip:%s@%s>
                Call-ID: %s
                CSeq: %d MESSAGE
                Max-Forwards: %d
                Content-Type: Application/MANSCDP+xml
                Content-Length: %d

                %s
                """;

        return String.format(sipTemplate,
                deviceId, deviceIp,
                platformIp, branch,
                platformId, platformIp, branch.substring(0, 8),
                deviceId, deviceIp,
                callId,
                cseq,
                maxForwards,
                contentLen,
                xmlBody
        );
    }

    // ============ 测试示例 ============
    public static void main(String[] args) {
        // 组网参数
        String platformId = "34010000000000000000";
        String platformIp = "192.168.1.200";
        String deviceId   = "34010000001320000001";
        String deviceIp   = "192.168.1.100";
        String sn         = "202604301001";

        // 1. 生成云台向上指令
        String ptzCmd = PtzCommandEnum.up();
        // 2. 生成PTZ控制XML
        String ptzXml = Gb28181XmlUtil.buildPtzControlXml(deviceId, ptzCmd, sn);
        // 3. 组装完整SIP MESSAGE报文
        String fullSipMsg = buildSipMessage(platformId, platformIp, deviceId, deviceIp, ptzXml);

        System.out.println("===== 完整GB28181 SIP MESSAGE 报文 =====");
        System.out.println(fullSipMsg);
    }
}

四、使用说明

  1. 只需配置:

    • 平台 ID/IP
    • 设备 ID/IP
    • 自增 SN 序列号
  2. 三步发指令:

    • PtzCommandEnum 拿 PTZ 指令
    • Gb28181XmlUtil 生成 XML
    • Gb28181SipMessageUtil 拼成完整 SIP 报文
    • 通过 UDP 5060 端口 发给设备即可

五、扩展能力(我可以继续给你写)

如果你需要,我可以再帮你补齐:

  1. 注册 REGISTER 报文生成工具类
  2. 视频点播 INVITE+SDP 报文生成
  3. 简易 UDP 发送客户端,直接发报文调摄像头
相关推荐
xun-ming1 小时前
AI时代Java程序员自救手册
java·开发语言·人工智能
张健11564096481 小时前
C++访问控制与友元
java·开发语言·c++
Sam_Deep_Thinking2 小时前
中小团队需要一个资源微服务
java·微服务·架构
Thanks_ks2 小时前
透过 Copy-On-Write 机制:理解并发编程中的性能与一致性权衡
java·多线程·并发编程·底层原理·写时复制·copyonwrite·性能优
一只幸运猫.2 小时前
JAVA后端面试题
java·开发语言
空中海2 小时前
第三章:Maven高级篇 — 插件开发与多模块工程
java·maven
秋92 小时前
TiDB 数据库全链路实战指南:从下载部署到 Java 高并发调优
java·数据库·tidb
JAVA面经实录9172 小时前
Java开发工程基础完整手册(企业实战完整版)
java·开发语言·git·ci/cd·svn·github·intellij idea
李艺为2 小时前
Fake Device Test作假屏幕分辨率分析
android·java