SIPDroid.docx
AndroidSIPdroidProjectSharingMay232011Warning:Ifyouhaveanyquestions,adviceorsomethinge1.se,p1.ease1.etteamknow.FightTeamContents怎么学习androidSiPdrOid开源代码3SiPdroid流程详细分析3SiPdrOid会话遨请流程(一)4Sipdroid会话遨请流程(二)5SiPdrOid中像效劳器注用是如何实现的(一)7Sipdroid注册(二)-Sipdroid注册S1.P消息分析9SiPdroid注册(三)-注册返回结果的监听11SiPdroid数据发送流程13Sipdroid中的视频通话是如何实现的16SiPdroid中":步及到的吉媚?,挛1/18Sipdroid涉及到的冰议之RFC3261忽么学习androidSiPdroid开源代码?SiPdrOid目前有24个包,,140多个java文件.首先学习SipdrOid,至少辨明白SiPdroid是怎么玩的,实现的主要功能是什么,具体的流程操作是怎么执行的.先整理下下面的问题:一.Sipdroid的数据流程怎么发送的?参考文档:二.Sipdroid中果用的是什么协议?这点#常的重要,因为SiPdroid栗用的是RFC3261快议,大家看了RFC3261砂砍后,你就会明白.Sipdroid中对于MeSSage的料袋是如何完成,那么MeSSage的豺笠和生成这块所涉及到得设计模式和代码,你根本就可以弄明白参考文档:三,分块来弄Sipdroii1.首先Sipdroid的架构真是设计的是乖常的人性化以及牛X,为什么呢.功能块是完金独立前分开的,高内聚低耦合.SiPdrOid本身来说妩像一座非常施以攻克的堡全,但是咱们只要一块一块的攻.不久就发现整做城堡就被搞定了.一报来说,应该这么做:1.研究注册流程参考文档:2 .畀究会话遨请流程3 .视嵬通话通话流程4 .整理SiPdroid的架叫5 .畿取右用信息,比方视嫉和声音的描弊四库.协议的封装和设计模式等1.SipDroid模块简单分析U1.层,负责界面显示模块和界面时间传递Engine软件核心处理层.启动各种效劳,初始化软件卷数。处理各种U1.时间.港椅配置文件信息,保存全局居性变量.其中包括USerAgenProfi1.e(用户配置文件属性),USerAgent(用户事件处理).SiPdmidEngine(核心於理.所有的U1.的事件,参数设计.效劳的启动都由比文件调度.RCgiS1.CrAgent(注册效劳於理)SipS:提供所有Sip消息模型,所有SiP消息的处理流程,包括发送,接收,封装,解码等等网络传输:提供音频,视须信息的处理,此模块会对音残视须选行即时编诏解码,同时发送数据。同时还提供JSTNNAT透传技术。2.SipDroid流程分析:段号:拨号请求由U1.通过ReCeiVer需送信息交蛤SiPDrOidEngine处理,在SiPDrOidEngine做一些验证,然后交蛤USerMine处理。其中CaII(Stringtarget_ur1.,boo1.eanSend_anonymous)为判断是否匿名拨号再此方法中.会鹤立一个EXICndedCaI1.对象.以提供应SiD协议校使用,然后调用EX1.CndCdCa1.I的CaII方法处理.之后由EXtendedCaI1.的ca1.1.,调用EXtendedInv1.teD1.ti1.og来发送invite请求.由InViteDiaIog执行具体的invite调用InviteTransactionC1.ient的request方法,最后由InviteTransactionC1.ient发送request请求,在InViI。TranSaenOnCIient中会通过SiPPrOvider.来发送消息.井18开对IS口监听.来收SiP消息.发送消息主要有(UDP传输I1.dpTransportTCP传输TcpTransport)未电:在启动程序的时候会通itSipDroidEngine会根jg配置,创立-个PrOVider,这里用到UdP传输,创立一个UdPProVider.UdPProVer是一个Thread.创立的时候就会启动歧程.开始裳听收到的信息.当受到信息后.通过OnSerViCeTfnniniIted方法.把对象传出到UdPTranSPOrt,由UdPTranSPort处理,再通过onTransportTerminated方法传出到SipProvider定象.最后将在SipProvider的ProcessReceived.Message方法中处理收到的消息.最后从IiStenerS(InaP)中取出相应的IiStener.最后逋i±相应的IiStener中的OnRecciYcYcssagcO来父理具体Sip请求SiPdroid会话邀请流程(一)u«<A9f<QtoQfcWJO/wtewr>*<MQeM*w*9,MMM9*MtocyCTMtHrMtHUqunC>jvodr.fquM.u*to.u*11.uf1.cuct.u<Mon.dMCf9<r.ktM1台IMMIm9MM<XMtejIB片比较直观,但是衰建却不够详细,下面咱们详细分析下流程:会话送请所涉及到得突:SipdroidEngine(ca1.1)-UserAgcnt(ca1.1.)-ExtendedCa1.1(ca1.1)-InvitcDia1.og(invite)左边的代表涉及到的类,右段代表涉及到的核心方法.从左到右进行观察,左边的#UMr一个右边类费的,数作为自己的成员函数,就是SiPdrOidEngine有一个成员函数Ua.这不Ua是USerAgCnt类型的。*InviteDia1.og中的invite函数所做的事情也是非常的葡单,生成会话遵清的message然.后通过SipProvider发送出去就行了,那么发送完毕后,怎么实现对发送结果的IS听呢?其实官己猜想一下也猜想到效劳器返回数据会什么类型的?1.等待对方应答中2 .对方已经应容,进入双边通话模式中,同时手机这边开始声音和视须的采集.(声音和视领的票果,这个是核心中的核心啜,马上就要弄到这块了,兴奋田)3 .超时,对方无应答.在二的分析中,咱们用倒推的方法来分析下客户期在接受到效劳期的返回后,传遑到了印里去进行会话递清的结果了.客户端是怎么实现的.Sipdroid会话邀请流程(二)这里咱们要弄明白的是,SiPdroid会话遨谓的结果是在哪里进行监听的,以及这种效果是怎么实现的?发送消息统一是由Sipdroid的SendMCSSHge来进行发送的,然后返回的数据咱们可以在Sipdroid的OnReceiVeMessage中东进行获取。在SiPdroid注册结果的盅听:这篇文章中.咱们分析了下,首先会话的类51有很多种.注地会话,遨诂会话,遗话会话等等,因此在OnReCeiV。比,SSage中会对当前进行的会话进行判断,根据当前的会话1D,判惭出当前具体的会话类型,然后具体的会话类型通过谒用自己的成员函数(会话接口对象的接口方法)将数据会话接口对象.那么分析就简单了.便推下:1.型谓会话类是谁?2 .遨请会话美再会话接口是耶个.速请会话类会在获取到返回的数据后将获得到得数据传说给会话接口的接口方法中3 .分析会语接口中的方法是怎么处理邀请回话类返回的数据的?只要咱们这样分析,咱们就可以倒推出最终数据是怎么处理的,处理数据的核心其实还是更新UI界面和进行要辑判断,所以故终的於理必须是距离U1.界面近的美.会话逮请类是:InvjtcTransactionC1.icntinvit<?_tc-mr«Invit<?Trans-?icti1111CIient(sipprovider,invitereq.this):nvite.tc.request0;SipPcrvider在获取到数据后是怎么传给会话邀请美得?。个具体的会话类梆会继承一个抽象的女.这个牯象的会话类继承了SiPPrOVider1.iStener,在SipProvider获得message后,在OnReceiverMessage中,会通过执行SipProvider1.istener的接口方法将数据传给是实现了此接口的美,在会话邀请类中也就会传递给具体的会话类InYiteTransaction.每一个具体类在初雄化的时候,是必须有SiPPrOVider作为参数的,然后在通过SipProvider的addSiPProVider1.iStener(id.SipProYier1.istneiO指定会话类型和会话接11,还有SipProvider是唯一和独立的.因此一个会话中,只可能存在一种会话类里.InviteTranSaCtiOnCIien1.在OnReCeiVeNeSSaKe会将数据传递给transaction1istener,transactionIiStener其实就是InViteDia1.og,InviteDia1.og实匏了TransactionC1.ient1.istener,并在InViteTranSaCtionC1.inet的时候传递进去T,所以数据都是按照这样的烫辑往上传的,剩下的分析就非常简单了,大家自己分析吧.,所以最终的数据还是会回到UserAgent里面Ca1.1.1.istenerAdapter接口方法里面.这个方法还提巧的,谁发送的请求最后就由津最终耒处理这个巡回的结果.幡后%SipdroidEnginedt是这些核心类用来交互的一个地儿,然后咱们在启动的ACtHVity里面就只管理用SipdroidEngine提供的方法来控制指令就成了,牛X的樨柒,RegisterAgent敢先发送注册请求,最后的注册结果也得RegiSterAgent来处理.UserAgent最先发出会话邀请请求,最后的邀清结果也将USerAget来处理.Sipdroid中像效男总注号是如何实现的(一)关于Sipdroid是加何实现像效劳注册的?首先告诉大家代码块在哪里,注的的核心在RegiSterAgent类中的函弱register(inttime)中,注册的核心是:1. /Create11essagere(11nrfifi<*dbynv11rfrnjg)2. Messagereq=ssaeFactory.creat<ReuiSterRequest(sip_provider.3. target,tnrget.nmVanrAddress(ux¢rpro).qva1.ue,icsi):4.5. req.$0IExpiresHendcr(newExpircs1.kdcr(String.v111.ucf(expireti11r);注册稍微简单一点,因为只是需要客户潴和效劳器进行第定就行了,注册在SIP协议中称f昼记效劳.再向效劳提供商进行注册的时候,效劳提供商你会给我们一个UR1.这个UR1.在SiDdroid中被封装在SiPUR1.中的,这个UR1.写的格式如下:sip:,用户名+主机名。登陆效劳过程中的具体流程如下:程序启动便自动进行初始化在初始化的过程中.每隔一段的时间.客户爱这辿就要发送RegiSIer信息冷效劳器.RCgiS1.Cr中的信息包含了效劳提供商分配绐当前用户的S1.PUR1.,通俗点说,SIPURI就是富户墙的标识,这个标识是必须是唯一的:效劳器通过获得当首期户的UR1.便可以绑定这个用户.然后写到一个数据展中.在SIP协议中,这个叫做定位效劳(1.ocationserver)发送的请求的格式如下:E1.REGISTERBob->RegistrarREGISTERsip:registrar,SIP2.0Via:SIP2.OUI)Pbobspc.bi1.oxi.c<jh:5060;branch=z9hG1.bKnashds7Max-Fonrards:70To:Bob<sip:>Fr<三:Bob<sip:>tag=456248Ca1.1.-ID:8138176376S123(三98sdasdhO9CScq:1826REGISTERContact:<sip:>Expires:7200Contcnt-1.enRth:0注册会在2小时后超时。注册效劳器回应一个200()K,返回的信息包分如下:F2200OKRegistiir->BobS1P/2.0200OKVia:S1.1.,2.0/UDPbobspc.hiIoxi.co三:5060:branch=z9hG4hKnashds7;received-192.0.2.4To:Bob<sip:>;tag=2493k59kdFran:Bob<sip:>;tag=456248Ca1.1.-ID:81381763768423O«998sdasdhO9CSeq:1826R1.iGISTERContact:<si>z>Expires:7200Content-1.ength:0这里面涉及到很多参数.但是在RFe3261中如有详细的介绍。第二督将给大家介绍下,发送的注册消息体里面的。个拿数所代表的意义.Sipdroid注哥(二)-Sipdroid注册S1.P消息分析发送注班的message的结构作如下:F1.REGISTERBob->RegistrarREGISTERsip:registrar,SIP2.OVia:SIP2.0/UDPbobspc.hi1.oxi.coe:5OfiO:branch=z9hG4hKnash<is7Max-Forwards:70To:Bob<sip:>Frab:Bob<sip:>;tag=456248Ca1.1.-ID:8138I7637681.23(>g998sdasd09CSeq:1826REGISTERContact:<sip:>Expires:7200Content-1.ength:0下面咱们分析下.这里面的数据?里面的蛾格在RFC3261协议中已经有很滑足的说明了,只是比较的分散.上面的数据琳为:S1.P消息.S1.P分议是基于文本的机议,笠用UTF-8字Q鬃.SIP消息的大致限成是按照下密的格式进行的.一般消息=起始行*消息包头CR1.F/cr1.f也就是回车换行的意思消息正文起始行=请求行/状态行需要注虞的是,每一行结束后都要想回车换行rn,并且回车换行只允许加到求足,其余的位置不允许出现回车换行请求分析:Request-1.ine=MethodSPReqUeSt-UR1.SPSIP-VERSIONCR1.F/SP代表空格这个建请走行的格式.K1.hod定义了6中方法.REGISTER用于登记联系信息.INVITE,CK.CANCE1.用于陇立会话,BYE用于结束会话ReqUeS1.UR1.就是注册费分配给你的唯一的标识符.效劳器需要这个数据来于你进行绑定,S1.P-VERSIoN:请求和应答消息都包含的当前所有的S1.P版本,一皎写SIP/2.0就行了后面的那些参数:Toi三1.CsgCa1.ITD这些字段在SIP消息中被称为头城,这些头城包含了路由用的核心信息,比方消息地址.事物的唯一标志等ToRFC3261中的详匆解号在8.1.1.2拿节TO头域是第一个并且也是最先指定请求的逻辑接受地,或者是这个请求的用户或者资谏的addressof-rccord(这个语句解锋的有点抽象.To头城的写法雪SP表示空格)姓名(可用可不用)SPSIP1.R1.exa三p1.e:To:523851253<sip=>Froe详维的说明文档请畚加RFC32618.1.1.3章节Froe1.n头域包含了请求发起老的三辑标;,可以是用户的addrcss-of-record.Fr三头域的主要作用是用来实现对请求的检查,同时让效劳器选择一个规则对请求进行处理,同样Frg也可以包含一4请求人的姓名,使得注意的是,FrOm还必须包含一个TAG,这个tag是UAC(用户代理客户端,Sipdroid?其实也就是SiPdrOid程序令产生的)囱动给你产生的,Iag的详细描述在Rrc326119.9拿掌.FraB格式:Fr<:姓名(可有可无)SP<sips:>:tag=a48sC1.F(回车换行)RFC3261怖议中对于Can-ID写的已经是非常非常详细了,直接站出来给大家看:CauTD是一个在一系列消息中,区分一姐消息的唯一标志.在对话中的任一UR的所有请求和所有应答的CaU-ID必须一致。在UA的每次注母中,都应该是一样的.在会话外的时候.UAC发翅一个新的清求,这个Ca1.I-ID头域必须由UAC产生一个全局(在时间和空间上都是)唯一的Ca1.I-ID.除非是请求关的方法(method)指明了别的产生方式.所有的SIPUA都必须保证自己产生的CaIITD不会和其他UR产生的Ca1.1.-ID重夏。注意,如果是请求的重和尝试,则重新禁试的清求不被当作-个萦的请求,所以不需要新的CaU-ID(重蓊尝试的请求例如:认证冲突等等)。(见8.1.3.5我们强烈建议用雷码乱序随机串(RFCI75O2>来产生Ca1.1TD.实现中,可以用类似"IOca1.iMhcsJ这样的格式产生.Ca1.1.TD是大小与敏感的,并且通过的单字节/字节的来进行比收.采用密玛乱序随机率可以降低会话横奇听的时机,并且降低CaII-ID重复的冲突.不规定或者要求使用用户界面来选择输入Ca1.1.-ID头域的值.参见20.8节Cseq旭成格式:一系列的依序号自,方法Cseq头域是用来区分和做位事务的项序使用的,也由一个方法(method)和一系列的顺序号码组成。方法(method必题和请求的方法一致.君于对话外的非REG1.STER请求来说,项序号码可以是任意的.这个顺序号码必然可以由32位的无铝号整数式达,必须小于2.31。只要遵循了上逑指导方针,客户堵可以用任意的方法来产生这个CSeq头域。12.2.1.1节访建了在器话中如何创立CSeq例子:Cscq:4711INV1.TESipdroid注勒(=)-注哥返回结果的收听看Sipdroid的源码,发送注册BeSSag。后,是如何实现对注胎返回结果进行蜜听的?Sipdroid的数据发送流程是这样的:先直接蛤大家说下结果:对注册结果的故听是通过RegiSterAgent来进行监听的,因为RegiSterAgent实现了TransaciionC1.ient1.isienerO,通过/* Wh<MitheTransactionC1.ientgoesintothe,Cpeted"statereceivinga 2xxresponse*/pub1.icvoidr>nTransSccessResxnse(TransactionCIienttc.Messageresp):出数即可实现对返回结果的长听。那么按照SiIxirCid的数据发送流用.敢终获取到得结果是会传递到SipProvidcr中的OnRCCCiyCrMeSSagCO接口方法中,那么如何来实现将OnRBCBiVerMeSSUge中获琅到的结果传爱到Reg1.sterAgent中呢?这里其实迂真的提景服涉及SiPdrOid栗构的哥们的.大量的运用回调和接口来进行数据的转发.注册的流程是这样的:RegisterAgent-register(inttime)register函数主餐干两件事情,一是生成注册消息的message,另一个就是发送这个message,message可以看这转文章message发送成功后,那么彼将发送,发送是通过:/Transac1.ionC1.icnitt=newTransactinC1.ient(sip_providcr,req.this,30000):t.request();未完成的,roqu。St函数中有两行代码非常重要:sipprovider.addSipProvider1.istener(transactionid.this);connection_id=sipprovider.SendMessage(request):sipprov息后,通过OnReCRiVONoSSag。来接受消息,接受消息后就会进行一件事情的判断,判断发送message的"ansac1.ionid来判断此前发送的请求是用来注册,还是用来迸行会要的遨请呢?IranSaSi。1.id其实就是一个标识.标识会话类型的.会话类型包括:注册.通话请求等等然后在OnRccciveMessagc中进行判断。SipProvider中有如Tz的一个参数:/*1.istofprovider1.isteners*/1.1.asht<b1.e<IdentiTier.SipProvider1.Jstener>1.istenersnu1.1.;IiS1.CnCr3里面含有的对应关系为会话标识符-会话接口,比方注册过程就是注册会话标识符时应注册会话接口,所,只要是会话类型那么如然要实现会话接口SiprOVider1.188xr.会话有很多种,比方注册会话,通话会话,视密会话,加么SiPdroid的开发者就提取了他们的共同点,封装成了一个抽象的会话类型:pub1.icabstractc1.assTransactioniHp1.enentsSipProvider1.iste11erTimer1.istener:具体的会话都必须继承TranSaCtion.Transaction联认的已经维承了SipProvidor1.istener<>所以呢.具体的数据最终会返回到具体的会话类中,注册的会话类是:TranSaCtiCnC1.ien1.在TransactionC1.ient中道过OnReceiverMessaRc就可以获得效劳器返回的注册应答的数据,那么如果TransactionC1.ient如何将应答的数据返回给RegisterAgent呢?在TransactionC1.icnt初始化的时候t=newTransactionC1.ient(sipprovider,req.RegisterAgent.this.30000);ReKiSIerAKCnI将自己作为TranSaCtionCIiCnt1.iS1.enCr传送了TransactionC1.ient中,那么咱们就只需要在TransactionC1.ient的OnReCeiVerMCSSage中通过调用TriInSaCtion1.iStener的orTransProvisiona1Response(this,nsg),数据就返回到了RegisterAgent呢。理解了其实就非离的找单,大的小格根本就不会偏叁,以后所有的会话塞来取的这样的一套模式,言个会话都会维承TranSaCtion,每隔具体的会话都有一个具体的会话接D的或者会话客户提的,大家沿着这样的方向研究.相把根本就会弄的非常明白了,剌下的就是细节了.SiIXiroid数据发送流程pub1.icc1.assSipProviderimp1.ementsConfigurab1.e.Transport1.istener实现TranSgrt1.iStener的目的是什么?得单,为T实现回调.SipProvider实现了TranSPOrt1.iStenCr,记住-这个很重要.数据发送对应的流理对应如下,再这里假设message就是巳经生成好了的(实际上的IneSSago涉及到很多的协衩.播了很长时候.这会还在犯案)SipdroidProviderUdpTransport-Udpprovider-UdpSocket1.IdpSocket拥有我们最直接的两个方法:Sendreceive.方法原型如下:Receivesadatagra三packetfromthissocket./pub1.icvoidreceive(UdpPacketpkt)throwsjava.io.IOExceptionDatagramPacketdgrampkt.getDatagramPacket();socket,receive(dgram):pkt.SetDatiigraaPacket(dgram);)/*Sendsan1.DPpacketfromthissocket./pub1.icvoidsend(UdpPacketpkt)throwsjava.io.IOExceptionsocket,send(pkt.getDatagramPacket();IdpPrnvider褥有UdpSocket.依托UdPSOCket未实现数据的收发.但是receive是阻塞的。因此UdPPrQVider必然要继承thread来让自己成为线程:*Themainthread/pub1.icvoidrun()(bytehuf=newbyteBUFFERSIZE:/UdpPacket是DatciProgramPacket更深层次的一封装UdpPacketpacket=newIdpPacket(buf.buf.1.ength):Exceptionerror=nu1.1.:1.ongexpire=0:if(a1.ivc_ti(r»e>0)expire=Systen.CurrentTimeHi11is()+<1.iveti三e;try(/socket.SetSoTiineoui(sockct_tineout);modified/1.pwhi1.e(!stop)Itry(socket,receive(packet):catch(InterruptedIOExceptionie)(if(a1.ivetime>04&System.CurrentTimeMi11is()>expire)ha1.t0:continue;)if(packet,gthO>=inini(num_1.ength)(If(1.istener!=nu1.1.)1.istener.OnRcccivedPacket(this.DaCk<11):/严史注意这里if(H1.iVRJ加。>0)expire=System,CurrentTimeMiI1.isO+a1.ivetime:packet=newUdpPacket(buf.buf.1.ength):)catch(Exception¢)(error=c:stop=true:)isrunning三fa1.se;if(1.istener!=nu1.1.)1.istener.OnSRrViCeTenIinated(this,error);1.istener=nu1.1:)dpPonider中有一个MpProviderIis:oner,在UdpProvider进行初始化的时候便指定了SiproidIdpTransport-1.dpProvider-UdPSOCkRt(仔细看这个料始化的流程图.我给出它们的构造函散)pub1.iIdpProvider(UdpSocketsocket.UdpProvider1.istenerIiS1.E2】>UdPPn>vidcr构造函数pub1.icUdpTransport(intport.Transpor11.istener1.istener)/UdpTransProti®ft.UdpTransport实现TUdpProvider1.istenerudp=newIkipTransx>rt(host_port,host_ipaddr.Sipdroid,this):所以流程是怎么样的呢?案户端接收到效劳港返回的数据后,苦先是在UdPPrOVider的run里面的,上面的红色字体注意没.UdpPevidRr会用IkJpProvidcr1.istoner进行回调UdPrOVider1.iS1.CnCr是谁呢.是UdpTransport,S为CdpTransport实现TUdpProvider1.istenor接口,并在自己的构造函数中将自己作为参数传递给了UdpProvider.好了,数据己羟到了UdPTranSpOr1.手里了,看下面的UdPTranSPOr1.是如何实现的?/*WhenanewUDPdatagramisreceived./pub1.icvoidOnReceivedPacket(IJdpProviderudp,IdpPacketpacket)Messagemsg=newMessage(packet);msg.setRemoteAddress(packet.getIpAddressO.toString();msg.SetRemotePort(packet.getPort();msg.SCtTransport(PROTOUDP):if(1.istener!三nu1.1)1.istener.OnReceivedMessage(this9asg)UdpTiansport同样只需要调用OnReceivcdMcssage就可以将数据传回给SipProvidcr呢,这样SipProvider便茯得了从效劳落返回的信息,然后程序在获得信息后要钝的就是对耻SSage解析.并进行适配,确定手机客户提这边怎么来哨应。通俗点说是上级将接口传递给下级,下级在获得数据后便通过该接口将数据返回给上级.Sipdroid中的视获遵话是如何实现的?Sipdroid中的视嫉第理是怎么样的?涉及到视然传输的美是Org.sipdroid,sipua.Ui中的Videoanera.VideoCaneraNew.VideoCameraNew2.VideoPrewView,首先呢.双边的视频观者,走的还是数据机包,有数据报包的ip和瑞D就行了.那么发送视视领数据的方式和观看视版数指的方式是幼苗实现的呢?发送视匏数据就非畲的巧妙了,在AndrOid拍传的那祭文It中.采用的楚获取演令帧的数据并进行发送来实现的,详细文档见:这种方式的弊靖就是预览顿的编吗特别的消耗时间,说畅性差,而且对地吗器的效率的依耐性比敏高.但是SiMroid可以直接的从MediaRCeOrd里面巳泾生成好的初知数据中提取出H264/H263的数据.这些数据巴经短用了相应的编码,具体的怎么实现提取H263/H264的,我会在后面说,非常牛X哦.然后作为观看段呢?怎么观看呢,其实现看就2行代码,mVidcoFrac.SCtVideoVRI(Uri.pai,sc<"rtsp!r÷Rcccivcr.engine(mContcxt),RCtRemoteAddrO+*/*+Receiver,engine(Ineontext).getRemoteVideoO+,/sipdroid*);通过内置的VideoViS来通过RTSP来进行描故,那么也就是说效劳器会将传里的RTP的现发散霜流好装成RTSP的流传递给手机的Vide3ieu来实现观看,同样也不需要解码库,真是涉及独到啊.所以Siix1.roid开源代玛里只有声音的编码库,没有视演的维码库.Sipdroid中涉及到的皆须编券玛库?今天整理下SiPdroid中涉及我的音频和视瓶措解:码库,苫先呢咱们必须明白,SiPdroid中提供的可选的青党福码选项.和手机内置支持的音原编码方式。Sipdroid中提供的音频编码格式一共有6种:在org.sipdroid,codecs包中的Codecs类中:Codecs的成员函数包含了所有的Code类型,它们都渔承于Codecprivatestaticfina1.YeCtOrCodec>codecs-IKwVeCtOr<Codcc>0(Iadd<nevG722O)1/sdd(ne(rS1.1.K240);savespace(Vnti1.aEtinonIibraryforni1.bitratesgetsavai1.ab1.e?)/addGwvS1I.K160);/addOwvSI1.K80):add<n<va1.a*);/7PeMAadd(newu1.aw(),PQI1.,dd<ne<rSp9ex0);add<n<GSMO);add(nevBV16();11;聚集声音是由org.sipdroid,media包中的JAudio1.auncher来完成的JAudio1.aunchcr继承于Thread.在run方法中会在通话抗态下,不断的乐集声咨并进行声音的编码并发送,发送枭用的协议是RTP协设.SiPdrOid的开源工程中提供了4,音频格式的编码和解码库,这四种声音格式分别是G722.SPEI式.GSM.BV16.可梏的建,我的HTC2.2手机对这四种格氏都不支持,一般采用的是PCMU也就是G7HU格式的声音源,关于PcMU的详细介绍,请参加文档:语音通话过程中是通过UserAgent中的IaUnChMediaAppication未进行最先发出的:声音的编码格式应该是在没置的时候就进行指定和匹配好了,因为在IaunchMedia.App1.ication中Codecs.Mapc=Codecs.getCodec(Ioca1.sdp):是直接获取的.Map里曲就包含了CodCCs,这个COdeCS指定了具体的编码类.在我的HTC2.2中就是PeM;在Sipdroid中对应的声青编解码格式就是org.sipdroid,codecs包中的UIHW类了.当你大家测试的时候也可以再设置的时候固定死音频的幅码格式,这样好分析.Sipdroid涉及到的协衩之RFC3261Sipdroid是不断的向效劳器发送Message来实现和效劳之何的通信的,发送统一是由org.zoo1.u.sip.provider.SipProvider提供的SendMeSSage来实现的,因此在SiPdrOidEngine中的StartEngine初始化整个工程中的核心类的时候,这些类的构迨函数中都SipProvider这个参数.(设计的几个核心类包括:USerAge1.ItRegisierAgentKeepA1.iveSipUSerAgen1.PrOfiIe,这几个类中都拥有SipProvide叁数.它多郡指向的是同一SipProvider对象)下面未扯下谈:既然数据都是由SiPPr。Vider来进发送和接受的,那么根