加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
mainpage.dox 187.06 KB
一键复制 编辑 原始数据 按行查看 历史
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127
/*!
* \mainpage Janus - General purpose WebRTC server
*
* \par Developer Documentation for the Janus WebRTC server
* This is the main developer documentation for the Janus WebRTC
* Server, generated with the help of
* <a href="http://www.doxygen.org">Doxygen</a>. Make sure you
* check the \ref DEPS before attempting a compilation. If you are
* interested in how to compile, install and use Janus,
* checkout the \ref README information. A \ref FAQ page is also available.
*
* \par A general purpose WebRTC server
* The Janus WebRTC Server has been conceived as a <tt>general purpose</tt>
* server. As such, it doesn't provide any functionality per se
* other than implementing the means to set up a WebRTC media communication
* with a browser, exchanging JSON messages with it, and relaying RTP/RTCP
* and messages between browsers and the server-side application logic they're attached to. Any specific
* feature/application needs to be implemented in server side plugins,
* that browsers can then contact via the Janus core to take advantage of
* the functionality they provide. Example of such plugins can be
* implementations of applications like echo tests, conference bridges,
* media recorders, SIP gateways and the like.
*
* The reason for this is simple: we wanted something that would have a
* <tt>small footprint</tt> (hence a C implementation) and that we could only
* equip with what was <tt>really needed</tt> (hence pluggable modules). That is,
* something that would allow us to deploy either a full-fledged WebRTC
* server on the cloud, or a small nettop/box to handle a specific use case.
*
* \par Architecture and APIs
* The core of the server is specified in the \ref core section. The protocols
* implemented in the Janus core are listed in the \ref protocols group
* instead. A list of plugins provided out of the box by Meetecho are
* documented in the \ref pluginslist page: these plugins can be changed
* or extended to match your requirements, or just used as a simple
* reference should you be interested in writing a new plugin from
* scratch (and you're definitely welcome to!). A \ref pluginapi to
* create new plugins, or understand how they're conceived, is documented
* as well. A documentation on the available API tranports and the
* HTTP/WebSocket JavaScript API to use Janus and the plugins it
* makes available in your web application can be found in the \ref JS
* and \ref rest pages. New API transports can be created referring to
* the \ref transportapi page. If you're interested in monitoring Janus
* resources, you can refer to the \ref admin page. Event handler
* plugins can also be used for the purpose: refer to the \ref eventhandlerapi
* page if you're interested in creating your own. Janus also supports
* \ref recordings out of the box, so check the related documentation
* to know more about how that works.
*
* Finally, some information on how to deploy Janus and your web
* applications that want to make use of it are provided in the \ref deploy
* page. If you're interested in starting Janus as a service/daemon rather
* than launching it normally, check the information provided in the
* \ref service page. Some additional \ref resources are also listed in
* case you're interested in talking to Janus from different languages
* and platforms.
*
* To conclude, the \ref debug page contains info on how you can help us
* fixing issues you might encounter along the road.
*
* \section copyright Copyright and author
*
* Janus WebRTC Server © 2014-2019 <a href="http://www.meetecho.com/">Meetecho</a> (http://www.meetecho.com/)
*
* \author Lorenzo Miniero <lorenzo@meetecho.com> ( \ref CREDITS )
*
* \section license License
* This program is free software, distributed under the terms of
* the GNU General Public License Version 3. For more details and licensing
* options, including a commercial license, see the \ref COPYING page.
*
*/
/*! \page DEPS Dependencies
*
* The application and the plugins depend on the following open source
* software and libraries, so make sure you install the related development
* versions before attempting a compilation:
*
* - \b GLib: http://library.gnome.org/devel/glib/
* - \b pkg-config: http://www.freedesktop.org/wiki/Software/pkg-config/
* - \b gengetopt: http://www.gnu.org/software/gengetopt/ (command line)
* - \b Jansson: http://www.digip.org/jansson/ (JSON)
* - \b libconfig: https://hyperrealm.github.io/libconfig/ (configuration files)
* - \b libnice: http://nice.freedesktop.org/wiki/ (ICE/STUN/TURN, at least v0.1.15 suggested, master recommended)
* - \b OpenSSL: http://www.openssl.org/ (DTLS, at least v1.0.1e)
* - \b libsrtp: https://github.com/cisco/libsrtp (SRTP, at least v1.5 suggested)
* - \b usrsctp: http://code.google.com/p/sctp-refimpl/ (\c optional, Data Channels)
* - \b libmicrohttpd: http://www.gnu.org/software/libmicrohttpd/ (\c optional, Web server)
* - \b libwebsockets: https://libwebsockets.org/ (\c optional, WebSockets)
* - \b rabbitmq-c: https://github.com/alanxz/rabbitmq-c (\c optional, v1.0.4, RabbitMQ)
* - \b paho.mqtt.c: https://eclipse.org/paho/clients/c (\c optional, v1.1.0 for MQTT v3.1 & v3.1.1 or v1.3.0 for MQTT v5)
* - \b nanomsg: https://nanomsg.org/ (\c optional, Nanomsg)
* - \b Sofia-SIP: http://sofia-sip.sourceforge.net/ (\c optional, only needed for the SIP plugin)
* - \b libopus: http://opus-codec.org/ (\c optional, only needed for the bridge plugin)
* - \b libogg: http://xiph.org/ogg/ (\c optional, only needed for the voicemail plugin)
* - \b libcurl: https://curl.haxx.se/libcurl/ (\c optional, only needed for the TURN REST API,
* RTSP support in the Streaming plugin and the sample Event Handler plugin)
* - \b Lua: https://www.lua.org/download.html (\c optional, only needed for the Lua plugin)
* - \b npm: https://docs.npmjs.com/ (\c optional, used during build for generating JavaScript modules)
*
*/
/*! \page JS JavaScript API
* Janus exposes, assuming the HTTP transport has been compiled, a
* pseudo-RESTful interface, and optionally also WebSocket/RabbitMQ/MQTT/Nanomsg/UnixSockets
* interfaces as well, all of which based on JSON messages. These
* interfaces are described in more detail in the \ref plainhttp \ref WS
* \ref rabbit \ref apimqtt \ref apinanomsg and \ref unix documentation respectively, and all allow clients to
* take advantage of the features provided by Janus and the functionality
* made available by its plugins. Considering most clients will be web browsers,
* a common choice will be to rely on either the REST or the WebSockets
* interface for the purpose. To make things easier for web
* developers, a JavaScript library (\c janus.js) is available that can
* make use of both interfaces using exactly the same API. This library
* eases the task of creating sessions with the Janus core, attaching WebRTC
* users to plugins, send and receive requests and events to the plugins
* themselves and so on. For real examples of how this library can be
* used, check the demos in the \b html folder of this package. Notice
* that the \c janus.js library makes use of the features made available
* by the <a href="https://github.com/webrtc/adapter">webrtc-adapter</a>
* shim, which means that your web application should always include it
* as a dependency. For instance, all the demos link to it externally via
* <a href="https://cdnjs.com/">cdnjs.com</a>.
*
* \note The current \c janus.js library allows you to provide custom implementations of
* certain dependencies, in order to make it easier to integrate with other JavaScript
* libraries and frameworks. Using this feature you can ensure \c janus.js does not (implicitly)
* depend on certain global variables. Two implementations are included in \c janus.js itself:
*
* -# \ref js-default-deps which relies on native browser APIs,
* which in turn require somewhat more modern browsers
* -# \ref js-old-deps which uses jQuery (http://jquery.com/) instead,
* and should provide equivalent behaviour to previous versions of \c janus.js
*
* By default \ref js-default-deps will be used, but you can override this
* when initialising the Janus library and pass a custom dependencies object instead.
* For details, refer to: \ref js-dependencies
*
* In general, when using the Janus features, you would normally do the following:
*
* -# include the Janus JavaScript library in your web page;
* -# initialize the Janus JavaScript library and (optionally) passing its dependencies;
* -# connect to the server and create a session;
* -# create one or more handles to attach to a plugin (e.g., echo test and/or streaming);
* -# interact with the plugin (sending/receiving messages, negotiating a PeerConnection);
* -# eventually, close all the handles and shutdown the related PeerConnections;
* -# destroy the session.
*
* The above steps will be presented in order, describing how you can use
* the low level API to accomplish them. Consider that in the future we might
* provide higher level wrappers to this API to address specific needs, e.g.,
* a higher level API for each plugin: this would make it even easier to use
* the server features, as a high level API for the streaming plugin, for
* instance, may just ask you to provide the server address and the ID of
* the \c &lt;video&gt; element to display the stream in, and would take care of all the
* above mentioned steps on your behalf. Needless to say, you're very welcome
* to provide wrapper APIs yourself, if you feel a sudden urge to do so! :-)
*
* \section janusjs Using janus.js
*
* As a first step, you should include the Janus library in your project.
* Depending on your needs you can either use \c janus.js or one of the generated
* JavaScript module variants of it. For available module syntaxes and how to build the
* corresponding variants, see: \ref js-modules
*
\verbatim
<script type="text/javascript" src="janus.js" ></script>
\endverbatim
*
* The core of the JavaScript API is the \c Janus object. This object needs
* to be initialized the first time it is used in a page. This can be done
* using the static \c init method of the object, which accepts the
* following options:
*
* - \c debug: whether debug should be enabled on the JavaScript console, and what levels
* - \c true or \c "all": all debuggers enabled (Janus.trace, Janus.debug, Janus.log, Janus.warn, Janus.error)
* - array (e.g., <code>["trace", "warn"]</code>): only enable selected debuggers (allowed tokens: trace, debug, log, warn, error)
* - \c false: disable all debuggers
* - \c callback: a user provided function that is invoked when the initialization is complete
* - \c dependencies: a user provided implementation of Janus library dependencies
*
* Here's an example:
*
*
\verbatim
Janus.init({
debug: true,
dependencies: Janus.useDefaultDependencies(), // or: Janus.useOldDependencies() to get the behaviour of previous Janus versions
callback: function() {
// Done!
});
\endverbatim
*
* \note When using one of the JavaScript module variants of \c janus.js, you
* will need to import the \c Janus symbol from the module first. See also: \ref js-modules
* For example, using the ECMAScript module variant, the above example should be altered to:
*
*
\verbatim
import * as Janus from './janus.es.js'
Janus.init({
debug: true,
dependencies: Janus.useDefaultDependencies(), // or: Janus.useOldDependencies() to get the behaviour of previous Janus versions
callback: function() {
// Done!
});
});
\endverbatim
*
* Once the library has been initialized, you can start creating sessions.
* Normally, each browser tab will need a single session with the server: in
* fact, each Janus session can contain several different plugin handles
* at the same time, meaning you can start several different WebRTC sessions
* with the same or different plugins for the same user using the same
* Janus session. That said, you're free to set up different Janus
* sessions in the same page, should you prefer so.
*
* Creating a session is quite easy. You just need to use the \c new constructor
* to create a new \c Janus object that will handle your interaction with the
* server. Considering the dynamic and asynchronous nature of Janus sessions
* (events may occur at any time), there are several properties and callbacks you
* can configure when creating a session:
*
* - \c server: the address of the server as a specific address (e.g.,
* http://yourserver:8088/janus to use the plain HTTP API or ws://yourserver:8188/
* for WebSockets) or as an array of addresses to try sequentially to allow
* automatic for fallback/failover during setup;
* - \c iceServers: a list of STUN/TURN servers to use (a default STUN server
* will be used if you skip this property);
* - \c ipv6: whether IPv6 candidates should be gathered or not;
* - \c withCredentials: whether the \c withCredentials property of XHR requests
* should be enabled or not (false by default, and only valid when using HTTP
* as a transport, ignored for WebSockets);
* - \c max_poll_events: the number of events that should be returned when polling;
* the default is 1 (polling returns an object), passing a higher number will
* have the backend return an array of objects instead (again, only valid for
HTTP usage as this is strictly related to long polling, ignored for WebSockets);
* - \c destroyOnUnload: whether we should destroy automatically try and
* destroy this session via Janus API when \c onbeforeunload is called (true by default);
* - \c token , \c apisecret: optional parameters only needed in case you're \ref auth ;
* - a set of callbacks to be notified about events, namely:
* - \c success: the session was successfully created and is ready to be used;
* - \c error: the session was NOT successfully created;
* - \c destroyed: the session was destroyed and can't be used any more.
*
* These properties and callbacks are passed to the method as properties
* of a single parameter object: that is, the \c Janus constructor takes a
* single parameter, which although acts as a container for all the available
* options. The \c success callback is where you tipically start your application
* logic, e.g., attaching the peer to a plugin and start a media session.
*
* Here's an example:
*
\verbatim
var janus = new Janus(
{
server: 'http://yourserver:8088/janus',
success: function() {
// Done! attach to plugin XYZ
},
error: function(cause) {
// Error, can't go on...
},
destroyed: function() {
// I should get rid of this
}
});
\endverbatim
*
* As anticipated, the server may be a specific address, e.g.:
*
\verbatim
var janus = new Janus(
{
server: 'http://yourserver:8088/janus',
// or
server: 'ws://yourserver:8188/',
[..]
\endverbatim
*
* or an array of addresses. Such an array can be especially useful if
* you want the library to first check if the WebSockets server is
* reachable and, if not, fallback to plain HTTP, or just to provide
* a link multiple instances to try for failover. This is an example of
* how to pass a 'try websockets and fallback to HTTP' array:
*
\verbatim
var janus = new Janus(
{
server: ['ws://yourserver:8188/','http://yourserver:8088/janus'],
[..]
\endverbatim
*
* Once created, this object represents your session with the server.
* you can interact with a \c Janus object in several different ways.
* In particular, the following properties and methods are defined:
*
* - \c getServer(): returns the address of the server;
* - \c isConnected(): returns \c true if the Janus instance is connected
* to the server, \c false otherwise;
* - \c getSessionId(): returns the unique Janus session identifier;
* - \c attach(parameters): attaches the session to a plugin, creating an handle;
* more handles to the same or different plugins can be created at the same time;
* - \c destroy(parameters): destroys the session with the server, and closes
* all the handles (and related PeerConnections) the session may have with any plugin as well.
*
* The most important property is obviously the \c attach() method, as
* it's what will allow you to exploit the features of a plugin to manipulate
* the media sent and/or received by a PeerConnection in your web page.
* This method will create a plugin handle you can use for the purpose,
* for which you can configure properties and callbacks when calling the
* \c attach() method itself. As for the \c Janus constructor, the \c attach()
* method takes a single parameter that can contain any of the following
* properties and callbacks:
*
* - \c plugin: the unique package name of the plugin (e.g., \c janus.plugin.echotest );
* - \c opaqueId: an optional opaque string meaningful to your application (e.g., to map all the handles of the same user);
* - a set of callbacks to be notified about events, namely:
* - \c success: the handle was successfully created and is ready to be used;
* - \c error: the handle was NOT successfully created;
* - \c consentDialog: this callback is triggered just before \c getUserMedia is called
* (parameter=<b>true</b>) and after it is completed (parameter=<b>false</b>); this means it can
* be used to modify the UI accordingly, e.g., to prompt the user about the need to accept the device access consent requests;
* - \c webrtcState: this callback is triggered with a <b>true</b> value
* when the PeerConnection associated to a handle becomes active (so ICE, DTLS and
* everything else succeeded) from the Janus perspective, while <b>false</b> is
* triggered when the PeerConnection goes down instead; useful to figure out
* when WebRTC is actually up and running between you and Janus (e.g., to notify
* a user they're actually now active in a conference); notice that in case
* of <b>false</b> a reason string may be present as an optional parameter;
* - \c iceState: this callback is triggered when the ICE state for the
* PeerConnection associated to the handle changes: the argument of the callback
* is the new state as a string (e.g., "connected" or "failed");
* - \c mediaState: this callback is triggered when Janus starts or stops
* receiving your media: for instance, a \c mediaState with type=<b>audio</b> and
* on=<b>true</b> means Janus started receiving your audio stream (or started
* getting them again after a pause of more than a second); a \c mediaState with
* type=<b>video</b> and on=<b>false</b> means Janus hasn't received any video
* from you in the last second, after a start was detected before; useful to
* figure out when Janus actually started handling your media, or to detect
* problems on the media path (e.g., media never started, or stopped at some time);
* - \c slowLink: this callback is triggered when Janus reports trouble
* either sending or receiving media on the specified PeerConnection, typically
* as a consequence of too many NACKs received from/sent to the user in the
* last second: for instance, a \c slowLink with uplink=<b>true</b> means
* you notified several missing packets from Janus, while uplink=<b>false</b>
* means Janus is not receiving all your packets; useful to figure out when
* there are problems on the media path (e.g., excessive loss), in order to
* possibly react accordingly (e.g., decrease the bitrate if most of our
* packets are getting lost);
* - \c onmessage: a message/event has been received from the plugin;
* - \c onlocalstream: a local \c MediaStream is available and ready to be displayed;
* - \c onremotestream: a remote \c MediaStream is available and ready to be displayed;
* - \c ondataopen: a Data Channel is available and ready to be used;
* - \c ondata: data has been received through the Data Channel;
* - \c oncleanup: the WebRTC PeerConnection with the plugin was closed;
* - \c detached: the plugin handle has been detached by the plugin itself,
* and so should not be used anymore.
*
* Here's an example:
*
\verbatim
// Attach to echo test plugin, using the previously created janus instance
janus.attach(
{
plugin: "janus.plugin.echotest",
success: function(pluginHandle) {
// Plugin attached! 'pluginHandle' is our handle
},
error: function(cause) {
// Couldn't attach to the plugin
},
consentDialog: function(on) {
// e.g., Darken the screen if on=true (getUserMedia incoming), restore it otherwise
},
onmessage: function(msg, jsep) {
// We got a message/event (msg) from the plugin
// If jsep is not null, this involves a WebRTC negotiation
},
onlocalstream: function(stream) {
// We have a local stream (getUserMedia worked!) to display
},
onremotestream: function(stream) {
// We have a remote stream (working PeerConnection!) to display
},
oncleanup: function() {
// PeerConnection with the plugin closed, clean the UI
// The plugin handle is still valid so we can create a new one
},
detached: function() {
// Connection with the plugin closed, get rid of its features
// The plugin handle is not valid anymore
}
});
\endverbatim
*
* So the \c attach() method allows you to attach to a plugin, and specify
* the callbacks to invoke when anything relevant happens in this interaction.
* To actively interact with the plugin, you can use the \c Handle object
* that is returned by the \c success callback (pluginHandle in the example).
*
* This \c Handle object has several methods you can use to interact with
* the plugin or check the state of the session handle:
*
* - \c getId(): returns the unique handle identifier;
* - \c getPlugin(): returns the unique package name of the attached plugin;
* - \c send(parameters): sends a message (with or without a jsep to
* negotiate a PeerConnection) to the plugin;
* - \c createOffer(callbacks): asks the library to create a WebRTC compliant OFFER;
* - \c createAnswer(callbacks): asks the library to create a WebRTC compliant ANSWER;
* - \c handleRemoteJsep(callbacks): asks the library to handle an incoming WebRTC compliant session description;
* - \c dtmf(parameters): sends a DTMF tone on the PeerConnection;
* - \c data(parameters): sends data through the Data Channel, if available;
* - \c getBitrate(): gets a verbose description of the currently received stream bitrate;
* - \c hangup(sendRequest): tells the library to close the PeerConnection; if the optional \c sendRequest argument is
* set to \c true, then a \c hangup Janus API request is sent to Janus as well (disabled by default, Janus can usually
* figure this out via DTLS alerts and the like but it may be useful to enable it sometimes);
* - \c detach(parameters): detaches from the plugin and destroys the handle, tearing
* down the related PeerConnection if it exists.
*
* While the \c Handle API may look complex, it's actually quite straightforward
* once you get the concept. The only step that may require a little more
* effort to understand is the PeerConnection negotiation, but again, if
* you're familiar with the WebRTC API, the \c Handle actually makes it
* a lot easier.
*
* The idea behind it's usage is the following:
*
* -# you use \c attach() to create a \c Handle object;
* -# in the \c success callback, your application logic can kick in: you may
* want to send a message to the plugin (<code>send({msg})</code>), negotiate
* a PeerConnection with the plugin right away ( \c createOffer followed
* by a <code>send({msg, jsep})</code>) or wait for something to happen to do anything;
* -# the \c onmessage callback tells you when you've got messages from the plugin;
* if the \c jsep parameter is not null, just pass it to the library, which will take
* care of it for you; if it's an \b OFFER use \c createAnswer (followed by a
* <code>send({msg, jsep})</code> to close the loop with the plugin), otherwise use
* \c handleRemoteJsep ;
* -# whether you took the initiative to set up a PeerConnection or the plugin did,
* the \c onlocalstream and/or the \c onremotestream callbacks will provide
* you with a stream you can display in your page;
* -# each plugin may allow you to manipulate what should flow through the
* PeerConnection channel: the \c send method and \c onmessage callback
* will allow you to handle this interaction (e.g., to tell the plugin
* to mute your stream, or to be notified about someone joining a virtual room),
* while the \c ondata callback is triggered whenever data is received
* on the Data Channel, if available (and the \c ondataopen callback
* will tell you when a Data Channel is actually available).
*
* The following paragraphs will delve a bit deeper in the negotiation
* mechanism provided by the \c Handle API, in particular describing
* the properties and callbacks that may be involved. To follow the approach
* outlined by the W3C WebRTC API, this negotiation mechanism is heavily
* based on asynchronous methods as well. Notice that the following paragraphs
* address the first negotiation step, that is the one to create a new
* PeerConnection from scratch: to know how to originate or handle a
* renegotiation instead (e.g., to add/remove/replace a media source, or
* force an ICE restart) check the \ref renegotiation section instead.
*
* - \c createOffer takes a single parameter, that can contain any of the
* following properties and callbacks:
* - \c media: you can use this property to tell the library which media (audio/video/data)
* you're interested in, and whether you're going to send and/or receive any of them; by default
* audio and video are enabled in both directions, while the Data Channels are disabled;
* this option is an object that can take any of the following properties:
* - \c audioSend: \c true/false (do or do not send audio);
* - \c audioRecv: \c true/false (do or do not receive audio);
* - \c audio: \c true/false (do or do not send \b and receive audio, takes precedence on the above);
* - \c audio: object with \c deviceId property (specify ID of audio device to capture, takes precedence on the above;
* devices list can be accessed with \c Janus.listDevices(callback) );
* - \c videoSend: \c true/false (do or do not send video);
* - \c videoRecv: \c true/false (do or do not receive video);
* - \c video: \c true/false (do or do not send \b and receive video, takes precedence on the above);
* - \c video: \c "lowres"/"lowres-16:9"/"stdres"/"stdres-16:9"/"hires"/"hires-16:9"
* (send a 320x240/320x180/640x480/640x360/1280x720 video, takes precedence on the above; default is \c "stdres" )
* this property will affect the resulting getUserMedia that the library will issue; please
* notice that Firefox doesn't support the \c "16:9" variants, which will fallback
* to the ones; besides, \c "hires" and \c "hires-16:9" are currently synonymous, as
* there's no 4:3 high resolution constraint as of now;
* - \c video: \c "screen" (use screensharing for video, disables audio, takes precedence on both audio and video);
* - \c video: object with \c deviceId , \c width and/or \c height properties (specify ID of video device to capture
* and optionally resolution to use, takes precedence on the above; devices list can be accessed with \c Janus.listDevices(callback) );
* - \c data: \c true/false (do or do not use Data Channels, default is false)
* - \c failIfNoAudio: \c true/false (whether a getUserMedia should fail if audio send is asked, but no audio device is available, default is false)
* - \c failIfNoVideo: \c true/false (whether a getUserMedia should fail if video send is asked, but no video device is available, default is false)
* - \c screenshareFrameRate: in case you're sharing a screen/application, allows you to specify the framerate (default=3);
* - \c trickle: \c true/false, to tell the library whether you want
* Trickle ICE to be used (true, the default) or not (false);
* - \c stream: optional, only to be passed in case you obtained a MediaStream object yourself with a \c getUserMedia
* request, and that you want the library to use instead of having it get one by itself (makes
* the \c media property useless, as it won't be read for accessing any device);
* - a set of callbacks to be notified about the result, namely:
* - \c success: the session description was created (attached as a parameter) and is ready to be sent to the plugin;
* - \c error: the session description was NOT successfully created;
* - \c customizeSdp: you can modify the sdp generated by the webrtc engine if you need;
* - \c createAnswer takes the same options as createOffer, but requires
* an additional one as part of the single parameter argument:
* - \c jsep: the session description sent by the plugin (e.g., as received
* in an \c onmessage callback) as its OFFER.
*
* Whether you use \c createOffer or \c createAnswer depending on the scenario,
* you should end up with a valid \c jsep object returned in the \c success
* callback. You can attach this \c jsep object to a message in a \c send request
* to pass it to the plugin, and have Janus negotiate a PeerConnection
* with your application.
*
* Here's an example of how to use \c createOffer, taken from the Echo Test demo page:
*
\verbatim
// Attach to echo test plugin
janus.attach(
{
plugin: "janus.plugin.echotest",
success: function(pluginHandle) {
// Negotiate WebRTC
echotest = pluginHandle;
var body = { "audio": true, "video": true };
echotest.send({"message": body});
echotest.createOffer(
{
// No media property provided: by default,
// it's sendrecv for audio and video
success: function(jsep) {
// Got our SDP! Send our OFFER to the plugin
echotest.send({"message": body, "jsep": jsep});
},
error: function(error) {
// An error occurred...
},
customizeSdp: function(jsep) {
// if you want to modify the original sdp, do as the following
// oldSdp = jsep.sdp;
// jsep.sdp = yourNewSdp;
}
});
},
[..]
onmessage: function(msg, jsep) {
// Handle msg, if needed, and check jsep
if(jsep !== undefined && jsep !== null) {
// We have the ANSWER from the plugin
echotest.handleRemoteJsep({jsep: jsep});
}
},
[..]
onlocalstream: function(stream) {
// Invoked after createOffer
// This is our video
},
onremotestream: function(stream) {
// Invoked after handleRemoteJsep has got us a PeerConnection
// This is the remote video
},
[..]
\endverbatim
*
* This, instead, is an example of how to use \c createAnswer, taken from the Streaming demo page:
*
\verbatim
// Attach to echo test plugin
janus.attach(
{
plugin: "janus.plugin.streaming",
success: function(pluginHandle) {
// Handle created
streaming = pluginHandle;
[..]
},
[..]
onmessage: function(msg, jsep) {
// Handle msg, if needed, and check jsep
if(jsep !== undefined && jsep !== null) {
// We have an OFFER from the plugin
streaming.createAnswer(
{
// We attach the remote OFFER
jsep: jsep,
// We want recvonly audio/video
media: { audioSend: false, videoSend: false },
success: function(ourjsep) {
// Got our SDP! Send our ANSWER to the plugin
var body = { "request": "start" };
streaming.send({"message": body, "jsep": ourjsep});
},
error: function(error) {
// An error occurred...
}
});
}
},
[..]
onlocalstream: function(stream) {
// This will NOT be invoked, we chose recvonly
},
onremotestream: function(stream) {
// Invoked after send has got us a PeerConnection
// This is the remote video
},
[..]
\endverbatim
*
* Of course, these are just a couple of examples where the scenarios
* assumed that one plugin would only receive (Echo Test) or generate
* (Streaming) offers. A more complex example (e.g., a Video Call plugin)
* would involve both, allowing you to either send offers to a plugin,
* or receive some from them. Handling this is just a matter of checking
* the \c type of the \c jsep object and reacting accordingly.
*
* \section renegotiation Updating an existing PeerConnection (renegotiations)
* While the JavaScript APIs described above will suffice for most of the
* common scenarios, there are cases when updates on a PeerConnection may
* be needed. This can happen whenever, for instance, you want to add a
* new media source (e.g., add video to an audio only call), replace an
* existing one (e.g., switch from capturing the camera to sharing your
* screen), or trigger an ICE restart because of a network change. All
* these actions require a renegotiation to occur, which means a new SDP
* offer/answer round to update the existing PeerConnection.
*
* Since version \c 0.2.6, renegotiations are indeed supported by Janus,
* and the \c janus.js library exposes ways to easily handle the process
* of updating a media session. More specifically, there are additional
* properties you can pass to \c createOffer and \c createAnswer for the
* purpose: most of the properties introduced in the previous section will
* still be usable, as it will be clearer in the next paragraphs.
*
* The new properties you can pass to \c media in \c createOffer and
* \c createAnswer are the following:
*
* - \c addAudio: if set, start capturing audio if you weren't (will fail
* if you're sending audio already);
* - \c addVideo: if set, start capturing video if you weren't (will fail
* if you're sending video already);
* - \c addData: if set, negotiate a datachannel if it didn't exist (is
* actually just a synonym for \c data:true );
* - \c removeAudio: if set, stop capturing audio and remove the local audio track;
* - \c removeVideo: if set, stop capturing video and remove the local video track;
* - \c replaceAudio: if set, stop capturing the current audio (remove the
* local audio track), and capture a new audio source;
* - \c replaceVideo: if set, stop capturing the current video (remove the
* local video track), and capture a new video source.
*
* Notice that these properties are only processed when you're trying a
* renegotiation, and will be ignored when creating a new PeerConnection.
*
* These properties don't replace the existing \c media properties, but go
* along with them. For instance, when adding a new video stream, or
* replacing an existing one, you can still use the video related properties
* as before, e.g., to pass a specific device ID or asking for a screenshare
* instead of a camera. Besides, notice that you'll currently have to pass
* info on the streams you want to keep as well, or they might be removed:
* this means that, if for instance you want to replace the video source,
* but want to keep the audio as it is, passing \c audio:false to the new
* createOffer will potentially disable audio.
*
* It's important to point out that, as for negotiations that result in
* the creation of a new PeerConnection in the first place, how to perform
* a renegotiation in practice will typically vary depending on the plugin
* that you're trying to do it for. Some plugins may allow you to offer
* a renegotiation, others may require you to send a different request
* instead in order to trigger a renegotiation from the plugin. As it
* will be clearer later, this is especially true for ICE restarts. As
* such, apart from the generic and core-related definitions introduced
* in this section, please refer to the documentation for each individual
* plugin for more information about how to perform renegotiations in
* specific use cases.
*
* Here's a simple example of how you can use \c removeVideo to remove
* the local video capture in a session, e.g., in the EchoTest demo:
*
\verbatim
// Remove local video
echotest.createOffer(
{
media: { removeVideo: true },
success: function(jsep) {
Janus.debug(jsep);
echotest.send({message: {audio: true, video: true}, "jsep": jsep});
},
error: function(error) {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});
\endverbatim
*
* This other example shows how you can add a new video stream to an-audio
* only PeerConnection instead:
*
\verbatim
// Add local video
echotest.createOffer(
{
media: { addVideo: true },
success: function(jsep) {
Janus.debug(jsep);
echotest.send({message: {audio: true, video: true}, "jsep": jsep});
},
error: function(error) {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});
\endverbatim
*
* Finally, this example shows how you can replace the video track, by
* also showing how you can combine this with one of the properties we
* already met in the previous section:
*
\verbatim
// Replace local video
echotest.createOffer(
{
media: {
video: {
deviceId: "44f4740bee234ce6ddcfea8e59e8ed7505054f75edf27e3a12294686b37ff6a7"
},
replaceVideo: true
},
success: function(jsep) {
Janus.debug(jsep);
echotest.send({message: {audio: true, video: true}, "jsep": jsep});
},
error: function(error) {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});
\endverbatim
*
* Notice that renegotiations involving media changes (both local and remote)
* will likely result in new calls to the \c onlocalstream and \c onremotestream
* application callbacks: as such, be prepared to see those callbacks called
* for the same PeerConnection more than once during the course of a media session.
*
* \section restarts ICE restarts
* While ICE restarts can be achieved with a renegotiation, they're complex
* enough to deserve a specific subsection. In fact, ICE restarts don't
* address changes in the media, but in the underlying transport itself.
* They're used, for instance, when there's a network change (e.g., the
* IP address changed, or the user switched from WiFi to 4G). In order for
* this to work, new candidates must be exchanged, and connectivity checks
* must be restarted in order to find the new optimal path.
*
* With \c janus.js, you can only force an ICE restart when sending a new
* offer. In order to do so, all you need to do is add `iceRestart:true`
* to your `createOffer` call, and an ICE restart will be requested. The
* following example shows how this can be done with the EchoTest:
*
\verbatim
echotest.createOffer({
iceRestart: true,
media: { data: true },
success: function(jsep) {
echotest.send({message: {audio: true, video: true}, jsep: jsep});
}
});
\endverbatim
*
* In this particular example, we're not asking for any change on the
* media streams, but just an ICE restart. If successful, as soon as the
* answer is received, the client and Janus will restart the ICE process
* and find a new path for the media packets.
*
* Notice that, with Janus and its plugins, you won't always be able to
* force an ICE restart by sending a new SDP offer yourself: some plugins,
* like the Streaming plugin for instance, will want to always send an
* offer themselves, which means they'll be the ones actually forcing the
* ICE restart from a negotiation perspective. In order to still allow
* users to actually originate the process, all the stock Janus plugins
* that assume they'll be sending offers for some or all of their media
* streams also expose APIs to force an ICE restart from the server side.
* You can learn more about this on a plugin level basis
* <a target="_blank" href="https://github.com/meetecho/janus-gateway/pull/753">here</a> and
* <a target="_blank" href="https://github.com/meetecho/janus-gateway/pull/1099">here</a>.
* Besides, make sure you read the documentation for each of the plugins
* you're interested in using ICE restarts for, as the details for how
* to perform it properly are typically provided there.
*
* <hr>
*
* This is it! For more information about the API, have a look at the
* demo pages that are available in the \b html folder in this package.
*
*/
/*!\page js-modules Using janus.js as JavaScript module
*
* To facilitate integration of \c janus.js within modular JavaScript code bases,
* you can instruct the build system(s) to generate a modular variants of \c janus.js.
* Generated modules may then be copied to your own JavaScript projects and seamlessly integrated with your own project's build system.
*
* Building the modules can be done in two ways:
*
* -# As part of a regular build of the Janus WebRTC Server, using \c make, by enabling the integrated support via \c configure
* -# By running NPM commands manually. This may be useful if you are looking to build just the JavaScript modules without
* incurring the overhead of a full build of Janus.
*
* As an alternative to generating the module and copying it to your project, you can also tweak
* your module bundler to use \c janus.js directly from the official Janus repository. See more
* details (including concrete instructions for Webpack): \ref js-webpack
*
* \section auto-build-js-modules Building modules using make
* Each supported variant may be enabled by passing a corresponding \c --enable-javascript-*-module flag
* (with or without a \c =yes directive) to \c configure before invoking \c make to build Janus.
* Please note: if you do not pass any such flag, by default no modules will be built.
*
* The following table provides a summary of available module formats and their corresponding \c configure options:
*
* <table class="table table-striped">
* <tr><th>Module format (syntax)</th><th>File name</th><th>configure flag to pass</th></tr>
* <tr><td>ECMAScript</td><td>janus.es.js</td><td>\c --enable-javascript-es-module</td></tr>
* <tr><td>Universal Module Definition (UMD)</td><td>janus.umd.js</td><td>\c --enable-javascript-umd-module</td></tr>
* <tr><td>CommonJS</td><td>janus.cjs.js</td><td>\c --enable-javascript-common-js-module</td></tr>
* <tr><td>Immediately Invoked Function Expression (IIFE)</td><td>janus.iife.js</td><td>\c --enable-javascript-iffe-module</td></tr>
* </table>
*
* The \c --enable-all-js-modules shortcut is available, in case you want to enable and build them all.
*
* When built and installed, these module variants may be found in the \c $PREFIX/share/janus/javascript
* folder, alongside the \c janus.js file itself (assuming \c $PREFIX the installation directory passed to \c configure).
*
* \note Building the JavaScript modules still requires NPM and may involve an \c install which means \c npm must be able
* to download dependencies. By default \c configure will attempt to auto-detect available \c npm on your PATH, but
* if you have installed NPM outside the PATH you can override this by passing the (full) path to your \c npm executable, e.g.:
*
\verbatim
./configure NPM=/path/to/my/custom/npm --enable-javascript-es-module=yes
\endverbatim
*
* \section manual-build-modules Building modules manually with NPM
* You can also opt to build modules by invoking \c npm manually. The \c npm subdirectory contains the necessary
* configuration files to get you started:
*
\verbatim
cd ./npm
npm install
npm run rollup -- --o /path/to/desired/output/file-name.js --f cjs # or es, iffe, umd, amd, ...
\endverbatim
*
* Using \c npm directly is useful if you want to build the JavaScript modules only, without building Janus itself
* or if you are looking for advanced customisation options or alternative formats which are not integrated in \c configure yet.
* As you may have surmised from the example command, the actual build consists mostly of invoking \c rollup with the
* correct parameters. For more information on available parameters, please refer to the \c rollup documentation:
*
* -# https://rollupjs.org/#command-line-flags
* -# https://rollupjs.org/#configuration-files
*
* \section js-webpack Using janus.js directly with Webpack and other bundlers
*
* Generating a converted version of \c janus.js and copying it to your project is not always the best
* solution. In many situations it may be prefered to let your JavaScript module bundler (e.g.
* <a href="https://webpack.js.org">Webpack</a>) grab the file directly from the official Janus repository.
* Doing that you can manage \c janus.js just like any other dependency coming from Github or the npm Registry,
* getting rid of the manual copy step and letting the bundler take care of version management, updates
* and downloads.
*
* Of course, the first step is to include the official Janus repository as a dependency in your
* project by adding it to your \c packages.json file.
*
\verbatim
{
"dependencies": {
"janus-gateway": "git://github.com/meetecho/janus-gateway.git"
}
}
\endverbatim
*
* That will automatically drag in the dependency on the appropriate version of the
* <a href="https://www.npmjs.com/package/webrtc-adapter">WebRTC Adapter</a> from the npm Registry.
* But \c janus.js expects such adapter to be available as a global variable.
* So we have to make that happen for it to work properly. In the case of Webpack, is as easy as
* adding this to your \c webpack.config.js file.
\verbatim
const webpack = require('webpack');
module.exports = {
plugins: [
// janus.js does not use 'import' to access to the functionality of webrtc-adapter,
// instead it expects a global object called 'adapter' for that.
// Let's make that object available.
new webpack.ProvidePlugin({ adapter: 'webrtc-adapter' })
]
}
\endverbatim
*
* On the other hand, \c janus.js defines the \c Janus object globally. So a small tweak is also
* needed to serve such object via \c export. That can be done using
* <a href="https://webpack.js.org/loaders/exports-loader/">exports-loader</a> and adding this to
* \c webpack.config.js
\verbatim
module.exports = {
module: {
rules: [
// janus.js does not use 'export' to provide its functionality to others, instead
// it creates a global variable called 'Janus' and expects consumers to use it.
// Let's use 'exports-loader' to simulate it uses 'export'.
{
test: require.resolve('janus-gateway'),
use: 'exports-loader?Janus=Janus'
}
]
}
}
\endverbatim
*
* With that extra configuration, the official \c janus.js can be used directly in any modular
* JavaScript code base without any previous transformation of the file. That means you can simply
* do this to access to the Janus API from your modular code.
\verbatim
import { Janus } from 'janus-gateway';
\endverbatim
* For more detailed or updated documentation check the
* <a href="https://webpack.js.org/guides/shimming/">Webpack shimming guide</a> or the equivalent
* documentation for your bundler of choice.
*/
/*!\page js-dependencies Working with custom janus.js dependencies
*
* Certain dependencies of \c janus.js may be passed during library initialization as
* a property list containing the following keys:
*
* -# \c newWebSocket: a function which given WebSockets server and protocol arguments
* should return a new WebSocket (or something that acts like it)
* -# \c webRTCAdapter: an \c adapter object such as provided by the
* <a href="https://github.com/webrtc/adapter">webrtc-adapter</a> library
* -# \c isArray: a function which tests if a given argument is a JavaScript array
* -# \c checkJanusExtension: a function which tests if the Janus Screensharing extension
* for Chrome is installed/available. This can be done by testing whether or not an element
* with an \c id attribute value of \c janus-extension-installed is present.
* -# \c httpAPICall: a function which given an url and options argument performs an
* HTTP API request to Janus. This function is not as straightforward to implement,
* see the section on \ref js-http-apicall below for details.
*
* Depending on your needs you do not have to provide all these dependencies, e.g.
* you do not need to implement the \c httpAPICall function if your application relies
* exclusively on WebSockets to access the Janus API.
*
* Two implementations of the dependencies object are provided by \c janus.js:
*
* -# \c Janus.useDefaultDependencies
* -# \c Janus.useOldDependencies
*
* In turn, each of these implementations accept their dependencies as arguments or fallback on
* certain global variables. Below follows an overview:
*
* \section js-default-deps Janus.useDefaultDependencies
* The \c Janus.useDefaultDependencies method relies on the following native browser APIs:
*
* -# \c Promise: support for \c Promises as standardised in ES 6 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)
* -# \c fetch: support for the \c fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
* -# \c WebSocket: support for the \c WebSocket API (https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
* -# \c document.querySelector: support for the \c document.querySelector API (https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
*
* Additionally the \c adapter object from the <a href="https://github.com/webrtc/adapter">webrtc-adapter</a> library is also required.
* These dependencies may either be passed explicitly to the function as a property list with keys of the same name, or
* if omitted the function will fallback to relying on global variables of that name instead.
*
* Example:
\verbatim
var customDependencies = Janus.useDefaultDependencies({
fetch: myCustomFetchImplementation // myCustomFetchImplementation should provide a compatible fetch() API
});
var relyingOnGlobalsEntirely = Janus.useDefaultDependencies();
\endverbatim
*
* Being able to passe dependencies like this is especially useful in the context of modern ES modules:
*
\verbatim
import adapter from 'webrtc-adapter';
// other imports elided
const setupDeps = () => Janus.useDefaultDependencies({
adapter,
// other dependencies elided
});
export const initialiseJanusLibrary = () => Janus.init({dependencies: setupDeps()});
\endverbatim
*
* \section js-old-deps Janus.useOldDependencies
* The \c Janus.useOldDependencies method relies on:
*
* -# \c jQuery: the JQuery library (http://jquery.com/)
* -# \c WebSocket: support for the \c WebSocket API (https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
* -# \c adapter: the \c adapter object from the <a href="https://github.com/webrtc/adapter">webrtc-adapter</a> library
*
* This function provides a simple upgrade path for existing applications which are heavily
* tied to jQuery (especially since previous versions of \c janus.js depended on it).
*
* \section js-http-apicall httpAPICall
* The \c httpAPICall function is used to issue API calls to the Janus HTTP(S) interfaces.
* It will be passed two arguments:
*
* -# \c url: a string which refers to the (server) URL of the API endpoint to contact
* -# \c options a property list (see below)
*
* Any return values from the \c httpAPICall function will be ignored.
*
* When working with HTTP request or response bodies, the \c httpAPICall is responsible for
* serialisation to, and deserialisation from the 'wire format' (JSON).
* That is: the \c httpAPICall must transform objects to JSON or parse JSON as and when required.
* Similarly, the \c httpAPICall is also responsible for setting appropriate HTTP
* \c Content-Type (application/json) and/or \c Accept headers.
*
* The \c options argument may contain the following keys:
*
* -# \c timeout: a timeout in miliseconds which should be imposed on the request.
* The \c httpAPICall implementation is required to implement support for imposing timeouts
* on HTTP API requests.
* -# \c body: payload to include as body of the outgoing HTTP request.
The \c httpAPICall must encode it in the 'wire format' (JSON).
* -# \c withCredentials: a boolean indicating whether or not HTTP credentials should be sent
* -# \c success: a callback which should be dispatched when an API request was successful.
* -# \c error: a callback which should be dispatched when an API request was unsuccessful, or timed out
* -# \c async: a boolean hint which indicates whether or not asynchronous requests are desirable.
* This hint is a primarily a remnant for backwards compatible behaviour when working with jQuery.
*
* The \c success callback should be passed the deserialised API response body.
* The \c error callback accepts two arguments: a descriptive status text string and the raw error object
* which caused the \c error callback to be invoked.
*
* \note The \c httpAPICall represents the primary way to intercept HTTP(S) API calls issued from within the
* \c janus.js library. You can use this mechanism to augment outgoing requests with additional headers
* or to intercept responses. For example:
*
* -# You can support authentication schemes based on the HTTP \c Authorization header by
* injecting it into outgoing API requests and routing them through a proxy.
* -# You can intercept incoming responses and extract data from custom header values generated by a proxy.
* -# You can combine both to implement a robust defence against <a href="https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)">CSRF</a>
* -# You can reroute the control flow entirely, and e.g. use \c httpAPICall as an action creator in your
* <a href="http://redux.js.org/">Redux</a> application.
*
* \section js-extension Custom Screensharing Extension for Chrome
* To use a different extension for screensharing permissions in Chrome you can pass a \c extension object
* to \c Janus.useDefaultDependencies and \c Janus.useOldDependencies.
* The object should provide the following methods:
*
* -# \c init(): Do any setup work here. Will be called once when the dependencies are loaded.
* -# \c isInstalled(): should return a boolean indicating whether the Extension was detected and is ready to use.
* -# \c getScreen(callback): make a call to the extension to get a \c streamId here. The streamId can be obtained
* from chrome using <a href="https://developer.chrome.com/extensions/desktopCapture">chrome.desktopCapture.chooseDesktopMedia()</a>.
* When the request is successful pass the \c streamId back using <tt>callback(null, streamId)</tt>,
* otherwise pass an \c Error object like \c callback(error)
*/
/*! \page rest RESTful, WebSockets, RabbitMQ, MQTT, Nanomsg and UnixSockets API
*
* Since version \c 0.0.6, there are three different ways to interact with a
* Janus instance: a \ref plainhttp (the default), a \ref WS, a \ref rabbit, \ref apimqtt, \ref apinanomsg
* and a \ref unix (both optional, need an external library to be available). All of
* the interfaces use the same messages (in terms of requests, responses
* and notifications), so almost all the concepts described in the
* \ref plainhttp section apply to the WebSocket/RabbitMQ/MQTT/Nanomsg/UnixSockets interfaces as well.
* Besides, since version \c 0.1.0 the transport mechanism for the Janus API
* has been made modular, which means other protocols for transporting
* Janus API messages might become available in the future: considering the
* Janus protocol is supposed to be mostly agnostic to the protocol it is
* transported on, the concepts explained in the following sections should
* apply to those as well.
*
* As it will be explained later in the \ref WS, \ref rabbit, \ref apimqtt, \ref apinanomsg and \ref unix sections
* below, the only differences come when addressing specific sessions/handles
* and in part in how you handle notifications using something different than
* the REST interface: in fact, since with WebSockets, RabbitMQ, MQTT, Nanomsg and UnixSockets
* (and, as anticipated, with other protocols that may be added in the future too)
* there's no REST-based path involved, you'll need a couple of additional
* identifiers to bridge the gap.
* Some details are also provided in case you're interested in \ref auth.
*
* \section plainhttp Plain HTTP REST Interface
* As anticipated in the \ref JS documentation, the server deploys a
* RESTful interface that clients can exploit. The \c janus.js library
* makes use of it in a transparent way, but if you're interested in
* more details about it (e.g., because you want to talk to the server
* your own way), this page described the interface and the protocol
* the API exposes and uses.
*
* There are basically three types/levels of endpoints you can meet:
*
* -# \ref root (\c /janus by default, but configurable), which
* you only \b POST to in order to create a Janus session;
* -# \ref sessions (e.g., \c /janus/12345678, using the
* identifier retrieved with a previous create), which you either send
* a \b GET to (long poll for events and messages from plugins) or a \b POST
* (to create plugin handles or manipulate the session);
* -# \ref handles (e.g., \c /janus/12345678/98765432, appending
* the handle identifier to the session one) which you only send \b POST
* messages to (messages/negotiations for a plugin, handle manipulation),
* as all events related to this handle would be received in the session
* endpoint \b GET (the \c janus.js library would redirect the incoming
* messages to the right handle internally).
*
* Messages and requests you can send to and receive from any of the
* above mentioned endpoints are described in the following chapters.
* In general, all messages share at least two fields:
*
* - \c janus: the request/event (e.g., "create", "attach", "message", etc.);
* - \c transaction: a random string that the client can use to match incoming
* messages from the server (since, as explained in the \ref plugins
* documentation, all messages are asynchronous).
*
* Different messages will of course add different information to this
* base syntax. Error message, instead, usually have these fields:
*
* - \c janus: this would be "error";
* - \c transaction: this would be the transaction identifier of the request
* that failed;
* - \c error: a JSON object containing two fields:
* - \c code: a numeric error code, as defined in apierror.h;
* - \c reason: a verbose string describing the cause of the failure.
*
* An example of an error is presented here:
*
\verbatim
{
"janus" : "error",
"transaction" : "a1b2c3d4"
"error" : {
"code" : 458
"reason" : "Could not find session 12345678"
}
}
\endverbatim
*
*
* \section info Getting info about the Janus instance
* The API exposes an \c info endpoint you can query to get information
* about the Janus instance you're talking to. Specifically, it returns
* information about the version of the Janus server, whether some of the
* optional features (e.g., Data Channels or IPv6) are supported or not,
* and which transports and plugins are available.
*
* To get this information, just send an HTTP \b GET message to the \c info
* endpoint (e.g., http://yourserver:8088/janus/info), which will return
* something like this:
*
\verbatim
{
"janus": "server_info",
"transaction": "i1bzIL341Kl2",
"name": "Janus WebRTC Server",
"version": 73,
"version_string": "0.7.3",
"author": "Meetecho s.r.l.",
"data_channels": "true", // Data channels are supported
"ipv6": "false", // IPv6 is not configured
"ice-tcp": "false", // ICE-TCP support is disabled,
[..]
"transports": {
"janus.transport.http": {
"name": "JANUS REST (HTTP/HTTPS) transport plugin",
"author": "Meetecho s.r.l.",
"description": "This transport plugin adds REST (HTTP/HTTPS) support to the Janus API via libmicrohttpd.",
"version_string": "0.0.2",
"version": 2
},
[..] // Other transport plugins
},
"plugins": {
"janus.plugin.sip": { // The SIP plugin is available
"version_string": "0.0.7",
"description": "This is a simple SIP plugin for Janus, allowing WebRTC peers to register at a SIP server and call SIP user agents through Janus.",
"author": "Meetecho s.r.l.",
"name": "JANUS SIP plugin",
"version": 7
},
"janus.plugin.videoroom": { // The Video SFU plugin is available
"version_string": "0.0.3",
"description": "This is a plugin implementing a videoconferencing SFU (Selective Forwarding Unit) for Janus, that is an audio/video router.",
"author": "Meetecho s.r.l.",
"name": "JANUS VideoRoom plugin",
"version": 3
},
[..] // Other plugins
}
\endverbatim
*
* You can use this information to selectively enable or disable features
* in your application according to what's available in the Janus instance
* you're trying to contact.
*
*
* \section root The server root
* The server root is \c /janus by default but, as anticipated, it is
* configurable, either via command line or in the \c janus.jcfg configuration.
*
* You can only contact the server root when you want to create a new
* session with the server. To do so, you need to \b POST the a \c janus "create"
* JSON message to the server:
*
\verbatim
{
"janus" : "create",
"transaction" : "<random alphanumeric string>"
}
\endverbatim
*
* If the request is successful, you'll receive the unique session identifier
* in a response formatted like this:
*
\verbatim
{
"janus" : "success",
"transaction" : "<same as the request>",
"data" : {
"id" : <unique integer session ID>
}
}
\endverbatim
*
* In case of an error, you'll receive an error message as the one introduced
* before. This request, if issued with a POST to the server root, can only
* fail if you miss any of the required fields in the request.
*
*
* \section sessions The session endpoint
* Once you've created a session, a new endpoint you can use is created
* in the server. Specifically, the new endpoint is constructed by
* concatenating the server root and the session identifier you've been
* returned (\c e.g., \c /janus/12345678).
*
* This endpoint can be used in two different ways:
*
* -# using a parameter-less \b GET request to the endpoint, you'll
* issue a long-poll request to be notified about events and incoming
* messages from this session;
* -# using a \b POST request to send JSON messages, you'll interact
* with the session itself.
*
* <hr>
*
* \par Long-poll requests
* The long-poll will only trigger events related to messages you're
* being sent from plugins, and as such will be clearer to understand
* once you read the \ref handles section. That said, the events are formatted
* this way:
*
* - \c janus: this would be "event";
* - \c sender: this would be the unique numeric plugin handle identifier;
* - \c transaction: this is optional: it is either related to a request
* you sent to a plugin before, or it may be missing in case this is an
* event the plugin sent on its own account;
* - \c plugindata: a JSON object containing the info coming from the plugin itself:
* - \c plugin: the plugin's unique package name (e.g., \c janus.plugin.echotest);
* - \c data: an opaque JSON object that is plugin specific.
* - \c jsep: an optional JSON object containing the JSEP SDP (offer or
* answer) the plugin may send to negotiate a WebRTC PeerConnection with
* the client (check the \ref handles section for more details).
*
* An example of such an event (in this case, sent by the janus_echotest.c
* plugin in response to a request) is presented here:
*
\verbatim
{
"janus" : "event",
"sender" : 1815153248,
"transaction" : "sBJNyUhH6Vc6",
"plugindata" : {
"plugin": "janus.plugin.echotest",
"data" : {
"echotest" : "event",
"result" : "ok"
}
},
}
\endverbatim
*
* The long-poll request has a 30 seconds timeout. If it has no event to
* report, a simple \em keep-alive message will be triggered:
*
\verbatim
{
"janus" : "keepalive",
}
\endverbatim
*
* As with all long-poll based approaches, it's up to your application
* to send a new polling request as soon as an event or a keep-alive
* has been received.
*
* Notice that, by default, the long poll returns a single event: that is,
* as soon as a message becomes available in the session queue, that event
* is returned and the long poll closes. If you want to receive more events
* within the context of the same long poll, you can pass the \c maxev
* query string parameter to the GET, e.g.:
*
\verbatim
GET http://host:port/janus/<sessionid>?maxev=5
\endverbatim
*
\verbatim
[
{
// Event #1
"janus" : "event",
[..]
},
{
// Event #2
"janus" : "event",
[..]
},
[..]
]
\endverbatim
*
* This request will instruct the server to return at maximum 5 events
* within the context of the same long poll, formatted as a JSON array
* of events. Please beware that this does \b NOT mean that you'll
* always get 5 events this way: it only means that, if a message becomes
* available in the queue and more events are present as well, Janus will
* return more than one without needing you to send multiple long polls
* immediately thereafter to get them. For this reason, don't be surprised
* if even with a \c maxev parameter set, you'll still get a single
* event being notified as the sole object in the returned array.
*
* <hr>
*
* \par Interacting with the session
* To interact with the session, e.g., to create a new handle to attach
* to a plugin or destroy the current session, you need to send a \b POST
* JSON message to the session endpoint.
*
* To attach to a plugin in order to exploit its features, you need to
* \b POST a \c janus "attach" JSON message to the server; you'll need
* of course to provide information on the plugin you want to attach to,
* which can be done using the \c plugin field:
*
\verbatim
{
"janus" : "attach",
"plugin" : "<the plugin's unique package name>",
"transaction" : "<random string>"
}
\endverbatim
*
* Notice that you can also provide an optional \c opaque_id string
* identifier (for more details on why this might be useful, read more
* <a href="https://github.com/meetecho/janus-gateway/pull/748">here</a>).
* If the request is successful, you'll receive the unique plugin handle
* identifier in a response formatted the same way as the session create
* one, that is like this:
*
\verbatim
{
"janus" : "success",
"transaction" : "<same as the request>",
"data" : {
"id" : <unique integer plugin handle ID>
}
}
\endverbatim
*
* In case of an error, you'll receive an error message as the one introduced
* before. This request, if issued with a POST to a valid session endpoint, can only
* fail if you miss any of the required fields in the request or if the
* plugin you requested is not available in the server.
*
* To destroy the current session, instead, just send a "destroy" \c janus
* request:
*
\verbatim
{
"janus" : "destroy",
"transaction" : "<random string>"
}
\endverbatim
*
* This will also destroy the endpoint created for this session.
* If your session is currently managing one or more plugin handles,
* make sure you destroy them first (as explained in the next section).
* The server tries to do this automatically when receiving a session
* destroy request, but a cleaner approach on the client side would help
* nonetheless avoid potential issues.
*
* \section handles The plugin handle endpoint
* Once you've created a plugin handle, a new endpoint you can use is created
* in the server. Specifically, the new endpoint is constructed by
* concatenating the server root, the session identifier and the new
* plugin handle identifier you've been returned (\c e.g.,
* \c /janus/12345678/98765432).
*
* You can use this plugin handle for everything that is related to the
* communication with a plugin, that is, send the plugin a message,
* negotiate a WebRTC connection to attach to the plugin, and so on.
*
* To send a plugin a message/request, you need to \b POST the handle
* endpoint a \c janus "message" JSON payload. The \c body field will
* have to contain a plugin-specific JSON payload. In case the message
* also needs to convey WebRTC-related negotiation information, a \c jsep
* field containing the JSON-ified version of the JSEP object can be
* attached as well.
*
* \note If you attach a \c jsep object, whether it's an offer or an answer,
* you're stating your will to negotiate a PeerConnection. This means that
* an empty or invalid \c jsep object will trigger a validation and will
* cause the whole request to fail, so make sure you exclude the field
* completely from your request if all you're interested into is sending
* a message to a plugin.
*
* Here's an example of a message you may send the janus_echotest.c plugin
* to mute your audio:
*
\verbatim
{
"janus" : "message",
"transaction" : "sBJNyUhH6Vc6",
"body" : {
"audio" : false
}
}
\endverbatim
*
* The same message containing negotiation information as well, instead,
* (an OFFER, in this example), is presented here:
*
\verbatim
{
"janus" : "message",
"transaction" : "sBJNyUhH6Vc6",
"body" : {
"audio" : false
},
"jsep" : {
"type" : "offer",
"sdp" : "v=0\r\no=[..more sdp stuff..]"
}
}
\endverbatim
*
* Please notice that, if for any reason you don't want to use the
* trickling of ICE candidates from your application (which means you'll
* include them all in the SDP OFFER or ANSWER, which is usually not
* recommended), you'll have to add an additional <code>"trickle" : false</code>
* attribute to the "jsep" object, to explicitly tell Janus you won't
* send any \c trickle candidate (by default Janus will always assume
* support for trickle).
*
* If you're going to \c trickle candidates, instead, there is an ad-hoc
* message you can use to do so which is called, unsurprisingly, \c trickle
* and which you can use to send one or more trickle candidates to Janus.
* Since such a message is related to a specific PeerConnection, it will
* need to be addressed to the right Handle just as the \c message introduced
* previously. A \c trickle message can contain three different kind of
* information:
*
* - a single trickle candidate;
* - an array of trickle candidates;
* - a null candidate or a \c completed JSON object to notify the end of the
* candidates.
*
* This is an example of a single candidate being trickled:
*
\verbatim
{
"janus" : "trickle",
"transaction" : "hehe83hd8dw12e",
"candidate" : {
"sdpMid" : "video",
"sdpMLineIndex" : 1,
"candidate" : "..."
}
}
\endverbatim
*
* This, instead, is an example of how to group more trickle candidates
* in a single request (particularly useful if you're wrapping Janus in
* your server and want to reduce the number of transactions):
*
\verbatim
{
"janus" : "trickle",
"transaction" : "hehe83hd8dw12e",
"candidates" : [
{
"sdpMid" : "video",
"sdpMLineIndex" : 1,
"candidate" : "..."
},
{
"sdpMid" : "video",
"sdpMLineIndex" : 1,
"candidate" : "..."
},
[..]
]
}
\endverbatim
*
* Finally, this is how you can tell Janus that you sent all the trickle
* candidates that were gathered:
*
\verbatim
{
"janus" : "trickle",
"transaction" : "hehe83hd8dw12e",
"candidate" : {
"completed" : true
}
}
\endverbatim
*
* Plugins may handle this requests synchronously or asynchronously. In
* the former, plugins would return a response to the request itself
* immediately; in the latter, instead, the plugin would only notify a
* successful reception of the request, which it would process later.
* Considering the asynchronous nature of the Janus API, a successful
* management of such messages within Janus would in such case result in
* a \c janus "ack" messages being sent back to the client. A logical response
* to those messages, if needed, would be provided as an event in the
* long-poll interface described previously, and clients would be able
* to match it to the original request by means of the transaction
* identifiers. It is worth noting, though, that should a WebRTC negotiation
* be involved you don't have to expect an ANSWER to your OFFER to be
* sent back in the same transaction. A plugin may decide, in its
* application logic, to not provide you with an ANSWER right away, but
* only after some internal state changes occur. It's up to your application
* to handle the negotiation state accordingly.
*
* An example of an "ack" being sent back to the client, using the previous
* sample request as a reference, is presented here:
*
\verbatim
{
"janus" : "ack",
"transaction" : "sBJNyUhH6Vc6"
}
\endverbatim
*
* If you receive this ack instead of a "success" response, you can be
* sure the plugin has received the message, and is going to process it soon.
*
* In case of an error, instead, you'll receive an error message as the one
* introduced before. This request, if issued with a POST to a valid plugin
* handle endpoint, can only fail if you miss any of the required fields
* in the request, if the plugin you tried to contact is not available in
* the server anymore, if an error occurred in the plugin when trying to
* receive the message or if the \c jsep SDP you may have provided is
* invalid.
*
* To destroy the plugin handle, instead, just send a "detach" \c janus
* request:
*
\verbatim
{
"janus" : "detach",
"transaction" : "<random string>"
}
\endverbatim
*
* This will also destroy the endpoint created for this plugin handle.
* If your plugin handle is also managing an ongoing WebRTC connection
* with the plugin, make sure it is torn down as part of this process.
* The plugin implementation and the Janus core should do this
* automatically, but implementing the right behaviour in clients would
* help avoid potential issues nonetheless.
*
* If you're interested in keeping the handle alive but want to hang up
* the associated PeerConnection, if available, just send a "hangup" \c janus
* request:
*
\verbatim
{
"janus" : "hangup",
"transaction" : "<random string>"
}
\endverbatim
*
* This is usually not required, as you can typically just hangup your
* WebRTC PeerConnection normally and Janus will figure out it's gone
* by itself. Anyway, there are cases where this might be useful (e.g.,
* the connection was stuck in some weird ICE/DTLS state) as it can be
* used to reset the connection state for the handle.
*
* \section events WebRTC-related events
*
* As anticipated in the previous sections, Janus can send events and
* notifications at any time through the long poll channel (or, as it
* will be explained later, through the related push mechanisms made
* available by other transport protocols ). While this channel is
* mostly used to convey asynchronous notifications originated by
* plugins as part of the messaging they may have with the application
* using it, the same channel is actually used by Janus to trigger
* events related to different aspects pertaining a specific handle.
*
* In particular, for each handle involving a PeerConnection Janus
* provides notifications about its current state. To do so, the
* following events may be received as well:
*
* - \c webrtcup: ICE and DTLS succeeded, and so Janus correctly
* established a PeerConnection with the user/application;
* - \c media: whether Janus is receiving (\c receiving: \c true/false)
* audio/video (\c type: \c "audio/video") on this PeerConnection;
* - \c slowlink: whether Janus is reporting trouble sending/receiving
* (\c uplink: \c true/false) media on this PeerConnection;
* - \c hangup: the PeerConnection was closed, either by Janus or by
* the user/application, and as such cannot be used anymore.
*
* As such, to monitor the status of a PeerConnection as seen from
* Janus you can make use of these events to track what's going on. A
* correct flow for an active PeerConnection would be one that, after a
* WebRTC negotiation and setup, results in a \c webrtcup event followed
* by two \c media events (in case both audio and video have been
* negotiated) specifying that the first audio/video packets have been
* received. A \c hangup event would inform the user/application that
* no media is being exchanged with Janus anymore.
*
* Here are a few examples of how these events may look like.
*
* A PeerConnection becoming ready:
*
\verbatim
{
"janus" : "webrtcup",
session_id: <the session identifier>,
sender: <the handle identifier>
}
\endverbatim
*
* First audio bytes being received by Janus:
*
\verbatim
{
"janus" : "media",
session_id: <the session identifier>,
sender: <the handle identifier>,
"type" : "audio",
"receiving" : true
}
\endverbatim
*
* Audio not getting to Janus anymore for some reason:
*
\verbatim
{
"janus" : "media",
"session_id" : <the session identifier>,
"sender" : <the handle identifier>
"type" : "audio",
"receiving" : false
}
\endverbatim
*
* Audio getting to Janus again (same message as first audio):
*
\verbatim
{
"janus" : "media",
"session_id" : <the session identifier>,
"sender" : <the handle identifier>
"type" : "audio",
"receiving" : true
}
\endverbatim
*
* Janus reporting problems sending media to a user (user sent many NACKs
* in the last second; uplink=true is from Janus' perspective):
*
\verbatim
{
"janus" : "slowlink",
"session_id" : <the session identifier>,
"sender" : <the handle identifier>
"uplink" : true,
"nacks" : <number of NACKs in the last second>
}
\endverbatim
*
* PeerConnection closed for a DTLS alert (normal shutdown):
*
\verbatim
{
"janus" : "hangup",
"session_id" : <the session identifier>,
"sender" : <the handle identifier>,
"reason" : "DTLS alert"
}
\endverbatim
*
* It is important to point out that the \c media event notifications
* only apply if your PeerConnection is going to actually send media to
* Janus. A \c recvonly PeerConnection, for instance (e.g., as the
* Streaming plugin would create) would never trigger any \c media
* event, as Janus would never be receiving media, but only send it.
*
* \section WS WebSockets Interface
* In recent version of Janus we added support for WebSockets to control
* the server, along the already existing (and still the default) REST
* API. In fact, while WebSockets still present some more issues in terms
* of reachability when compared to plain HTTP, they definitely provide
* a more efficient means for implementing a bidirectional communication.
* This is especially useful if you're wrapping the Janus API on your
* servers, as it allows you to avoid all the noise and overhead introduced
* by several concurrent HTTP transactions and long polls by relying on
* what may be seen as a single "control channel".
*
* To interact with Janus using WebSockets you MUST specify a specific
* subprotocol, named \c janus-protocol, e.g.,
*
\verbatim
var websocket = new WebSocket('ws://1.2.3.4:8188', 'janus-protocol');
\endverbatim
*
* The \c janus.js library does this automatically.
*
* As anticipated at the beginning of this section, the actual messages
* being exchanged are exactly the same. This means that all the concepts
* introduced before still apply: you still create a session, attach to
* a plugin and interact with it exactly the same way. What is different
* is, of course, the REST path approach that becomes unavailable when
* using a WebSocket as a control channel. To address the idenfitiers
* that become missing using WebSockets, you'll need to add additional
* fields to the requests when necessary.
*
* So, when you want to create a session using the REST API, you send a
* POST to the server base path:
*
\verbatim
{
"janus" : "create",
"transaction" : "<random alphanumeric string>"
}
\endverbatim
*
* The same applies if you're interested in getting generic info from the
* Janus instance. Since there's no \b GET you can use, a specific \c janus
* request type called \c info is available:
*
\verbatim
{
"janus" : "info",
"transaction" : "<random alphanumeric string>"
}
\endverbatim
*
* Since you'd contact the base path for both requests, you don't need to add any identifier
* for this scenario. But if instead you want to attach to a plugin within
* the context of a specific session, using the REST API you'd send a
* post to the \c /janus/<session-id> endpoint:
*
\verbatim
{
"janus" : "attach",
"plugin" : "<the plugin's unique package name>",
"transaction" : "<random string>"
}
\endverbatim
*
* To make this work with WebSockets as well, you need to add a further
* field called \c session_id in the request:
*
\verbatim
{
"janus" : "attach",
"session_id" : <the session identifier>, // NEW!
"plugin" : "<the plugin's unique package name>",
"transaction" : "<random string>"
}
\endverbatim
*
* which will allow the WebSocket server to understand which session this
* request pertains to. At the same time, when you need to address a
* specific handle (e.g., to send a message to a plugin, or negotiate a
* WebRTC PeerConnection) you'll need to add a \c handle_id field to the
* request as well, or the request will be rejected:
*
\verbatim
{
"janus" : "message",
"session_id" : <the session identifier>, // NEW!
"handle_id" : <the handle identifier>, // NEW!
"transaction" : "sBJNyUhH6Vc6",
"body" : {
"audio" : false
}
}
\endverbatim
*
* Considering the bidirectional nature of WebSockets and the fact that
* the channel will be shared for different requests, you'll need to pay
* extra attention to the \c transaction identifier, which will allow you
* to map incoming responses and events to the request you sent that
* originated them.
*
* An \b important aspect to point out is related to keep-alive messages
* for WebSockets Janus channels. A Janus session is kept alive as long
* as there's no inactivity for 60 seconds: if no messages have been
* received in that time frame, the session is torn down by the server.
* A normal activity on a session is usually enough to prevent that;
* for a more prolonged inactivity with respect to messaging, on plain
* HTTP the session is usually kept alive through the regular long poll
* requests, which act as activity as long as the session is concerned.
* This aid is obviously not possible when using WebSockets, where a single channel is
* used both for sending requests and receiving events and responses. For
* this reason, an ad-hoc message for keeping alive a Janus session should
* to be triggered on a regular basis:
*
\verbatim
{
"janus" : "keepalive",
"session_id" : <the session identifier>,
"transaction" : "sBJNyUhH6Vc6"
}
\endverbatim
*
* This will make sure that the server detects activity on the session
* even when no actual messages are being exchanged with handles.
*
* As a last point, another slight difference with WebSockets comes from
* how push notifications are implemented. In the \ref plainhttp this is
* done via long polls: that is, you explicitly subscribe to notifications,
* and have to do that again as soon as an event has been received. With
* WebSockets, this is not needed: as soon as you create a session on a
* WebSocket, that channel becomes automatically subscribed for events
* related to that sessions, and you'll receive them on the same WebSocket.
* For the same reason, as soon as the WebSocket is closed, all the sessions
* created within its context are considered closed as well, and so their
* resources (including all the handles and PeerConnections) will be
* released as well.
*
* \note The same \c janus.js JavaScript library can be used both with the
* REST and the WebSockets API: all you need to do is provide the right
* Janus server address during the initialization and the library will
* use one or the other according to the protocol prefix.
*
* \section rabbit RabbitMQ interface
* The semantics of how the requests have to be built, when compared to
* the usage of plain HTTP, is exactly the same as for WebSockets, so
* refer to the \ref WS documentation for details about that.
*
* Of course, there are other aspects that differ when making use of
* RabbitMQ messaging to talk to Janus, rather than using HTTP messages
* or WebSockets. Specifically, RabbitMQ just basically forwards messages
* on queues, and as such implementing a pseudo-bidirectional channel
* as the Janus API requires some precaution.
*
* In particular, when configuring Janus to use RabbitMQ you'll have to
* specify \b two \b queues:
*
* - a queue for \b incoming messages (application -> Janus);
* - a queue for \b outgoing messages (Janus -> application).
*
* The proper usage of these queues will allow you to implement the kind
* of bidirectional channel Janus needs.
*
* Another aspect to point out is that Janus requires all requests to
* have a random \c correlation_id identifier. In fact, as pointed out
* in the previous sections, the Janus API is conceived as a request/response
* protocol that can involve asynchronous notifications as well. In order
* to make sure that an application can match a received response to one
* of the requests made earlier, Janus copies the \c correlation_id
* identifier from the original request in the response to it: this is
* compliant with the
* <a href="https://www.rabbitmq.com/tutorials/tutorial-six-python.html">RPC pattern</a>
* as specified in the RabbitMQ documentation. Notifications originated by
* Janus, instead, will not include a \c correlation_id identifier, and as
* such applications shouldn't expect any: applications will still be able
* to match a notification to a request, if the involved plugin was
* implemented to do so, by looking at the Janus-level \c transaction
* identifier.
*
* \section apimqtt MQTT interface
* The semantics of how the requests have to be built, when compared to
* the usage of plain HTTP, is exactly the same as for WebSockets, so
* refer to the \ref WS documentation for details about that.
*
* Of course, there are other aspects that differ when making use of
* MQTT messaging to talk to Janus, rather than using HTTP messages
* or WebSockets. Similar to RabbitMQ, MQTT just basically forwards messages
* on queues, and as such implementing a pseudo-bidirectional channel
* as the Janus API requires some precaution.
*
* In particular, when configuring Janus to use MQTT you'll have to
* specify \b two \b queues:
*
* - a queue for \b incoming messages (application -> Janus);
* - a queue for \b outgoing messages (Janus -> application).
*
* The proper usage of these queues will allow you to implement the kind
* of bidirectional channel Janus needs.
*
* \section apinanomsg Nanomsg interface
* The semantics of how the requests have to be built, when compared to
* the usage of plain HTTP, is exactly the same as for WebSockets, RabbitMQ
* and MQTT, so refer to the \ref WS documentation for details about that.
*
* Apart from that, the only configuration needed is related to the Nanomsg
* address to use, and whether it should be used to bind locally or to
* connect to a remote endpoint. Notice that only the \c NN_PAIR pattern
* is supported by the plugin, so no Pub/Sub or other variations.
*
* \section unix UnixSockets interface
* The semantics of how the requests have to be built, when compared to
* the usage of plain HTTP, is exactly the same as for WebSockets, RabbitMQ
* MQTT and Nanomsg, so refer to the \ref WS documentation for details about that.
*
* Apart from that, the only configuration needed is related to the path
* the client and server will be sharing, and the socket type. Notice that only the
* \c SOCK_SEQPACKET and \c SOCK_DGRAM types are supported in the plugin.
*
*/
/*! \page auth Authenticating the Janus API
* By default no authentication is involved when using the Janus API.
* This means that the API is completely open, and that everybody can
* talk to Janus and its plugins and set up media connections. There are
* times, though, where limiting access to Janus may be desirable, e.g.,
* when you want to prevent unauthorized users to join a service you
* created, or when you wrap the Janus API in your server and you want
* your application to be the only one to be able to interact with
* Janus from a messaging perspective.
*
* There are a couple of ways to authenticate requests in Janus:
*
* - using a \ref token (useful for web users);
* - using a \ref signed (useful for web users);
* - using a \ref secret (useful when wrapping the Janus API).
*
* \section token Stored token based authentication mechanism
* The token based authentication mechanism expects all users to provide,
* in each request, a \c token string attribute: if this token is
* known to Janus, the request will be accepted, otherwise it will be
* rejected as an \c unauthorized response. Configuring the token based
* authentication mechanism is easy enough: you can do that either via
* the command line (\c -A or \c --token-auth ) or in the \c janus.jcfg
* configuration (\c token_auth value in the \c general section).
*
* These tokens are completely opaque to Janus, meaning they can be
* pretty much anything that you want. Janus does not do any form of
* authorization/authentication itself: it's up to you to provide it
* with valid tokens users can use, e.g., as part of your server-side
* application handling users. You can add and remove tokens
* dynamically using the \ref admin, which means you will need to enable
* it if you want to use tokens, or otherwise all requests will fail
* (Janus will never have a valid token, so all requests will be rejected).
*
* You add tokens using the \c add_token admin request, while you
* remove them using \c remove_token. You can also limit the scope of tokens
* to specific plugins, by passing a list of plugins to \c add_token or
* modifying the token properties via \c allow_token and \c disallow_token.
* By default (\c add_token without any plugin specified) Janus assumes
* a new token is allowed to access all plugins. A list of all the
* existing tokens can be retrieved with a \c list_tokens request.
*
* Here are a couple of examples of how you can use the requests:
*
\verbatim
{
"janus" : "add_token",
"token": "a1b2c3d4",
"transaction" : "sBJNyUhH6Vc6",
"admin_secret": "adminpassword"
}
\endverbatim
*
* This adds a new token (a1b2c3d4) that is allowed to access all the
* plugins in Janus (no limitation provided in \c add_token ). To create
* a new token and limit the scope to a few selected plugins, you can
* use this other syntax instead (notice the extra \c plugins array):
*
\verbatim
{
"janus" : "add_token",
"token": "a1b2c3d4",
"plugins": [
"janus.plugin.streaming",
"janus.plugin.videoroom"
],
"transaction" : "sBJNyUhH6Vc6",
"admin_secret": "adminpassword"
}
\endverbatim
*
* In this other example, we're creating a new token, and also telling
* Janus that the only plugins a user with this token can access are
* the Streaming and Videoroom plugins. An attempt to attach to a
* different plugin (e.g., EchoTest) will result in an error.
*
* You can change the permissions a token has with respect to plugin
* access at any time. In the following example, we add a new plugin
* to the permissions for an existing token:
*
\verbatim
{
"janus" : "allow_token",
"token": "a1b2c3d4",
"plugins": [
"janus.plugin.echotest"
],
"transaction" : "sBJNyUhH6Vc6",
"admin_secret": "adminpassword"
}
\endverbatim
*
* This way, the provided token is now also allowed to access the EchoTest
* plugin. To remove a permission, the syntax is this one instead:
*
\verbatim
{
"janus" : "disallow_token",
"token": "a1b2c3d4",
"plugins": [
"janus.plugin.videoroom"
],
"transaction" : "sBJNyUhH6Vc6",
"admin_secret": "adminpassword"
}
\endverbatim
*
* To retrieve a list of all the valid tokens Janus is aware of, together
* with the plugins each of them is allowed to access, a \c list_tokens
* request can be used:
*
\verbatim
{
"janus" : "list_tokens",
"transaction" : "sBJNyUhH6Vc6",
"admin_secret": "adminpassword"
}
\endverbatim
*
* Finally, you can get rid of a token using a \c remove_token request:
*
\verbatim
{
"janus" : "remove_token",
"token": "a1b2c3d4",
"transaction" : "sBJNyUhH6Vc6",
"admin_secret": "adminpassword"
}
\endverbatim
*
* As anticipated, with the token based mechanism enabled, all users
* will need to provide a valid token as part of their requests. This is
* done by adding a \c token attribute to the request root, e.g.:
*
\verbatim
{
"janus" : "create",
"transaction" : "sBJNyUhH6Vc6",
"token": "usertoken"
}
\endverbatim
*
* The same applies for the long poll GET messages as well, which will
* need to contain the \c token as a query string parameter.
*
* A valid token will mean the request will be accepted and processed
* normally. A missing or invalid token, instead, will result in an
* error being returned:
*
\verbatim
{
"janus" : "error",
"transaction" : "sBJNyUhH6Vc6",
"error" : {
"code" : 403,
"reason" : "Unauthorized request (wrong or missing secret/token)"
}
}
\endverbatim
*
* An attempt to use a valid token to attach to a plugin it is not
* allowed to access, instead, will result in a different error:
*
\verbatim
{
"janus" : "error",
"transaction" : "sBJNyUhH6Vc6",
"error" : {
"code" : 405,
"reason" : "Provided token can't access plugin 'janus.plugin.echotest'"
}
}
\endverbatim
*
* \section signed HMAC-Signed token authentication
* Simple token based authentication requires the application host to
* continuously update the Janus instance on permission changes.
* Since Janus stores the tokens in memory, it can be problematic to guarantee
* the permissions of a dynamic application stay in sync with Janus.
*
* This problem can be solved by using a type of nonce / lease system to
* let the application server generate automatically expiring tokens without
* requiring direct communication with or any data storage in Janus.
*
* You can use the HMAC signed token mechanism by enabling token authentication
* in general, as above (\c -A or \c --token-auth) and specifying an encryption
* secret using \c --token-auth-secret. The same can be accomplished using
* \c token_auth and \c token_auth_secret in the \c general section of
* \c janus.jcfg.
*
* With Signed token support enabled, dynamic token creation via the \ref admin
* is not supported. Instead, Janus will look for tokens with a format like:
*
\verbatim
<timestamp>,janus,<plugin1>[,plugin2...]:<signature>
\endverbatim
*
* Where \c timestamp is a UNIX timestamp (seconds since 0:00 UTC, 1.1.1970)
* that marks the point in time at which the token expires;
* \c plugin1 etc. are the \c bundle names of plugins (such as \c janus.plugin.videoroom);
* and \c signature is the base64-encoded HMAC-SHA1 signature of the expiry
* timestamp in ASCII format, hashed using the \c --token-auth-secret as a key.
*
* The following function can be used to sign tokens using the node.js crypto library:
*
\verbatim
const crypto = require('crypto');
function getJanusToken(realm, data = [], timeout = 24 * 60 * 60) => {
const expiry = Math.floor(Date.now() / 1000) + timeout;
const strdata = [expiry.toString(), realm, ...data].join(',');
const hmac = crypto.createHmac('sha1', secret);
hmac.setEncoding('base64');
hmac.write(strdata);
hmac.end();
return [strdata, hmac.read()].join(':');
};
const token = getJanusToken('janus', ['janus.plugin.videoroom']),
\endverbatim
*
* The \c janus parameter here is the \c realm of the token. For authenticating the
* Janus API it should always be set to \c janus.
*
* When Janus encounters a token, it will:
*
* - verify that the timestamp has not passed
* - verify that the signature matches the timestamp
* - if the request requires access to a plugin, verify that the signature allows access
*
* Since the auth secret should never leave the application side, a signature
* like this can only be generated by the application server, which needs to
* be configured using the same secret.
*
* Please note that tokens of this sort cannot be revoked after being signed
* and passed to the client. Instead of signing tokens with late expirys,
* it is recommended to use tokens with shorter durations and generate and
* transition to a new token within the expiry time of every last token when
* the lease time is unknown and security is critical.
*
* \section secret Shared static secret
* Several deployers showed an interest in wrapping the Janus API on
* their server side: this allows them to keep the interaction with their
* users the way it was before, while still benefiting from the features
* Janus provides. This is an easy enough step, as it just needs developers
* to relay the involved SDP, and implementing the Janus API messages to
* handle the logic.
*
* That said, since in this case Janus would be contacted, through the API,
* just by a limited number of applications (e.g., application servers
* made in node.js, Ruby, Java Servlets or whatever) and not random
* browsers, it is reasonable to involve a mechanism to control who is
* allowed to contact and control it. The previous section described
* how you can exploit a token based mechanism for authenticating
* requests, but since in this case you only need a single application,
* or a limited set of them,
* to be able to talk to Janus, it's worthwhile to resort to something
* simpler and more static. To allow for that, Janus also exposes a
* shared API secret mechanism: that is, you configure Janus with a string
* applications need to present when sending requests, and if they don't,
* Janus rejects them with an \c unauthorized message.
*
* Configuring the API secret mechanism is easy enough: you can do that
* either via the command line (\c -a or \c --apisecret ) or in the
* \c janus.jcfg configuration (\c api_secret value in the \c general section).
* When enabled, all requests addressed to that Janus instance \b MUST
* also contain an \c apisecret field in the Janus message headers. For
* instance, this message presented above would fail:
*
\verbatim
{
"janus" : "create",
"transaction" : "<random alphanumeric string>"
}
\endverbatim
*
\verbatim
{
"janus" : "error",
"transaction" : "<same as request>"
"error" : {
"code" : 403,
"reason" : "Unauthorized request (wrong or missing secret/token)"
}
}
\endverbatim
*
* For a successful transaction, the message would have to look like this:
*
\verbatim
{
"janus" : "create",
"apisecret" : "<API secret configured in Janus>",
"transaction" : "<random alphanumeric string>"
}
\endverbatim
*
* The same applies for the long poll GET messages as well, which will
* need to contain the \c apisecret as a query string parameter.
*
*/
/*! \page admin Admin/Monitor API
* Recent versions of Janus introduced a new feature: an Admin/Monitor
* API that can be used to ask Janus for more specific information
* related to sessions and handles. This is especially useful when you
* want to debug issues at the media level.
*
* \note Right now, this new API mostly allows you to retrieve information,
* but only act on part of it: for more interaction (e.g., to force a
* session removal), you can rely on the existing \ref rest for the purpose.
* Besides, notice that this is a pull-based API. If you're interested in
* asynchronous notifications about the internal state of core and plugins,
* check the recently added janus_eventhandler mechanism instead.
*
* The API, for security reasons, is typically not enabled by default in any of the
* transport plugins: that's definitely the case for the stock transport
* plugins, for instance, while additional, third party plugins may choose
* to expose the functionality without requiring any tweaking. As to the
* existing transport, you can enable the admin API by editing the \c [ \c admin \c ]
* section in the related transport configuration file (e.g., \c janus.transport.http.jcfg
* for the REST interface, to use the admin API over HTTP). The configuration
* is pretty much the same as the one for the Janus API. In addition, you
* can configure restrictions in the form of a password/secret that clients
* need to provide or other transport-specific ones.
*
* For what concerns the syntax, it's very similar to the \ref rest and
* so this page will briefly discuss the differences. Notice that, when
* using WebSockets, you'll have to use <code>janus-admin-protocol</code>
* as the subprotocol, instead of the <code>janus-protocol</code> of the
* regular Janus API.
*
* \section adminreq Admin API requests
* There are several different requests that this API implementents, so,
* to make this documentation easier to read and the functionality easier
* to identify, we can group requests depending on what they provide.
*
* \subsection adminreqg Generic requests
* - \c info: get the generic on the Janus instance; this returns exactly
* the same information that a Janus API \c info request would return,
* and doesn't require any secret;
* - \c ping: a simple ping/pong mechanism for the Admin API, that returns
* a \c pong back that the client can use as a healthcheck or to measure
* the protocol round-trip time; together with the \c info request introduced
* above, it's the only one that doesn't require a secret.
*
* \subsection adminreqc Configuration-related requests
* - \c get_status: returns the current value for the settings that can be
* modified at runtime via the Admin API (see below);
* - \c set_session_timeout: change the session timeout value in Janus;
* - \c set_log_level: change the log level in Janus;
* - \c set_log_timestamps: selectively enable/disable adding a timestamp
* to all log lines Janus writes on the console and/or to file;
* - \c set_log_colors: selectively enable/disable using colors in all
* log lines Janus writes on the console and/or to file;
* - \c set_locking_debug: selectively enable/disable a live debugging of
* the locks in Janus on the fly (useful if you're experiencing deadlocks
* and want to investigate them);
* - \c set_refcount_debug: selectively enable/disable a live debugging of
* the reference counters in Janus on the fly (useful if you're experiencing
* memory leaks in the Janus structures and want to investigate them);
* - \c set_libnice_debug: selectively enable/disable libnice debugging;
* - \c set_max_nack_queue: change the value of the max NACK queue window;
* - \c set_no_media_timer: change the value of the no-media timer property;
* - \c set_slowlink_threshold: change the value of the slowlink-threshold property.
*
* \subsection adminreqt Token-related requests
* - \c add_token: add a valid token (only available if you enabled the \ref token);
* - \c allow_token: give a token access to a plugin (only available if you enabled the \ref token);
* - \c disallow_token: remove a token access from a plugin (only available if you enabled the \ref token);
* - \c list_tokens: list the existing tokens (only available if you enabled the \ref token);
* - \c remove_token: remove a token (only available if you enabled the \ref token).
*
* \subsection adminreqs Session-related requests
* - \c accept_new_sessions: configure whether Janus should accept new
* incoming sessions or not; this can be particularly useful whenever, e.g.,
* you want to stop accepting new sessions because you're draining this instance;
* - \c list_sessions: list all the sessions currently active in Janus
* (returns an array of session identifiers);
* - \c destroy_session: destroy a specific session; this behaves exactly
* as the \c destroy request does in the Janus API.
*
* \subsection adminreqh Handle- and WebRTC-related requests
* - \c list_handles: list all the ICE handles currently active in a Janus
* session (returns an array of handle identifiers);
* - \c handle_info: list all the available info on a specific ICE handle;
* if a \c plugin_only property is set to \c true then only the plugin-specific
* information is returned, excluding the more verbose WebRTC info and stats;
* - \c start_pcap: start dumping incoming and outgoing RTP/RTCP packets
* of a handle to a pcap file (e.g., for ex-post analysis via Wireshark);
* - \c stop_pcap: stop the pcap dump;
* - \c start_text2pcap: same as above, but saves to a text file instead,
* to be fed to \c text2pcap in order to generate a \c .pcap or \c .pcapng file;
* - \c stop_text2pcap: stop the text2pcap dump;
* - \c message_plugin: send a synchronous request to a plugin and return a
* response; implemented by most plugins to facilitate and streamline the
* management of plugin resources (e.g., creating rooms in a conference plugin);
* - \c hangup_webrtc: hangups the PeerConnection associated with a specific
* handle; this behaves exactly as the \c hangup request does in the Janus API.
* - \c detach_handle: detached a specific handle; this behaves exactly
* as the \c detach request does in the Janus API.
*
* \subsection adminreqe Event handlers-related requests
* - \c query_eventhandler: send a synchronous request to an event handler and
* return a response; implemented by most event handlers to dynamically
* configure some of their properties;
* - \c custom_event: push a custom "external" event to notify via event handlers;
* this can be useful whenever info from a third-party application needs to be
* easily correlated to events originated by Janus, or to push information
* Janus doesn't have available (e.g., a script polling CPU usage regularly).
*
* \subsection adminreql Custom logging-related requests
* - \c custom_logline: push a custom "external" string to print on the logs;
* this can be useful whenever info from a third-party application needs to be
* injected in the Janus logs for whatever reason. The log level can be chosen.
*
* \subsection adminreqz Helper requests
* - \c resolve_address: helper request to evaluate whether this Janus instance
* can resolve an address via DNS, and how long it takes;
* - \c test_stun: helper request to evaluate whether this Janus instance
* can contact a STUN server, what is returned, and how long it takes.
*
* \section adminsyntax Admin API syntax
* Following the same spirit of the \ref rest these methods need to be
* invoked on the right path and/or providing the right \c session_id and
* \c handle_id identifiers. Specifically, the following requests must be invoked
* without any session/handle information, as they're global requests:
*
* - \c info , \c ping , \c get_status , all the configuration setters, all
* the token requests, all the event-handler related requests, all the
* helper requests, \c accept_new_sessions and \c list_sessions
*
* Here's an example of how such a request and its related response might look like:
*
\verbatim
POST /admin
{
"janus" : "list_sessions",
"transaction" : "<random alphanumeric string>",
"admin_secret" : "<password specified in janus.jcfg, if any>"
}
\endverbatim
*
*
\verbatim
{
"janus" : "success",
"transaction" : "<same as the request>",
"sessions" : [
<session ID #1>,
<session ID #2>,
[..]
<session ID #n>
]
}
\endverbatim
*
* On the other hand, some requests may be targeting a specific session,
* in which case a \c session_id property must be provided. Specifically,
* these are the requests that do need a valid session identifier:
*
* - \c destroy_session , \c list_handles
*
* Using the REST API, this can be done by appending the session identifier
(e.g., one of the ID returned by a \c list_sessions call) to the API root,
* but a more generic approach that works for all transports is to just
* specify a \c session_id property in the request, e.g.:
*
\verbatim
POST /admin/12345678
{
"janus" : "list_handles",
"session_id" : 12345678,
"transaction" : "<random alphanumeric string>",
"admin_secret" : "<password specified in janus.jcfg, if any>"
}
\endverbatim
*
*
\verbatim
{
"janus" : "success",
"transaction" : "<same as the request>",
"session_id" : 12345678,
"handles" : [
<handle ID #1>,
<handle ID #2>,
[..]
<handle ID #n>
]
}
\endverbatim
*
* Finally, some requests need not only a valid session identifier, but
* a handle identifier as well, as they may address a specific handle
* that the Janus instance is serving. It is the case for all requests
* that address a specific handle and/or the related PeerConnection,
* namely:
*
* - \c handle_info , all the pcap-related requests, \c message_plugin ,
* \c hangup_webrtc and \c detach_handle
*
* The following is an example of how a \c handle_info call addressing
* a specific handle might look like. Since this is a handle-specific
* request, the correct handle identifier must be
* referenced, e.g., by appending the ID to the session it belongs to
* or adding a \c handle_id attribute besides the \c session_id parent:
*
\verbatim
POST /admin/12345678/98765432
{
"janus" : "handle_info",
"session_id" : 12345678,
"handle_id" : 98765432,
"transaction" : "<random alphanumeric string>",
"admin_secret" : "<password specified in janus.jcfg, if any>"
}
\endverbatim
*
*
\verbatim
{
"janus" : "success",
"transaction" : "<same as the request>",
"session_id" : 12345678,
"handle_id" : 98765432,
"info" : {
"session_id" : 12345678,
"session_last_activity": 7927759122,
"session_transport": "janus.transport.websockets",
"handle_id" : 98765432,
"opaque_id": "echotest-YZcsLRCI4uSV",
"loop-running": true,
"created": 18695669309,
"current_time": 18706199704,
"plugin": "janus.plugin.echotest",
"plugin_specific": {
// plugin specific (e.g., EchoTest internals)
},
"flags": {
// flags
},
"agent-created": 18696092523,
"ice-mode": "full",
"ice-role": "controlled",
"sdps": {
"profile": "UDP/TLS/RTP/SAVPF",
"local": "v=0[..]",
"remote": "v=0[..]"
},
"queued-packets": 0,
"streams": [
// WebRTC info, including SSRCs, codecs, ICE and DTLS states, RTCP stats, etc.
]
}
}
\endverbatim
*
* With respect to the \c handle_info request we used as an example, here,
* the actual content of the last response is omitted for brevity, but
* you're welcome to experiment with it in order to check whether more
* information (of a different nature, maybe) may be useful to have. In
* particular, you may want to play with the plugin-specific details, as
* different plugins will return different information according to what
* they provide: for instance, the VideoRoom plugin might clarify whether
* a handle is being used for publishing media or for receiving it, and
* what are the involved IDs, the current status of the delivery, and so on.
* At the same time, the \c streams object will contain invaluable details
* related to the WebRTC PeerConnection associated with the handle, as
* in input/output statistics statistics (bytes, bytes per seconds, NACKs,
* etc.) or the SDP/ICE/DTLS states. Notice that the information as
* returned by the Admin API here is just a snapshot: if you're more
* interested in how this information evolves in a more dynamic way, you
* may want to start using the Event Handlers instead, which return pretty
* much the same information, but conveying it as dynamic events pushed
* to an application you control.
*
* \section adminpcap Capturing unencrypted WebRTC traffic
* As anticipated, you can also enable/disable the dumping of the RTP/RTCP
* packets a handle is sending and receiving to a pcap or text2pcap file. This is
* especially useful for debugging reasons, e.g., to check whether or not
* there are issues in a specific packet Janus is sending or receiving
* with tools like Wireshark. Notice that this is not supposed to be used
* for recording Janus streams: while it can be used for that, the
* janus_recorder utility is much more suited for the task, and is what
* all plugins make use of when they're interested in \ref recordings .
*
* The syntax for the \c start_pcap and \c start_text2pcap commands is
* trivial, and apart from the command name pretty much the same: all you
* need to specify are information on the handle to dump, information
* on the target file (target folder and filename), and whether to truncate
* packets or not before dumping them:
*
\verbatim
POST /admin/12345678/98765432
{
"janus" : "start_pcap", // Use start_text2pcap for a text file instead
"folder" : "<folder to save the dump to; optional, current folder if missing>",
"filename" : "<filename of the dump; optional, random filename if missing>",
"truncate" : "<number of bytes to truncate packet at; optional, truncate=0 (don't truncate) if missing>",
"transaction" : "<random alphanumeric string>",
"admin_secret" : "<password specified in janus.jcfg, if any>"
}
\endverbatim
*
* If successful, the full path of the dump file can be obtained by doing
* a \c handle_info request. A \c stop_pcap or \c start_text2pcap command
* is even easier to generate, as it doesn't need any parameter:
*
\verbatim
POST /admin/12345678/98765432
{
"janus" : "stop_pcap", // Use stop_text2pcap if you started a text-based capture
"transaction" : "<random alphanumeric string>",
"admin_secret" : "<password specified in janus.jcfg, if any>"
}
\endverbatim
*
*/
/*! \page deploy Deploying Janus
*
* When you're going to deploy Janus (e.g., to try the demos we made
* available out-of-the-box), there's one thing that is important to point
* out: while Janus does indeed provide an HTTP RESTful interface (documented
* in \ref rest), it does \b NOT also act as a webserver for static files.
* This means you'll need a different webserver to host static files, including
* HTML/PHP/JSP/etc. pages, JavaScript files, images and whatever is part
* of your web application.
*
* That said, deploying Janus is, in principle, quite simple: just start Janus on a
* machine, put the HTML and JavaScript that will make use of it on a webserver
* somewhere, make sure the JavaScript code is configured with the right
* address for the server and you're done!
*
* Let's assume, for the sake of simplicity, that your webserver is serving
* files on port \c 80. By default, Janus binds on the \c 8088 port for HTTP.
* So, if Janus and the webserver hosting the are co-located, all you need to get your
* application working is configure the web application to point to the right
* address for the server. In the demos provided with these packages, this
* is done by means of the \c server variable:
*
\verbatim
var server = "http://" + window.location.hostname + ":8088/janus";
\endverbatim
*
* which basically tells the JavaScript application that the Janus API can be
* contacted at the same host as the website but at a different port (8088) and path (/janus).
* In case you configured the server differently, e.g., 7000 as the port
* for HTTP and /my/custom/path as the API endpoint, the \c server variable
* could be built this way:
*
\verbatim
var server = "http://" + window.location.hostname + ":7000/my/custom/path";
\endverbatim
*
* In case the webserver and Janus are <b>NOT</b> colocated, instead, just
* replace the \c window.location.hostname part with the right address of
* the server, e.g.:
*
\verbatim
var server = "http://www.example.com:8088/janus";
\endverbatim
*
* It's important to point out, though, that this more "static" approach
* only works if the webserver is serving files via HTTP. As soon as you
* start involving \b HTTPS, things start to get more complicated: in fact,
* for security reasons you cannot contact an HTTP backend if the page is
* made available via HTTPS. This means that if you're interested in serving
* your web application via HTTPS, you'll need to enable the HTTPS embedded
* webserver in Janus as well, and configure the JavaScript code to refer to
* that itself, e.g.:
*
\verbatim
var server = "https://" + window.location.hostname + ":8089/janus";
\endverbatim
*
* assuming \c 8089 is the port you configured Janus to use for HTTPS.
* To make this more "dynamic", e.g., allow both HTTP and HTTPS instead of
* just sticking to one, you might make use of something like this:
*
\verbatim
var server = null;
if(window.location.protocol === 'http:')
server = "http://" + window.location.hostname + ":8088/janus";
else
server = "https://" + window.location.hostname + ":8089/janus";
\endverbatim
*
* that is evaulate the right address to use at runtime.
*
* Anyway, there's a much easier way to address these scenarios, which
* is explained in the next section.
*
* \section apache Deploying Janus behind a web frontend
*
* To avoid most of the issues explained above, an easy approach can be
* deploying Janus behind a frontend (e.g., Apache HTTPD, nginx, lighttpd
* or others) that would act as a reverse proxy for incoming requests.
* This would allow you to make the Janus API available as a relative path
* of your web application, rather than a service reachable at a different
* port and/or domain.
*
* Configuring the web application, as a consequence, would be even easier,
* as all you'd need to do would be to provide a relative path for the API,
* e.g.:
*
\verbatim
var server = "/janus";
\endverbatim
*
* which would automatically work whether the page is served via HTTP or
* HTTPS. In fact, all the HTTPS requests would be terminated at the webserver,
* which would then always send simple HTTP messages to the server itself.
*
* An easy way to do so in Apache HTTPD is by means of the following directives:
*
\verbatim
ProxyRequests Off
ProxyVia Off
ProxyPass /janus http://127.0.0.1:8088/janus retry=0
ProxyPassReverse /janus http://127.0.0.1:8088/janus
\endverbatim
*
* Different versions of HTTPD or different webservers may require a
* different syntax, but the principle is usually always the same: you instruct
* the webserver to act as a proxy for a local endpoint, in this case a
* Janus instance colocated at the webserver and configured with the
* default settings.
*
* A way to do the same with nginx, as explained by some Janus users
* <a href="https://groups.google.com/forum/#!topic/meetecho-janus/dIv-4s0HOdw">here</a>,
* is the following directive:
*
\verbatim
location /janus {
proxy_pass http://127.0.0.1:8088/janus;
}
\endverbatim
*
* \section webserver A quick and easy web server
* While opening WebRTC-powered web applications by just opening the
* application HTML files from file system works with some browsers, it
* doesn't in others. Specifically, this works in Firefox but not in Chrome
* (see <a href="https://github.com/meetecho/janus-gateway/issues/291">issue #291</a>).
* Anyway, considering that you will eventually want other people besides
* you to use your Janus services, this means that to test and use Janus
* you'll want/need to host your applications on a webserver.
*
* If you're not interested in configuring a full-fledged webserver, but
* are only interested in a quick and easy way to test the demos, you can
* make use of the embedded webservers some frameworks like PHP and Python
* provide. To start a webserver for the demos, for instance, just open a
* terminal in the \c html folder of the project, and type:
*
*\verbatim
php -S 0.0.0.0:8000
\endverbatim
*
* or:
*
*\verbatim
python -m SimpleHTTPServer 8000
\endverbatim
*
* This will setup a webserver on port \c 8000 for you to use, meaning you'll
* just need to have your browser open a local connection to that port to
* try the demos:
*
*\verbatim
http://yourlocaliphere:8000
\endverbatim
*
* You can do the same on a different port to also access the HTML version of the Doxygen generated
* documentation, starting the embedded webservers from the \c docs/html
* folder instead:
*
*\verbatim
php -S 0.0.0.0:9000
\endverbatim
*
* or:
*
*\verbatim
python -m SimpleHTTPServer 9000
\endverbatim
*
* \section deplyws Using Janus with WebSockets
*
* Configuring the usae of WebSockets rather than the REST API in the JavaScript
* library is quite trivial, as it's a matter of passing a \c ws:// address
* instead of an \c http:// one to the constructor. That said, most of the same
* considerations provided for the REST API apply here as well, e.g.,
* to just use \c window.location.hostname if the webserver and Janus are
* colocated:
*
\verbatim
var server = "ws://" + window.location.hostname + ":8188/";
\endverbatim
*
* to specify the port if you change it:
*
\verbatim
var server = "ws://" + window.location.hostname + ":7000/";
\endverbatim
*
* and/or the right address of the server in case the webserver and Janus
* are <b>NOT</b> colocated:
*
\verbatim
var server = "ws://www.example.com:8188/";
\endverbatim
*
* Notice how the path (\c /janus by default for HTTP) is not provided
* for WebSockets, as it is ignored by the server.
*
* The considerations for deploying Janus behind a proxy/webserver, though,
* differ if you use WebSockets, as most webservers don't provide an easy
* way to proxy WebSocket requests, and usually require custom modifications
* for the purpose. Recent versions of HTTPD (>= 2.4.5), with the right
* module (proxy_wstunnel), do allow you to also proxy WebSockets requests the
* same way you do with HTTP, which can be useful to do the same
* WSS-to-WS proxying in a frontend. Here's a sample configuration:
*
\verbatim
<IfModule mod_proxy_wstunnel.c>
ProxyPass /janus-ws ws://127.0.0.1:8188 retry=0
ProxyPassReverse /janus-ws ws://127.0.0.1:8188
</IfModule>
\endverbatim
*
* that will allow you to expose a <code>wss://myserver/janus-ws</code>
* or <code>ws://myserver/janus-ws</code> address, and have all communication
* forwarded to and from Janus at <code>ws://127.0.0.1:8188</code>.
*
* Similar configurations are probably available for other systems as well,
* so in case this is something you're interested in, we recommend you
* follow the best practices related to that made available by the web server developers.
*
* \section both Using fallback addresses
* As anticipated in the \ref JS section, you can also pass an array of servers
* to the Janus library initialization. This allows you, for instance, to
* pass a link to both the WebSockets and REST interfaces, and have the
* library try them both to see which one is reachable, e.g.:
*
\verbatim
var ws_server = "ws://" + window.location.hostname + ":8188/";
var http_server = "http://" + window.location.hostname + ":8088/janus";
var servers = [ws_server, http_server];
\endverbatim
*
* which is especially useful if you're not sure whether or not WebSockets
* will work in some specific networks. Please notice that, for the individual
* servers listed in the array, the same considerations given above (e.g.,
* in terms of relative vs. absolute linking) still apply.
*
* Such an approach can also be used when you've deployed several different
* instances of Janus, and you want the library to try some and fallback
* to others if any of them is not reachable for any reason.
*
*/
/*! \page service Janus as a daemon/service
*
* By default, Janus starts in foreground, and as such works as a server
* application that you start normally and displays output on the console.
* That said, there are several reasons why you may not want to keep
* Janus in the foreground, while still being interested in checking
* the console to see what's happening.
*
* There are different ways to "daemonize" it and have it run as a service,
* though. This page tries to summarize a few ways to do so, starting
* from "dumb" approaches like sending to background and/or using screen/tmux,
* to more sophisticated approaches involving \c systemd, \c upstart
* and others.
*
* \section daemon Running Janus as a daemon
* Since version \c 0.1.0, you can run Janus as a daemon application. To
* do so, just pass either \c -b or \c --daemon as a command line
* argument, and Janus will be daemonized. Just beware, though, that
* since this results in stdout/stdin/stderr being closed, you MUST
* specify a log file for Janus to use, either via command line (\c -L
* or \c --log-file ) or in \c janus.jcfg.
*
* \section bg Running in background
* Another simple way to run Janus in the background is to just append the
* \c & character to the command line. Anyway, this will still "flood" the console
* with output from Janus. While there are ways to handle it (e.g., as
* explained <a href="http://www.thegeekstuff.com/2010/05/unix-background-job/">here</a>),
* a nice and easy way to handle this is redirecting the output to a
* separate file, e.g., a dedicated log:
*
\verbatim
/opt/janus/bin/janus -d 5 -6 >/path/to/mylogfile 2>&1 &
\endverbatim
*
* This is especially useful in case you want to keep a log of what
* happened when Janus was running, and can also be used as a simple and
* effective way to watch the console "live" using \c tail:
\verbatim
tail -f /path/to/mylogfile
\endverbatim
*
* \section screen Terminal multiplexers
* Another easy way to run Janus in the background is using terminal
* multiplexers like \c screen or \c tmux. If you're not familiar with
* such applications, you can find a quick overview
* <a href="https://en.wikipedia.org/wiki/Terminal_multiplexer">here</a>.
*
* The following is a simple example with \c screen:
*
\verbatim
screen -S janus -d -m
screen -r janus -X stuff $'/opt/janus/bin/janus -d 5 -6\n'
\endverbatim
*
* This will create a session called "janus" and launch Janus in it with
* a few command line options (in this case, just the option to enable
* IPv6 support and set the debug to verbose). Janus will then be running
* in the background: accessing the console is just a matter of attaching
* to the "janus" screen:
*
\verbatim
screen -r janus
[CTRL+A+D to detach again]
\endverbatim
*
* Terminal multiplexers usually allow for logging the output to file
* as well, if you want to keep an history of what happened during the
* Janus lifetime.
*
* \section systemd systemd
* This section shows how you can add Janus as a service to
* <a href="https://en.wikipedia.org/wiki/Systemd">systemd</a>.
*
\verbatim
[Unit]
Description=Janus WebRTC Server
After=network.target
[Service]
Type=simple
ExecStart=/opt/janus/bin/janus -o
Restart=on-abnormal
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
\endverbatim
*
* \note Remember to adjust the path in ExecStart to match the Janus binary path.
*
* \warning Please beware that, per the default \c RateLimitInterval and
* and \c RateLimitBurst values in the default sytemd configuration, logger
* messages are dropped if they arrive faster than ~33 per second. You
* may want to configure them accordingly, or otherwise Janus log messages
* may be missing. To fix this, setting <code>RateLimitInterval=1s</code>
* and <code>RateLimitBurst=2000</code> in
* <code>/etc/systemd/journald.conf</code> is usually enough.
*
* \note systemd example provided by
* <a href="https://github.com/meetecho/janus-gateway/pull/306">\@saghul</a>
*
* \section upstart upstart
* This section shows how you can add Janus as a daemon to
* <a href="http://upstart.ubuntu.com/">upstart</a>, which is
* typically available on Ubuntu systems.
*
\verbatim
description "janus"
start on filesystem or runlevel [2345]
stop on runlevel [!2345]
limit nofile 50000 50000
limit core unlimited unlimited
respawn
respawn limit 10 5
exec /opt/janus/bin/janus
\endverbatim
*
* \note upstart example provided by
* <a href="https://github.com/meetecho/janus-gateway/pull/306">\@ploxiln</a>
*
* \warning In case starting Janus depends on some external conditions, you
* may need to modify the \c start and \c stop lines accordingly. Here you can
* find an <a href="https://github.com/meetecho/janus-gateway/pull/455">example</a>,
* provided by <a href="https://github.com/meetecho/janus-gateway/pull/455">\@stormbkk87</a>,
* showing how you can wait, for instance, for RabbitMQ to start before starting Janus too.
*
* \section sysvinit sysvinit
* This section shows how you can add Janus as a daemon to
* SysVinit based systems.
*
\verbatim
#!/bin/sh
### BEGIN INIT INFO
# Provides: Janus
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Janus WebRTC Server
# Description: Janus WebRTC Server
### END INIT INFO
DAEMON=/usr/bin/janus
DAEMON_NAME=janus
# Add any command line options for your daemon here
DAEMON_OPTS="-D -o"
# This next line determines what user the script runs as.
# Root generally not recommended but necessary if you are using the Raspberry Pi GPIO from Python.
DAEMON_USER=root
# The process ID of the script when it runs is stored here:
PIDFILE=/var/run/$DAEMON_NAME.pid
. /lib/lsb/init-functions
do_start () {
log_daemon_msg "Starting system $DAEMON_NAME daemon"
start-stop-daemon --start --background --no-close --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON -- $DAEMON_OPTS >> /var/log/$DAEMON_NAME.log 2>&1
log_end_msg $?
}
do_stop () {
log_daemon_msg "Stopping system $DAEMON_NAME daemon"
start-stop-daemon --stop --pidfile $PIDFILE --retry 10
log_end_msg $?
}
case "$1" in
start|stop)
do_${1}
;;
restart|reload|force-reload)
do_stop
do_start
;;
status)
status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
;;
*)
echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
exit 1
;;
esac
exit 0
\endverbatim
*
* \note sysvinit example provided by
* <a href="https://github.com/saghul">\@saghul</a>
*
* \section supervisor supervisor
* This section shows how you can add Janus to
* <a href="http://supervisord.org/">supervisor</a>, which is
* typically available on Ubuntu systems.
*
\verbatim
[program:janus]
command=/opt/janus/bin/janus
user=root
autostart=true
autorestart=true
stderr_logfile=/var/log/janus.err.log
stdout_logfile=/var/log/janus.out.log
\endverbatim
*
* \note The above configuration file should be added to
* <code>/etc/supervisor/conf.d/janus.conf</code>. Then the following commands
* should be run:
*
\verbatim
sudo supervisorctl reread
sudo supervisorctl update
\endverbatim
*
* \section Others
* TODO.
*
*/
/*! \page debug Debugging Janus
*
* In the magical world of fairies and unicorns, the sun always shines
* and everything always works smoothly and without issues. Unfortunately,
* this is not the world we live in, and so you might still encounter
* issues using Janus, e.g., unexpected crashes and the like. We always
* try and tackle bugs as soon as we spot them, but some issues may be
* always lingering in the background.
*
* Should you encounter a bug or a crash, open a new
* <a href="https://github.com/meetecho/janus-gateway/issues/new">issue</a>
* on GitHub. Make sure you carefully read the
* <a href="https://github.com/meetecho/janus-gateway/blob/master/CONTRIBUTING.md">guidelines</a>
* for contributing, or otherwise we may decide to close the issue and
* not even look at it.
*
* What's important for us to look into issues and bugs definitely is
* having enough information to do so. As such, whenever possible try to
* provide as many details and data as possible. Quite useful to us are
* GDB stacktraces and/or AddressSanitizer output. The following sections
* give a quick overview on how you can collect this information after
* a crash, but for a more detailed description of the tools you should
* refer to the related documentation pages and tutorials.
*
* \section gdb GDB
* GDB is the <a href="http://www.gnu.org/software/gdb/">GNU Project Debugger</a>
* and is an effective tool for looking at what has happened (or is
* happening) inside an application. As such, it's quite useful to spot
* bugs and the like, as it can provide information about the values of
* variables when they were used and the application crashed.
*
* When Janus crashes, you should get a core dump file somewhere. This is
* a recorded state of the application memory at the time of crashing, and
* so a backtrace of what lead to an issue can help. You can open such
* a core dump file via gdb this way:
*
\verbatim
gdb /path/to/bin/janus /path/to/coredump
gdb bt
\endverbatim
*
* The \c bt command retrieves the backtrace, and is what you should provide
* as part of your new issue.
*
* \note Please \c DON'T paste this backtrace in the issue text. Use a
* service like <a href="https://gist.github.com/">Gist</a> or
* <a href="http://pastebin.com/">Pastebin</a> and pass the generated
* link instead.
*
* \section sanitizer Address Sanitizer
* An even better tool for spotting issues is
* <a href="https://code.google.com/p/address-sanitizer/">Address Sanitizer</a>,
* a fast memory error detector. Since it can spot memory errors, it's
* very useful to find out about hidden race conditions and the like.
*
* Unlike GDB which can be used as is, though, to use Address Sanitizer
* you'll first need to recompile Janus with some new settings, as it
* requires a specific dependency on a library, libasan, which you'll need
* to install through your repository manager if needed. Besides, you'll
* need at least gcc 4.8 for this to work: older versions of gcc won't
* work.
*
* Once you've installed libasan, reconfigure Janus like this:
*
\verbatim
CFLAGS="-fsanitize=address -fno-omit-frame-pointer" LDFLAGS="-lasan" ./configure --prefix=/opt/janus
\endverbatim
*
* Of course you're free to add whatever additional configuration parameter
* you were using before: the important parts are the environment variables
* before that. Once done configuring, do a \c make \c clean (to make sure
* everything is recompiled from scratch) and then a \c make and \c make \c install
* as usual.
*
* At this point, your Janus version should be Address Sanitizer compliant.
* To make sure, try using \c ldd to check whether libasan is indeed a
* dependency or not:
*
\verbatim
ldd janus | grep asan
\endverbatim
*
* If it is, you're done: whenever Janus crashes for any reason, you'll
* get additional output from Address Sanitizer automatically with details
* on what went wrong, and that's what you should provide as part of the
* issue content. Just as a side note, please beware that using Address
* Sanitizer Janus will run just a bit slower, even though not to the
* point of being unusable (as when using, e.g., valgrind).
*
* \note Please \c DON'T paste Address Sanitizer output in the issue text.
* Use a service like <a href="https://gist.github.com/">Gist</a> or
* <a href="http://pastebin.com/">Pastebin</a> and pass the generated
* link instead.
*
*/
/*! \page pluginslist Plugins documentation
* Out of the box, Janus comes with a set of different and heterogeneous
* media manipulation plugins. These can be used individually or composed
* together at an application level for building complex WebRTC-based
* media applications.
*
* The list of plugins currently available is the following. Since new
* plugins may become available available in the future, make sure you
* come back to this page for more information.
*
* - \ref echotest
* - \ref streaming
* - \ref videocall
* - \ref sipsofia
* - \ref sipre
* - \ref nosip
* - \ref audiobridge
* - \ref videoroom
* - \ref textroom
* - \ref recordplay
* - \ref voicemail
* - \ref lua
* - \ref duktape
*/
/*! \page recordings Recordings
* Janus supports recordings of WebRTC sessions out of the box, assuming
* plugins take advantage of the feature. Specifically, recording as a
* functionality is implemented in the Janus core, specifically using the
* janus_recorder structure and the related methods. When enabled, media
* streams are recorded to a custom format (that we introduce below):
* as such, it's then up to individual plugins to expose ways for users
* to configure/start/stop recordings, and using the core functionality
* to actually implementing the recording part. At the time of writing,
* most plugins do implement it.
*
* \note This section covers recordings for the purpose of storage,
* archiving or further manipulation. If you're interested in recording
* for the purpose of debugging media sessions, you may want to refer to
* the \ref adminpcap documentation instead, as that would allow you
* to capture unencrypted RTP/RTCP packets sent/received to/from Janus
* in a format tools like Wireshark and tcpdump support.
*
* \section mjr Meetecho Janus Recordings
* As anticipated, the janus_recorder core functionality saves media
* streams to a custom format that we call the "Meetecho Janus Recordings"
* format. When saved to file, the custom \c mjr extension is used.
*
* Each \c mjr file contains a single media stream. This means that if
* if you want to record, for instance, an audio/video stream, you'll need
* two separate \c mjr files: one just for audio, and the other just for
* video. Each \c mjr file then basically just contains a structured
* dump of the RTP packets exactly as they arrived: after a short header
* that describes the data contained in the recording (i.e., type of
* media, the codec, when it was created, when the first packet was written),
* each RTP packet is saved together with info on its length.
*
*\verbatim
+-----------------------------------------------+
| MJR00001 (8 bytes) |
+-----------------------------------------------+
| LEN (2 bytes) | JSON header (variable length) |
+-----------------------------------------------+
| MEETECHO (8 bytes) |
+-----------------------------------------------+
| LEN (2 bytes) | RTP packet (variable length) |
+-----------------------------------------------+
| MEETECHO (8 bytes) |
+-----------------------------------------------+
| LEN (2 bytes) | RTP packet (variable length) |
+-----------------------------------------------+
| MEETECHO (8 bytes) |
+-----------------------------------------------+
| LEN (2 bytes) | RTP packet (variable length) |
+-----------------------------------------------+
| ... |
+-----------------------------------------------+
\endverbatim
*
* This makes the recording process very lightweight, as Janus doesn't
* need to do anything more that just saving the packets to file: no
* CPU intensive operation like transcoding or frame manipulation is
* done by the janus_recorder instances. RTP packets don't even need to
* be saved in order, as the \c mjr files can be post-processed later
* and, as we'll see, re-ordering of the stored packets is part of the
* activities that our post-processor performs when doing so.
*
* \subsection mjrdata Saving data channels
* While we've so far only mentioned RTP packets, and so audio and video,
* Janus actually also natively supports the recording of datachannels.
* In that case, the recording will be a structured dump not of RTP
* packets, but of the individual messages that were received. Just as
* we said for audio and video, since \c mjr files only cover individual
* streams, data recordings will need their own instance as well.
*
* \section mjrproc Post-processing the recordings
* Once a recording is available in the \c mjr format, it obviously needs
* some transformation before it can be consumed by external tools, e.g.,
* media players or third-party applications for further processing (like
* muxing audio and video together, or mixing multiple video streams
* together).
* Out of the box, Janus comes with a simple post-processing tool whose
* only job is re-ordering the available RTP packets, extracting the
* media frames from the RTP packets (which for video might mean
* extracting the same frame from multiple packets in sequence), and
* saving the media frames to a well-known media format. To make this
* simple, this tool can, for instance, convert an audio \c mjr recording
* to an \c opus file, or a video \c mjr recording containing VP8 packets
* to a \c webm file instead. Notice that no transcoding is done by this
* postprocessor either: frames are extracted exactly as they were sent
* originally, and just saved to a media container in a way that multimedia
* applications can consume them. If further processing is needed (e.g.,
* muxing, mixing, transcoding, or other), then this is up to third-party
* applications that can work with existing media files.
*
* For more information on the Janus recordings post-processor, check
* the documentation for the janus-pp-rec.c executable.
*
*/
/*! \page resources Resources
* This page contains pointers to some third-party resources, in particular
* distro repos for an easier installation of Janus, where available,
* client stacks, libraries and bindings in other languages, that is
* tools that you find helpful to interact with Janus outside of the
* context of the \c janus.js JavaScript library we provide. It is not
* a complete list, but just a summary of the material that has been
* shared so far on the <a href="https://groups.google.com/forum/#!forum/meetecho-janus">meetecho-janus</a>
* Google group.
*
* If you've developed anything related to Janus (client stacks, plugins,
* transports, etc.) and you're willing to share them with the community,
* or you know any such effort that is not listed here, just let us know
* and we'll add it on this page.
* <br/><br/>
*
* \section repos Distro repositories
*
* <table class="table table-striped">
* <tr><th>Distro</th><th>Author</th><th>Repo</th><th>Description</th></tr>
* <tr>
* <td>Debian</td>
* <td>Debian VoIP Team</td>
* <td><a href="https://packages.debian.org/source/sid/janus">Janus packages (sid)</a></td>
* <td>Debian Sid</td>
* </tr>
* <tr>
* <td>Debian/Ubuntu</td>
* <td><a href="https://github.com/saghul">Saúl Ibarra Corretgé </a></td>
* <td><a href="http://projects.ag-projects.com/projects/documentation/wiki/Repositories">AG Projects Repo</a></td>
* <td>Debian Jessie, Ubuntu Trusty and Ubuntu Xenial</td>
* </tr>
* </table>
* <br/>
*
* \section stacks Client-side stacks
*
* <table class="table table-striped">
* <tr><th>Language</th><th>Author</th><th>Project</th><th>Description</th></tr>
* <tr>
* <td>JavaScript/node</td>
* <td><a href="https://github.com/ndarilek">Nolan Darilek</a></td>
* <td><a href="https://github.com/ndarilek/node-janus">node-janus</a></td>
* <td>node and browserify compatible integration layer for the Janus WebRTC server</td>
* </tr>
* <tr>
* <td>JavaScript/node</td>
* <td><a href="https://github.com/DamonOehlman">Damon Oehlman</a></td>
* <td><a href="https://github.com/rtc-io/rtc-janus">rtc-janus</a></td>
* <td>node and browserify compatible integration layer for the Janus WebRTC server:
* experimental and incomplete as per the author words, but a good starting point</td>
* </tr>
* <tr>
* <td>JavaScript/node</td>
* <td><a href="https://github.com/sjkummer">Sebastian Schmid</a></td>
* <td><a href="https://github.com/sjkummer/janus-gateway-js">janus-gateway-js</a></td>
* <td>Simple JavaScript client for janus-gateway that runs in the browser as well as in Node.js</td>
* </tr>
* <tr>
* <td>JavaScript/node</td>
* <td><a href="https://www.sipwise.com/">sip:wise</a></td>
* <td><a href="https://www.npmjs.com/~sipwise">admin/videoroom client</a></td>
* <td>Node.js clients that implement the Admin API and VideoRoom functionality</td>
* </tr>
* <tr>
* <td>JavaScript/node</td>
* <td><a href="https://github.com/mquander">Marshall Quander</a></td>
* <td><a href="https://github.com/mquander/minijanus.js">minijanus.js</a></td>
* <td>A super-simplistic and -minimal wrapper for talking to the Janus signalling API</td>
* </tr>
* <tr>
* <td>JavaScript/node</td>
* <td><a href="https://github.com/TechTeamer">TechTeamer</a></td>
* <td><a href="https://github.com/TechTeamer/janus-api">janus-api</a></td>
* <td>Javascript (node and browser side) API for Janus WebRTC server</td>
* </tr>
* <tr>
* <td>ruby</td>
* <td><a href="https://github.com/cargomedia">Cargo Media</a></td>
* <td><a href="https://github.com/cargomedia/janus-gateway-ruby">janus-gateway-ruby</a></td>
* <td>ruby client side API wrapper for the Janus API (websocket only at the moment)</td>
* </tr>
* <tr>
* <td>C#/.NET</td>
* <td><a href="https://github.com/Computician">Benjamin Trent</a></td>
* <td><a href="https://github.com/Computician/JanusSharp">JanusSharp</a></td>
* <td>C#/.Net client side API wrapper for the Janus API</td>
* </tr>
* <tr>
* <td>PHP</td>
* <td><a href="https://github.com/BenJaziaSadok">Mohamed Sadok Ben Jazia</a></td>
* <td><a href="https://github.com/BenJaziaSadok/janus-gateway-php">janus-gateway-php</a></td>
* <td>Client-side PHP/javascript implementation of the Janus and Admin APIs</td>
* </tr>
* <tr>
* <td>PHP</td>
* <td><a href="https://github.com/mvnrsa">Marnus van Niekerk</a></td>
* <td><a href="https://github.com/mvnrsa/JanusPHPclass">Janus PHP Class</a></td>
* <td>Client-side PHP Class implementing the Janus Admin API</td>
* </tr>
* <tr>
* <td>Golang</td>
* <td><a href="https://github.com/nowylie">Nicholas Wylie</a></td>
* <td><a href="https://github.com/nowylie/go-janus">go-janus</a></td>
* <td>Golang library to the Janus API (Unix Sockets/SOCK_DGRAM only at the moment)</td>
* </tr>
* <tr>
* <td>Elixir</td>
* <td><a href="https://github.com/ndarilek">Nolan Darilek</a></td>
* <td><a href="https://github.com/ndarilek/elixir-janus">elixir-janus</a></td>
* <td>Elixir client side API wrapper for the Janus WebRTC server</td>
* </tr>
* <tr>
* <td>OBS</td>
* <td><a href="https://github.com/CoSMoSoftware">CoSMo Software</a></td>
* <td><a href="https://github.com/CoSMoSoftware/OBS-studio-webrtc">OBS-studio-webrtc</a></td>
* <td>This is a fork of obs-studio with support for webrtc in general, and Janus Video Room plugin in particular</td>
* </tr>
* <tr>
* <td>OCaml</td>
* <td><a href="https://github.com/monstasat">Alexander Yanin</a></td>
* <td><a href="https://github.com/monstasat/janus-ocaml">Janus-ocaml</a></td>
* <td>Library for Janus WebRTC server handling written in OCaml (HTTP only)</td>
* </tr>
* <tr>
* <td>Haskell</td>
* <td><a href="https://github.com/oofp">oofp</a></td>
* <td><a href="https://github.com/oofp/janus-connector">janus-connector</a></td>
* <td>Haskell binding of Janus client protocol using WebSocket transport with examples</td>
* </tr>
* </table>
* <br/>
*
* \section mobile Mobile resources
*
* <table class="table table-striped">
* <tr><th>OS</th><th>Author</th><th>Project</th><th>Description</th></tr>
* <tr>
* <td>Android</td>
* <td><a href="https://github.com/Computician">Benjamin Trent</a></td>
* <td><a href="https://github.com/Computician/janus-gateway-android">janus-gateway-android</a></td>
* <td>API wrapper that utilizes the native WebRTC build and is made to ease communication with Janus</td>
* </tr>
* <tr>
* <td>iOS</td>
* <td><a href="https://github.com/davibe">Davide Bertola</a></td>
* <td><a href="https://github.com/davibe/cordova-webrtc-janus-gateway">cordova-webrtc-janus-gateway</a></td>
* <td>cordova application that interfaces with Janus and is based on the PhoneRTC cordova plugin</td>
* </tr>
* <tr>
* <td>Android/iOS</td>
* <td><a href="https://github.com/atyenoria">Akinori Nakajima</a></td>
* <td><a href="https://github.com/atyenoria/react-native-webrtc-janus-gateway">react-native-webrtc-janus-gateway</a></td>
* <td>Video conference system for mobile application on react-native-webrtc + Janus WebRTC server</td>
* </tr>
* <tr>
* <td>Android/iOS</td>
* <td><a href="https://github.com/WorldViews">WorldViews</a></td>
* <td><a href="https://github.com/WorldViews/JanusMobile">JanusMobile</a></td>
* <td>react-native based Janus mobile client</td>
* </tr>
* </table>
* <br/>
*
* \section pi Raspberry Pi resources
*
* <table class="table table-striped">
* <tr><th>Author</th><th>Project</th><th>Description</th></tr>
* <tr>
* <td><a href="http://linux-projects.org">Linux Projects</a></td>
* <td><a href="http://www.linux-projects.org/rpi-videoconference-demo-os/">Rpi VideoConference OS</a></td>
* <td>Ready-to-use OS for video conferences over the web from a Raspberry Pi</td>
* </tr>
* <tr>
* <td><a href="http://linux-projects.org">Linux Projects</a></td>
* <td><a href="http://www.linux-projects.org/uv4l/tutorials/janus-gateway/">UV4L, User Space Video Collection</a></td>
* <td>Software modules providing solutions for encrypted live data, audio and video streaming, mirroring, conferencing</td>
* </tr>
* </table>
* <br/>
*
* \section docker Docker resources
*
* <table class="table table-striped">
* <tr><th>Author</th><th>Project</th><th>Description</th></tr>
* <tr>
* <td><a href="https://github.com/krull">Brendan Jocson</a></td>
* <td><a href="https://github.com/krull/docker-janus">docker-janus</a></td>
* <td>Debian 8 based docker image for Meetecho's Janus Gateway</td>
* </tr>
* <tr>
* <td><a href="https://github.com/atyenoria">Akinori Nakajima</a></td>
* <td><a href="https://github.com/atyenoria/janus-gateway-docker">janus-gateway-docker</a></td>
* <td>Janus WebRTC server Docker Image for Media Streaming Expert User</td>
* </tr>
* </table>
* <br/>
*
* \section evhandlers Event Handlers (monitoring/troubleshooting)
*
* <table class="table table-striped">
* <tr><th>Language</th><th>Author</th><th>Project</th><th>Description</th></tr>
* <tr>
* <td>node-js</td>
* <td><a href="https://github.com/thehunmonkgroup">Chad Phillips</a></td>
* <td><a href="https://github.com/thehunmonkgroup/janus-event-server">janus-event-server</a></td>
* <td>Simple plugin-based server to receive/process events from Janus</td>
* </tr>
* <tr>
* <td>Rust</td>
* <td><a href="https://github.com/mozilla">Mozilla</a></td>
* <td><a href="https://github.com/mozilla/janus-eventhandler-sqlite">janus-eventhandler-sqlite</a></td>
* <td>A Janus event handler plugin that writes events to a SQLite database</td>
* </tr>
* </table>
* <br/>
*
* \section thirdplugins Third-party plugins
*
* <table class="table table-striped">
* <tr><th>Author</th><th>Project</th><th>Description</th></tr>
* <tr>
* <td><a href="https://github.com/cargomedia">Cargo Media</a></td>
* <td><a href="https://github.com/cargomedia/janus-gateway-rtpbroadcast">janus-gateway-rtpbroadcast</a></td>
* <td>Janus-gateway plugin to broadcast RTP video</td>
* </tr>
* <tr>
* <td><a href="https://github.com/mquander">Marshall Quander</a></td>
* <td><a href="https://github.com/mquander/janus-plugin-rs">janus-plugin-rs</a></td>
* <td>Rust bindings and wrappers for creating Janus plugins in Rust</td>
* </tr>
* </table>
* <br/>
*
* \section thirdtrasports Third-party transports
*
* <table class="table table-striped">
* <tr><th>Author</th><th>Project</th><th>Description</th></tr>
* <tr>
* <td><a href="https://github.com/nowylie">Nicholas Wylie</a></td>
* <td><a href="https://github.com/nowylie/janus-ud-transport">janus-ud-transport</a></td>
* <td>Janus transport plugin that adds support for Datagram messages over Unix Domain Sockets</td>
* </tr>
* </table>
* <br/>
*
*/
/*! \page README README
* \verbinclude README.md
*/
/*! \page CREDITS Credits
*
* Janus WebRTC Server © 2014-2019 <a href="http://www.meetecho.com/">Meetecho</a> (http://www.meetecho.com/)
*
* \b Author:
* Lorenzo Miniero <lorenzo@meetecho.com>
*
* Several open source components have been used to implement this software:
*
* - \b GLib: http://library.gnome.org/devel/glib/
* - \b pkg-config: http://www.freedesktop.org/wiki/Software/pkg-config/
* - \b gengetopt: http://www.gnu.org/software/gengetopt/ (command line)
* - \b Jansson: http://www.digip.org/jansson/ (JSON)
* - \b libconfig: https://hyperrealm.github.io/libconfig/ (configuration files)
* - \b libnice: http://nice.freedesktop.org/wiki/ (ICE/STUN/TURN, at least v0.1.15 suggested, master recommended)
* - \b OpenSSL: http://www.openssl.org/ (DTLS, at least v1.0.1e)
* - \b libsrtp: https://github.com/cisco/libsrtp (SRTP, at least v1.5 suggested)
* - \b usrsctp: http://code.google.com/p/sctp-refimpl/ (\c optional, Data Channels)
* - \b libmicrohttpd: http://www.gnu.org/software/libmicrohttpd/ (\c optional, Web server)
* - \b libwebsockets: https://libwebsockets.org/ (\c optional, WebSockets)
* - \b rabbitmq-c: https://github.com/alanxz/rabbitmq-c (\c optional, v1.0.4, RabbitMQ)
* - \b paho.mqtt.c: https://eclipse.org/paho/clients/c (\c optional, v1.1.0 for MQTT v3.1 & v3.1.1 or v1.3.0 for MQTT v5)
* - \b nanomsg: https://nanomsg.org/ (\c optional, Nanomsg)
* - \b Sofia-SIP: http://sofia-sip.sourceforge.net/ (\c optional, only needed for the SIP plugin)
* - \b libopus: http://opus-codec.org/ (\c optional, only needed for the bridge plugin)
* - \b libogg: http://xiph.org/ogg/ (\c optional, only needed for the voicemail plugin)
* - \b libcurl: https://curl.haxx.se/libcurl/ (\c optional, only needed for the TURN REST API,
* RTSP support in the Streaming plugin and the sample Event Handler plugin)
* - \b Lua: https://www.lua.org/download.html (\c optional, only needed for the Lua plugin)
* - \b npm: https://docs.npmjs.com/ (\c optional, used during build for generating JavaScript modules)
*
*/
/*! \page COPYING License
* This program is free software, distributed under the terms of the GNU
* General Public License Version 3.
*
* If you're interested in a commercial license (e.g., because GPLv3 is
* not suited for what you need, you're interested in technical support
* or want to sponsor the development of new features), feel free to
* <a href="https://janus.conf.meetecho.com/support">contact us</a>.
*
* \verbinclude COPYING
*/
/*! \page FAQ Frequently Asked Questions
* This page contains a list of FAQ as gathered on the
* <a href="https://groups.google.com/forum/?pli=1#!forum/meetecho-janus">meetecho-janus</a>
* Google group and the
* <a href="https://github.com/meetecho/janus-gateway/issues">Issues</a>
* page on GitHub. It obviously also includes things we're being asked all the
* time in general! If your question is not listed here or not available
* anywhere in this documentation, feel free to refer to the group for
* generic help, or to the Issues page for bugs in the implementation.\n\n
*
* <hr>
*
* -# <a href="#janus">What is Janus?</a>\n
* -# <a href="#meetecho">What is Meetecho?</a>\n
* -# <a href="#pronounce">Now that we're at it, how is Meetecho pronounced??</a>\n
* -# <a href="#videos">I just started with Janus and am overwhelmed by the amount of info, documentation, etc... any easy way to dive in?</a>\n
* -# <a href="#origin">Why is Janus called like that?</a>\n
* -# <a href="#license">Is the license AGPLv3 or GPLv3? Do you provide alternative license mechanisms as well?</a>\n
* -# <a href="#OS">On what OS can I install Janus?</a>\n
* -# <a href="#datachans">Are Data Channels supported?</a>\n
* -# <a href="#usrsctp">I don't care about Data Channels, do I have to compile usrsctp anyway?</a>\n
* -# <a href="#usrsctperr">I can't install usrsctp, I'm getting errors about dereferencing pointers?</a>\n
* -# <a href="#gateway">Can I use Janus as a gateway to my Freeswitch/Kamailio/Asterisk/other SIP infrastructure?</a>\n
* -# <a href="#jssip">Can I use existing SIP stacks (e.g., JsSIP) with Janus?</a>\n
* -# <a href="#transcoding">Does Janus support transcoding?</a>\n
* -# <a href="#recording">Does Janus support recording?</a>\n
* -# <a href="#websockets">Can I use WebSockets instead of plain HTTP to interact with Janus?</a>\n
* -# <a href="#rabbitmq">Can I use RabbitMQ instead of HTTP/WebSockets to interact with Janus?</a>\n
* -# <a href="#unixsockets">Can I use Unix Sockets instead of HTTP/WebSockets/RabbitMQ to interact with Janus?</a>\n
* -# <a href="#mqtt">Can I use MQTT instead of HTTP/WebSockets/RabbitMQ/Unix Sockets to interact with Janus?</a>\n
* -# <a href="#nanomsg">Can I use Nanomsg instead of HTTP/WebSockets/RabbitMQ/MQTT/Unix Sockets to interact with Janus?</a>\n
* -# <a href="#transports">What about \<my favourite control protocol\> instead?</a>\n
* -# <a href="#demos">I've launched Janus, how do I try the demos?</a>\n
* -# <a href="#certificates">I'm trying the demos, but I get "Janus down" or certificate errors!</a>\n
* -# <a href="#nodejs">Can I use Janus with node.js or other frameworks?</a>\n
* -# <a href="#monitoring">How do I monitor/manage my Janus instance?</a>\n
* -# <a href="#writeplugin">I want to write my own plugin, where do I start?</a>\n
* -# <a href="#ulimit">I'm using the VideoRoom plugin and, when several users are handled, I get
* a "Too many open files" errors and Janus crashes</a>\n
* -# <a href="#https">When I enable the HTTPS web server in Janus, the CPU goes crazy</a>\n
* -# <a href="#turn">I enabled TURN in the Janus configuration, but my clients behind a firewall can't connect</a>\n
* -# <a href="#benchmark">Is there any benchmark on Janus performances?</a>\n
* -# <a href="#scaling">How do I scale Janus?</a>\n
* -# <a href="#requests">Can you implement a feature/plugin/application I want?</a>\n
* -# <a href="#learning">I want to learn more on Janus!</a>\n
*
* <hr>
*
* \anchor janus
* -# <b>What is Janus?</b>\n
* .
* Janus is an open source WebRTC server written by <a href="http://www.meetecho.com">Meetecho</a>,
* conceived as modular and, as much as possible,
* general purpose. It acts as a WebRTC endpoint browsers can interact
* with, and different modules can determine what should be done with
* the media. This means that you can do SIP, videoconferencing, streaming
* and tons of other stuff using the same box! And if what you need is
* not there, you can always write your own module and expand Janus.\n\n
* .
* \anchor meetecho
* -# <b>What is Meetecho?</b>\n
* .
* Meetecho is a company founded by a few researchers, post-docs and
* Ph.Ds coming from the Universty of Napoli Federico II. We've been
* working on real-time multimedia applications over the Internet for
* years, and at one point we decided to try and make products out
* of our research efforts. Our web conferencing platform and Janus
* are part of those efforts.\n\n
* .
* \anchor pronounce
* -# <b>Now that we're at it, how is Meetecho pronounced??</b>\n
* .
* We're being asked that a lot! We've heard so many variants and different
* pronounciations of the name that we could make a book out of it!
* When we chose the name, we wanted it to sound like
* <a href="https://www.youtube.com/watch?v=TkgDOMSv9PE">this</a>,
* which means \a awesome! in Italian. The extra H was a mistake on our
* side, as obviously \a echo is pronouced differently than \a eco! Long
* story short, it doesn't really matter how you pronounce it: just
* do it and help us be famous! :-)\n\n
* .
* \anchor videos
* -# <b>I just started with Janus and am overwhelmed by the amount of info, documentation, etc... any easy way to dive in?</b>\n
* .
* Fair point! Janus and its concepts/APIs can be a lot to digest in a short time...
* An easy way to start is watching one of the several presentations we've done
* on Janus these last months. Most if not all of them try to provide a
* complete introduction to the context Janus was built in, how it was
* born, the architecture we chose for it and so on. As such, it should
* be a useful starting point for whoever is interested in learning
* what Janus can do and how to use it.\n\n
* There are several videos available that you can find online (most of the slides
* available on <a href="https://www.slideshare.net/LorenzoMiniero/">SlideShare</a>),
* here are some of them as quick pointers:
* - Presentations at <a href="https://www.youtube.com/watch?v=u0PyXgAC8m4">vuc485</a>,
* <a href="https://www.youtube.com/watch?v=VnflQF7oCLA">vuc584</a>
* and <a href="https://www.youtube.com/watch?v=XnQ7ECOpRIU">vuc640</a> (last one more focused on IETF remote participation);
* - Presentation at <a href="https://www.youtube.com/watch?v=SFeWYewoL7Q">OpenSIPS summit 2016</a>;
* - Presentation at <a href="https://www.youtube.com/watch?v=yvt-vMHW83c">Kamailio World 2016</a>;
* - Presentation at <a href="https://www.youtube.com/watch?v=WfNciKbsP80">WebRTC Meetup Tokyo #12</a>;
* - Presentation at <a href="https://www.youtube.com/watch?v=gArqopeNQY0">DevDay Napoli</a> (in Italian);
* - Presentation on Event Handlers at <a href="https://www.youtube.com/watch?v=UT9CDhoHL_Q">FOSDEM 2017</a>;
* - Presentation on different SIP options in Janus at <a href="https://www.youtube.com/watch?v=anmyMC6Ovl8&t=25112s">OpenSIPS 2017</a>;
* - Presentation on WebRTC load testing at <a href="https://www.youtube.com/watch?v=SnvTAsYtZ5s">Kamailio World 2017</a>;
* - Presentation on SIP, WebRTC and Asterisk at <a href="https://www.youtube.com/watch?v=IaPDufOzVek">Astricon 2017</a>;
* - Presentation at <a href="https://www.youtube.com/watch?v=cSV0X1JgcKY">WebRTC Rockstars Tour (Singapore)</a>;
* - Presentation at <a href="https://youtu.be/dsVDzh9sS1A?t=51m00s">WebRTC Meetup Tokyo #17</a> (in Japanese);
* - Interview on the origins of Janus, at <a href="http://www.allthingsrtc.org/2017/10/30/lorenzo-miniero-creator-janus/">AllThingRTC.org</a>;
* - Presentation on the Janus Lua plugin, at <a href="https://www.youtube.com/watch?v=NVLdbbnmUAA">FOSDEM 2018</a>;
* - Presentation on how to integrate Janus and HOMER/HEPIC, at <a href="https://www.youtube.com/watch?v=YUZqhu2-tbM">OpenSIPS 2018</a>;
* - Presentation on Security, Authentication and Privacy in WebRTC, at <a href="https://www.youtube.com/watch?v=ewNJMci62rs">Kamailio World 2018</a>;
* - Presentation on Janus and Scalability, at <a href="https://www.youtube.com/watch?v=zxRwELmyWU0">CommCon 2018</a>;
* - Interview on Janus, at <a href="https://www.youtube.com/watch?v=dzQhyw1jiaA">ClueCon Weekly</a>;
* - Presentation at <a href="https://vimeo.com/303014581">Voip2day 2018</a> (here for the <a href="https://vimeo.com/302814764">Spanish version</a>);
* - Presentation on Janus and SIP at <a href="https://www.youtube.com/watch?v=beHHL0Ew5xY">OpenSIPS 2019</a>;
* - Presentation on RTC fuzzing in Janus at <a href="https://www.youtube.com/watch?v=YTN88fUiGoI">Kamailio World 2019</a>;
* - Presentation on Multistream support in Janus (Unified Plan) at <a href="https://www.youtube.com/watch?v=xbsHYvBjsdY">CommCon 2019</a>;
* - Presentation on Janus at <a href="https://www.youtube.com/watch?v=2LHto3iufzU">ClueCon 2019</a>. \n\n
* Apart from these presentations, make sure you also check the slides
* and presentations from <a href="https://januscon.it">JanusCon</a>,
* the Janus conference we hosted here in Napoli.
* \n\n
* .
* \anchor origin
* -# <b>Why is Janus called like that?</b>\n
* .
* Quoting <a href="http://en.wikipedia.org/wiki/Janus">Wikipedia</a>:
* "<i>In ancient Roman religion and myth, Janus (Latin: Ianus, pronounced
* [ˈiaː.nus]) is the god of beginnings and transitions, and thereby of
* gates, doors, passages, endings and time. He is usually depicted as
* having two faces, since he looks to the future and to the past.</i>"
* Considering the general purpose nature of our server, where one face always looks
* at the future (WebRTC) and the other at the past (whatever the modules
* allows you to do, be it legacy stuff or not), Janus looked like the
* perfect name for it! And besides, we're Italian, Ancient Rome was
* awesome and mythology rules... ;-)
* \n\n
* .
* \anchor januslicense
* -# <b>Is the license AGPLv3 or GPLv3? Do you provide alternative license mechanisms as well?</b>\n
* .
* Janus is licensend under the GPLv3 licence. At the very beginning
* we chose AGPLv3 for a simple reason: we wanted our work to be open source,
* and we wanted interested people to play with it and contribute back
* whatever improvement they could provide to the core. This is not always
* the case with open source software, which is sometimes just seen as
* free stuff you can exploit without helping back, and AGPLv3 looked like
* the easiest way to do that. That said, we were almost immediately
* made aware that this license mechanism is
* <a href="https://groups.google.com/forum/?pli=1#!searchin/discuss-webrtc/janus/discuss-webrtc/LJHXkIsAaEU/fHgJ2z0sxfoJ">not very appreciated</a>
* around, especially because of some
* interpretations about it that could affect the way proprietary stuff
* is deployed. We obviously cared about these concerns, and that's what
* eventually lead us to pick GPLv3 as a license, which should make it
* easier for Janus to be integrated in heterogeneous scenarios.\n\n
* Anyway, if for some reason you're not comfortable with GPLv3 for your
* needs, we have a <a href="https://janus.conf.meetecho.com/support">commercial license</a>
* offering as well.\n\n
* .
* \anchor OS
* -# <b>On what OS can I install Janus?</b>\n
* .
* At the moment only Linux is officially supported. Anyway, Janus does
* compile on Mac OS as well, thanks to contributions from the community,
* and so should work fine there as well. Windows support is also provided
* as a <a href="https://github.com/meetecho/janus-gateway/pull/597">pull request</a>
* by a Janus contributor: anyway, please beware that Windows support is behind the current
* version of development.\n\n
* .
* \anchor datachans
* -# <b>Are Data Channels supported?</b>\n
* .
* Yes they are! Starting from version \c 0.0.3 of Janus, we added a first
* experimental support to Data Channels, that can as such be used in
* plugins that choose to support them. Right now, they are handled in
* several plugins like the Echo Test, VideoCall, VideoRoom and TextRoom plugins.\n\n
* Please notice that right now we only support text data: hopefully support
* for binary streams will be available soon as well. Until that happens,
* you'll have to resort to text-based encodings like Base64 to share
* binary data through Janus.\n\n
* .
* \anchor usrsctp
* -# <b>I don't care about Data Channels, do I have to compile usrsctp anyway?</b>\n
* .
* Support for Data Channels is optional, so if you didn't install the library
* the configure script will go around them and compile Janus without Data Channels
* support. If you did install the library and don't care about Data Channels,
* but only about audio and/or video, pass the \c --disable-data-channels
* option to the configure script to explicitly disable them. If you're updating
* an existing install, issue a \c make \c clean before compiling again, or
* you might encounter issues with pre-existing symbols.\n\n
* .
* \anchor usrsctperr
* -# <b>I can't install usrsctp, I'm getting errors about dereferencing pointers?</b>\n
* .
* Apparently recent compilers are stricter with respect to some code
* syntaxes, and this seems to be affecting the way \c usrsctp is written
* as of now. Some users managed to fix this issue by passing an export
* before the \c bootstrap and \c configure steps in the \c usrsctp
* compilation:\n\n
*\verbatim
export CFLAGS="-fno-strict-aliasing" ./boostrap
export CFLAGS="-fno-strict-aliasing" ./configure --prefix=/usr
make && make install
\endverbatim
* Another solution seems to be removing all the \c -O2 occurrences
* in the generated \c configure script.\n\n
* .
* \anchor gateway
* -# <b>Can I use Janus as a gateway to my Freeswitch/Kamailio/Asterisk/other SIP infrastructure?</b>\n
* .
* Of course! One of the modules we provide out of the box is a SIP
* gateway plugin based on the <a href="http://sofia-sip.sourceforge.net/">Sofia-SIP</a>
* library stack. These plugin allows a web user to register at a SIP
* proxy/server either as an authenticated user or as a guest, and
* start or receive calls from other SIP users, including other web users
* exploiting the same plugin. Janus will take care of all the WebRTC-related
* stuff (ICE, DTLS, SRTP), which means that on the SIP side it will
* be plain RTP only, much easier and lighter to handle for legacy
* implementations. SDES-SRTP is also supported on the SIP side in case
* it is required.\n\n
* .
* \anchor jssip
* -# <b>Can I use existing SIP stacks (e.g., JsSIP) with Janus?</b>\n
* .
* Janus uses a custom JSON-based protocol for all the communication
* between web users and plugins in the server, so no, that's not
* possible right now. While there are some controls that give you access
* to some of the SIP details (e.g., requesting SRTP negotiation or injecting
* custom headers), the SIP plugin in Janus only exposes some very
* high level information to web users (e.g., registration failed/succeeded,
* incoming call, decline, hangup, etc.), without delving in any SIP-related
* detail, which is instead completely demanded to the server-side plugin
* itself. This ensures that web users can take advantage of SIP functionality
* in an easy way, without having to worry about the details and complexity
* of SIP within JavaScript.\n\n
* .
* \anchor transcoding
* -# <b>Does Janus support transcoding?</b>\n
* .
* Janus is a simple intermediary between WebRTC users and server-side
* plugins providing application logic, so no, it doesn't provide any
* transcoding functionality per-se. If transcoding is needed, this is
* supposed to be implemented within plugins themselves. That said,
* apart from the AudioBridge plugin which acts as an audio MCU,
* none of the plugins we provide out-of the box does transcoding,
* since we wanted the implementation to be lightweight and besides
* there are several existing tools and third-party implementations that
* could be leveraged for the purpose.\n\n
* .
* \anchor recording
* -# <b>Does Janus support recording?</b>\n
* .
* Yep! The Janus core provides an integrated way of recording all
* the media streams that go through it, whether it's audio, video or
* data, and almost all stock plugins do exploit it one way or another.
* Recording is implemented as a structured dump of all RTP and data
* files exactly as they were transmitted or sent: as such, no manipulation
* is done while recording, and all post-processing is demanded to
* an external tool. For more information on this, check the
* <a href="https://janus.conf.meetecho.com/docs/janus-pp-rec_8c.html#details">documentation</a>.\n\n
* .
* \anchor websockets
* -# <b>Can I use WebSockets instead of plain HTTP to interact with Janus?</b>\n
* .
* Since version \c 0.0.4, you can! At first we chose a REST-based plain HTTP communication
* for a simple reason: we noticed that there were some scenarios (e.g.,
* client firewalls) where websockets wouldn't work, even though WebRTC
* did. To improve the chances of success in the communication, we
* then chose this simpler approach with respect to signalling. Besides,
* plain HTTP is much easier to proxy and/or place behind frontends
* like Apache HTTPD or nginx than WebSockets, another aspect that
* played a decisive role in our decision, as we were also very interested
* in making the integration of Janus in heterogeneous environments
* as easy as possible. That said, WebSockets also provide substantial
* benefits when compared to plain HTTP, and definitely make life easier to
* server side integrators as well, e.g., in terms of overhead and use of
* resources. For more information, check the \ref WS page. \n\n
* .
* \anchor rabbitmq
* -# <b>Can I use RabbitMQ instead of HTTP/WebSockets to interact with Janus?</b>\n
* .
* Since version \c 0.0.6, you can! This is a feature that several
* developers asked for, especially those that are interested in wrapping
* the Janus API on the server side, and implement the communication
* on the client side their own way. Specificaly, Janus now supports
* RabbitMQ based messaging as an alternative "transport" for API
* requests, responses and notifications, meaning it can be used with
* or without HTTP and WebSockets, depending on your requirements.
* For more information, check the \ref rabbit page. \n\n
* .
* \anchor unixsockets
* -# <b>Can I use Unix Sockets instead of HTTP/WebSockets/RabbitMQ to interact with Janus?</b>\n
* .
* Since version \c 0.2.1, you can! More specifically, you can use a
* \c SOCK_SEQPACKET or a \c SOCK_DGRAM socket to control a Janus instance.
* Notice that this feature is only available when installing Janus on a Linux machine.
* For more information, check the \ref unix page. \n\n
* .
* \anchor mqtt
* -# <b>Can I use MQTT instead of HTTP/WebSockets/RabbitMQ/Unix Sockets to interact with Janus?</b>\n
* .
* Since version \c 0.2.1, you can! This was a very welcome contribution by
* a Janus user, as it makes it even easier to have Janus interact with IoT deployments.
* For more information, check the \ref apimqtt page. \n\n
* .
* \anchor nanomsg
* -# <b>Can I use Nanomsg instead of HTTP/WebSockets/RabbitMQ/MQTT/Unix Sockets to interact with Janus?</b>\n
* .
* Since version \c 0.4.2, you can! For more information, check the \ref apinanomsg page. \n\n
* .
* \anchor transports
* -# <b>What about \<my favourite control protocol\> instead?</b>\n
* .
* Since version \c 0.1.0, the transports for the Janus API have been made
* modular. This means that, assuming a transport plugin implementing
* support for your favourite protocol has been made available, you
* can just add it to the Janus transport modules folder and it should
* work. If no plugin has been implemented, you may even want to do so
* yourself, or ask for ours or others help.\n\n
* .
* \anchor demos
* -# <b>I've launched Janus, how do I try the demos?</b>\n
* .
* The demos are available in the \c html folder in the project. That
* said, the integrated web server in Janus does not serve static files
* as well, so you'll have to make them available using a different
* webserver. Details about how to deploy Janus are provided in
* \ref deploy.\n\n
* .
* \anchor certificates
* -# <b>I'm trying the demos, but I get "Janus down" or certificate errors!</b>\n
* .
* Again, make sure you've read and are following the instructions on how to
* effectively deploy Janus in \ref deploy. Most likely you're either trying
* to open the WebRTC demos using HTTP instead of HTTPS (something that
* browsers will not allow, if not on localhost for testing), trying
* to contact Janus via an insecure protocol through a secure page, or
* using an insecure certificate for Janus itself. All of these problems
* are explained and solved easily in the \ref deploy documentation.\n\n
* .
* \anchor nodejs
* -# <b>Can I use Janus with node.js or other frameworks?</b>\n
* .
* Not natively, but since interaction with Janus is demanded to
* a JSON based communication transported on a network protocol (HTTP,
* WebSockets, RabbitMQ and others), this can be abstracted quite easily
* in several different ways. A common approach is implementing the Janus
* API in a server-side application, so that you handle users your own way
* and with your own API, while controlling Janus as a media server yourself
* by wrapping its API. Check the \ref resources documentation page
* for a list of Janus API wrappers in different programming languages
* that ou can use within your application
* to control a Janus instance from there instead of the browser. Should
* you decide to write your own Janus API wrapper, don't hesitate to let
* us know so that we can advertise yours there too!\n\n
* .
* \anchor monitoring
* -# <b>How do I monitor/manage my Janus instance?</b>\n
* .
* Since version \c 0.2.2 there are a couple of different ways you can do
* that. The first and most immediate one is making use of the Admin API,
* which you can find documented in the \ref admin page. It is a request/response
* protocol that can be used to poll information on existing sessions and
* handles, and which also provides a lot of useful WebRTC-related information
* on PeerConnections Janus is managing. You can also find a very useful
* <a href="http://www.meetecho.com/blog/understanding-the-janus-admin-api">blog post</a>
* where we describe in detail how the Admin API can be used to investigate issues. \n\n
* A more recent, and potentially much more powerful, addition to Janus
* are the Event Handlers. Unlike the Admin API, which is query-based,
* Event Handlers provide a mechanism to dynamically feed you with real-time
* and live data on whatever is happening within Janus, whether it's the
* core or any of the plugins. You can find more information, along with
* an example of how to receive such events, in the
* <a href="https://github.com/meetecho/janus-gateway/pull/536">pull request</a>
* page from where this effort was merged. More guidelines and implementations
* will definitely follow. \n\n
* .
* \anchor writeplugin
* -# <b>I want to write my own plugin, where do I start?</b>\n
* .
* Great! Depending on the kind of plugin you want to implement (application plugin,
* transport plugin, event handler plugin), some of the details may change,
* but the concept is typically the same. There are APIs you can refer to,
* documented in \ref pluginapi , \ref transportapi and \ref eventhandlerapi.
* The existing plugins are also an excellent way to start to get
* comfortable with the API: a good starting point may be the Echo Test
* plugin, which is a very simple and barebone implementation that
* simply bounces back whatever it is sent, and also involves some
* rough application logic to determine its behaviour (e.g., messages
* coming from web users that selectively enable or disable video).
* You may want to check third-party plugins as well in the \ref resources
* as well, as they'll give you an idea of how other users did the same.
* If you need any help with this, feel free to ask for help on the Google group:
* we're always excited whenever new Janus plugins are realized!\n\n
* .
* \anchor ulimit
* -# <b>I'm using the VideoRoom plugin and, when several users are handled, I get
* a "Too many open files" errors and Janus crashes</b>\n
* .
* As all applications on Linux environments, Janus is bound to the
* constraints imposed by the OS and/or the user. One of these constraints
* is related to how many file descriptors the application, or all the
* applications, can open. On several distributions this number is, by
* default, quite low, which can cause the issue you experienced. This
* value, together with others, can be modified, per-user or for all users,
* using the \c ulimit application. For a simple and quick way to handle
* this refer to the guide provided by the MongoDB developers:
* http://docs.mongodb.org/manual/reference/ulimit/ \n\n
* .
* \anchor https
* -# <b>When I enable the HTTPS web server in Janus, the CPU goes crazy</b>\n
* .
* As discussed in a recent <a href="https://groups.google.com/forum/?pli=1#!topic/meetecho-janus/lD8A0VqXsNs">post</a>
* on our Google group, this is caused by an occasional problem within
* libmicrohttpd, the library we use to implement an embedded web server
* in Janus. This is not deterministic, as the high CPU usage does happen
* on some distributions (e.g., Ubuntu 12.04), while it doesn't on
* others (e.g., Ubuntu 14.04). Anyway, this only can happen if you enable
* HTTPS support within Janus itself: you can still have a safe HTTPS
* usage with Janus if you deploy it behind a frontend (e.g., Apache HTTPD)
* that takes care of this on its behalf. Refer to the \ref deploy section
* for more details about this.\n\n
* .
* \anchor turn
* -# <b>I enabled TURN in the Janus configuration, but my clients behind a firewall can't connect</b>\n
* .
* As explained in the \c janus.jcfg documentation, the TURN settings you
* configure there refer to Janus \b itself, \b not the clients that make use
* of its services. This means that, whether you configure a static TURN
* server and the related credentials, or the REST API client stack to
* retrieve them dynamically, you're asking Janus to gather relay candidates
* for ITSELF. This is only useful if you know that your Janus instance
* will not be deployed on a public address (as it usually will) but will
* instead potentially sit behind a restrictive component like a firewall,
* or if you simply want to limit the number of open ports and so force
* all media traffic to go through the TURN server port alone.\n\n
* If you want your clients to gather relay candidates, instead, this
* needs to be done on the client side (e.g., in JavaScript, if your
* clients are web applications). If you're using our \ref JS check
* the \c echotest.js code, which has a commented portion that explains
* how to provide one or more TURN servers to make use of. If you're
* handling the WebRTC-related stuff on your own and are contacting
* Janus some other way, please refer to the related way of specifying
* STUN and TURN servers instead.\n\n
* .
* \anchor benchmark
* -# <b>Is there any benchmark on Janus performances?</b>\n
* .
* Benchmarking Janus is not an easy task, especially if we consider
* its general purpose nature. In fact, Janus by itself does not much
* more than negotiating WebRTC PeerConnections and relaying frames
* around, while most of the application login is in the modules. As
* you can imagine, different modules may have very different requirements
* and impact on the performances. For instance, the Echo Test is probably
* much lighter than the Video SFU, even if they're handling the same
* number of users. This means that such a benchmarking does not have
* much sense unless you contextualise the scenarios.\n\n
* You can find some results on tests we made ourselves in a couple of
* publications we wrote and available
* <a href="http://janus.conf.meetecho.com/citeus">here</a>. One of those
* introduces a WebRTC stress testing tool we implemented called Jattack,
* for which a <a href="https://www.youtube.com/watch?v=UwNq8p0m1js">video of the presentation</a>
* is available. You can find some more details and considerations in an older
* <a href="https://groups.google.com/forum/?pli=1#!topic/meetecho-janus/ydGcbMt7IX0">post</a>
* on our Google group too.\n\n
* .
* \anchor scaling
* -# <b>How do I scale Janus?</b>\n
* .
* This question is way too generic to answer here. As explained in the previous
* point, Janus is not an easily measurable entity, as it very much depends
* on which of the plugins you're involving in the scenarios that interest you
* and how. The same considerations also apply to scaling the scenario you
* implemented, as different plugins may require different approaches to
* do that. \n\n
* In general, Janus does not have any built-in multi-tenant support. Each
* Janus instance is conceived to be standalone, and works by itself. That
* said, there are different ways in which you can implement scalability in
* your service. One of them is implementing a wrapper/controller application
* that is in charge of multiple Janus instances, so that it can distribute
* the load depending on the requests. If the scenario allows for it,
* you can also mix concepts from different plugins on different Janus
* instances (e.g., use the RTP forwardiing feature of the VideoRoom plugin
* to make the same VideoRoom publisher available as a Streaming mountpoint
* on other Janus machines). Anyway, as explained each application may have
* very different requirements when it comes to scalability. \n\n
* Should you be interested in implementing scalability in your application and
* need help, <a href="https://janus.conf.meetecho.com/support">contact us</a>.\n\n
* .
* \anchor requests
* -# <b>Can you implement a feature/plugin/application I want?</b>\n
* .
* We're constantly working on new features and on improving what's
* already there, and we do love feedback from users. That said, we're
* a small team and we do have to pay our bills, so we always have to
* reserve our resources wisely. If there's a feature you'd like to
* see implemented, tell us on our Google group, and discuss it with
* other users: it may be on our schedule, or someone else may be
* already working on it to contribute it back to the project. You
* may even want to try and build it yourself and help us make Janus
* even better! \n\n
* If you really need something that isn't there, you may also want to consider
* <a href="https://janus.conf.meetecho.com/support">contacting us</a>
* for a sponsored development or consulting.\n\n
* .
* \anchor learning
* -# <b>I want to learn more on Janus!</b>\n
* .
* That's great! The first obvious suggestion is of course to carefully
* read the documentation here: we worked hard on it and are constantly
* expanding it, so it should always be the first source of information
* whenever in doubt. We have a great Google group as well where the
* <a href="https://groups.google.com/forum/#!forum/meetecho-janus">community</a>
* shares questions, data and more everyday, so make sure you join too! \n\n
* We also provide training on Janus and WebRTC in general, so if interested
* just <a href="https://janus.conf.meetecho.com/support">contact us</a>.\n\n
* .
*/
/*! \defgroup core Core
* \brief Core implementation of the server
* \details The Janus WebRTC Server is founded on a core that glues the
* involved parts together. The main code is janus.c that implements
* the logic behind the server itself: it implements the web server that
* interacts with browsers, and handles sessions with them. This includes
* taking care of media signalling and negotiation, and bridging peers
* with available plugins.
*/
/*! \defgroup protocols Protocols
* \brief Implementations of the WebRTC protocols
* \details The WebRTC specification (WEBRTC/RTCWEB) currently mandates
* the usage of a few protocols and techniques. The code in this group
* takes care of them all (SDP, ICE, DTLS-SRTP, RTP/RTCP).
* \ingroup core
*/
/*! \defgroup plugins Plugins
* \brief Janus plugins available out of the box
* \details In order to showcase how different plugins can implement
* completely different applications on top of the Janus core, a few
* plugin implementations are provided out of the box. The API for
* writing a new plugin is specified in the \ref pluginapi section.
*/
/*! \defgroup pluginapi Plugin API
* \brief Plugin API (aka, how to write your own plugin)
* \details The plugin.h header specifies the API a plugin needs to
* implement and make available in order to be used by the server and
* exposed to browsers.
* \ingroup plugins
*/
/*! \defgroup luapapi Lua plugin API
* \brief Lua plugin (aka, how to write your own plugin in Lua)
* \details The Janus Lua plugin allows you to write your application
* logic in Lua, instead of creating a new plugin in C: check the
* documentation in janus_lua.c for info on the APIs. Some additional
* hooks in C may be required, which is what the janus_lua_data.h and
* janus_lua_extra.c code is for.
* \ingroup plugins
*/
/*! \defgroup jspapi Duktape plugin API
* \brief Duktape plugin (aka, how to write your own plugin in JavaScript)
* \details The Janus Duktape plugin allows you to write your application
* logic in JavaScript, instead of creating a new plugin in C: check the
* documentation in janus_duktape.c for info on the APIs. Some additional
* hooks in C may be required, which is what the janus_duktape_data.h and
* janus_duktape_extra.c code is for.
* \ingroup plugins
*/
/*! \defgroup transports Transports
* \brief Transport plugins available out of the box
* \details In order to showcase how different transport plugins can implement
* support for the Janus API over different transport protocols, a few
* plugin implementations are provided out of the box. The API for
* writing a new plugin is specified in the \ref transportapi section.
*/
/*! \defgroup transportapi Transport API
* \brief Transport API (aka, how to write your own transport plugin)
* \details The transport.h header specifies the API a plugin needs to
* implement and make available in order to expose a new transport protocol
* that can be used by the server for talking the Janus API.
* \ingroup transports
*/
/*! \defgroup eventhandlers Event Handlers
* \brief Event handler plugins available out of the box
* \details In order to showcase how different plugins can handle events
* originated by the Janus core or any of its plugins, a sample plugin
* implementation is provided out of the box. The API for writing a new
* event handler plugin is specified in the \ref eventhandlerapi section.
*/
/*! \defgroup eventhandlerapi Event Handler API
* \brief Event Handler API (aka, how to write your own event handler plugin)
* \details The eventhandler.h header specifies the API a plugin needs to
* implement and make available in order to receive events from Janus.
* \ingroup eventhandlers
*/
/*! \defgroup tools Tools and utilities
* \brief Tools and utilities
* \details Set of simple tools and utilities that may be of help when
* used in conjunction with Janus.
*/
/*! \defgroup postprocessing Recordings post-processing utility
* \brief \ref recordings post-processing utility
* \details This simple utility (janus-pp-rec.c) allows you to
* post-process \ref recordings generated by the janus_recorder helper (e.g.,
* in the Video SFU plugin).
* \ingroup tools
*/
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化