SIP呼叫录音流程示例说明SRC/SRS-RFC8068,呼叫转接,呼叫保持重启等场景中的录音数据交互流程

在IP语音通信呼叫中,我们最关注的两大核心数据是信令数据和RTP语音的数据。当然,目前主流的信令是SIP协议,我们已经介绍了很多,也介绍了关于RTP协议方面的内容。针对RTP语音来说,除了关注其RTP处理流程以外,我们还要关注RTP或者语音的录音输出处理。

呼叫录音的重要性是不言而喻的,在未出现语音呼叫和语音识别技术结合的场景之前,语音录音的应用仅仅限于人工监听或者人工质检,标准化程度比较低,针对海量数据的处理能力也极其有限。因为语音识别技术和大数据的赋能,对语音数据的深加工也是用户的必然要求,通过语音识别引擎和大数据云计算的支持,可以进一步提高海量数据的处理效率,增加用户体验实时性。但是,一般企业办公通信或者在呼叫中心场景中,呼叫流程存在多种交互方式,呼叫流程变化很大,有时一个呼叫会话可能涉及到不同接听对象。如果在未理解呼叫流程的前提下,简单分析一个语音文件很难全面反映实际接听业务完整流程,最终可能导致数据分析结果和业务的脱节问题,形成了各种信息孤岛,造成了资源浪费和决策失控。因此,读者如果要掌握管理整个呼叫中心业务录音场景,需要全面了解呼叫录音或者会话录音的呼叫流程。

在针对基于SIP协议会话录音的呼叫流程技术细节方面,RFC8068提供了一个相对比较全面的详解说明,读者可以根据此规范来进一步了解SIP呼叫录音的流程。在以下的针对RFC8068的详解中,我们将针对RFC8068结合SIP呼叫录音规范SIPREC进行说明和讨论。以下讨论内容中包括关于SIPREC规范,以及基于SIPREC规范支持的几种会话录音流程场景说明。

SIP呼叫录音流程示例说明SRC/SRS-RFC8068,呼叫转接,呼叫保持重启等场景中的录音数据交互流程
SBC-SIPREC录音服务器-宇高

1-关于RFC8068规范和SIPREC规范背景说明

关于RFC8068的基础来自于SIP呼叫录音规范-SIPREC,关于SIPREC协议规范的讨论涉及了SIPREC客户端(SRC)和服务器端(SRS)。笔者已经对此规范做了完整的讨论,并且对其它呼叫录音方式存在的问题做了讨论,用户可以先了解关于SRC和SRS流程进一步获得基本的关于SIPREC知识。一些重点行业用户和比较大型的SBC(比如奥科SBC,Ribbon的SBC都支持了SIPREC,宇高SIPREC服务器)应用场景中,SIPREC是一个必要支持功能。因此,我们需要对这些相关技术协议做全面了解。

2-关于RFC8068

本协议主要罗列从SRC和SRS的会话流程以及双方提取的metadata数据。通过metadata才能真正绑定会话关系。在本文档中,笔者会使用很多简称格式来表达特定的概念,这些都是metadata的描述。关于metadata的具体属性,我们这里不会做详细说明,用户可以参考RFC7856规范进行了解,在RFC7856中对每个metadata属性有非常明确的描述。首先我们介绍呼叫流程和metadata收发的流程。

SIP呼叫录音流程示例说明SRC/SRS-RFC8068,呼叫转接,呼叫保持重启等场景中的录音数据交互流程

在以上呼叫流程中,流程忽略了SIP信令的细节(例如ACK,re-INVITE或BYEs),我们这里仅了解从F1到Fn-1的flow,主要说明metadata的概要数据收发,包括以下四个主要呼叫大类是否混音的说明。

  1. SRC对SRS服务器发送未混音的媒体流,包括了SRC是一个SIP UA或者B2UA的场景。
  2. SRC对SRS服务器发送已混音的媒体流,这里的SRC是一种以会议模式发送的场景。
  3. SRC支持了一个持续的RS(录音会话),以上两种类别的一个混合模式。
  4. 特殊呼叫控制模式(类似于塔式控制模式,应用于交易所,拍卖行的控制各种交易时所需要的呼叫)。这种呼叫控制模式是一种分布式的交换机控制模式,可以支持并行呼叫处理。

3-呼叫录音中SRC未混音发送流程

在未混音发送流程中,包括了四种呼叫示例(在以下的示例中,因为流程中的xml交互数据太多,因此呼叫流程交互数据忽略。),这四种示例包括:

3.1-基本呼叫流程未混音。呼叫方和被呼叫方各自发送自己的语音和视频,都基于同样的通信会话(Communication Session(RFC7865))。在此示例中,SRC是一个基于呼叫方和被呼叫方之间的B2BUA实体,SRC没有对媒体流进行混音,直接发送到了SRS服务器端。

3.2-呼叫保持和重启。一个在Alice和Bob创建的呼叫,创建了RS进行录音。Bob将Alice的呼叫置于呼叫保持状态,然后重新启动呼叫,这个流程是刚才使用的同一RS的一个部分。读者这里要注意,recv和send来指示呼叫参与者是否继续进行媒体流交互。这个xml数据包括了hold数据和resume的数据。

呼叫保持中的hold数据,
<?xml version="1.0" encoding="UTF-8"?>
        <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
          <datamode>partial</datamode>
            <participantstreamassoc
           // Alice仅接收不发送 ,无发送           
             participant_id="srfBElmCRp2QB23b7Mpk0w=="> // 关联Alice
             <recv>8zc6e0lYTlWIINA6GR+3ag==</recv>
             <recv>EiXGlc+4TruqqoDaNE76ag==</recv>
            </participantstreamassoc>
            <participantstreamassoc
           // Bob仅发送不接收,无接收
                       
             participant_id="zSfPoSvdSDCmU3A3TRDxAw=="> // 关联Bob
              <send>8zc6e0lYTlWIINA6GR+3ag==</send>
              <send>EiXGlc+4TruqqoDaNE76ag==</send>
             </participantstreamassoc>
           </recording>
           
// 呼叫重启数据,呼叫保持以后重新启动RTP通话,双方都支持接收和发送
 <?xml version="1.0" encoding="UTF-8"?>
        <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
          <datamode>partial</datamode>
            <participantstreamassoc
             participant_id="srfBElmCRp2QB23b7Mpk0w==">
             <send>i1Pz3to5hGk8fuXl+PbwCw==</send>
             <send>UAAMm5GRQKSCMVvLyl4rFw==</send>
             <recv>8zc6e0lYTlWIINA6GR+3ag==</recv>
             <recv>EiXGlc+4TruqqoDaNE76ag==</recv>
            </participantstreamassoc>
            <participantstreamassoc
             participant_id="zSfPoSvdSDCmU3A3TRDxAw==">
              <send>8zc6e0lYTlWIINA6GR+3ag==</send>
              <send>EiXGlc+4TruqqoDaNE76ag==</send>
              <recv>i1Pz3to5hGk8fuXl+PbwCw==</recv>
             <recv>UAAMm5GRQKSCMVvLyl4rFw==</recv>
             </participantstreamassoc>
           </recording>

3.3-呼叫转接示例(基于re-INVITE或者Refer转接方式)。Alice和Bob创建呼叫,然后通过SRC作为一个B2BUA发送xml数据。然后Alice发起一个呼叫转接,转接完成后,SRC对SRS发送一个呼叫参与者修改的xml数据。在这个示例中,Alice退出转接,最终Bob和Carol创建了通话,SRC开始对Bob和Carol进行录音。这里有两种转接处理方式,一种是在同样的会话中进行转接,使用re-INVITE进行转接处理。在这种转接中,Alice退出会话,同时Carol加入到会话中。


<?xml version="1.0" encoding="UTF-8"?>
      <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
             <datamode>partial</datamode>
              <session session_id="hVpd7YQgRW2nD22h7q60JQ==">
           <sipSessionID>3363127f0d084c10876dddd4f8e5eeb9
           ;remote=2272bb7e70fe41dba0025ae9a26d54cf</sipSessionID>
        </session>
         <participant
            participant_id="Atnm1ZRnOC6Pm5MApkrDzQ==">
            <nameID aor="sip:carol@example.com">
             <name xml:lang="it">Carol</name>
           </nameID>
         </participant>
         <participantsessionassoc
            participant_id="Atnm1ZRnOC6Pm5MApkrDzQ=="
            session_id="hVpd7YQgRW2nD22h7q60JQ=="> // Carol加入这个会话
            <associate-time>2013-12-16T23:41:07Z</associate-time>
         </participantsessionassoc>
         <participantsessionassoc
            participant_id="srfBElmCRp2QB23b7Mpk0w=="
            session_id="hVpd7YQgRW2nD22h7q60JQ=="> // Alice指示退出会话
             <disassociate-time>2013-12-16T23:41:07Z</disassociate-time>
          </participantsessionassoc>
          <participantstreamassoc
             participant_id="zSfPoSvdSDCmU3A3TRDxAw=="> // Bob
            <send>8zc6e0lYTlWIINA6GR+3ag==</send>
            <send>EiXGlc+4TruqqoDaNE76ag==</send>
            <recv>60JAJm9UTvik0Ltlih/Gzw==</recv>
            <recv>AcR5FUd3Edi8cACQJy/3JQ==</recv>
         </participantstreamassoc>
         <participantstreamassoc
            participant_id="Atnm1ZRnOC6Pm5MApkrDzQ=="> // Carol
           <send>60JAJm9UTvik0Ltlih/Gzw==</send>
           <send>AcR5FUd3Edi8cACQJy/3JQ==</send>
           <recv>8zc6e0lYTlWIINA6GR+3ag==</recv>
           <recv>EiXGlc+4TruqqoDaNE76ag==</recv>
           <associate-time>2013-12-16T23:42:07Z</associate-time>
         </participantstreamassoc>
    </recording>

另外一种是使用一个新的会话进行转接处理,使用Refer转接方式进行处理。在SRC创建的同一组CS中,使用一个新的会话来处理呼叫转接。在这种处理方式中,SRC首先发一个option数据消息,通知Alice退出就的CS会话。然后,SRC可以通过INVITE携带一个新的session,表示不再使用旧的会话。

  <?xml version="1.0" encoding="UTF-8"?>
      <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
             <datamode>partial</datamode>
         <session session_id="hVpd7YQgRW2nD22h7q60JQ==">
         // 指示和这个会话相关的都将关闭停止。停止时间如下
           <stop-time>2010-12-16T23:41:07Z</stop-time> 
         </session>
         <participantsessionassoc
            participant_id="srfBElmCRp2QB23b7Mpk0w=="
            session_id="hVpd7YQgRW2nD22h7q60JQ==">
             <disassociate-time>2010-12-16T23:41:07Z</disassociate-time>
          </participantsessionassoc>
         <participantsessionassoc
            participant_id="zSfPoSvdSDCmU3A3TRDxAw=="
            session_id="hVpd7YQgRW2nD22h7q60JQ==">
            <disassociate-time>2010-12-16T23:41:07Z</disassociate-time>
          </participantsessionassoc>
    </recording>

然后因为通过Refer方式处理的转接,所以SRC在转接后发送一个指示修改的xml数据。在这个示例中,我们假设SRC使用了同样的CS继续进行通话流程。xml中的sipSessionID节点数据表示Bob和Carol在UUID的配对中。


<?xml version="1.0" encoding="UTF-8"?>
       <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
              <datamode>complete</datamode>
          <session session_id="bfLZ+NTFEeCNxQTuRyQBmw==">
          // 本地和远端配对,使用新的会话处理
            <sipSessionID>3363127f0d084c10876dddd4f8e5eeb9
            ;remote=2272bb7e70fe41dba0025ae9a26d54cf
            </sipSessionID>
            <start-time>2010-12-16T23:41:07Z</start-time>
          </session>
          <participant
              participant_id="zSfPoSvdSDCmU3A3TRDxAw==">
              <nameID aor="sip:Bob@biloxy.com"/>
           </participant>
           <participant
             participant_id="Atnm1ZRnOC6Pm5MApkrDzQ==">
             <nameID aor="sip:carol@example.com"/>
          </participant>
           <stream stream_id="60JAJm9UTvik0Ltlih/Gzw=="
              session_id="bfLZ+NTFEeCNxQTuRyQBmw==">
              <label>96</label>
          </stream>

3.4-呼叫挂机。当呼叫参与方的任何一方如果挂机的话,SRC会对SRS发送指示数据表示双方挂机。


 <?xml version="1.0" encoding="UTF-8"?>
       <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
              <datamode>partial</datamode>
          <session session_id="hVpd7YQgRW2nD22h7q60JQ==">
          // 停止时间
             <stop-time>2010-12-16T23:41:07Z</stop-time>
          </session>
          <participantsessionassoc
             participant_id="srfBElmCRp2QB23b7Mpk0w=="
             session_id="hVpd7YQgRW2nD22h7q60JQ==">
             // 停止关联
            <disassociate-time>2010-12-16T23:41:07Z</disassociate-time>
           </participantsessionassoc>

          <participantsessionassoc
             participant_id="zSfPoSvdSDCmU3A3TRDxAw=="
            session_id="hVpd7YQgRW2nD22h7q60JQ==">
            // 停止关联
             <disassociate-time>2010-12-16T23:41:07Z</disassociate-time>
           </participantsessionassoc>
      </recording>

4-呼叫录音中SRC已混音发送流程

在混音模式发送流程中,发出流程中的SRC是会议模式的一个部分,SRC可以是focus或者会议参与方。这里的SRS服务器端可以是一个SIP用户代理或者MEDIACTRL架构的部分实体组件。因为挂机信息和前面的未混音处理方式一样,所以这里的所有挂机数据都未列出。

SIP呼叫录音流程示例说明SRC/SRS-RFC8068,呼叫转接,呼叫保持重启等场景中的录音数据交互流程

4.1-基本呼叫流程带混音发送场景。这里的呼叫参与方是Alice和Bob, 他们都是在一个CS中的部分组件实体。在这种呼叫模式下,每个呼叫参与方会进入到会议模式环境中,也就是通常说的MCU(Multipoint Control Unit (MCU))中。在此会议模式中,每个呼叫参与方的媒体流都会被其他呼叫或者会议参与方接收。以下是通过SRC发起的INVITE带混音数据,发送到SRS服务器端。这里要注意的是,xml中包括了两种Session-IDs. 一种是关联介于Alice和会议Focus之间的SIP会话,另外一种Session-ID是关联介于Bob和会议focus之间的SIP会话。另外,因为Alice和Bob都是呼入到了会议模式,因此,他们的Session-ID都不相同。


<?xml version="1.0" encoding="UTF-8"?>
       <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
              <datamode>complete</datamode>
         <session session_id="hVpd7YQgRW2nD22h7q60JQ==">
            <sipSessionID>fa3b60f27e91441e84c55a9a0095f075
             ;remote=a358d2b81a444a8c8fb05950cef331e7</sipSessionID>
             <sipSessionID>ca718e1430474b5485a53aa5d0bea45e
             ;remote=68caf509b9284b7ea45f84a049febf0a</sipSessionID>
             <start-time>2010-12-16T23:41:07Z</start-time>
         </session>
          <participant
             participant_id="srfBElmCRp2QB23b7Mpk0w==">
            <nameID aor="sip:alice@atlanta.com">
             <name xml:lang="it">Alice</name>
            </nameID>
         </participant>
          <participant
              participant_id="zSfPoSvdSDCmU3A3TRDxAw==">
              <nameID aor="sip:bob@biloxy.com">
               <name xml:lang="it">Bob</name>
            </nameID>
          </participant>
          <stream stream_id="i1Pz3to5hGk8fuXl+PbwCw=="
              session_id="hVpd7YQgRW2nD22h7q60JQ==">
              <label>96</label>
          </stream>
          // 各自的会议关联session-ID
          <participantsessionassoc
             participant_id="srfBElmCRp2QB23b7Mpk0w=="
             session_id="hVpd7YQgRW2nD22h7q60JQ==">
           <associate-time>2010-12-16T23:41:07Z</associate-time>
          </participantsessionassoc>
          <participantsessionassoc
              participant_id="zSfPoSvdSDCmU3A3TRDxAw=="
       session_id="hVpd7YQgRW2nD22h7q60JQ==">
             <associate-time>2010-12-16T23:41:07Z</associate-time>
          </participantsessionassoc>
          <participantstreamassoc
             participant_id="srfBElmCRp2QB23b7Mpk0w==">
             <send>i1Pz3to5hGk8fuXl+PbwCw==</send>
             <recv>i1Pz3to5hGk8fuXl+PbwCw==</recv>
          </participantstreamassoc>

          <participantstreamassoc
              participant_id="zSfPoSvdSDCmU3A3TRDxAw==">
            <send>i1Pz3to5hGk8fuXl+PbwCw==</send>
            <recv>i1Pz3to5hGk8fuXl+PbwCw==</recv>
          </participantstreamassoc>
     </recording>

4.2-带SRC混音的呼叫保持和重启流程。这个示例和前面介绍的主要流程都是相同的。在呼叫保存中,呼叫启动时,SRC就开始混音,双方的xml数据分别是发送和接收。如果双方开启了重新通话后,SRC对SRS发送INVITE更新后,双方的xml数据会更新为都能同时发送和接收。


//呼叫保持阶段
<?xml version="1.0" encoding="UTF-8"?>
       <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
              <datamode>partial</datamode>
              <stream stream_id="i1Pz3to5hGk8fuXl+PbwCw=="
              session_id="hVpd7YQgRW2nD22h7q60JQ==">
              <label>96</label>
          </stream>
          <participantstreamassoc
             participant_id="srfBElmCRp2QB23b7Mpk0w==">
              <recv>i1Pz3to5hGk8fuXl+PbwCw==</recv>
          </participantstreamassoc>
          <participantstreamassoc
              participant_id="zSfPoSvdSDCmU3A3TRDxAw==">
            <send>i1Pz3to5hGk8fuXl+PbwCw==</send>
          </participantstreamassoc>
     </recording>
 // 呼叫重新启动后
 <?xml version="1.0" encoding="UTF-8"?>
       <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
              <datamode>partial</datamode>
              <stream stream_id="i1Pz3to5hGk8fuXl+PbwCw=="
              session_id="hVpd7YQgRW2nD22h7q60JQ==">
              <label>96</label>
          </stream>
 // 双方可以同时send和recv
         <participantstreamassoc
             participant_id="srfBElmCRp2QB23b7Mpk0w==">
             <send>i1Pz3to5hGk8fuXl+PbwCw==</send>
             <recv>i1Pz3to5hGk8fuXl+PbwCw==</recv>
          </participantstreamassoc>
          <participantstreamassoc
              participant_id="zSfPoSvdSDCmU3A3TRDxAw==">
            <send>i1Pz3to5hGk8fuXl+PbwCw==</send>
           <recv>i1Pz3to5hGk8fuXl+PbwCw==</recv>
         </participantstreamassoc>
     </recording>  

4.3-在会话中加入或者丢弃一个会议参与方。读者可能都知道,在一般电话的会议模式中,会议期间可能仍然有新的用户进入,也可能有其他会议参与方退出会议。这些处理刚才同样也可以应用在会话录音中,无论是新进入者还是退出的用户,都需要记录其会话数据。这种环境中,SRC可以是会议的focus或者会议参与者。这里假设,Alice和Bob已经在会议中,第三方Carol加入到会议中,然后SRC对其他人发送xml数据指示有新的会议人员加入。


<?xml version="1.0" encoding="UTF-8"?>
       <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
              <datamode>partial</datamode>
              <session session_id="hVpd7YQgRW2nD22h7q60JQ==">
            <sipSessionID>fa3b60f27e91441e84c55a9a0095f075
             ;remote=a358d2b81a444a8c8fb05950cef331e7</sipSessionID>
             <sipSessionID>ca718e1430474b5485a53aa5d0bea45e
             ;remote=68caf509b9284b7ea45f84a049febf0a</sipSessionID>
             <sipSessionID>497c0f13929643b4a16858e2a3885edc
             ;remote=0e8a82bedda74f57be4a4a4da54167c4</sipSessionID>
         </session>
         // carol 加入会议
              <participant
             participant_id="Atnm1ZRnOC6Pm5MApkrDzQ==">
             <nameID aor="sip:carol@example.com">
              <name xml:lang="it">Carol</name>
              
  // 一段时间后,Alice退出会议
              
 <?xml version="1.0" encoding="UTF-8"?>
       <recording xmlns='urn:ietf:params:xml:ns:recording:1'>
              <datamode>partial</datamode>
              <session session_id="hVpd7YQgRW2nD22h7q60JQ==">
             <sipSessionID>ca718e1430474b5485a53aa5d0bea45e
             ;remote=68caf509b9284b7ea45f84a049febf0a</sipSessionID>
             <sipSessionID>497c0f13929643b4a16858e2a3885edc
             ;remote=0e8a82bedda74f57be4a4a4da54167c4</sipSessionID>
         </session>
              <participantsessionassoc
             participant_id="srfBElmCRp2QB23b7Mpk0w=="
             session_id="hVpd7YQgRW2nD22h7q60JQ==">
             // 退出会议
           <disassociate-time>2010-12-16T23:41:07Z</disassociate-time>
          </participantsessionassoc>
      </recording>

4.4-挂机处理流程。挂机流程大概和前面的挂机流程类似。首先通知服务器端停止会话录音,在xml数据中发送会话停止录音时间和挂机时间。

5-塔式呼叫控制模式。特殊行业中使用的一种录音模式,一些股票交易所或者拍卖行使用这种录音方式进行录音。不像现在基于大数据云部署的电话系统的处理方式,在传统的分布式交换机部署场景中,存储空间和系统是非常昂贵的,也不能很灵活地实现扩展。因此,为了实现最优的存储设置,推荐使用的方式是将来自于不同的呼叫终端的多并发呼叫进行混音。每个呼叫作为一个CS,将这些呼叫汇聚成一个单个的RS。这样就可以实现将多个CS汇聚为一个RS,可以从SRC客户端发送到SRS服务器端。

这种录音模式环境中,存在三种录音的可能性:

1)CS1和CS2都使用同样的focus混音,这个被使用的focus是在每个CS中是一个SRC。

2)CS1 SRC是一个focus,其他的会议参与方CS都是会议模式的SRC。混音依赖于CS1来处理。

3)会议中,CS1和CS2都是SRC。

在RFC8068-3.5章节中,规范作者仅讨论了第一种模式和XML数据,其他可能性未做进一步描述。因为是一种特殊场景,而且无太多细节数据,这里不再讨论。读者如果有兴趣的话,可以参考RFC8068继续学习。

总结

笔者针对RFC8068规范为读者解读了关于SIP协议会话录音的呼叫呼叫转接,呼叫保持重启等场景如何录音。这些会话录音包括了未混音和混音状态下的数据收发的处理。主要针对会话数据XML数据中的数据变动进行了解读。在这些交互数据中,会话-ID,参与方数据ID,挂机时间都有非常丰富的关联性。和传统录音方式相比,通过这些数据的支持可以更好和SIP信令数据进行深度绑定,最终实现用户数据同步。但是,在本规范中仅讨论了几种呼叫用例,其实在实际用户场景中,特别是基于终端-SBC(SRC-SRS)-IPPBX的用户场景中,还有更多呼叫业务需要处理,而且这些业务和IPPBX端绑定比较紧密,最终流程实现仍然需要大家进一步去优化。

获得关于SIP/IP语音相关技术分享-加入“SIP实验室技术分享群“-QQ号-589995817

参考资料:

www.sip.org.cn

SIPREC

www.dinstar.cn

https://www.rfc-editor.org/rfc/rfc8068.html

https://www.rfc-editor.org/rfc/rfc7245.html

https://www.rfc-editor.org/rfc/rfc7865

作者:james.zhu
来源: SIP实验室

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论