Newer
Older
safe_production_front / public / DispatchLib / DispatchWsWorkerPoc.js
wangxitong on 16 Aug 53 KB first commit
/************************** 语音处理 ******************************/
BufferLen = 0;
MessageBufferLen = 0;

Shared_Buffer = false;     //是否启用SharedArrayBuffer 共享内存模式

AudioBuffer_Play_Left = null;
AudioBuffer_Play_Right = null;
Audio_Play_Write_Index = null;
Audio_Play_Read_Index = null;
Audio_Play_Length = null;

Audio_Capture_Flag = null;
AudioBuffer_Capture = null;
Audio_Capture_Write_Index = null;
Audio_Capture_Read_Index = null;
Audio_Capture_Length = null;

Wasm_Play_Left = null;
Wasm_Play_Right = null;

Wasm_Capture_Audio = null;
Wasm_SendRtp = null;
Wasm_RecvRtp = null;

Wasm_Rtp_SSRC = parseInt(Math.random() * 1000) + 1;
Wasm_EndRtp = null;

HTONL = function (U32_Num) {
    var U8_Array = new Uint8Array(4);

    U8_Array[0] = (U32_Num & 0xFF000000) >> 6*4;
    U8_Array[1] = (U32_Num & 0x00FF0000) >> 4*4;
    U8_Array[2] = (U32_Num & 0x0000FF00) >> 2*4;
    U8_Array[3] = U32_Num & 0x000000FF;
    
    return U8_Array
}

NTOHL = function (U8_Array) {
    var U32_Num = (U8_Array[0] << 6*4) + (U8_Array[1] << 4*4) + (U8_Array[2] << 2*4) + U8_Array[3]

    return parseInt(U32_Num)
}

//初始化媒体
PttAudioBufferInit = function (parm) {
    
    console.log("DispatchWsWorkerPoc PttAudioBufferInit Begin");

    if (parm.Mode == "SharedArrayBuffer") 
    {
        BufferLen = parm.BufferLen;
        MessageBufferLen = parm.Message_BufferLen;

        Shared_Buffer = true;

        AudioBuffer_Play_Left = new Int16Array(parm.Shared_Play_Left);
        AudioBuffer_Play_Right = new Int16Array(parm.Shared_Play_Right);
        Audio_Play_Write_Index = new Uint32Array(parm.Shared_Play_Write_Index);
        Audio_Play_Read_Index = new Uint32Array(parm.Shared_Play_Read_Index);
        Audio_Play_Length = new Uint32Array(parm.Shared_Play_Length);

        Audio_Capture_Flag = new Uint32Array(parm.Shared_Capture_Flag);
        AudioBuffer_Capture = new Int16Array(parm.Shared_Capture);
        Audio_Capture_Write_Index = new Uint32Array(parm.Shared_Capture_Write_Index);
        Audio_Capture_Read_Index = new Uint32Array(parm.Shared_Capture_Read_Index);
        Audio_Capture_Length = new Uint32Array(parm.Shared_Capture_Length);
    }
    else
    {
        BufferLen = parm.BufferLen;
        MessageBufferLen = parm.Message_BufferLen;

        Shared_Buffer = false;
        
        AudioBuffer_Play_Left = new Int16Array(BufferLen);
        AudioBuffer_Play_Right = new Int16Array(BufferLen);
        Audio_Play_Write_Index = new Uint32Array(1);
        Audio_Play_Read_Index = new Uint32Array(1);
        Audio_Play_Length = new Uint32Array(1);

        Audio_Capture_Flag = new Uint32Array(1);
        AudioBuffer_Capture = new Int16Array(BufferLen);
        Audio_Capture_Write_Index = new Uint32Array(1);
        Audio_Capture_Read_Index = new Uint32Array(1);
        Audio_Capture_Length = new Uint32Array(1);

        Audio_Capture_Flag[0] = 0;

        Audio_Capture_Read_Index[0] = 0;
        Audio_Capture_Write_Index[0] = 0;
    }
    Audio_Play_Length[0] = 0;
    Audio_Capture_Length[0] = 0;

    Module._initCodec(DcInfo.ID, 0);

    Wasm_Play_Left = Module._malloc(640 * Int16Array.BYTES_PER_ELEMENT);
    Wasm_Play_Right = Module._malloc(640 * Int16Array.BYTES_PER_ELEMENT);

    Wasm_Capture_Audio = Module._malloc(640 * Int16Array.BYTES_PER_ELEMENT);
    Wasm_SendRtp = Module._malloc(500 * Uint8Array.BYTES_PER_ELEMENT);
    Wasm_EndRtp = Module._malloc(500 * Uint8Array.BYTES_PER_ELEMENT);
    Wasm_RecvRtp = Module._malloc(500 * Uint8Array.BYTES_PER_ELEMENT);

    setInterval(function () {
        //播放
        var getAudioRet = Module._getAudio(Wasm_Play_Left, Wasm_Play_Right);

        var play_left_Int16 = Module.HEAP16.subarray(Wasm_Play_Left / Int16Array.BYTES_PER_ELEMENT, Wasm_Play_Left / Int16Array.BYTES_PER_ELEMENT + 640); //从数组取数据
        var play_right_Int16 = Module.HEAP16.subarray(Wasm_Play_Right / Int16Array.BYTES_PER_ELEMENT, Wasm_Play_Right / Int16Array.BYTES_PER_ELEMENT + 640); //从数组取数据

        AudioBuffer_Play_Left.set(play_left_Int16, Audio_Play_Write_Index[0]);
        AudioBuffer_Play_Right.set(play_right_Int16, Audio_Play_Write_Index[0]);

        Audio_Play_Write_Index[0] = Audio_Play_Write_Index[0] + 640;

        if (getAudioRet == 0)
        {
            if (Shared_Buffer)
            {
                Audio_Play_Length[0] = Audio_Play_Length[0] + 640;
            }
            else
            {
                //消息模式
                if (Audio_Play_Write_Index[0] % MessageBufferLen == 0)
                {
                    postMessage({
                        WsMsg: "AudioPlayBuffer",
                        BufferLeft: AudioBuffer_Play_Left.subarray(Audio_Play_Write_Index[0] - MessageBufferLen, Audio_Play_Write_Index[0]),
                        BufferRight: AudioBuffer_Play_Right.subarray(Audio_Play_Write_Index[0] - MessageBufferLen, Audio_Play_Write_Index[0]),
                    });
                }
            }
        }
       
        if (Audio_Play_Write_Index[0] >= BufferLen) {
            Audio_Play_Write_Index[0] = 0;
        }

        if (Audio_Capture_Flag[0] == 1 && websocket && websocket.hasOpen) {
            //采集发送

            if (Audio_Capture_Length[0] >= 640)
            {
                //console.log("PttAudioCapBuffer send write_index:", Audio_Capture_Write_Index[0], " len:", Audio_Capture_Length[0], "read_index:", Audio_Capture_Read_Index[0]);
               
                var cap = AudioBuffer_Capture.subarray(Audio_Capture_Read_Index[0], Audio_Capture_Read_Index[0] + 640);
                Audio_Capture_Read_Index[0] = Audio_Capture_Read_Index[0] + 640;
                if (Audio_Capture_Read_Index[0] >= BufferLen) {
                    Audio_Capture_Read_Index[0] = 0;
                }
                
                Module.HEAP16.set(cap, Wasm_Capture_Audio / Int16Array.BYTES_PER_ELEMENT); //数据推入数组
                var len = Module._encodeOnePacket(Wasm_Capture_Audio, 4, Wasm_SendRtp);
    
                var rtp_u8 = Module.HEAPU8.subarray(Wasm_SendRtp / Uint8Array.BYTES_PER_ELEMENT, Wasm_SendRtp / Uint8Array.BYTES_PER_ELEMENT + len); //从数组取数据
    
                var arraybuffer = new ArrayBuffer(len);
                var rtp_with_head = new Uint8Array(arraybuffer);
                rtp_with_head.set(rtp_u8, 0);
    
                var ssrc = HTONL(Wasm_Rtp_SSRC);
                rtp_with_head.set(ssrc, 4+8);
    
                //websocket发送
                for (i = 0; i < PttChannelList.length; i++) {
                    var channel = PttChannelList[i];
                    if (channel && channel.nSpeakStatus == 1) {
                        
                        var callid = HTONL(channel.nCallID);
                        rtp_with_head.set(callid, 4+20);
    
                        var view = new DataView(arraybuffer);
                        websocket.send(view);
                    }
                }

                Audio_Capture_Length[0] = Audio_Capture_Length[0] - 640;
            }
        }
    }, 80);

    console.log("DispatchWsWorkerPoc PttAudioBufferInit Done");
}

PttAudioCapBuffer = function (parm) {
    AudioBuffer_Capture.set(parm.Buffer, Audio_Capture_Write_Index[0]);

    //console.log("PttAudioCapBuffer fill write_index:", Audio_Capture_Write_Index[0], " len:", parm.Buffer.length, "read_index:", Audio_Capture_Read_Index[0]);

    Audio_Capture_Write_Index[0] = Audio_Capture_Write_Index[0] + parm.Buffer.length;
    if (Audio_Capture_Write_Index[0] >= BufferLen) {
        Audio_Capture_Write_Index[0] = 0;
    }

    Audio_Capture_Length[0] = Audio_Capture_Length[0] + parm.Buffer.length;

    //echo test
    //postMessage({
    //    WsMsg: "AudioPlayBuffer",
    //    BufferLeft: parm.Buffer,
    //    BufferRight: parm.Buffer,
    //});
}

RecvBinaryData = function (data) {
    var BinaryData = new Uint8Array(data);
    if (BinaryData[0] == 0x61 && BinaryData[1] == 0x70) //ap
    {
        var callid_net = BinaryData.subarray(4+20, 4+20+4);
        var callid = NTOHL(callid_net);

        //console.log("RecvAudioData callid:", callid, "len:", BinaryData.length, BinaryData[11], BinaryData[12]);

        var index = PttChannelList_CallID.get(callid);
        if (typeof index != 'undefined') {
            var channel = PttChannelList[index];

            Module.HEAPU8.set(BinaryData, Wasm_RecvRtp / Uint8Array.BYTES_PER_ELEMENT);

            Module._decodeOnePacket(index, Wasm_RecvRtp, BinaryData.length);
        }
    }
}


/************************** 对讲业务 ******************************/
function PttChannel(index) {
    this.Index = index;
    this.nChannelIDs = [];
    this.nCallMode = -1;        //0-组呼 1-单呼 2-临时组呼
    this.cGroupNumber = "";
    this.nGroupPriority = 7;
    this.cUserNumber = "";
    this.lUserNumList = [];
    this.lGroupNumList = []
    this.nCallID = 0;
    this.nMoniterStatus = 0;    //-1-等待重新监听 0-未监听 1-监听中
    this.nCallStatus = 0;       //0-空闲 1-呼叫中
    this.nSpeakStatus = 0;      //0-空闲 1-讲 2-听
    this.cSpeakerNumber = "";
    this.cSpeakerName = "";

    this.nCallTalk = 0;         //呼叫并申请话权标识位
}


PttChannelListIndex = 0;
PttChannelList = [];                    //PttChannel[Index]
PttChannelList_CallID = new Map();      //CallID - Index
PttChannelList_ChannelID = new Map();   //ChannelID - Index

PttSpeakingChannelNum = 0;

onWebWorkerMessage_Poc = function (parm) {
    switch (parm.Msg) {
        case "AudioBufferInit":
            PttAudioBufferInit(parm);
            break
        case "AudioCapBuffer":
            PttAudioCapBuffer(parm);
            break           
        case "PttLoadChannelReq":
            PttLoadChannel(parm);
            break
        case "PttReleaseChannelReq":
            PttReleaseChannel(parm);
            break
        case "PttMonitorReq":
            PttMonitor(parm);
            break
        case "PttCallReq":
            PttCall(parm);
            break
        case "PttTalkRequestReq":
            PttTalkRequest(parm);
            break
        case "PttCallTalkRequest":
            PttCallTalkRequest(parm);
            break
        case "PttTalkReleaseReq":
            PttTalkRelease(parm);
            break
        case "PttSetVolumeReq":
            PttSetVolume(parm);
            break
        case "PttSetTrackReq":
            PttSetTrack(parm);
            break
        case "PttCallInsert":
            PttCallInsert(parm);
            break
        case "PttCallBreak":
            PttCallBreak(parm);
            break
        case "PttMsgSendReq":
            PttMsgSendReq(parm);
            break
    }
}


//加载通道
PttLoadChannel = function (parm) {
    var CallMode = parm.CallMode;

    if (CallMode == 0) {
        for (i = 0; i < PttChannelList.length; i++) {
            var channel = PttChannelList[i];
            if (channel && channel.nCallMode == 0 && channel.cGroupNumber == parm.GroupNumber) {
                for (j = 0; j < channel.nChannelIDs.length; j++) {
                    if (channel.nChannelIDs[j] == parm.ChannelID) {
                        return;
                    }
                }

                channel.nChannelIDs.push(parm.ChannelID)

                PttChannelList_ChannelID.set(parm.ChannelID, channel.Index);

                console.log("Use PttChannel ", JSON.stringify(channel));
                console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
                console.log("PttChannelList_CallID ", PttChannelList_CallID);

                return;
            }
        }

        var index = -1;
        for (var i = 0; i < 100; i++) {
            if (!PttChannelList[i]) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            index = PttChannelListIndex;
            PttChannelListIndex++;
        }

        var channel = new PttChannel(index);
        channel.nCallMode = 0;
        channel.cGroupNumber = parm.GroupNumber;
        channel.nGroupPriority = parm.GroupPriority;
        channel.nChannelIDs.push(parm.ChannelID)
        PttChannelList[index] = channel;
        PttChannelList_ChannelID.set(parm.ChannelID, channel.Index);

        console.log("New PttChannel ", JSON.stringify(channel));
        console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
        console.log("PttChannelList_CallID ", PttChannelList_CallID);

    } else if (CallMode == 1) {
        for (i = 0; i < PttChannelList.length; i++) {
            var channel = PttChannelList[i];
            if (channel && channel.nCallMode == 1 && channel.cUserNumber == parm.UserNumber) {
                for (j = 0; j < channel.nChannelIDs.length; j++) {
                    if (channel.nChannelIDs[j] == parm.ChannelID) {
                        return;
                    }
                }

                channel.nChannelIDs.push(parm.ChannelID)

                PttChannelList_ChannelID.set(parm.ChannelID, channel.Index);

                console.log("Use PttChannel ", JSON.stringify(channel));
                console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
                console.log("PttChannelList_CallID ", PttChannelList_CallID);

                return;
            }
        }

        var index = -1;
        for (var i = 0; i < 100; i++) {
            if (!PttChannelList[i]) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            index = PttChannelListIndex;
            PttChannelListIndex++;
        }

        var channel = new PttChannel(index);
        channel.nCallMode = 1;
        channel.cUserNumber = parm.UserNumber;
        channel.nChannelIDs.push(parm.ChannelID)
        PttChannelList[index] = channel;
        PttChannelList_ChannelID.set(parm.ChannelID, channel.Index);

        console.log("New PttChannel ", JSON.stringify(channel));
        console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
        console.log("PttChannelList_CallID ", PttChannelList_CallID);

    } else if (CallMode == 2) {
        for (i = 0; i < PttChannelList.length; i++) {
            var channel = PttChannelList[i];
            if (channel && channel.nCallMode == 2 && channel.lUserNumList == parm.UserList && channel.lGroupNumList == parm.GroupList) {
                for (j = 0; j < channel.nChannelIDs.length; j++) {
                    if (channel.nChannelIDs[j] == parm.ChannelID) {
                        return;
                    }
                }

                channel.nChannelIDs.push(parm.ChannelID)

                PttChannelList_ChannelID.set(parm.ChannelID, channel.Index);

                console.log("Use PttChannel ", JSON.stringify(channel));
                console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
                console.log("PttChannelList_CallID ", PttChannelList_CallID);

                return;
            }
        }

        var index = -1;
        for (var i = 0; i < 100; i++) {
            if (!PttChannelList[i]) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            index = PttChannelListIndex;
            PttChannelListIndex++;
        }

        var channel = new PttChannel(index);
        channel.nCallMode = 2;
        channel.lUserNumList = parm.UserList;
        channel.lGroupNumList = parm.GroupList;
        channel.nChannelIDs.push(parm.ChannelID)
        PttChannelList[index] = channel;
        PttChannelList_ChannelID.set(parm.ChannelID, channel.Index);

        console.log("New PttChannel ", JSON.stringify(channel));
        console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
        console.log("PttChannelList_CallID ", PttChannelList_CallID);

    }
}

//释放通道
PttReleaseChannel = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index != 'undefined') {
        var channel = PttChannelList[index];
        PttChannelList_ChannelID.delete(ChannelID)

        for (j = 0; j < channel.nChannelIDs.length; j++) {
            if (channel.nChannelIDs[j] == ChannelID) {
                channel.nChannelIDs.splice(j, 1);
                break;
            }
        }

        if (channel.nChannelIDs.length == 0) {
            //全部释放
            PttChannelList[index] = null;
            PttChannelList_CallID.delete(channel.nCallID);

            Module._setVolume(index, 100);
            Module._setChannel(index, 1, 1);

            console.log("Del PttChannel ", JSON.stringify(channel));
            console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
            console.log("PttChannelList_CallID ", PttChannelList_CallID);
        } else {
            //有复用
            console.log("Use PttChannel ", JSON.stringify(channel));
            console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
            console.log("PttChannelList_CallID ", PttChannelList_CallID);
        }

    }
}

//开始/取消监听
PttMonitor = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index == 'undefined') {
        var msgData = {
            Msg: "PttMonitorRsp",
            Type: parm.Type,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }
    var channel = PttChannelList[index];
    if (parm.Type) {
        if (channel.nMoniterStatus == 1) {
            //已监听
            var msgData = {
                Msg: "PttMonitorRsp",
                Type: parm.Type,
                Result: 0,
            };
            postMessage(msgData);

        } else {
            //未监听
            msg = new WsBaseMsg("Poc_MonitorGroup_Req", 4);
            msg.onRspFail = function (reason) {
                var msgData = {
                    Msg: "PttMonitorRsp",
                    Result: 20,
                    Type: parm.Type,
                };

                postMessage(msgData);
            }
            if (channel.nCallMode == 1)
            {
                msg.Set("cGroupNumber", channel.cUserNumber);
            }
            else
            {
                msg.Set("cGroupNumber", channel.cGroupNumber);
            }
            msg.Set("nCallMode", channel.nCallMode);
            msg.Set("nGroupHostType", 1);
            msg.Send("Poc_MonitorGroup_Rsp");
        }
    } else {
        if (channel.nMoniterStatus == 1) {
            //已监听
            msg = new WsBaseMsg("Poc_MonitorGroup_Req", 4);
            msg.onRspFail = function (reason) {
                var msgData = {
                    Msg: "PttMonitorRsp",
                    Result: 20,
                    Type: parm.Type,
                };

                postMessage(msgData);
            }
            if (channel.nCallMode == 1)
            {
                msg.Set("cGroupNumber", channel.cUserNumber);
            }
            else
            {
                msg.Set("cGroupNumber", channel.cGroupNumber);
            }
            msg.Set("nCallMode", channel.nCallMode);
            msg.Set("nGroupHostType", 0);
            msg.Send("Poc_MonitorGroup_Rsp");

        } else {
            //未监听
            var msgData = {
                Msg: "PttMonitorRsp",
                Type: parm.Type,
                Result: 0,
            };
            postMessage(msgData);

        }
    }
}

//发起/结束呼叫
PttCall = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index == 'undefined') {
        var msgData = {
            Msg: "PttCallRsp",
            Type: parm.Type,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }
    var channel = PttChannelList[index];
    if (parm.Type) { //发起呼叫
        if (channel.nCallStatus == 1) {
            //呼叫中
            var msgData = {
                Msg: "PttCallRsp",
                Type: parm.Type,
                Result: 0,
            };
            postMessage(msgData);

        } else {
            //空闲
            msg = new WsBaseMsg("Poc_CallApply_Req", 8);
            msg.onRspFail = function (reason) {
                var msgData = {
                    Msg: "PttCallRsp",
                    Result: 20,
                    Type: parm.Type,
                };

                postMessage(msgData);
            }
            msg.Set("nRequsetID", index);
            msg.Set("nCallMode", channel.nCallMode);
            
            var lUserNumList = []
            var lGroupNumList = []

            if (channel.nCallMode == 0) { //组呼
                lGroupNumList[0] = channel.cGroupNumber;
            } else if (channel.nCallMode == 1) { //单呼
                lUserNumList[0] = channel.cUserNumber;
            } else {    //临时组呼
                lUserNumList = channel.lUserNumList;
                lGroupNumList = channel.lGroupNumList;
            } 

            msg.Set("lGroupNumList", lGroupNumList);
            msg.Set("lUserNumList", lUserNumList);

            msg.Send("Poc_CallApply_Rsp");
        }
    } else {    //释放呼叫
        if (channel.nCallStatus == 1) {
            //呼叫中
            if (channel.nCallID == 0) {
                var msgData = {
                    Msg: "PttCallRsp",
                    Type: parm.Type,
                    Result: 0,
                };
                postMessage(msgData);

                channel.nCallStatus = 0;

                return
            }

            msg = new WsBaseMsg("Poc_CallRelease_Req", 9);
            msg.onRspFail = function (reason) {
                var msgData = {
                    Msg: "PttCallRsp",
                    Result: 20,
                    Type: parm.Type,
                };

                postMessage(msgData);
            }
            msg.Set("nCallID", channel.nCallID);
            msg.Set("nOperationType", 1);
            msg.Send("Poc_CallRelease_Rsp");

        } else {
            //空闲
            var msgData = {
                Msg: "PttCallRsp",
                Type: parm.Type,
                Result: 0,
            };
            postMessage(msgData);

        }
    }
}

//申请话权
PttTalkRequest = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index == 'undefined') {
        var msgData = {
            Msg: "PttTalkRequestRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    var channel = PttChannelList[index];
    if (channel.nCallID == 0) {
        var msgData = {
            Msg: "PttTalkRequestRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    if (channel.nSpeakStatus != 1) {
        //讲话中,不重复处理
        msg = new WsBaseMsg("Poc_SpeakApply_Req", 5);
        msg.onRspFail = function (reason) {
            var msgData = {
                Msg: "PttTalkRequestRsp",
                ChannelID: ChannelID,
                Result: 20,
            };
            postMessage(msgData);
        }
        msg.Set("nCallID", channel.nCallID);
        msg.Send("Poc_SpeakApply_Rsp");
    } else {
        var msgData = {
            Msg: "PttTalkStatusNotify",
            Type: channel.nSpeakStatus,
            Cause: 0,
            Talker: "",
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }
    }
}

//发起呼叫并申请话权
PttCallTalkRequest = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index == 'undefined') {
        var msgData = {
            Msg: "PttCallRsp",
            ChannelID: ChannelID,
            Type: 1,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    var channel = PttChannelList[index];
    if (channel.nSpeakStatus == 1) {
        //讲话中,不重复处理
        var msgData = {
            Msg: "PttTalkStatusNotify",
            Type: channel.nSpeakStatus,
            Cause: 0,
            Talker: "",
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }
        return;
    }

    if (channel.nCallStatus == 1) {
        //申请话权
        PttTalkRequest({ChannelID:ChannelID})
        return;
    }

    if (channel.nCallMode == 0 && channel.nGroupPriority >= 7) {
        //非呼叫组
        PttTalkRequest({ChannelID:ChannelID});
        return;
    }
    
    if (channel.nCallMode == 1 && channel.nMoniterStatus == 1) {
        //网关
        PttTalkRequest({ChannelID:ChannelID});
        return;
    }
    
    channel.nCallTalk = 1;

    msg = new WsBaseMsg("Poc_CallApply_Req", 8);
    msg.onRspFail = function (reason) {
        var msgData = {
            Msg: "PttCallRsp",
            Result: 20,
            Type: parm.Type,
        };

        postMessage(msgData);
    }
    msg.Set("nRequsetID", index);
    msg.Set("nCallMode", channel.nCallMode);
    
    var lUserNumList = []
    var lGroupNumList = []

    if (channel.nCallMode == 0) { //组呼
        lGroupNumList[0] = channel.cGroupNumber;
    } else if (channel.nCallMode == 1) { //单呼
        lUserNumList[0] = channel.cUserNumber;
    } else {    //临时组呼
        lUserNumList = channel.lUserNumList;
        lGroupNumList = channel.lGroupNumList;
    } 

    msg.Set("lGroupNumList", lGroupNumList);
    msg.Set("lUserNumList", lUserNumList);

    msg.Send("Poc_CallApply_Rsp");
}

//释放话权
PttTalkRelease = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index == 'undefined') {
        var msgData = {
            Msg: "PttTalkReleaseRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    var channel = PttChannelList[index];
    if (channel.nCallID == 0) {
        var msgData = {
            Msg: "PttTalkReleaseRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    setTimeout(() => {//延迟采集
        channel.nCallTalk = 0;

        //尾帧
        var len = Module._encodeEndPacket(Wasm_EndRtp);
    
        var rtp_u8 = Module.HEAPU8.subarray(Wasm_EndRtp / Uint8Array.BYTES_PER_ELEMENT, Wasm_EndRtp / Uint8Array.BYTES_PER_ELEMENT + len); //从数组取数据

        var arraybuffer = new ArrayBuffer(len);
        var rtp_with_head = new Uint8Array(arraybuffer);
        rtp_with_head.set(rtp_u8, 0);

        var ssrc = HTONL(Wasm_Rtp_SSRC);
        rtp_with_head.set(ssrc, 4+8);

        var callid = HTONL(channel.nCallID);
        rtp_with_head.set(callid, 4+20);

        var view = new DataView(arraybuffer);
        websocket.send(view);

        
        msg = new WsBaseMsg("Poc_SpeakRelease_Req", 6);
        msg.onRspFail = function (reason) {
            var msgData = {
                Msg: "PttTalkReleaseRsp",
                ChannelID: ChannelID,
                Result: 20,
            };
            postMessage(msgData);
        }
        msg.Set("nCallID", channel.nCallID);
        msg.Send("Poc_SpeakRelease_Rsp");


    }, 300);

}

//设置对讲音量
PttSetVolume = function (parm) {
    if (typeof parm.ChannelID == "number" && typeof parm.Volume == "number") {
        if (parm.ChannelID == -1) {
            for (i = 0; i < PttChannelList.length; i++) {
                var channel = PttChannelList[i];
                if (channel) {
                    Module._setVolume(i, parm.Volume);
                }
            }
        } else {
            var index = PttChannelList_ChannelID.get(parm.ChannelID);
            if (typeof index != 'undefined') {
                Module._setVolume(index, parm.Volume);
            }
        }
    }
}

//通道设置声道
PttSetTrack = function (parm) {
    if (typeof parm.ChannelID == "number" && typeof parm.Track == "number") {
        var index = PttChannelList_ChannelID.get(parm.ChannelID);
        if (typeof index != 'undefined') {
            if (parm.Track == -1) {
                Module._setChannel(index, 1, 0);
            } else if (parm.Track == 0) {
                Module._setChannel(index, 1, 1);
            } else if (parm.Track == 1) {
                Module._setChannel(index, 0, 1);
            }
        }
    }
}

//呼叫强插
PttCallInsert = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index == 'undefined') {
        var msgData = {
            Msg: "PttCallInsertRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    var channel = PttChannelList[index];
    if (channel.nCallID == 0) {
        var msgData = {
            Msg: "PttCallInsertRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    msg = new WsBaseMsg("Poc_CallInsert_Req", 14);
    msg.onRspFail = function (reason) {
        var msgData = {
            Msg: "PttCallInsertRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);
    }
    msg.Set("nCallID", channel.nCallID);
    msg.Set("cCalledUserNum", parm.UserNumber);
    msg.Send("Poc_CallInsert_Rsp");
}

//呼叫强拆
PttCallBreak = function (parm) {
    var ChannelID = parm.ChannelID;
    var index = PttChannelList_ChannelID.get(ChannelID);
    if (typeof index == 'undefined') {
        var msgData = {
            Msg: "PttCallBreakRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    var channel = PttChannelList[index];
    if (channel.nCallID == 0) {
        var msgData = {
            Msg: "PttCallBreakRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);

        return;
    }

    msg = new WsBaseMsg("Poc_CallBreak_Req", 15);
    msg.onRspFail = function (reason) {
        var msgData = {
            Msg: "PttCallBreakRsp",
            ChannelID: ChannelID,
            Result: 20,
        };
        postMessage(msgData);
    }
    msg.Set("nCallID", channel.nCallID);
    msg.Set("cCalledUserNum", parm.UserNumber);
    msg.Send("Poc_CallBreak_Rsp");
}

PttMsgSendReq = function (parm) {
    msg = new WsBaseMsg("Poc_MediaMsg_Req", 12);
    msg.onRspFail = function (reason) {
        var msgData = {
            Msg: "MsgSendRsp",
            MsgIndex: parm.MsgIndex,
            Result: 20,
        };
        postMessage(msgData);
    }
    msg.Set("nCallingUserID", DcInfo.ID);
    msg.Set("cCallingUserNum", DcInfo.Number);
    msg.Set("nCallingUserType", 2);
    msg.Set("cCallingUserName", DcInfo.Name);
    
    var TargetType = parm.TargetType;
    msg.Set("nCalledType", TargetType);
    if (TargetType == 0 || TargetType == 2) {
        msg.Set("cCalledUserNum", parm.TargetInfo.UserNumber);
    }
    else if (TargetType == 1) {
        msg.Set("cCallingNickname", parm.TargetInfo.NickName);
        msg.Set("cCalledGroupNum", parm.TargetInfo.GroupNumber);
    }
    else if (TargetType == 3) {
        msg.Set("cTempGroupID", parm.TargetInfo.TempGroupID);
        msg.Set("cCalledGroupNum", parm.TargetInfo.GroupList);
        msg.Set("cCalledGroupNum", parm.TargetInfo.UserList);
    }
    var MsgType = parm.MsgType
    msg.Set("nMsgType", parm.MsgType);
    //校验参数
    if (MsgType == 0 || MsgType == 8) {
        msg.Set("cMsgContent", parm.MsgInfo.MsgString);
        msg.Set("cDescription", parm.MsgInfo.LocDescription);
    }
    else if (MsgType == 1 || MsgType == 2 || MsgType == 3 || MsgType == 5 || MsgType == 7) {
        msg.Set("cMsgContent", parm.MsgInfo.MsgString);
        msg.Set("cMsgAttach", parm.MsgInfo.MsgAttachAddr);
        msg.Set("nDuration", parm.MsgInfo.Duration);
        msg.Set("cDescription", parm.MsgInfo.LocDescription);
    }
    else if (MsgType == 4) {
        msg.Set("nLatitudeType", parm.MsgInfo.LatitudeType);
        msg.Set("nLatitude", parm.MsgInfo.Latitude);
        msg.Set("nLongitudeType", parm.MsgInfo.LongitudeType);
        msg.Set("nLongitude", parm.MsgInfo.Longitude);
        msg.Set("cDescription", parm.MsgInfo.LocDescription);
    }
    msg.Set("cMsgIndex", parm.MsgIndex);

    msg.Send("Poc_MediaMsg_Rsp");

}

PttOffline = function()
{
    for (i = 0; i < PttChannelList.length; i++) {
        var channel = PttChannelList[i];
        if (channel)
        {
            if (channel.nMoniterStatus != 0 || channel.nCallStatus != 0)
            {
                if (channel.nSpeakStatus == 1) {
                    if (PttSpeakingChannelNum != 0) {
                        //停止采集
                        PttSpeakingChannelNum--;
                        if (PttSpeakingChannelNum == 0) {
                            Audio_Capture_Flag[0] = 0;
                            postMessage({
                                WsMsg: "AudioCaptureStop",
                            });
                            console.log("Poc Capture Stop"); 
                        }
                    }
                }
    
                channel.nSpeakStatus = 0;

                var msgData = {
                    Msg: "PttTalkStatusNotify",
                    Type: channel.nSpeakStatus,
                    Cause: 0,
                    Talker: "",
                };
                for (j = 0; j < channel.nChannelIDs.length; j++) {
                    msgData.ChannelID = channel.nChannelIDs[j];
                    postMessage(msgData);
                }

                if (channel.nMoniterStatus == 1)
                {
                    channel.nMoniterStatus = -1;
                }
                channel.nCallStatus = 0;

                var msgData = {
                    Msg: "PttCallStatusNotify",
                    CallStatus: 0,
                    MonitorStatus: 0
                };
                for (j = 0; j < channel.nChannelIDs.length; j++) {
                    msgData.ChannelID = channel.nChannelIDs[j];
                    postMessage(msgData);
                }
            }
        }
    }  
}


PttOnline = function()
{
    for (i = 0; i < PttChannelList.length; i++) {
        var channel = PttChannelList[i];
        if (channel)
        {
            if (channel.nMoniterStatus == -1)
            {
                msg = new WsBaseMsg("Poc_MonitorGroup_Req", 4);
                msg.onRspFail = function (reason) {
                    var msgData = {
                        Msg: "PttMonitorRsp",
                        Result: 20,
                        Type: 1,
                    };
    
                    postMessage(msgData);
                }
                if (channel.nCallMode == 1)
                {
                    msg.Set("cGroupNumber", channel.cUserNumber);
                }
                else
                {
                    msg.Set("cGroupNumber", channel.cGroupNumber);
                }
                msg.Set("nCallMode", channel.nCallMode);
                msg.Set("nGroupHostType", 1);
                msg.Send("Poc_MonitorGroup_Rsp");
            }
        }
    }  
}

//——————————————————————————————————————— weboscket 接收 ———————————————————————————————————————————

//开始/取消监听应答
onWs_Poc_MonitorGroup_Rsp = function (data) {
    //{"cGroupNumber":"10000","nCallID":1,"nCallMode":0,"nGroupHostType":1,"nRetCode":1001}
    for (i = 0; i < PttChannelList.length; i++) {
        var channel = PttChannelList[i];
        if (channel) {
            if (channel.nCallMode == data.nCallMode &&
                (channel.cGroupNumber == data.cGroupNumber || channel.cUserNumber == data.cGroupNumber)) {

                var msgData = {
                    Msg: "PttMonitorRsp",
                    Type: data.nGroupHostType,
                    Result: data.nRetCode
                };
                for (j = 0; j < channel.nChannelIDs.length; j++) {
                    msgData.ChannelID = channel.nChannelIDs[j];
                    postMessage(msgData);
                }

                if (data.nRetCode == 0) {
                    //成功
                    if (data.nGroupHostType == 1) {
                        //开始监听
                        channel.nMoniterStatus = 1;
                        channel.nCallID = data.nCallID;
                        PttChannelList_CallID.set(data.nCallID, channel.Index);

                        var msgData = {
                            Msg: "PttCallStatusNotify",
                            CallStatus: channel.nCallStatus,
                            MonitorStatus: channel.nMoniterStatus,
                        };
                        for (j = 0; j < channel.nChannelIDs.length; j++) {
                            msgData.ChannelID = channel.nChannelIDs[j];
                            postMessage(msgData);
                        }

                    } else {
                        //取消监听
                        channel.nMoniterStatus = 0;
                        channel.nCallID = 0;
                        PttChannelList_CallID.delete(data.nCallID);

                        var msgData = {
                            Msg: "PttCallStatusNotify",
                            CallStatus: channel.nCallStatus,
                            MonitorStatus: channel.nMoniterStatus,
                        };
                        for (j = 0; j < channel.nChannelIDs.length; j++) {
                            msgData.ChannelID = channel.nChannelIDs[j];
                            postMessage(msgData);
                        }
                    }
                }

                break;
            }
        }
    }

    console.log("PttChannel MonitorGroup_Rsp", JSON.stringify(channel));
    console.log("PttChannelList_ChannelID ", PttChannelList_ChannelID);
    console.log("PttChannelList_CallID ", PttChannelList_CallID);
}

onWs_Poc_CallApply_Rsp = function (data) {
    var nCallMode = data.nCallMode;
    var nRequsetID = data.nRequsetID;
    var nCallID = data.nCallID;
    var channel = PttChannelList[nRequsetID];
    if (channel && channel.nCallMode == nCallMode) {
        var msgData = {
            Msg: "PttCallRsp",
            Type: 1,
            Result: data.nRetCode
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }

        if (data.nRetCode == 0) {
            //成功
            channel.nCallStatus = 1;
            channel.nCallID = data.nCallID;
            PttChannelList_CallID.set(data.nCallID, channel.Index);

            if (channel.nCallTalk == 1) {
                PttTalkRequest({ChannelID:channel.nChannelIDs[0]})
            }
        }

        var msgData = {
            Msg: "PttCallStatusNotify",
            CallStatus: channel.nCallStatus,
            MonitorStatus: channel.nMoniterStatus,
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }
    }
}

onWs_Poc_CallRelease_Rsp = function (data) {
    var nCallID = data.nCallID;
    var index = PttChannelList_CallID.get(nCallID);
    if (typeof index != 'undefined') {
        var channel = PttChannelList[index];
        var msgData = {
            Msg: "PttCallRsp",
            Type: 0,
            Result: data.nRetCode
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }

        if (data.nRetCode == 0) {
            //成功
            channel.nCallStatus = 0;
            
            if (channel.nMoniterStatus == 0) {
                channel.nCallID = 0;
                PttChannelList_CallID.delete(data.nCallID);
            }
                       
            var msgData = {
                Msg: "PttCallStatusNotify",
                CallStatus: channel.nCallStatus,
                MonitorStatus: channel.nMoniterStatus,
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }
        }       
    }
}

onWs_Poc_CalledSearch_Req = function (data) {

    var nCallMode = data.nCallMode;
    var nCallID = data.nCallID;

    msg = new WsBaseMsg("Poc_CalledSearch_Rsp", 304);
    msg.Set("nCallID", nCallID);
    msg.Set("nCallMode", nCallMode);
    msg.Set("nRetCode", 0);
    msg.Send();

    switch (nCallMode) {
        case 0:
            //组呼   
            var index = PttChannelList_CallID.get(nCallID);
            if (typeof index != 'undefined') {
                var channel = PttChannelList[index];
                channel.nCallStatus = 1;
                channel.nCallID = data.nCallID;
    
                var msgData = {
                    Msg: "PttCallStatusNotify",
                    CallStatus: channel.nCallStatus,
                    MonitorStatus: channel.nMoniterStatus,
                };
                for (j = 0; j < channel.nChannelIDs.length; j++) {
                    msgData.ChannelID = channel.nChannelIDs[j];
                    postMessage(msgData);
                }                
            }

            break;
        case 1:
            //单呼

            break;

        case 2:
            //临时组呼

            break;
    
        default:
            break;
    }
    

}

onWs_Poc_CalledRelease_Req = function (data) {
    var nCallID = data.nCallID;

    msg = new WsBaseMsg("Poc_CalledRelease_Rsp", 305);
    msg.Set("nCallID", nCallID);
    msg.Set("nRetCode", 0);
    msg.Send();

    var index = PttChannelList_CallID.get(nCallID);
    if (typeof index != 'undefined') {
        var channel = PttChannelList[index];

        if (channel.nSpeakStatus == 1) {
            if (PttSpeakingChannelNum != 0) {
                //停止采集
                PttSpeakingChannelNum--;
                if (PttSpeakingChannelNum == 0) {
                    Audio_Capture_Flag[0] = 0;
                    postMessage({
                        WsMsg: "AudioCaptureStop",
                    });
                    console.log("Poc Capture Stop"); 
                }
            }
        }

        channel.nSpeakStatus = 0;
        
        var msgData = {
            Msg: "PttTalkStatusNotify",
            Type: channel.nSpeakStatus,
            Cause: 0,
            Talker: "",
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }
        
        channel.nCallStatus = 0;
        
        if (channel.nMoniterStatus == 0) {
            channel.nCallID = 0;
            PttChannelList_CallID.delete(data.nCallID);
        }
        
        var msgData = {
            Msg: "PttCallStatusNotify",
            CallStatus: channel.nCallStatus,
            MonitorStatus: channel.nMoniterStatus,
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }
        
    }
}

onWs_Poc_SpeakApply_Rsp = function (data) {
    var nCallID = data.nCallID;
    var nRetCode = data.nRetCode;
    var index = PttChannelList_CallID.get(nCallID);
    if (typeof index != 'undefined') {
        var channel = PttChannelList[index];

        var msgData = {
            Msg: "PttTalkRequestRsp",
            Result: data.nRetCode
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }

        channel.nCallTalk = 0;

        if (nRetCode == 0) {
            //讲
            channel.nSpeakStatus = 1;

            if (PttSpeakingChannelNum == 0) {
                //启动采集
                Wasm_Rtp_SSRC++;
                Audio_Capture_Flag[0] = 1;
                postMessage({
                    WsMsg: "AudioCaptureStart",
                });
                console.log("Poc Capture Start");
            }
            PttSpeakingChannelNum++;

            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 0,
                Talker: "",
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }
        } if (nRetCode == 2) {
            //话权排队
            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 2,
                Talker: "",
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }
        } else {
            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 0,
                Talker: "",
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }
        }


    }


}

onWs_Poc_SpeakRelease_Rsp = function (data) {
    var nCallID = data.nCallID;
    var nRetCode = data.nRetCode;
    var index = PttChannelList_CallID.get(nCallID);
    if (typeof index != 'undefined') {
        var channel = PttChannelList[index];
        var msgData = {
            Msg: "PttTalkReleaseRsp",
            Result: data.nRetCode
        };
        for (j = 0; j < channel.nChannelIDs.length; j++) {
            msgData.ChannelID = channel.nChannelIDs[j];
            postMessage(msgData);
        }

        if (nRetCode == 0) {
            if (channel.nSpeakStatus == 1) {
                if (PttSpeakingChannelNum != 0) {
                    //停止采集
                    PttSpeakingChannelNum--;
                    if (PttSpeakingChannelNum == 0) {
                        Audio_Capture_Flag[0] = 0;
                        postMessage({
                            WsMsg: "AudioCaptureStop",
                        });
                        console.log("Poc Capture Stop"); 
                    }
                }
            }

            channel.nSpeakStatus = 0;

            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 0,
                Talker: "",
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }
        }
    }


}

onWs_Poc_SpeakApply_Notify = function (data) {
    var nCallID = data.nCallID;
    var index = PttChannelList_CallID.get(nCallID);
    if (typeof index != 'undefined') {
        var channel = PttChannelList[index];

        if (data.nCallingUserID == DcInfo.ID)
        {
            //讲
            channel.nSpeakStatus = 1;

            if (PttSpeakingChannelNum == 0) {
                //启动采集
                Wasm_Rtp_SSRC++;
                Audio_Capture_Flag[0] = 1;
                postMessage({
                    WsMsg: "AudioCaptureStart",
                });
                console.log("Poc Capture Start");
            }
            PttSpeakingChannelNum++;

            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 0,
                Talker: "",
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }
        }
        else
        {
            //听
            var nCallingUserID = data.nCallingUserID;
            var cCallingUserNum = data.cCallingUserNum;
            var cCallingUserName = data.cCallingUserName;
            var nCallingUserType = data.nCallingUserType;
            var nPriority = data.nPriority;
    
            channel.nSpeakStatus = 2;
    
            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 0,
                Talker: cCallingUserName,
                TalkerNum: cCallingUserNum,
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }
    
            Module._startSpeak(index);
        }

    }


}

onWs_Poc_SpeakRelease_Notify = function (data) {
    var nCallID = data.nCallID;
    var index = PttChannelList_CallID.get(nCallID);
    if (typeof index != 'undefined') {
        var channel = PttChannelList[index];

        var nForceRelease = data.nForceRelease;
        var cCallingUserNum = data.cCallingUserNum;

        if (cCallingUserNum == DcInfo.Number) {
            //自己话权超时
            if (PttSpeakingChannelNum != 0) {
                //停止采集
                PttSpeakingChannelNum--;
                if (PttSpeakingChannelNum == 0) {
                    Audio_Capture_Flag[0] = 0;
                    console.log("Poc Capture Stop");
                    postMessage({
                        WsMsg: "AudioCaptureStop",
                    });
                }
            }

            channel.nSpeakStatus = 0;

            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 1,
                Talker: "",
                TalkerNum: "",
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }

        } else {
            //他人释放

            channel.nSpeakStatus = 0;

            var msgData = {
                Msg: "PttTalkStatusNotify",
                Type: channel.nSpeakStatus,
                Cause: 0,
                Talker: "",
                TalkerNum: "",
            };
            for (j = 0; j < channel.nChannelIDs.length; j++) {
                msgData.ChannelID = channel.nChannelIDs[j];
                postMessage(msgData);
            }

        }
    }
}

onWs_Poc_MediaMsg_Rsp = function (data) {
    var msgData = {
        Msg: "MsgSendRsp",
        MsgIndex: data.cMsgIndex,
        Result: data.nRetCode,
    };
    postMessage(msgData);
}

onWs_Poc_MediaMsg_Req = function (data) {
    var msgData = {
        Msg: "MsgRecvNotify",
        MsgIndex: data.cMsgIndex,
        SenderType: data.nCallingUserType,
        SenderUserID: data.nCallingUserID,
        SenderUserNumber: data.cCallingUserNum,
        SenderUserName: data.cCallingUserName,
        SenderNickName: data.cCallingNickname,
        TargetType: data.nCalledType,
        TargetInfo: {

        },
        MsgType : data.nMsgType,
        MsgInfo: {

        },
    };

    var TargetType = data.nCalledType;
    var TargetInfo = {};
    if (TargetType == 0 || TargetType == 2) {
        TargetInfo.UserID = data.nCalledUserID;
        TargetInfo.UserNumber = data.cCalledUserNum;
        TargetInfo.UserName = data.cCalledUserName;
    }
    else if (TargetType == 1) {
        TargetInfo.GroupID = data.nCalledGroupID;
        TargetInfo.GroupNumber = data.cCalledGroupNum;
        TargetInfo.GroupName = data.cCalledGroupName;
    }
    else if (TargetType == 3) {
        TargetInfo.TempGroupID = data.cTempGroupID;
        TargetInfo.GroupNumberList = [];
        for (var i = 0; i < data.lGroupNumList.length; i++) {
            TargetInfo.GroupNumberList.push({
                GroupNumber:data.lGroupNumList[i]});
        }

        TargetInfo.UserNumberList = [];
        for (var i = 0; i < data.lUserNumList.length; i++) {
            TargetInfo.UserNumberList.push({
                GroupNumber:data.lUserNumList[i]});
        }
    }
    msgData.TargetInfo = TargetInfo;

    var MsgInfo = {};
    MsgInfo.MsgString = data.cMsgContent;
    MsgInfo.MsgAttachAddr = data.cMsgAttach;
    MsgInfo.Duration = data.nDuration;
    MsgInfo.LatitudeType = data.nLatitudeType;
    MsgInfo.Latitude = data.nLatitude;
    MsgInfo.LongitudeType = data.nLongitudeType;
    MsgInfo.Longitude = data.nLongitude;
    MsgInfo.LocDescription = data.cDescription;
    msgData.MsgInfo = MsgInfo;

    postMessage(msgData);
}

onWsTextMessage_Poc = function (msg) {
    switch (msg.msg) {
        case "Poc_MonitorGroup_Rsp":
            onWs_Poc_MonitorGroup_Rsp(msg.data)
            break;
        case "Poc_CallApply_Rsp":
            onWs_Poc_CallApply_Rsp(msg.data)
            break;
        case "Poc_CallRelease_Rsp":
            onWs_Poc_CallRelease_Rsp(msg.data)
            break;
        case "Poc_CalledSearch_Req":
            onWs_Poc_CalledSearch_Req(msg.data)
            break;
        case "Poc_CalledRelease_Req":
            onWs_Poc_CalledRelease_Req(msg.data)
            break;
        case "Poc_SpeakApply_Rsp":
            onWs_Poc_SpeakApply_Rsp(msg.data)
            break;
        case "Poc_SpeakRelease_Rsp":
            onWs_Poc_SpeakRelease_Rsp(msg.data)
            break;
        case "Poc_SpeakApply_Notify":
            onWs_Poc_SpeakApply_Notify(msg.data)
            break;
        case "Poc_SpeakRelease_Notify":
            onWs_Poc_SpeakRelease_Notify(msg.data)
            break;
        case "Poc_MediaMsg_Rsp":
            onWs_Poc_MediaMsg_Rsp(msg.data)
            break;
        case "Poc_MediaMsg_Req":
            onWs_Poc_MediaMsg_Req(msg.data)
            break;
    }
}


self.Module = {
    onRuntimeInitialized: function () {
        console.log("DispatchAudioCodec Onload");
    }
};

self.importScripts("DispatchAudioCodec.js");