| 
              Info
                
              NAT types
                
                  Network
address
                      translation (wp) 
                    
                      
                        
                          | 
 | 
 | 
 | description 
 | 
 | example 
 |  
                          | cone 
 | use the same port
                            numbers for internal and external IP tuples 
 | full cone 
 | allows inbound
                            connections from any source IP address and any
                            source port, as long as the destination tuple exists
                            in a previously created rule. 
 |    
{NAT
                              internal side}  |    {NAT
                              external side}  |  {Remote machine}|                        
                              |
 1. (INT_ADDR, INT_PORT) => [ (EXT_ADDR,
                              INT_PORT) -> (REM_ADDR, REM_PORT) ]
 2. (INT_ADDR, INT_PORT) <= [ (EXT_ADDR,
                              INT_PORT) <- (   *   
                              ,    *    ) ]
 | port forwarding |  
                          | 
 | 
 | (address-) restricted
                            cone 
 | 
 | 
 | 
 |  
                          | 
 | 
 | port-restricted cone 
 | 
 | 
 | 
 |  
                          | symmetric | always use different
                            numbers for each side of the NAT 
 | 
 | 
 | 
 | 
 | STUN/TURN (NAT
Types
                      and NAT Traversal)
                    
                      
                        
                          
                            
                              | 
 | symmetric | port-restricted
                                cone 
 | address-restricted
                                cone 
 | full cone 
 |  
                              | symmetric 
 | TURN 
 | TURN | STUN 
 | STUN 
 |  
                              | port-restricted
                                cone | TURN | STUN | STUN | STUN |  
                              | address-restricted
                                cone | STUN | STUN | STUN | STUN |  
                              | full cone | STUN | STUN | STUN | STUN | Tools to determine the type of NAT
                    
                  Eines i protocols / Tools and protocols
                
                  
                    
                      
                        
                          | 
 | 
 | RFC 
 | port 
 | programari / software 
 | description 
 |  
                          | 
 | 
 | 
 | UDP 
 | TCP 
 | (D)TLS 
 | 
 | 
 |  
                          | ICE 
 | Interactive
                            Connectivity Establishment 
 | 5245 
 | 
 | 
 | 
 | 
 | "ICE protocol
                            provides a structured mechanism to determine the
                            optimal communication path between two peers." (wp) "Coordinates the optimal method of establishing
                            connectivity between two peers using STUN and TURN"
                            (en)
 
 |  
                          | STUN | Session Traversal
                            Utilities for NAT | 3489
                            (CLASSIC-STUN) 5389
                            (STUN)
 | 3478 
 | 5349 |  | "The client,
                            typically operating inside a private network, sends
                            a binding request to a STUN server on the public
                            Internet. The STUN server responds with a success
                            response that contains the IP address and port
                            number of the client, as observed from the server's
                            perspective." (wp) |  
                          | TURN | Traversal Using Relay
                            NAT | 5766 6156
 7065
 
 | 
 | 
 | 
 |  | "TURN places a
                            third-party server to relay messages between two
                            clients when direct media traffic between peers is
                            not allowed by a firewall." (wp) "Allows an application or client to obtain IP
                            addresses and ports from an external relay server in
                            order to communicate with a peer" (en)
 
 | ICE
                    
                      ICE
                        (wp) RFC 5245Candidate transport
                        addresses
                        
                          
                            
                              
                                
                                  | 
 | 
 | 
 |  
                                  | host address 
 | host 
 | directly
                                    attached to a network interface 
 |  
                                  | server
                                    reflexive address 
 | srflx | public side
                                    of a NAT (STUN) 
 |  
                                  | relay 
 | relay 
 | allocated
                                    from a TURN server 
 | server reflexive (srflx) peer reflexive (prflx)relay2.2
Connectivity
                          checks
                        
                          Sort the candidate pairs in priority order.Send checks on each candidate pair in priority
                            order. Acknowledge checks received from the other agent.
                          ICE selects a valid pair of candidates4.
                          Sending the Initial Offer
                        
                          agent must:
                            
                              gather candidatesprioritize themeliminate redundant candidateschoose default candidatesformulate and send the SDP offerSTUN
                    
                      STUN
                        (wp) List
                          of 267 public STUN servers from EmerCoin project.
                          Tested 2017-08-08STUN DTLS
                        
                      works with NAT types (Limitations):
                        
                          full cone NATrestricted cone NATport restricted cone NATdoes not work with NAT types:
                        
                          symmetric (bi-directional) NATWireshark
                        
                          filter: classicstun (CLASSIC-STUN) (RFC
                              3489) stunc ... -b
                            
                              -> Binding Request<- Binding Response from bash
                        
                          How can I get my external IP address in a shell
                            script?
                            
                          clients
                            
                              WebRTC
samples
                                  Trickle ICE
                                
                                  If you test a STUN server, it works if you
                                    can gather a candidate with type "srflx". If you test a TURN server, it works if you
                                    can gather a candidate with type "relay".stunc (Sofia-SIP)
                                
                                  stunc stun.l.google.com:19302 -bstunc stun.voip.eutelia.it:3478 -bNAT type
                                    
                                      stunc stun.voip.eutelia.it:3478
                                          -nTLS
                                    
                                      on server, TCP/3478 must be openStuntman
                                   
                                  STUN server and client Compilation
                                    
                                      Dependencies
                                        
                                          Mageia
                                            
                                              urpmi install lib64boost-develSteps
                                        
                                      Installation
                                    
                                      Debian /Ubuntu
                                        
                                          apt-get install
                                              stuntman-clientÚs / Usage
                                    
                                      ./stunclient stun.e-fon.ch 3478TURN
                    
                      TURN
                        (wp) RFC 8656
                        (5766) extension to STUNrelays media works with:
                        
                          symmetric (bi-directional) NATInfo
                        
                      
                        
                          
                            Node, address,
                        traffic, transport.
                              | TURN client
 | client host
 transport address
 | NAT | client server-reflexive
 transport address
 | 
                                  TURN commands: ALLOCATION, ...TURN message: application data | TURN server
 transport address
 | TURN server
 | relayed transport address
 |  | peer transport address
 | PEER |  
                              | 
 | 
 | 
 | 
 | 
                                  UDPTCPTLS over TCPDTLS over UDP | 
 | 
 | local candidate: 
 |  | remote candidate | 
 | Servidor / Server
                        
                      config
                        
                        
                          
                            /etc/janus/...
                              
                                turn_server =turn_port =
 ...
TCP
                        
                          from client to server:
                            
                          from server to peer (relay):
                            
                              RFC
                                  6062?transport=tcp
                                  this will also force TCP between TURN
                                    client and TURN serverTCP
                              and TLS transport support for TURN
                            
                              "There is an extension to TURN, RFC 6062, that
                                defines the "full" TCP support: the data "after"
                                TURN can be relayed over TCP (not TLS). The
                                connection between the client and the TURN
                                server must be TCP or TLS if we want the traffic
                                to be relayed over TCP."What
                              happens when WebRTC shifts to TURN over TCPAutenticació / Authentication
                        
                      Ús / Usage
                        
                          Janus clients 
                            
                              Using
                                  TURN server with Janusechotest.js
                                
                                  janus = new Janus({iceServers: [{urls:
                                      "turn:myturnserver:5349", username:
                                      "guest", credential: "somepassword"},
 
{urls:
                                        "turn:myturnserver:5349?transport=tcp",
                                        username: "guest", credential:
                                        "somepassword"}],})
verify with about:webrtc(Firefox):force TURN (relay)
                                
                              Servidors / Servers
                
                  rfc5766-turn-server coTURN
                    
                      Instal·lació / Installation
                        
                      
                        
                          
                            
                              | 
 | AWS | coturn config | test from client 
 |  
                              | 
 | security group | /etc/coturn/turnserver.conf | protocol | stunc (sofia) | turnutils
                                (coturn) | TrickleICE |  
                              | non secure | TCP, UDP 3478 | 
 | STUN | stunc myturnserver -b | turnutils_stunclient myturnserver
 | 
                                  STUN or TURN URI: stun:myturnserver |  
                              | user=guest:somepassword | TURN | 
 | turnutils_uclient -v -u guest -w
                                  somepassword -p 3478 myturnserver  | 
                                  STUN or TURN URI: turn:myturnserverTURN username: guestTURN password: somepassword |  
                              | secure | TCP, UDP 5349 | #tls-listening-port=5349cert=/etc/letsencrypt/live/toto.org/fullchain.pem
 pkey=/etc/letsencrypt/live/toto.org/privkey.pem
 | STUN | stunc myturnserver:5349 -b | turnutils_stunclient -p 5349
                                  myturnserver | 
                                  STUN or TURN URI: stun:myturnserver:5349 |  
                              | #tls-listening-port=5349user=guest:somepasswordcert=/etc/letsencrypt/live/toto.org/fullchain.pem
 pkey=/etc/letsencrypt/live/toto.org/privkey.pem
 | TURN | 
 | turnutils_uclient -v -u guest -w
                                  somepassword -p 5349 myturnserver | 
                                  STUN or TURN URI: turn:myturnserver:5349TURN username: guestTURN password: somepassword | Config
                        
                           Transport between TURN client and TURN server (RFC
                              8656):
                            
                              
                                Note: on server, use
                                  | 
 | client 
 | turnserver.conf | 
 | 
 | 
 | 
 | turnutils_uclient | test.webrtc.org | Firefox |  
                                  | 
 | 
 | 
 | no-udp 
 | no-dtls 
 | no-tcp 
 | no-tls | 
 | 
 | about:webrtc |  
                                  | UDP | turn:myturnserver:3478 
 | listening-port=3478 | - 
 | 
 | 
 | 
 | [-p 3478] | Network: UDP enabled | 
 |  
                                  | DTLS over UDP | turns:myturnserver:5349 | tls-listening-port=5349 | 
 | - | 
 | 
 | -p 5349 | Network: UDP enabled | 
 |  
                                  | TCP | turn:myturnserver:3478 | listening-port=3478 | 
 | 
 | - 
 | 
 | [-p 3478] -t | Network: TCP enabled | 
 |  
                                  | TLS over TCP | turns:myturnserver:5349 | tls-listening-port=5349 | 
 | 
 | 
 | - 
 | -p 5349 -t | Network: TCP enabled | 
 |  ss -tulpn | grep turnto check open ports.Gathered candidates (relayed transport address) can
                            be UDP, even if transport between TURN client and
                            TURN server is established over TCP.
Transport between TURN server and peer (candidate
                            of type relay) (RFC
                              6062): (is transport=tcp also needed to
                            specify tcp transport between TURN client and TURN
                            server?)
 
                              
                                
                                  | 
 | client | turnserver.conf | 
 | turnutils_uclient | Firefox |  
                                  | 
 | 
 | no-udp-relay (also disables udp, tcp communication
                                    between client/server,
 even if, according to ss, ports are
                                    available)
 | no-tcp-relay (not working?)
 | 
 | about:webrtc |  
                                  | 
 | 
 | 
 | 
 | 
 | local candidate |  
                                  | UDP (RFC 8656) | turn:myturnserver:...[?transport=udp] | - | 
 | 
 | x.x.x.x:p/udp (relay-udp) |  
                                  | DTLS over UDP | turns:myturnserver:...[?transport=udp] | 
 | 
 | 
 | x.x.x.x:p/udp (relay-tls) |  
                                  | TCP (RFC 6062) | turn:myturnserver:...?transport=tcp | 
 | - | -T (implies -t) | x.x.x.x:p/udp (relay-tcp) |  
                                  | TLS over TCP (RFC 6062) | turns:myturnserver:...?transport=tcp | 
 | 
 | 
 | x.x.x.x:p/udp (relay-tls) | activate TLS/DTLS
                            
                              /etc/coturn/turnserver.conf
                                
                                  #tls-listening-port=5349cert=/etc/letsencrypt/live/toto.org/fullchain.pem
 pkey=/etc/letsencrypt/live/toto.org/privkey.pem
check from server
                                
                                  tail -n 200
                                      /var/log/coturn/turnserver.log ss -tulnpcheck from remote client
                                
                                  stunc turn.watchity.net:5349 -bturnutils_stunclient -p 5349
                                      myturnserver TrickleICE
                                    
                                      STUN or TURN URI:
                                        stun:myturnserver:5349Gather candidates:
                                        
                                          srflx udp
                                            <my_external_ip_address>non default ports (e.g. 443 for TLS)
                            
                              coturn.service
                                
                                  [Service] AmbientCapabilities=CAP_NET_BIND_SERVICE
 ...
After
                                  update of coturn can not connect to 443 #421without AmbientCapabilities, you
                                will see, in /var/log/coturn/turnserver.log
                                  ERROR: Fatal final failure: cannot
                                      bind DTLS/UDP listener socket to addr
                                      127.0.0.1:443add a user/password
                            
                              option 1 (these credentials will not work with
                                -u and -w options in turnutils_uclient):
                                
                                  /etc/coturn/turnserver.conf
                                    
                                  option 2:
                                
                                  sudo turnadmin -a -r mycompany.org
                                      -u convidat -p contrasenyacheck from remote client
                                
                                  turnutils_uclient -v -p 5349 -u
                                      convidat -w contrasenya myturnserverTrickleICE
                                    
                                      STUN or TURN URI:
                                        turns:myturnserver:5349TURN username: guestTURN password: somepasswordGather candidates:
                                        
                                          relay udp
                                            <turn_server_ip_address>...dynamic credentials:
                            
                              /etc/coturn/turnserver.conf
                                
                                  #lt-cred-mechuse-auth-secret
 static-auth-secret=north
somewhere (e.g. a completely different
                                server), generate temporary credentials,
                                calculated using the shared secret:
                                
                                  usercombo -> "timestamp_when_password_will_expire:userid"turn_user -> usercombo
 turn_password -> base64(hmac_sha1(secret,
                                    usercombo))
put them when accessing the coturn server
                                (e.g. from Janus echotest.js):
                                
                                  iceServers: [{urls:
                                      "turn:myturnserver:5349", username:
                                      turn_user, credential: turn_password},test with TrickleICE:
                                
                                  STUN or TURN URI: turns:myturnserver:5349TURN username: turn_userTURN password: turn_passwordGather candidates (you can also filter by
                                    "relay" only):
                                    
                                      relay udp
                                        <turn_server_ip_address>logs
                            
                              # sudo mkdir -p /var/log/coturn# sudo chown turnserver.turnserver
                                  /var/log/coturn
 log-file=/var/log/coturn/turnserver.log
 #syslog
 # Enable full ISO-8601 timestamp in all logs
 new-log-timestamp
AWS EC2
                        
                      Servidor / Server
                        
                          sudo systemctl enable coturn.servicesudo systemctl start coturn.servicesudo systemctl status coturn.serviceDebug and logs
                        
                          /var/log/coturn/turnserver.logUtils and test (turnutils)
                        
                          Instal·lació / Installation
                            
                              from source
                                
                              CentOS
                                
                                  sudo dnf install coturn-utilsÚs / Usage
                            
                              coturn/examples/scriptsturnadminman turnutilsturnutils_natdiscoveryturnutils_oauthturnutils_peerturnutils_stunclient
                                
                                  turnutils_stunclient myturnserverturnutils_uclientDebug
                
              Demos
                
                  AppRTC (see logs,
                    about:webrtc)  | 
        
          | 
              Info
                
                
              Dependències
                  / Dependencies
                
                  Ubuntu
                    
                  CentOS
                    
                      yum install epel-release git gccyum install libmicrohttpd-devel
                          jansson-devel openssl-devel libsrtp-devel glib-devel
                          opus-devel libogg-devel libsoup-devel pkgconfig
                          gengetopt libtool autoconf automake
libnice-devel
 yum install doxygen graphvizMageia
                    
                      Mageia 6
                        
                          urpmi libmicrohttpd-devel
                            gnutls-devel gengetopt
                              jansson-devel lib64lus-devel Mageia 5
                        
                          urpmi libmicrohttpd-devel
                            gnutls-devel gengetoptJansson
                            
                              to compile Janus >=v0.2.5 do not use
                                jansson-devel package version 2.4, as it has an
                                error in /usr/include/jansson.h
                                
                              Compilation:
                                
                                  wget
http://www.digip.org/jansson/releases/jansson-2.10.tar.gztar xvzf jansson-2.10.tar.gzcd jansson-2.10./configuremakemake checksudo make installsudo ldconfiglibmicrohttpd
                    
                      version >=0.9.59 is needed by Janus >=0.9.2IMPORTANT: check that no system libmicrohttpd-devel is
                        installed from tar file:
                        
                          wget
                              https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.71.tar.gztar xvf libmicrohttpd-0.9.71.tar.gzcd libmicrohttpd-0.9.71./configuremakesudo
                                make installNice
                    
                      WARNING: package provided by CentOS EPEL repositories
                        (libnice-0.1.3-4.el7.x86_64) is too old and will give problemsDependències / Dependencies
                        
                          CentOS
                            
                              sudo yum install glib2-develfrom tar file:
                        
                      from git:
                        
                          GitLab:
 
                              git clone
                                  https://gitlab.freedesktop.org/libnice/libnice.git
 GitHub:
 
                              git clone
                                  https://github.com/libnice/libnice.gitcd libnicecompilació / compilation
                        
                          ./configuremake
 sudo make install
Sofia-SIP
                    
                      Files
 wget
http://downloads.sourceforge.net/project/sofia-sip/sofia-sip/1.12.11/sofia-sip-1.12.11.tar.gztar xvzf sofia-sip-1.12.11.tar.gz
 cd sofia-sip-1.12.11
 ./configure
 make
 sudo make install # will install it in /usr/local/lib
 sudo ldconfiglibsrtp
                    
                  libusrsctp (needed when compiling
                    Janus with --enable-data-channels)
                      Dependències / Dependencies
                        
                      git clone https://github.com/sctplab/usrsctpcd usrsctp
 ./bootstrap
 ./configure
 make
 sudo make install
 sudo ldconfig
libwebsockets (needed when
                    compiling Janus with no --disable-websockets)
                      Dependències / Dependencies
                        
                          CentOS
                            
                              sudo yum install cmake openssl-develgit clone
                          https://libwebsockets.org/repo/libwebsocketscd libwebsockets
 # If you want the stable version of libwebsockets,
                          uncomment the next line
 # git checkout v2.4-stable
 mkdir build
 cd build
 # See
                          https://github.com/meetecho/janus-gateway/issues/732
                          re: LWS_MAX_SMP
 cmake -DLWS_MAX_SMP=1 -DCMAKE_INSTALL_PREFIX:PATH=/usr
                          -DCMAKE_C_FLAGS="-fpic" ..
 make && sudo make install
libconfig (needed to have bash tool ls-config)
                    
                      Dependències / Dependencies
                        
                          CentOS
                            
                              sudo yum install texinfo flex gcc-c++
                                  bison ...autoreconf
 ./configure
 make
 sudo make install
Janus compilation
                
                  # activate /usr/local/lib (nice,
                      sofia-sip) for
                      pkg-configexport PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/
 git clone https://github.com/meetecho/janus-gatewaycd janus-gateway
 git checkout v0.9.1
 sh autogen.sh
 ./configure --disable-websockets --disable-data-channels
                      --disable-rabbitmq --prefix=/usr --sysconfdir=/etc
                      --localstatedir=/var
 make
 sudo make install
websockets
                    
                      install libwebsockets ./configure --disable-data-channels
                          --disable-rabbitmq --prefix=/usr --sysconfdir=/etc
                          --localstatedir=/varWebSockets
                          API install config files in /etc/janus Eclipse
                    
                      New / C Project: GNU Autotools / Empty projectForks
                    
                  Problemes /
                    Problems
                    
                      when compiling with --enable-post-processing
 postprocessing/pp-h264.c: In function
                          ‘janus_pp_h264_create’:postprocessing/pp-h264.c:99:29: error: assignment of
                          member ‘video_codec’ in read-only object
 fctx->oformat->video_codec =
                          codec->id;
 ^
                          Solució / Solution
                            
                              check for different installed versions of
                                ffmpeg (e.g. from ffmpeg compilation and
                                gstreamer compilation)
                                
                                  compare:
                                    
                                      ffmpeg -versiongrep "define LIBAVCODEC_VERSION_"
                                        /usr/local/include/libavcodec/version.hreinstall ffmpeg after gstreamer
                                    compilation/usr/include/jansson.h:53:3: error: conflicting types
                        for 'json_t'
                        
                          Mageia: jansson-devel-2.4-4.1.mga5Solució / Solution
                            
                              /usr/include/jansson.h
 
                                  typedef struct json_t
                                      {json_type type;
 size_t refcount;
 } json_t;
Service
                
                  Janus
                      as a daemon/service janus.service
                    (/usr/lib/systemd/system/janus.service)
                    
                    
                      [Unit]Description=Janus WebRTC Gateway
 Wants=network.target
 After=syslog.target network.target remote-fs.target
                          nss-lookup.target cloud-init.service
 
 [Service]
 Type=simple
 ExecStart=/usr/local/bin/janus
 #User=janus
 #Group=janus
 Restart=on-failure
 LimitNOFILE=65536
 
 [Install]
 WantedBy=multi-user.target
manage service
                    
                      sudo systemctl status janus.servicesudo systemctl start janus.servicesudo systemctl stop janus.serviceConfiguració / Setup
                
                  /etc/janus/janus.jcfg
                    
                      debug
                        
                          general: {log_to_file =
                              "/var/log/janus/janus.log"            
                              # Whether to use a log file or not
 debug_level = 5
                                                                  
                              # Debug/logging level, valid values are 0-7
 ...
 }
/etc/janus/janus.cfg
                    
                      debug
                        
                          [general]log_to_file = /var/log/janus/janus.log
 debug_level =
                              7                        
;
                              Debug/logging level, valid values are 0-7
 debug_timestamps = yes
 
 [nat]
 # maybe nice debug messages are only available
                              when janus is called from command line, with:
 # export NICE_DEBUG=all
 # export G_MESSAGES_DEBUG=all
 # https://nice.freedesktop.org/libnice/libnice-Debug-messages.html
 nice_debug = true
nat
                          (these values are for Janus itself. For final clients,
                          modify the variable iceServers in javascript) 
                        
                          [nat]stun_server = stun.voip.eutelia.it
 stun_port = 3478
 turn_server =
 turn_port =
 turn_type =
 turn_user =
 turn_pwd =
 nice_debug
                              = true
DTLS
                        
                          ; Certificate and key to
                              use for DTLS.[certificates]
 cert_pem = /usr/share/janus/certs/mycert.pem
 cert_key = /usr/share/janus/certs/mycert.key
 
 [media]
 ;dtls_mtu = 1200
admin
                        
                          [general]admin_secret = mysecret
NACK
                        
                          [media]max_nack_queue = 500
/etc/janus/janus.transport.http.cfg
                    
                      CORS
                        
                          [cors]allow_origin =
                              https://<your_demos_server>:<your_demos_port>
                              # e.g. https://192.168.1.100:8080
enable HTTPS
                        on port 8089
                        
                          [general]https = yes       
                                     
                                  ; Whether to enable HTTPS
                              (default=no)
 secure_port = 8089   
                                      ; Web server
                              HTTPS port, if enabled
 
 ; Certificate and key to use for HTTPS.
 [certificates]
 cert_pem = /usr/share/janus/certs/mycert.pem
 cert_key = /usr/share/janus/certs/mycert.key
Let's
                              Encrypt certificates
                            
                              ; Certificate and key
                                  to use for HTTPS.[certificates]
 cert_pem =
                                  /etc/letsencrypt/live/www.example.org/fullchain.pem
 cert_key = /
etc/letsencrypt/live/www.example.org/privkey.pemProblemes / Problems
                                
                                  /var/log/janus/janus.log
                                      Couldn't start secure webserver
                                          on port 8089...Manually start janus as user janus,
                                        with high debug level
 
                                          sudo -i systemctl stop janus.service
 su janus -s /bin/bash -c
                                              "/bin/janus -d 7"Check that your user has access to
                                        certificate file:
 
                                          su janus -s /bin/bash -c "ls
                                              -l /etc/letsencrypt/live/www.example.org/fullchain.pem"Solució / Solution
                                        
                                          check that the user that is
                                            running the service has permission
                                            to access dirs: /etc/letsencrypt/live,
                                              /etc/letsencrypt/archiveNon-root
                                              access to Letsencrypt certificatesinstall latest versions of:
                                            sofia_sip, libnice, libsrtp,
                                            libmicrohttpd (I don't know which of
                                            them solves the problem) admin
                        
                          [admin]admin_http = yes
 admin_port = 7088
 admin_https = yes
 admin_secure_port = 7889
Amazon AWS
                    EC2
                    
                      Janus >=v0.4.4echo test demo needs a libnice version >0.1.14
                        (e.g. 0.1.16 master
                          28th June 2018 from git)
                        
                      you need to specify NAT-1-1 with the public IP address
                        (STUN server for Janus is not needed):
                        
                      open ports in security group
                        
                          TCP: 8088-8089UDP: ... (same ports as defined in  [media]
                              rtp_port_range, to avoid problems with
                            mobile networks)demos
                            
                          admin
                            
                          Debug
                
                  Configuració
/
                      Setup logs
                    
                      tail -n 200 -f /var/log/janus/janus.logadmin
                    
                      Understanding
the
                          Janus admin APIAdmin/Monitor
                          APIConfiguració
                          / Setup
                        
                          open port 7088 in firewall (and/or AWS security group) /etc/janus/janus.cfg
                            
                              [general]admin_secret = mysecret
/etc/janus/janus.transport.http.cfg
                            
                              [admin]admin_http = yes
 admin_port = 7088
systemctl restart janus.serviceÚs / Usage
                        
                          curl -X POST -H 'Content-Type:
                              application/json' --data-binary
                              '{"janus":"list_sessions","transaction":"1234","admin_secret":"mysecret"}'
                              http://<janus_server_ip_address>:7088/admincurl -X POST -H 'Content-Type:
                              application/json' --data-binary
'{"janus":"list_handles","transaction":"1234","admin_secret":"mysecret"}'
http://<janus_server_ip_address>:7088/admin/<session>curl -X POST -H 'Content-Type:
                              application/json' --data-binary
'{"janus":"handle_info","transaction":"1234","admin_secret":"mysecret"}'
http://<janus_server_ip_address>:7088/admin/<session>/<handle>Resposta / Response
                        
                          
                            
                              
                                
                                  | Header 
 | info
 |  | 
 | 
 | 
 |  
                                  | Plugin
                                    specific 
 | 
 | plugin_specific
 | ... 
 | 
 | 
 |  
                                  | Handle flags 
 | 
 | flags
 | 
 | 
 | 
 |  
                                  | SDPs 
 | 
 | sdps
 | 
 | 
 | 
 |  
                                  | PeerConnection 
 | 
 | streams
 | Header 
 |  | 
 |  
                                  | 
 | 
 | 
 | SSRC 
 | ssrc
 | 
 |  
                                  | 
 | 
 | 
 | ICE
                                    components 
 | components
 | 
                                      state: connecting, ready,
                                          disconnected, failed local-candidatesremote-candidatesselected-pairdtlsin-statsout-stats | Troubleshooting 
 
                      
                        
                          | 
 | processing 
 | 
 | 
 | 
 | 
 | succeeded 
 | 
 | 
 | 
 | 
 |  
                          | 
 | server 
 | 
 | client 
 | 
 | 
 | server 
 | 
 | client 
 | 
 | 
 |  
                          | 
 | admin 
 | tshark 
 | wireshark 
 | chrome://webrtc-internals | about:webrtc 
 | admin 
 | tshark 
 | wireshark 
 | chrome://webrtc-internals | about:webrtc |  
                          | ICE 
 | streams/components/ 
 | 
 | filter: stun 
 | iceconnectionstatechange:
                            checking | 
 | streams/components/ 
 
                              state: readyconnected: xxxxx  | 
 | 
 | 
 | 
 |  
                          | DTLS 
 | streams/components/dtls/ 
 
                              dtls-state: created valid: false ready: false  | 
 | filter: dtls 
 | 
 | 
 | streams/components/dtls/ 
 
                              dtls-state: connected valid: true ready: true  | 
 | 
 | 
 | 
 | tshark
                    
                      server
                        
                          get destination port:
                            
                              client: from Firefox about:webrtc "Remote
                                candidate"server /var/log/janus/janus.log: a=candidatetshark -d
                              udp.port==<destination_port>,rtp udp port
                              <destination_port>
                              8857
                                  14.757747410 192.168.0.101 -> 192.168.0.108
                                  RTP 153 PT=DynamicRTP-Type-109,
                                  SSRC=0xDE951CF3, Seq=61918, Time=1643530196 8862
                                  14.779327125 192.168.0.101 -> 192.168.0.108
                                  RTP 1126 PT=DynamicRTP-Type-120,
                                  SSRC=0xC0C0D699, Seq=31111, Time=617518567...
...Janus plugins
                
                  For old custom plugins, use v0.1.x (instead of v0.2.x)v0.1.x
                    
                  v0.2.x
                    
                      include janus/plugins/plugin.hMigration from v0.1.x to v0.2.x:
                        
                      3rd party plugins
                    
                  Included plugins
                    
                      streaming
                           
                          janus.plugin.streaming.c
                            (github)
                            
                            
                              Streaming API
                                
                                  CURL
                                      examples
                                    
                                  
                                    
                                      
                                        
                                          | 
 | request 
 | js 
 | request
                                            json 
 | response
                                            json 
 | event 
 | janus_...c 
 |  
                                          | synchronous (immediate response)
 
 | 
                                              listcreatedestroyrecordingenabledisable  | 
 | {"transaction":
                                              "21bGZvoTdbG8Ab6X",
 "janus": "message",
 "body":
                                              }{"request": "list"}{"request": "create","type": "rtp",
 "description": "First test",
"audio_port": 8006,
 "video_port": 8004
 ...}
 
 | {"janus": "success",
 "session_id":
                                              8566092198416479,
 "sender": 6220156789031370,
 "transaction":
                                              "21bGZvoTdbG8Ab6X",
 "plugindata": {
 "plugin":
                                              "janus.plugin.streaming",
 "data":
 
                                              }{"streaming": "list","list": [
 {
 "id": 1,
 "description": "Opus/VP8 live
                                                  stream coming from gstreamer",
 "type": "live",
 "audio_age_ms": 66673351,
 "video_age_ms": 66673351
 },
 ...
 ]
 }
{"streaming": "created","created": "3346122389194671",
 "permanent": false,
 "stream": {
 "id": 3346122389194671,
 "description": "First test",
 "type": "live",
 "is_private": false,
 "audio_port": 8006,
 "video_port": 8004
 }
 }
...  | - 
 |  |  
                                          | asynchronous (response in an event)
 
 | 
                                              watchstartpauseswitchstop  | startStream 
 | {"transaction":
                                              "21bGZvoTdbG8Ab6X",
 "janus": "message",
   "body":
     {"request":
                                              "watch",
      "id":
                                              ...}
 | 
 | 
                                              preparing startingstartedstopped  | 
 |  
                                          | onmessage:
                                              function(msg, jsep) {
   if(jsep !== undefined
                                              && jsep !== null) {(...)streaming.createAnswer
},
 
 | 
 | {"janus": "event",
 
"session_id":
                                              8566092198416479,"sender": 6220156789031370,
 "transaction":
                                              "21bGZvoTdbG8Ab6X",
 "plugindata": {
 "plugin":
                                              "janus.plugin.streaming",
 "data": {
 "streaming": "event",
 "result": {"status": "preparing"}
 }
 "jsep": {
 "type": "offer",
 "sdp": "..."
 }
}
 | 
 |  
                                          | {"transaction":
                                              "21bGZvoTdbG8Ab6X",
 "janus": "message",
 "body":
                                              {"request": "start"}"jsep": {"type": "answer",
 "sdp": "..."}
 | 
 | 
 |  
                                          | onmessage:
                                              function(msg, jsep) {}var result = msg["result"];
 if(result != undefined
                                              && result != null) {...
},
 
 | 
 | {"janus": "event",...
 
                                              "plugindata": {"plugin":
                                              "janus.plugin.streaming",
 "data": {
 "streaming": "event",
 
"result":
                                              {"status": "starting"} | 
 |  
                                          | 
 | {"janus": "event",...
 
                                              "plugindata": {"plugin":
                                              "janus.plugin.streaming",
 "data": {
 "streaming": "event",
 
"result":
                                              {"status": "started"} | 
 |  
                                          | onremotestream:
function(stream)
                                              {$('#videoremote').append('<video 
                                              id="remotevideo" width=320
                                              height=240 autoplay/>');
 Janus.attachMediaStream($('#remotevideo').get(0),
                                              stream);
 },
 | 
 | 
 | 
 | config
                            
                              /etc/janus/janus.plugin.streaming.cfg
                                
                                  
                                    
                                      | 
 | config file | config
                                        file 
 | streamer 
 | browser
                                        notes 
 |  
                                      | 
 | /etc/janus/ janus.plugin.streaming.jcfg
 | /etc/janus/janus.plugin.streaming.cfg
                                          (OBSOLETE) | 
 | Chrome 
 | Firefox 
 |  
                                      | VP8 / Opus 
 | 
 | [gstreamer-sample]type = rtp
 id = 1
 description = Opus/VP8 live stream
                                          coming from gstreamer
 audio = yes
 video = yes
 audioport = 5002
 audiopt = 111
 audiortpmap = opus/48000/2
 videoport = 5004
 videopt = 100
 videortpmap = VP8/90000
 secret = adminpwd
 |  | 
 | 
 |  
                                      | 
 | [opus-vp8-multicast]type = rtp
 id = 20
 description = Opus/VP8 live multicast
                                          stream
 audio = yes
 video = yes
 audioport = 5002
 audiomcast = 232.3.4.5
 audiopt = 111
 audiortpmap = opus/48000/2
 videoport = 5004
 videomcast = 232.3.4.5
 videopt = 100
 videortpmap = VP8/90000
 | 
                                          streaming
                                              RTP VP8/Opus with Gstreamerstreaming
                                              RTP VP8/Opus with ffmpeg
                                            
                                              ffmpeg -re -f lavfi -i
                                                  "testsrc=size=320x180:rate=24"
                                                  -f lavfi -i
                                                  "sine=frequency=440:sample_rate=48000,
                                                  aformat=channel_layouts=stereo"
                                                  -c:v vp8 -b:v 700k -an -f rtp
                                                  -payload_type 100
                                                  rtp://232.3.4.5:5004-c:a opus -strict -2 -b:a 64k
                                                  -vn -f rtp -payload_type 111
                                                  rtp://232.3.4.5:5002?pkt_size=1400-sdp_file
                                                  /tmp/vp8_opus_multicast.sdp?pkt_size=1400 | ok 
 | ok 
 |  
                                      | H.264 (unicast)
 | h264-sample: {type = "rtp"
 id = 10
 description = "H.264 live stream
                                          coming from gstreamer"
 audio = false
 video = true
 videoport = 8004
 videopt = 126
 videocodec = "h264"
 videofmtp = "profile-level-id=42e01f;packetization-mode=1"
 #secret = "adminpwd"
 }
 
 | 
 | 
                                          ffmpeg -re -f lavfi -i
                                              "testsrc=size=320x180:rate=24"
                                              -c:v libx264 -b:v 700k -pix_fmt
                                              yuv420p -profile:v
                                                baseline -level:v 31
                                              -an -f rtp -payload_type 126
                                              rtp://127.0.0.1:8004 -sdp_file
                                              /tmp/h264.sdpgst-launch-1.0
                                              -v videotestsrc ! videoconvert !
                                              x264enc ! video/x-h264,profile=baseline
                                              ! rtph264pay config-interval=10
                                              pt=126 ! udpsink host=127.0.0.1
                                              port=8004gst-launch-1.0
                                              -v videotestsrc !
                                              video/x-raw,width=1280,height=720
                                              ! videoconvert ! x264enc !
                                              video/x-h264,profile=baseline
                                              ! rtph264pay config-interval=10
                                              pt=126 ! udpsink host=127.0.0.1
                                              port=8004
 | janus.plugin.streaming.jcfg
 
 # All browsers also support H.264,
                                          often through Cisco's OpenH264 plugin.# The only profile that is
                                          definitely supported is the baseline
                                          one, which
 # means that if you try a higher one
                                          it might or might not work. No matter
 # which profile you encode, though,
                                          you can put a custom one in the SDP if
 # you override the fmtp SDP attribute
                                          via 'videofmtp'. The following is an
 # example of how to create a simple
                                          H.264 mountpoint: you can feed it via
 # an x264enc+rtph264pay pipeline in
                                          gstreamer, an ffmpeg script or other.
 #
 h264-sample: {...
 
                                          
                                            IMPORTANT: in order to
                                        have it working in Firefox,
                                        second byte cannot be 00 (not
                                        constrained); it must be e0
                                        (constrained)
                                              | profile-level-id | ffmpeg | Chrome | Firefox |  
                                              | 42e01f | -profile:v baseline
                                                  -level:v 31 | ok | ok |  
                                              | 4d0033 | -profile:v main -bf 0
                                                  -level:v 51 | ok | not ok |  
                                              | 4de033
 | -profile:v main -bf 0
                                                  -level:v 51 | ok 
 | ok 
 |  |  
                                      | H.264 (multicast)
 
 | 
 | [h264-multicast]type = rtp
 id = 10
 description = H.264 live multicast
                                          stream
 audio = no
 video = yes
 videoport = 8004
videomcast = 232.6.7.8
 videopt = 126videortpmap = H264/90000
 videofmtp =
                                          profile-level-id=42e01f\;packetization-mode=1
 | 
                                          ffmpeg -re -f lavfi -i
                                              "testsrc=size=320x180:rate=24"
                                              -c:v libx264 -b:v 700k -pix_fmt
                                              yuv420p -profile:v baseline
                                              -level:v 31 -an -f rtp
                                              -payload_type 126
                                              rtp://232.6.7.8:8004 -sdp_file
                                              /tmp/h264.sdpffmpeg -re -i sintel.mp4 -an
                                              -c copy -bsf:v h264_mp4toannexb -f
                                              rtp -payload_type 126
                                              rtp://232.6.7.8:8004-sdp_file /tmp/sintel.sdp?pkt_size=1400 | ok 
 | if
                                        profile.level-id is not specified,
                                        Firefox interprets offered sdp as: a=fmtp:126
                                          profile-level-id=420010;level-asymmetry-allowed=0;packetization-mode=1and Firefox response only contains VP8:
 
 a=rtpmap:120 VP8/90000It does not work.
 
 |  
                                      | H.264 / Opus | 
 | [h264-opus-multicast]type = rtp
 id = 4246246658112756
 description = h264_opus_multicast
 audio = yes
 audioport = 8002
 audiomcast = 232.3.4.5
 audiopt = 111
 audiortpmap = opus/48000/2
 audiofmtp = sprop-stereo=1
 video = yes
 videoport = 8004
 videomcast = 232.6.7.8
 videopt = 126
 videortpmap = H264/90000
 videofmtp =
                                          packetization-mode=1\;profile-level-id=42e01f
 data = no
 | 
                                          ffmpeg -re -f lavfi -i
                                              "testsrc=size=320x180:rate=24" -f
                                                lavfi -i
                                                "sine=frequency=440:sample_rate=48000,
                                                aformat=channel_layouts=stereo"
                                              -c:v libx264 -b:v 700k
                                              -pix_fmt yuv420p -profile:v
                                              baseline -level:v 31 -an -f rtp
                                              -payload_type 126
                                              rtp://232.6.7.8:8004?pkt_size=1400-c:a opus -strict
                                                -2 -b:a 64k -vn -f rtp
                                                -payload_type 111
                                                rtp://232.3.4.5:8002-sdp_file
                                              /tmp/h264_opus_multicast.sdp?pkt_size=1400 | 
 | 
 | Problemes / Problems
                            
                          videoroom
                        
                          janus.plugin.videoroom.c (github)
                            
                              Video Room API (VideoRoom
                                  plugin documentation)
                                
                                  
                                    
                                      
                                        
                                          | 
 | request 
 | event 
 |  
                                          | synchronous 
 | 
                                              createdestroyeditexistslistallowedkicklistparticipants  | - 
 |  
                                          | asynchronous 
 | 
                                              joinjoinandconfigureconfigurepublishunpublishstartpauseswitchstopaddremoveleave  |  | Problemes
/
                            Problems
                            
                          plain RTP
                        
                      DTLS
                
                  janus.cfg
                    
                      ; Certificate and key to use
                          for DTLS.[certificates]
 cert_pem = /usr/share/janus/certs/mycert.pem
 cert_key = /usr/share/janus/certs/mycert.key
 
 [media]
 ;dtls_mtu = 1200
Problems
                      with DTLS Problemes / Problems
                
                  Compilació
/
                      Compilation AWS EC2 Plugins
                    
                  Accés des de client / Access from client (Javascript
                    console)
                    
                      Javascript console
                        
                          hangup_media(plugin.h)
                            not called in Firefox
                              solucionat a
                                Firefox 55 / solved in Firefox 55
                                
                              meetecho-janus Google groups: hangup,
                                destroy_session, DTLS-SRTP
                                
                              WebRTC error...
                              {"name":"InternalError","message":"Starting video
                              failed"}(Firefox)
 WebRTC error...
                              {"name":"NotReadableError","message":"Could not
                              start video source"}(Chrome)
                              Solució / Solution
                                
                                  No podeu fer servir alhora la mateixa
                                    webcam des de dos navegadors diferents / You
                                    cannot use the same webcam from two browsers
                                    (Firefox/Chrome) at the same timeiOS
                            
                          Demos
                            
                              Echo test not working (always spinning)
                                
                              Browser debug logs
                        
                          [...:WARNING:nack_module.cc(237)] Sequence
                              number xxxx removed from NACK
                              list due to max retries.Missatges al servidor / Messages on server
                    (/var/log/janus/janus.log)
                    
                      [ERR] [dtls.c:janus_dtls_srtp_incoming_msg:923]
                          ... Oops, error creating inbound SRTP session for
                          component 1 in stream 1??[ERR] [dtls.c:janus_dtls_srtp_incoming_msg:924]
                          ...  -- 1 (srtp_err_status_fail)
Not video and not audio? dropping (SSRC...)(debug_level = 5)
                        Retransmitted ... packets due to NACK (video stream #0)
                          when using streaming plugin
                            
                              Issue
with
                                  streaming plugins: tons of video NACK
                                
                              everytime at the same point in video (video
                                freezes for a short time), you get some NACK
                                retransmissions
                                
                                  Solution: reduce the size of rtp packet of
                                    the source that feeds the mountpoint. E.g.
                                    if using ffmpeg:
                                    
                                      ffmpeg ... -f rtp
                                          rtp://230.15.129.230:10956?pkt_size=1400Waiting for candidates-done callback...
                          Only visible when:
                            
                          Debug
                              nat
                            
                              libnice-stun-DEBUG: STUN transaction
                                  retransmitted (timeout 397ms).libnice-stun-DEBUG: STUN transaction
                                  retransmitted (timeout 793ms).
 libnice-stun-DEBUG: STUN transaction
                                  retransmitted (timeout 3194ms).
 libnice-stun-DEBUG: STUN transaction
                                  retransmitted (timeout 6389ms).
 libnice-stun-DEBUG: STUN transaction
                                  retransmitted (timeout 12784ms).
 libnice-DEBUG: Agent 0x7fe068009050 : bind
                                  discovery timed out, aborting discovery item.
Solucions / Solutions
                            
                              do NOT use the following settings:
                                
                                  janus.cfg
                                    
                                      [nat]stun_port = 19302
 stun_server = stun3.l.google.com
if you have more than one network device
                                
                                  If you have a network device with no
                                    internet connection (e.g. mcd in aws),
                                    add it to the black list: janus.cfg
                                    
                                      ice_ignore_list
                                          = vmnet,172.16.[ERR]
                          [ice.c:janus_ice_cb_component_state_changed:1383]
                          [3053596813] ICE failed for component 1 in stream 1...[ERR] [ice.c:janus_ice_check_failed:1548]
                          [5472388112306727] ICE failed for component 1 in
                          stream 1...[WARN] [janus.transport.http]: Error in GNU
                          libmicrohttpd daemon.c:1826: close failed or[Wed May 16 10:32:21 2018] [WARN]
                          [janus.transport.http]: Error in GNU libmicrohttpd
                          daemon.c:3092: Close socket failed.
 [Wed May 16 10:32:21 2018] [WARN]
                          [janus.transport.http]: Error in GNU libmicrohttpd
                          daemon.c:3028: Failed to lock mutex.
 [Wed May 16 10:32:21 2018] [WARN]
                          [janus.transport.http]: Error in GNU libmicrohttpd
                          daemon.c:3101: Failed to unlock mutex.
 [Wed May 16 10:32:21 2018] [WARN]
                          [janus.transport.http]: Error in GNU libmicrohttpd
                          daemon.c:3081: Failed to remove FD from epoll set
[WARN]
                          nice_agent_set_port_range unavailable, port range
                          disabledTransport plugins folder:
                          /usr/lib/janus/transportsLoading transport plugin 'libjanus_pfunix.so'...
 [WARN] Unix Sockets server disabled (Janus API)
 [WARN] Unix Sockets server disabled (Admin API)
 [WARN] No Unix Sockets server started, giving up...
 [WARN] The 'janus.transport.pfunix' plugin could not
                          be initialized
 [FATAL] [janus.c:main:4167] No Janus API transport is
                          available... enable at least one and restart Janus
                          Solució / Solution
                            
                              install package libmicrohttpdroutines:dtls1_read_bytes:tlsv1 alert protocol
                          versionAccés des de client / Access
                from client
                
                  Info
                    
                  API
                    
                      with curl
                        
                          
                            
                              
                                
                                  | 
 | 
 | curl | using janus.js (either from html or an
                                      intermediate js)
 |  
                                  | general
                                    values 
 | 
 | janus_url_base=http://192.168.1.130:8088
                                      janus_url_base=https://192.168.1.130:8089
                                      janus_url=${janus_url_base}/janus
 cookies_options='-b galetes.txt -c
                                      galetes.txt'touch galetes.txt
 origin_url=
https://192.168.1.130:8080origin_header="-H 'Origin: ${origin_url}'"
 headers=${origin_header}
 cookies_options='-b galetes.txt -c
                                      galetes.txt'
 # accept self-signed certificates
 cert_options='-k'
transaction=1234567890
 | 
 var server =
                                        "http://192.168.1.128:8088/janus";Janus.init({...})
 |  
                                  | get info 
 | 
 | curl -i
                                      -X GET ${cert_options}
                                      ${janus_url}/info  | 
 |  
                                  | check CORS 
 | 
 | curl -i
                                      -X OPTIONS ${cert_options}
                                      ${cookies_options} "$headers"
                                      "${janus_url}"
 | 
 |  
                                  | get a new
                                    session 
 | 
 | response=$(curl
-X
                                      POST ${cert_options} ${cookies_options}
                                      "$headers" -H 'Content-Type:
                                      application/json' --data "{\"janus\":\"create\",\"transaction\":\"${transaction}\"}"
"${janus_url}"
                                      )cat galetes.txt
 session_id=$(echo "$response" | jq
                                      '.data.id')
 echo "session_id: $session_id"
 session
_url="${janus_url_base}/janus/${session_id}" | var janus = new Janus({...}) |  
                                  | attach to a plugin (e.g.: janus.plugin.streaming)
 
 | 
 | plugin_name="janus.plugin.streaming"response=$(curl -X POST ${cert_options}
                                      ${cookies_options} "$headers" -H
                                      'Content-Type: application/json' --data
                                      "{\"janus\":\"attach\",\"plugin\":\"${plugin_name}\",\"transaction\":\"${transaction}\"}"
"${session_url}"
                                      )
 plugin_session_id=$(echo "$response" | jq
                                      '.data.id')
 plugin_url="${session_url}/${plugin_session_id}"
 | janus.attach({...}) |  
                                  | send
                                    a message to the plugin (e.g.: janus.plugin.streaming)
 | e.g. list
                                    of existing mountpoints (available streams)
                                    in janus.plugin.streaming | message_body="{\"request\":\"list\"}"
 | 
 |  
                                  | create new
                                    mountpoint in janus.plugin.streaming | [id=...]admin_key=... # defined in
                                      janus.plugin.streaming.cfg: [general]
                                      admin_key
 message_body="{\"request\":\"create\",\"
type\":\"rtp\",\"id\":99,\"description\":\"stream_description\",\"audio\":true,\"video\":true,\"audioport\":1111,\"audiopt\":111,\"audiortpmap\":\"opus/48000/2\",\"videoport\":2222,\"videopt\":100,\"videortpmap\":\"VP8/90000\",\"permanent\":false,\"admin_key\":\"${admin_key}\"}" | 
 |  
                                  | destroy
                                    mountpoint in janus.plugin.streaming | id=99admin_secret="adminpwd"
 message_body="{\"request\":\"destroy\",\"id\":${id},\"secret\":\"${admin_secret}\"}"
 | 
 |  
                                  | (send
                                    message_body) 
 | curl -i
                                      -k -X POST -H 'Content-Type:
                                      application/json' --data-binary
                                      "{\"janus\":\"message\",
                                      \"transaction\":\"${transaction}\", \"body\":${message_body}
                                      }" "${plugin_url}" | pluginHandle.send({...}) |  
                                  | keep session
                                    active. If not called, the session will expire after
                                    value specified in janus.cfg session_timeout
                                    (default: 60 seconds)
 
 | 
 | rid=$(date
                                      +%s%03N)get_url="${session_url}?rid=${rid}&maxev=1"
 echo "url: $url"
 curl -v -i -X GET ${cert_options}
                                      ${cookies_options} "$headers" "${get_url}"
 cat galetes.txt
 | 
 |  
                                  | close session 
 | 
 | curl -i
                                      -X POST ${cert_options} ${cookies_options}
                                      "$headers" -H 'Content-Type:
                                      application/json' --data "{\"janus\":\"destroy\",\"transaction\":\"${transaction}\"}"
                                      "${session_url}"cat galetes.txt
 | janus.destroy({...}) | with
                        Javascript
                        
                          janus.js
                            
                              
                                
                                  
                                    
                                      | Janus.init()
                                        
                                          debug: ... dependencies:
                                              Janus.useDefaultDependencies callback:
                                              function(){...} |  
                                      | 
                                          var
                                                janus = new Janus({...})
                                              server: ... iceServers: ... ipv6: ... withCredentials: ... max_poll_events: ... destroyOnUnload: ... token: ... apisecret: ... success:
                                                  function() {...}error:
                                                  function(cause) {...}destroyed:
                                                  function() {...}janus.getServer()janus.isConnected()janus.getSessionId()janus.attach({...})
                                              plugin: ... opaqueId: ... success:
                                                  function(pluginHandle) {...}
                                                  pluginHandle.getId()pluginHandle.getPlugin()pluginHandle.send({...})pluginHandle.createOffer(callbacks)
                                                      media: {...}
                                                          audioSend:
                                                              true/falseaudioRecv:
                                                              true/falseaudio:
                                                              true/falseaudio: {...}videoSend:
                                                              true/falsevideoRecv:
                                                              true/falsevideo:
                                                              true/falsevideo:
"lowres"/"lowres-16:9"/"stdres"/"stdres-16:9"/"hires"/"hires-16:9"//
                                                              320x240/320x180/640x480/640x360/1280x720
video:
                                                              "screen"video: {...}
                                                              deviceId:
                                                                  ...//
                                                                  Janus.listDevices(callback)
width:
                                                                  ...height:
                                                                  ... data:
                                                              true/falsefailIfNoAudio:
                                                              true/falsefailIfNoVideo:
                                                              true/falsescreenshareFrameRate:
                                                              ...trickle:
                                                          true/false stream: ...success:
                                                          function(jsep) {...}// got sdp
error:
                                                          function() {...}pluginHandle.createAnswer(callbacks)
                                                      (same as CreateOffer)jsep: ...pluginHandle.handleRemoteJsep(callbacks)pluginHandle.dtmf(parameters)pluginHandle.data(parameters)pluginHandle.getBitrate()pluginHandle.hangup(sendRequest)pluginHandle.detach(parameters)
                                                      error:
                                                  function(cause) {...} consentDialog:
                                                  function(on) {...} webrtcState:
                                                  function() {...} iceState:
                                                  function() {...} mediaState:
                                                  function() {...}slowLink:
                                                  function() {...}onmessage:
                                                  function(msg, jsep) {...}onlocalstream:
                                                  function(stream) {...}onremotestream:
                                                  function(stream) {...}ondataopen:
                                                  function() {...}ondata:
                                                  function() {...}oncleanup:
                                                  function() {...}detached:
                                                  function() {...}janus.destroy({...}) |  
                                      | Janus.debug(...)
 | Exemples / Examples
                                
                                  basic session creation (all inside the
                                    document ready function)
                                    
                                      <!doctype
                                          html>
 <head>
 <meta charset="utf-8"/>
 <script
                                          type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/6.0.0/adapter.min.js"></script>
 <script
                                          type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 <script
                                          type="text/javascript"
                                          src="janus.js"></script>
 
 <script
                                          type="text/javascript">
 var server =
                                          "http://192.168.1.128:8088/janus";
 
 $(document).ready(function() {
 Janus.init({
 debug: true,
 dependencies:
                                          Janus.useDefaultDependencies(), // or:
                                          Janus.useOldDependencies() to get the
                                          behaviour of previous Janus versions
 callback: function() {
 //
                                          init completed
 
 //
                                          create gateway session
 var
                                          janus = new Janus(
 {
 server:
                                          server,
 withCredentials:
                                          true,
 success:
                                          function() {
 //
                                          gateway session created
 
 Janus.debug("----
                                          is connected: " + janus.isConnected()
                                          );
 Janus.debug("----
                                          session id: " + janus.getSessionId()
                                          );
 },
 error:
                                          function(cause) {
 //
                                          error when creating gateway session
 },
 destroyed:
                                          function() {
 //
                                          gateway session destroyed
 }
 });
 Janus.debug("----
                                          server: " + janus.getServer() );
 }
 });
 });
 </script>
 
 </head>
 
 <body>
 Janus minimal example.
 </body>
basic attach to a plugin (function
                                    plugin_client, called from document ready)
                                    
                                      <!doctype
                                          html>
 <head>
 <meta charset="utf-8"/>
 <script
                                          type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/6.0.0/adapter.min.js"></script>
 <script
                                          type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 <script
                                          type="text/javascript"
                                          src="janus.js"></script>
 
 <script
                                          type="text/javascript">
 /**
 * This script could
                                          be placed in a file.
 */
 var plugin_client =
                                          function(params) {
 
 var PLUGIN_PACKAGE =
                                          "janus.plugin.streaming";
 var janus = null;
 var myPluginHandle = null;
 
 this.start = function() {
 Janus.init({
 debug:
                                          true,
 dependencies:
                                          Janus.useDefaultDependencies(), // or:
                                          Janus.useOldDependencies() to get the
                                          behaviour of previous Janus versions
 callback:
                                          function() {
 //
                                          init completed
 
 //
                                          create gateway session
 janus
                                          = new Janus(
 {
 server:
                                          params.server,
 withCredentials:
                                          true,
 success:
                                          function() {
 //
                                          gateway session created
 Janus.log("Janus
                                          session id: " + janus.getSessionId()
                                          );
 
 //
                                            attach to plugin
 janus.attach(
 {
 plugin:
                                            PLUGIN_PACKAGE,
 success:
                                            _onAttachSuccess,
 error:
                                            _onError,
 onmessage:
                                            _onMessage,
 onlocalstream:
                                            _onLocalStream,
 onremotestream:
                                            _onRemoteStream,
 oncleanup:
                                            _onCleanUp
 });                           
                                          },
 error:
                                          function(cause) {
 //
                                          error when creating gateway session
 },
 destroyed:
                                          function() {
 //
                                          gateway session destroyed
 }
 });
 Janus.debug("Janus
                                          server: " + janus.getServer() );
 }
 });
 };
 
 this.stop = function() {
 if (janus) {
 janus.destroy();
 janus
                                          = null;
 }
 };
 
 function
                                            _onAttachSuccess(pluginHandle) {
 myPluginHandle
                                            = pluginHandle;
 Janus.log("Plugin
                                            attached: " +
                                            myPluginHandle.getPlugin() + ", id="
                                            + myPluginHandle.getId() );
 }
 
 function _onError(message) {
 Janus.error(message);
 }
 
 function _onMessage(msg, jsep) {
 Janus.debug("Got
                                            a message");
 Janus.debug(JSON.stringify(msg));
 }
 
 function _onLocalStream(stream) {
 Janus.debug("Got
                                            a local stream");
 Janus.debug(JSON.stringify(stream));
 }
 
 function _onRemoteStream(stream) {
 Janus.debug("Got
                                            a remote stream");
 Janus.debug(JSON.stringify(stream));
 }
 
 function _onCleanUp() {
 Janus.log("Got
                                            a cleanup notification");
 }
 
 };
 </script>
 
 
 <script
                                          type="text/javascript">
 var janus_server =
                                          "http://192.168.1.128:8088/janus";
 
 $(document).ready(function() {
 client = new plugin_client(
 {
 server:
                                          janus_server
 }
 );
 client.start();
 });
 </script>
 
 </head>
 
 <body>
 Janus minimal example.
 </body>
multiple player from streaming plugin
                                    
                                      <!doctype
                                          html>
 <head>
 <meta charset="utf-8"/>
 <script
                                          type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/6.0.0/adapter.min.js"></script>
 <script
                                          type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
 <script
                                          type="text/javascript"
                                          src="janus.js"></script>
 
 <script
                                          type="text/javascript">
 /**
 * This script could
                                          be placed in a file.
 */
 var plugin_client =
                                          function(params) {
 
 var PLUGIN_PACKAGE =
                                          "janus.plugin.streaming";
 var janus = null;
 var streaming = null;
 
 // visible players
 var number_feeds = 6;
 var feeds = [];
 
 // available mountpoints in Janus
                                          streaming plugin
 var mountpoints = [];
 
 this.start = function() {
 Janus.init({
 debug: true,
 dependencies:
                                          Janus.useDefaultDependencies(), // or:
                                          Janus.useOldDependencies() to get the
                                          behaviour of previous Janus versions
 callback: function() {
 // init completed
 
 // create gateway session
 janus = new Janus(
 {
 server: params.server,
 withCredentials: true,
 success: function() {
 // gateway session created
 Janus.log("## Janus session id: " +
                                          janus.getSessionId() );
 
 // attach to plugin
 janus.attach(
 {
 plugin: PLUGIN_PACKAGE,
 success: _onAttachSuccess,
 error: _onError,
 onmessage: _onMessage,
 onlocalstream: _onLocalStream,
 onremotestream: _onRemoteStream,
 oncleanup: _onCleanUp
 });
 },
 error: function(cause) {
 // error when creating gateway session
 },
 destroyed: function() {
 // gateway session destroyed
 }
 });
 Janus.debug("## Janus server: " +
                                          janus.getServer() );
 }
 });
 };
 
 this.stop = function() {
 if (janus) {
 janus.destroy();
 janus = null;
 }
 };
 
 function
                                          _onAttachSuccess(pluginHandle) {
 streaming = pluginHandle;
 Janus.log("## Plugin attached: " +
                                          streaming.getPlugin() + ", id=" +
                                          streaming.getId() );
 updateStreamsList();
 }
 
 function _onError(message) {
 Janus.error(message);
 }
 
 function _onMessage(msg, jsep) {
 Janus.debug("## Got a message");
 Janus.debug(msg);
 if(jsep !== undefined && jsep
                                          !== null) {
 Janus.debug("## Handling SDP as
                                          well...");
 Janus.debug(jsep);
 }
 }
 
 function _onLocalStream(stream) {
 Janus.debug("## Got a local stream");
 Janus.debug(JSON.stringify(stream));
 }
 
 function _onRemoteStream(stream) {
 Janus.debug("## Got a remote stream");
 Janus.debug(JSON.stringify(stream));
 }
 
 function _onCleanUp() {
 Janus.log("## Got a cleanup
                                          notification");
 }
 
 
 function updateStreamsList() {
 // get list of available mountpoints
                                          in streaming plugin
 var body = { "request": "list" };
 streaming.send(
 {
 "message": body,
 success: function(result) {
 if(result === null || result ===
                                          undefined) {
 bootbox.alert("Got no response to our
                                          query for available streams");
 return;
 }
 if(result["list"] !== undefined
                                          && result["list"] !== null) {
 mountpoints = result["list"];
 Janus.debug(mountpoints);
 populateAll(mountpoints);
 }
 }
 });
 }
 
 function populateAll (mountpoints) {
 // start a player for each mountpoint
 Janus.log("######## [populateAll]");
 for(var m in mountpoints) {
 var mountpoint_id =
                                          mountpoints[m]["id"];
 var type = mountpoints[m]["type"];
 var description =
                                          mountpoints[m]["description"];
 newRemoteFeed(mountpoint_id, type,
                                          description);
 }
 }
 
 function newRemoteFeed(mountpoint_id,
                                          type, description) {
 // start a player
 Janus.log("######## [newRemoteFeed]
                                          mountpoint_id: "+ mountpoint_id + ";
                                          type: " + type + "; description: " +
                                          description );
 var remoteFeed = null;
 janus.attach(
 {
 plugin: "janus.plugin.streaming",
 success: function(pluginHandle) {
 remoteFeed =
                                          pluginHandle;
 Janus.log("######## [newRemoteFeed]
                                          Plugin attached! (" +
                                          remoteFeed.getPlugin() + ", id=" +
                                          remoteFeed.getId() + ")");
 
 // assign a player
 for(var i=1;i<6;i++) {
 if(feeds[i] === undefined || feeds[i]
                                          === null) {
 feeds[i] = remoteFeed;
 remoteFeed.rfindex = i;
 break;
 }
 }
 
 // send watch request
 var body = { "request": "watch", "id":
                                          mountpoint_id };
 remoteFeed.send({"message": body});
 },
 error: function(error) {},
 onmessage: function(msg, jsep) {
 // received a message
 Janus.debug("########
                                          [newRemoteFeed.onmessage] Got a
                                          message (mountpoint_id: " +
                                          mountpoint_id + ")");
 Janus.debug(msg);
 
 // regular message
 var result = msg["result"];
 if(result != undefined &&
                                          result != null) {
 Janus.debug(result);
 if(result["status"] !== undefined
                                          && result["status"] !== null)
                                          {
 var status = result["status"];
 if(status === 'starting')
 Janus.debug("########
                                          [newRemoteFeed.onmessage] Starting,
                                          please wait...");
 else if(status === 'started')
 Janus.debug("########
                                          [newRemoteFeed.onmessage] Started");
 else if(status === 'stopped')
 Janus.debug("########
                                          [newRemoteFeed.onmessage] Stopped");
 } else if(msg["streaming"] ===
                                          "event") {
 // Is simulcast in place?
 var substream = result["substream"];
 var temporal = result["temporal"];
 if((substream !== null &&
                                          substream !== undefined) || (temporal
                                          !== null && temporal !==
                                          undefined)) {
 if(!simulcastStarted) {
 simulcastStarted = true;
 addSimulcastButtons();
 }
 // We just received notice that
                                          there's been a switch, update the
                                          buttons
 updateSimulcastButtons(substream,
                                          temporal);
 }
 }
 } else if(msg["error"] !== undefined
                                          && msg["error"] !== null) {
 Janus.error("######## [newRemoteFeed]
                                          Error: ", msg["error"]);
 }
 
 // message with an offer sdp
 if(jsep !== undefined && jsep
                                          !== null) {
 Janus.debug("########
                                          [newRemoteFeed.onmessage] Received an
                                          offer sdp (mountpoint_id: " +
                                          mountpoint_id + ")");
 Janus.debug(jsep);
 // create an answer with an sdp
 remoteFeed.createAnswer(
 {
 jsep: jsep,
 media: { audioSend: false, videoSend:
                                          false
                                          },      
                                          // We want recvonly audio/video
 success: function(jsep) {
 Janus.debug("########
                                          [newRemoteFeed.onmessage] Sending an
                                          answer sdp (mountpoint_id: " +
                                          mountpoint_id + ")");
 Janus.debug(jsep);
 var body = { "request": "start" };
 remoteFeed.send({"message": body,
                                          "jsep": jsep});
 //$('#watch').html("Stop").removeAttr('disabled').click(stopStream);
 },
 error: function(error) {
 Janus.error("WebRTC error:", error);
 bootbox.alert("WebRTC error... " +
                                          JSON.stringify(error));
 }
 });
 
 }
 },
 onremotestream: function(stream) {
 // a remote stream is available
 Janus.debug("########
                                          [newRemoteFeed.onremotestream] Remote
                                          stream is available (mountpoint_id: "
                                          + mountpoint_id + ")");
 
 // first time?
 if($('#remotevideo'+remoteFeed.rfindex).length
                                          > 0) {
 // Been here already: let's see if
                                          anything changed
 Janus.debug("########
                                          [newRemoteFeed.onremotestream] Been
                                          there already");
 var videoTracks =
                                          stream.getVideoTracks();
 if(videoTracks &&
                                          videoTracks.length > 0 &&
                                          !videoTracks[0].muted) {
 Janus.debug(videoTracks);
 //$('#novideo'+remoteFeed.rfindex).remove();
 //if($("#remotevideo"+remoteFeed.rfindex).get(0).videoWidth)
 //         
                                          $('#remotevideo'+remoteFeed.rfindex).show();
 }
 return;
 }
 
 // create the html5 player
 $('#videoremote' +
                                          remoteFeed.rfindex).append(
                                          '<h2>' + description +
                                          '</h2> <video class="rounded
                                          centered" id="remotevideo' +
                                          remoteFeed.rfindex + '" width=320
                                          height=240 controls
                                          autoplay/><hr>');
 
 // attach the remote stream to the
                                          html5 video player
 Janus.attachMediaStream($('#remotevideo'
                                          + remoteFeed.rfindex).get(0), stream);
 },
 oncleanup: function() {}
 }
 );
 }
 
 };
 </script>
 
 
 <script
                                          type="text/javascript">
 // var janus_server =
                                          "https://192.168.1.114:8089/janus";
 var janus_server = null;
 if(window.location.protocol ===
                                          'http:')
 janus_server = "http://" +
                                          window.location.hostname +
                                          ":8088/janus";
 else
 janus_server = "https://" +
                                          window.location.hostname +
                                          ":8089/janus";
 
 $(document).ready(function() {
 client = new plugin_client(
 {
 server: janus_server
 }
 );
 client.start();
 });
 </script>
 
 </head>
 
 <body>
 <h1>Multiple
                                          streams</h1>
 <div
                                          id="logs"></div>
 <div
                                          id="videoremote1"></div>
 <div
                                          id="videoremote2"></div>
 <div
                                          id="videoremote3"></div>
 <div
                                          id="videoremote4"></div>
 <div
                                          id="videoremote5"></div>
 <div
                                          id="videoremote6"></div>
 </body>
Demos (test web server) 
                
                  Available demos
                    
                      Streaming
                        Problemes / Problems
                          llista buida al desplegable «Stream list» ...http-server (NodeJS)
                    
                      Install NodeJS via nvm, and then:
                        
                          install http servernpm install -g http-server
configure firewall
                        
                          sudo systemctl start firewalld.servicesudo firewall-cmd --permanent --zone=public
                              --add-port=8080/tcp
 sudo firewall-cmd --reload
install html dir into /usr/share/janus/demos/
                          cd janus-gatewaysudo make install html
non-secure
                        
                          run http-server
                            
                              nvm use defaulthttp-server /usr/share/janus/demos
check it:
                            
                              http://<your_demos_server_ip>:8080/http://<your_demos_server_ip>:8080/demos/secure
                        
                          server
                            
                              nvm use defaulthttp-server --ssl --cert
                                  /usr/share/janus/certs/mycert.pem --key
                                  /usr/share/janus/certs/mycert.key
                                  /usr/share/janus/demos
client
                            
                              https://<your_demos_server_ip>:8080/https://<your_demos_server_ip>:8080/demos/Problemes /
                            Problems
                            
                              Probably a network error, is the gateway
                                  down?: [object Object]
                                  Solució / Solution:
                                    
                                      Des del navegador, accepteu manualment
                                        el certificat autosignat / From your
                                        browser, manually accept self-signed
                                        certificate in
                                        
                                          https://<your_janus_server_ip>:8089/Reviseu l'apartat [cors]
                                        del fitxer /etc/janus/janus.cfgnginx
                    
                      server
                        
                          Janus through Nginx
                            
                              Deploying
                                  Janus behind a web frontend/etc/nginx/default.d/janus.conf
                                
                                  # janus (webrtc
                                      server)location /janus {
 proxy_pass
                                      http://127.0.0.1:8088/janus;
 }
SELinux
                                
                                  setsebool -P
                                      httpd_can_network_connect 1chcon
                                      -u system_u -t httpd_config_t
                                      /etc/nginx/default.d/janus.confaccess to demos
                            
                              /etc/nginx/default.d/janus_demos.conf
                                  # janus demos
                                      (webrtc server)location /demos {
 root
                                      /usr/share/janus;
 }
SELinux
                                
                                   chcon -u
                                      system_u -t httpd_config_t
                                      /etc/nginx/default.d/janus_demos.confdemos must point to Janus through nginx (instead
                            of ports 8088/8089):
                            
                              cd /usr/share/demossed
                                  -i '/var janus = null;/ i var server =
                                  "/janus";' *.jshttps
                            
                              generate
                                  self-signed certificate and key
                                (/etc/pki/nginx/server.crt,
                                /etc/pki/nginx/private/server.key)
                                
                                  mkdir -p /etc/pki/nginx/privatecd /etc/pki/nginxopenssl req -new -nodes -keyout
                                      private/server.key -sha256 -x509 -out
                                      server.crt/etc/nginx/conf.d/ssl_8080.conf
                                
                                  # Settings for a
                                      TLS enabled server.
 server {
 listen      
                                      8080 ssl http2 default_server;
 listen      
                                      [::]:8080 ssl http2 default_server;
 server_name  _;
 root        
                                      /usr/share/nginx/html;
 
 ssl_certificate
                                      "/etc/pki/nginx/server.crt";
 ssl_certificate_key
                                      "/etc/pki/nginx/private/server.key";
 ssl_session_cache
                                      shared:SSL:1m;
 ssl_session_timeout  10m;
 ssl_ciphers
                                      HIGH:!aNULL:!MD5;
 ssl_prefer_server_ciphers on;
 
 # Load configuration
                                      files for the default server block.
 include
                                      /etc/nginx/default.d/*.conf;
 
 location / {
 }
 
 error_page 404
                                      /404.html;
 location = /40x.html {
 }
 
 error_page 500 502 503
                                      504 /50x.html;
 location = /50x.html {
 }
 }
SELinux
                                
                                  chcon
                                      -u system_u -t httpd_config_t
                                      /etc/nginx/default.d/ssl_8080.confsudo systemctl start nginx.serviceclient
                        
                          https://<your_demos_server_ip>/janus/info
                              Problemes / Problems
                                
                                  on server logs: connect() to
                                      127.0.0.1:8088 failed (13: Permission
                                      denied) while connecting to upstream,
                                      client: ...https://<your_demos_server_ip>/demos |