#coding:utf-8

class Protocal_1078:
    def __init__(self):
        self.frameHeader1078 = "30316364"                 # JT/T 1078 头  固定为0x30 0x31 0x63 0x64，ASCII码为01cd
        self.V = 2 << 6                                   # V  固定为2
        self.P = 0 << 5                                   # P  固定为0
        self.X = 0 << 4                                   # X  RTP头是否需要扩展位，固定为0
        self.CC = 1                                       # CC  固定为1
        self.M = 1 << 7                                   # M 标志位，确定是否完整数据帧的边界，因为数据体的最大长度是950字节，而一个视频I帧通道要远远超过950字节，所以视频的一个帧通常会分包
        self.PT = 98                                      # PT 98:表示H264  99:表示H265
        self.sn = 0                                       # 包序号   初始为0，每发送一个RTP数据包，序列号加1
        self.sim = "013146201117"                         # 终端设备SIM卡号
        self.logicC = 1                                   # 逻辑通道
        self.dataType = 0 << 4                            # 数据类型 ， 0000：数据I祯，0001：视频P帧，0010：视频B帧，0011：音频帧，0100：透传数据
        self.pkgTag = 1                                   # 分包处理 ，0000：原子包，不可拆分等，0001：分包处理时的第一个包，0010：分包处理时的最后一个包，0011：分包处理时的中间包
        self.time = 33                                    # 时间戳
        self.lastKeyTime = 33                            # Last I Frame Interval 该祯与上一个关键祯之间的时间间隔，单位毫秒（ms），当数据类型为非视频祯时，则没有该字段
        self.lastTime = 33                                # Last Frame Interval  该祯与上一个祯之间的时间时间，单位毫秒(ms)，当数据类型为非视频祯时，则没有该字段
        self.lenS = 950                                   # 数据长度
        self.dataBody = ""                                # 数据体，要发送的帧数据

        # self.host = "10.100.11.125"
        self.host = "10.16.15.85"
        self.port = 1078
        self.BUF_SIZE = 2048

    def setDataBody(self,data):
        self.dataBody = data
    def setM(self,data):
        self.M = data << 7
    def setSim(self,data):
        while len(data) < 12:
            data = "0" + data
        self.sim = data
    def setLogcC(self,data):
        self.logicC = data
    def setSn(self,data):
        self.sn = data

    def setTime(self,data):
        self.time = data
    def setLastKeyTime(self,data):
        self.lastKeyTime = data
    def setLastTime(self,data):
        self.lastTime = data

    #####################################################
    # 从帧数据中获取帧类型
    #####################################################
    def getFrameType(self):
        # 0x67 (0 11 00111) SPS    非常重要       type = 7
        # 0x68 (0 11 01000) PPS     非常重要       type = 8
        # 0x65 (0 11 00101) IDR帧  关键帧  非常重要 type = 5
        # 0x61 (0 11 00001) I帧        重要         type=1    非IDR的I帧 不大常见
        # 0x41 (0 10 00001) P帧      重要         type = 1
        # 0x01 (0 00 00001) B帧     不重要        type = 1
        # 0x06 (0 00 00110) SEI     不重要        type = 6
        frameTypeHex = self.dataBody[8:10]
        return frameTypeHex

    #####################################################
    # 数字转换为16进制字符串，通过传入字节数可自动补0
    # 传入数据格式所占字节数
    #####################################################
    def int2hexStringByBytes(self, num,bytescount=1):
        hexStr = hex(num)[2:]
        while len(hexStr) < (bytescount * 2):
            hexStr = "0" + hexStr
        return hexStr

    #####################################################
    # 根据长度分割字符串
    #####################################################
    def splitStrByLen(self,strs,num):
        result = []
        if num > len(strs):
            result.append(strs)
        else:
            result.append(strs[:num])
            strs = strs[num:]
            while len(strs) > num:
                result.append(strs[:num])
                strs = strs[num:]
            if len(strs) > 0:
                result.append(strs)
        return result


    #####################################################
    # 生成单个数据包
    #####################################################
    def genPkg(self,data):
        msg = ""
        msg = self.frameHeader1078
        msg = msg + self.int2hexStringByBytes(self.V + self.P + self.X + self.CC)
        msg = msg + self.int2hexStringByBytes(self.M + self.PT)
        msg = msg + self.int2hexStringByBytes(self.sn,2)
        msg = msg + self.sim
        msg = msg + self.int2hexStringByBytes(self.logicC)
        msg = msg + self.int2hexStringByBytes(self.dataType + self.pkgTag)
        msg = msg + self.int2hexStringByBytes(self.time,8)
        msg = msg + self.int2hexStringByBytes(self.lastKeyTime,2)
        msg = msg + self.int2hexStringByBytes(self.lastTime,2)
        msg = msg + self.int2hexStringByBytes(int(len(data) / 2),2)
        msg = msg + data
        return msg

    #####################################################
    # 生成单个数据包
    #####################################################
    def genAudioPkg(self,data):
        msg = ""
        msg = self.frameHeader1078
        msg = msg + self.int2hexStringByBytes(self.V + self.P + self.X + self.CC)
        self.PT = 19
        msg = msg + self.int2hexStringByBytes(self.M + self.PT)
        msg = msg + self.int2hexStringByBytes(self.sn,2)
        msg = msg + self.sim
        msg = msg + self.int2hexStringByBytes(self.logicC)
        msg = msg + self.int2hexStringByBytes(self.dataType + self.pkgTag)
        msg = msg + self.int2hexStringByBytes(self.time,8)
        msg = msg + self.int2hexStringByBytes(int(len(data) / 2),2)

        msg = msg + data
        return msg

    #####################################################
    # 根据帧数据，生成多个数据包(视频)
    #####################################################
    def genPkgsByFrame(self):
        f_type = self.getFrameType()
        if f_type == "65" or f_type == "61":
            self.dataType = 0 << 4              # 0000
        elif f_type == "41":
            self.dataType = 1 << 4              # 0001
        elif f_type == "01":
            self.dataType = 2 << 4              # 0010
        else:
            self.dataType = 2 << 4              # 0010
        datas = self.splitStrByLen(self.dataBody,1900)
        pkgs = []
        for i in range(0,len(datas)):
            if len(datas) == 1:
                self.pkgTag = 0                        # 原子包  0000
            else:
                if i == 0:
                    self.pkgTag = 1                    # 第一个包  0001
                elif i < (len(datas) - 1):
                    self.pkgTag = 3                    # 中间包  0011
                else:
                    self.pkgTag = 2                    # 最后一个包  0010
            pkg = self.genPkg(datas[i])
            pkgs.append(pkg)
            if self.sn >= 65535:
                self.sn = 0
            self.sn = self.sn + 1
        return pkgs

    #####################################################
    # 根据帧数据，生成多个数据包(音频频)
    #####################################################
    def genAudioPkgsByFrame(self):
        self.dataType = 3 << 4
        datas = self.splitStrByLen(self.dataBody,1900)
        pkgs = []
        for i in range(0,len(datas)):
            if len(datas) == 1:
                self.pkgTag = 0                        # 原子包  0000
            else:
                if i == 0:
                    self.pkgTag = 1                    # 第一个包  0001
                elif i < (len(datas) - 1):
                    self.pkgTag = 3                    # 中间包  0011
                else:
                    self.pkgTag = 2                    # 最后一个包  0010
            pkg = self.genAudioPkg(datas[i])
            pkgs.append(pkg)
            if self.sn == 65535:
                self.sn = 0
            self.sn = self.sn + 1
        return pkgs



if __name__ == "__main__":
    pro = Protocal_1078()
    # print(Protocal_1078().genPkg())
    # Protocal_1078().readvideoFile()
    # pro.getFrameType()










