Janus Gateway test feed

master
informatic 2018-06-15 15:01:13 +02:00
parent d104473457
commit 3a6c16e916
21 changed files with 3857 additions and 15 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
ui

View File

@ -20,23 +20,30 @@ ENV SNOWMIX /usr/local/lib/Snowmix-${SNOWMIX_VERSION}
RUN useradd snowmix && mkdir /home/snowmix /run/snowmix && chown snowmix /home/snowmix /run/snowmix
RUN apt install -y --no-install-recommends git python3
WORKDIR /config
RUN apt install -y --no-install-recommends gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-plugins-base gstreamer1.0-x
USER snowmix
CMD snowmix
#RUN apt install -y --no-install-recommends git python3
# build gstreamer 1.0 from cerbero source
# the build commands are split so that docker can resume in case of errors
RUN git clone --depth 1 git://anongit.freedesktop.org/gstreamer/cerbero
#RUN git clone --depth 1 git://anongit.freedesktop.org/gstreamer/cerbero
# hack: to pass "-y" argument to apt-get install launched by "cerbero bootstrap"
RUN sed -i 's/apt-get install/apt-get install -y/g' cerbero/cerbero/bootstrap/linux.py
#RUN sed -i 's/apt-get install/apt-get install -y/g' cerbero/cerbero/bootstrap/linux.py
RUN apt install -y --no-install-recommends python3-setuptools sudo
#RUN apt install -y --no-install-recommends python3-setuptools sudo
RUN cd cerbero; ./cerbero-uninstalled bootstrap
RUN git config --global user.email "you@example.com" && git config --global user.name "Your Name"
RUN cd cerbero; ./cerbero-uninstalled build \
glib bison gstreamer-1.0
#RUN cd cerbero; ./cerbero-uninstalled bootstrap
#RUN git config --global user.email "you@example.com" && git config --global user.name "Your Name"
#RUN cd cerbero; ./cerbero-uninstalled build \
# glib bison gstreamer-1.0
RUN apt install -y --no-install-recommends python3-dev python-dev
RUN cd cerbero; perl -pi -e 's/[^[:ascii:]]//g' packages/gstreamer-1.0/license.txt
RUN cd cerbero; ./cerbero-uninstalled package gstreamer-1.0
#RUN apt install -y --no-install-recommends python3-dev python-dev
#RUN cd cerbero; perl -pi -e 's/[^[:ascii:]]//g' packages/gstreamer-1.0/license.txt
#RUN cd cerbero; ./cerbero-uninstalled package gstreamer-1.0
#RUN cd cerbero; ./cerbero-uninstalled build \
# gst-plugins-base-1.0 gst-plugins-good-1.0
@ -47,7 +54,3 @@ RUN cd cerbero; ./cerbero-uninstalled package gstreamer-1.0
#RUN cd cerbero; ./cerbero-uninstalled build \
# gst-libav-1.0
WORKDIR /config
USER snowmix
CMD snowmix

162
config/janus/janus.cfg Normal file
View File

@ -0,0 +1,162 @@
; General configuration: folders where the configuration and the plugins
; can be found, how output should be logged, whether Janus should run as
; a daemon or in foreground, default interface to use, debug/logging level
; and, if needed, shared apisecret and/or token authentication mechanism
; between application(s) and Janus.
[general]
configs_folder = /opt/janus/etc/janus ; Configuration files folder
plugins_folder = /opt/janus/lib/janus/plugins ; Plugins folder
transports_folder = /opt/janus/lib/janus/transports ; Transports folder
;log_to_stdout = false ; Whether the Janus output should be written
; to stdout or not (default=true)
;log_to_file = /var/log/janus.log ; Whether to use a log file or not
;daemonize = true ; Whether Janus should run as a daemon
; or not (default=run in foreground)
;pid_file = /tmp/janus.pid ; PID file to create when Janus has been
; started, and to destroy at shutdown
;interface = 1.2.3.4 ; Interface to use (will be used in SDP)
debug_level = 4 ; Debug/logging level, valid values are 0-7
;debug_timestamps = yes ; Whether to show a timestamp for each log line
;debug_colors = no ; Whether colors should be disabled in the log
;api_secret = janusrocks ; String that all Janus requests must contain
; to be accepted/authorized by the Janus core.
; Useful if you're wrapping all Janus API requests
; in your servers (that is, not in the browser,
; where you do the things your way) and you
; don't want other application to mess with
; this Janus instance.
;token_auth = yes ; Enable a token based authentication
; mechanism to force users to always provide
; a valid token in all requests. Useful if
; you want to authenticate requests from web
; users. For this to work, the Admin API MUST
; be enabled, as tokens are added and removed
; through messages sent there.
admin_secret = janusoverlord ; String that all Janus requests must contain
; to be accepted/authorized by the admin/monitor.
; only needed if you enabled the admin API
; in any of the available transports.
;server_name = MyJanusInstance ; Public name of this Janus instance
; as it will appear in an info request
; Certificate and key to use for DTLS.
[certificates]
cert_pem = /opt/janus/share/janus/certs/mycert.pem
cert_key = /opt/janus/share/janus/certs/mycert.key
; Media-related stuff: you can configure whether if you want
; to enable IPv6 support (still WIP, so handle with care), the maximum size
; of the NACK queue (in milliseconds, defaults to 1000ms=1s) for retransmissions, the
; range of ports to use for RTP and RTCP (by default, no range is envisaged), the
; starting MTU for DTLS (1472 by default, it adapts automatically),
; if BUNDLE should be forced (defaults to false) and if RTCP muxing should
; be forced (defaults to false).
[media]
;ipv6 = true
;max_nack_queue = 1000
;rtp_port_range = 20000-40000
;dtls_mtu = 1200
;force-bundle = true
;force-rtcp-mux = true
; NAT-related stuff: specifically, you can configure the STUN/TURN
; servers to use to gather candidates if the gateway is behind a NAT,
; and srflx/relay candidates are needed. In case STUN is not enough and
; this is needed (it shouldn't), you can also configure Janus to use a
; TURN server; please notice that this does NOT refer to TURN usage in
; browsers, but in the gathering of relay candidates by Janus itself,
; e.g., if you want to limit the ports used by a Janus instance on a
; private machine. Furthermore, you can choose whether Janus should be
; configured to work in ICE-Lite mode (by default it doesn't). Finally,
; you can also enable ICE-TCP support (beware that it currently *only*
; works if you enable ICE Lite as well), choose which interfaces should
; be used for gathering candidates, and enable or disable the
; internal libnice debugging, if needed.
[nat]
;stun_server = stun.voip.eutelia.it
;stun_port = 3478
nice_debug = false
;ice_lite = true
;ice_tcp = true
; In case you're deploying Janus on a server which is configured with
; a 1:1 NAT (e.g., Amazon EC2), you might want to also specify the public
; address of the machine using the setting below. This will result in
; all host candidates (which normally have a private IP address) to
; be rewritten with the public address provided in the settings. As
; such, use the option with caution and only if you know what you're doing.
; Besides, it's still recommended to also enable STUN in those cases,
; and keep ICE Lite disabled as it's not strictly speaking a public server.
;nat_1_1_mapping = 1.2.3.4
; You can configure a TURN server in two different ways: specifying a
; statically configured TURN server, and thus provide the address of the
; TURN server, the transport (udp/tcp/tls) to use, and a set of valid
; credentials to authenticate...
;turn_server = myturnserver.com
;turn_port = 3478
;turn_type = udp
;turn_user = myuser
;turn_pwd = mypassword
; ... or you can make use of the TURN REST API to get info on one or more
; TURN services dynamically. This makes use of the proposed standard of
; such an API (https://tools.ietf.org/html/draft-uberti-behave-turn-rest-00)
; which is currently available in both rfc5766-turn-server and coturn.
; You enable this by specifying the address of your TURN REST API backend,
; the HTTP method to use (GET or POST) and, if required, the API key Janus
; must provide.
;turn_rest_api = http://yourbackend.com/path/to/api
;turn_rest_api_key = anyapikeyyoumayhaveset
;turn_rest_api_method = GET
; You can also choose which interfaces should be explicitly used by the
; gateway for the purpose of ICE candidates gathering, thus excluding
; others that may be available. To do so, use the 'ice_enforce_list'
; setting and pass it a comma-separated list of interfaces or IP addresses
; to enforce. This is especially useful if the server hosting the gateway
; has several interfaces, and you only want a subset to be used. Any of
; the following examples are valid:
; ice_enforce_list = eth0
; ice_enforce_list = eth0,eth1
; ice_enforce_list = eth0,192.168.
; ice_enforce_list = eth0,192.168.0.1
; By default, no interface is enforced, meaning Janus will try to use them all.
;ice_enforce_list = eth0
; In case you don't want to specify specific interfaces to use, but would
; rather tell Janus to use all the available interfaces except some that
; you don't want to involve, you can also choose which interfaces or IP
; addresses should be excluded and ignored by the gateway for the purpose
; of ICE candidates gathering. To do so, use the 'ice_ignore_list' setting
; and pass it a comma-separated list of interfaces or IP addresses to
; ignore. This is especially useful if the server hosting the gateway
; has several interfaces you already know will not be used or will simply
; always slow down ICE (e.g., virtual interfaces created by VMware).
; Partial strings are supported, which means that any of the following
; examples are valid:
; ice_ignore_list = vmnet8,192.168.0.1,10.0.0.1
; ice_ignore_list = vmnet,192.168.
; Just beware that the ICE ignore list is not used if an enforce list
; has been configured. By default, Janus ignores all interfaces whose
; name starts with 'vmnet', to skip VMware interfaces:
ice_ignore_list = vmnet
; You can choose which of the available plugins should be
; enabled or not. Use the 'disable' directive to prevent Janus from
; loading one or more plugins: use a comma separated list of plugin file
; names to identify the plugins to disable. By default all available
; plugins are enabled and loaded at startup.
[plugins]
; disable = libjanus_voicemail.so,libjanus_recordplay.so
; You can choose which of the available transports should be enabled or
; not. Use the 'disable' directive to prevent Janus from loading one
; or more transport: use a comma separated list of transport file names
; to identify the transports to disable. By default all available
; transports are enabled and loaded at startup.
[transports]
; disable = libjanus_rabbitmq.so

View File

@ -0,0 +1,19 @@
; [<unique room ID>]
; description = This is my awesome room
; is_private = yes|no (whether this room should be in the public list, default=yes)
; secret = <optional password needed for manipulating (e.g. destroying) the room>
; pin = <optional password needed for joining the room>
; sampling_rate = <sampling rate> (e.g., 16000 for wideband mixing)
; record = true|false (whether this room should be recorded, default=false)
; record_file = /path/to/recording.wav (where to save the recording)
[general]
;admin_key = supersecret ; If set, rooms can be created via API only
; if this key is provided in the request
[1234]
description = Demo Room
secret = adminpwd
sampling_rate = 16000
record = false
;record_file = /tmp/janus-audioroom-1234.wav

View File

@ -0,0 +1 @@
; The Echo Test plugin doesn't need any configuration

View File

@ -0,0 +1,4 @@
; path = where to place recordings in the file system
[general]
path = /opt/janus/share/janus/recordings

View File

@ -0,0 +1,19 @@
[general]
; Specify which local IP address to use. If not set it will be automatically
; guessed from the system
; local_ip = 1.2.3.4
; Enable local keep-alives to keep the registration open. Keep-alives are
; sent in the form of OPTIONS requests, at the given interval inseconds.
; (0 to disable)
keepalive_interval = 120
; Indicate if the server is behind NAT. If so, the server will use STUN
; to guess its own public IP address and use it in the Contact header of
; outgoing requests
behind_nat = no
; User-Agent string to be used
; user_agent = Cool WebRTC Gateway
; Expiration time for registrations
register_ttl = 3600

View File

@ -0,0 +1,126 @@
; [stream-name]
; type = rtp|live|ondemand|rtsp
; rtp = stream originated by an external tool (e.g., gstreamer or
; ffmpeg) and sent to the plugin via RTP
; live = local file streamed live to multiple listeners
; (multiple listeners = same streaming context)
; ondemand = local file streamed on-demand to a single listener
; (multiple listeners = different streaming contexts)
; rtsp = stream originated by an external RTSP feed (only
; available if libcurl support was compiled)
; id = <unique numeric ID> (if missing, a random one will be generated)
; description = This is my awesome stream
; is_private = yes|no (private streams don't appear when you do a 'list'
; request)
; secret = <optional password needed for manipulating (e.g., destroying
; or enabling/disabling) the stream>
; pin = <optional password needed for watching the stream>
; filename = path to the local file to stream (only for live/ondemand)
; audio = yes|no (do/don't stream audio)
; video = yes|no (do/don't stream video)
; The following options are only valid for the 'rtp' type:
; audioport = local port for receiving audio frames
; audiomcast = multicast group port for receiving audio frames, if any
; audiopt = <audio RTP payload type> (e.g., 111)
; audiortpmap = RTP map of the audio codec (e.g., opus/48000/2)
; videoport = local port for receiving video frames
; videomcast = multicast group port for receiving video frames, if any
; videopt = <video RTP payload type> (e.g., 100)
; videortpmap = RTP map of the video codec (e.g., VP8/90000)
; videobufferkf = yes|no (whether the plugin should store the latest
; keyframe and send it immediately for new viewers, EXPERIMENTAL)
; url = RTSP stream URL (only for restreaming RTSP)
;
; To test the [gstreamer-sample] example, check the test_gstreamer.sh
; script in the plugins/streams folder. To test the live and on-demand
; audio file streams, instead, the install.sh installation script
; automatically downloads a couple of files (radio.alaw, music.mulaw)
; to the plugins/streams folder.
[general]
;admin_key = supersecret ; If set, mountpoints can be created via API
; only if this key is provided in the request
[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
[file-live-sample]
type = live
id = 2
description = a-law file source (radio broadcast)
filename = /opt/janus/share/janus/streams/radio.alaw ; See install.sh
audio = yes
video = no
secret = adminpwd
[file-ondemand-sample]
type = ondemand
id = 3
description = mu-law file source (music)
filename = /opt/janus/share/janus/streams/music.mulaw ; See install.sh
audio = yes
video = no
secret = adminpwd
;
; Firefox Nightly supports H.264 through Cisco's OpenH264 plugin. The only
; supported profile is the baseline one. This is an example of how to create
; a H.264 mountpoint: you can feed it an x264enc+rtph264pay pipeline in
; gstreamer.
;
[h264-sample]
type = rtp
id = 10
description = H.264 live stream coming from gstreamer
audio = no
audioport = 8005
audiopt = 111
audiortpmap = MPA/44100/2
video = yes
videoport = 8004
videopt = 96
videortpmap = H264/90000
videofmtp = profile-level-id=42e01f\;packetization-mode=1
#videofmtp = profile-level-id=64001f\;packetization-mode=1
;
; This is a sample configuration for Opus/VP8 multicast streams
;
;[gstreamer-multicast]
;type = rtp
;id = 20
;description = Opus/VP8 live multicast stream coming from gstreamer
;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
;
; This is a sample configuration for an RTSP stream
; NOTE WELL: the plugin does NOT transcode, so the RTSP stream MUST be
; in a format the browser can digest (e.g., VP8 or H.264 for video)
;
;[rtsp-test]
;type = rtsp
;id = 99
;description = RTSP Test
;audio = no
;video = yes
;url=rtsp://127.0.0.1:8554/unicast

View File

@ -0,0 +1,19 @@
; [<unique room ID>]
; description = This is my awesome room
; is_private = yes|no (whether this room should be in the public list, default=yes)
; secret = <optional password needed for manipulating (e.g. destroying) the room>
; pin = <optional password needed for joining the room>
; post = <optional backend to contact via HTTP post for all incoming messages>
[general]
;admin_key = supersecret ; If set, rooms can be created via API only
; if this key is provided in the request
json = indented ; Whether the data channel JSON messages should be indented (default),
; plain (no indentation) or compact (no indentation and no spaces)
[1234]
description = Demo Room
; is_private = yes
secret = adminpwd
; pin = roompwd
; post = http://example.com/forward/here

View File

@ -0,0 +1 @@
; The Video Call plugin doesn't need any configuration

View File

@ -0,0 +1,28 @@
; [<unique room ID>]
; description = This is my awesome room
; is_private = yes|no (whether this room should be in the public list, default=yes)
; secret = <optional password needed for manipulating (e.g. destroying) the room>
; pin = <optional password needed for joining the room>
; publishers = <max number of concurrent senders> (e.g., 6 for a video
; conference or 1 for a webinar)
; bitrate = <max video bitrate for senders> (e.g., 128000)
; fir_freq = <send a FIR to publishers every fir_freq seconds> (0=disable)
; audiocodec = opus|isac32|isac16|pcmu|pcma (audio codec to force on publishers, default=opus)
; videocodec = vp8|vp9|h264 (video codec to force on publishers, default=vp8)
; record = true|false (whether this room should be recorded, default=false)
; rec_dir = <folder where recordings should be stored, when enabled>
[general]
;admin_key = supersecret ; If set, rooms can be created via API only
; if this key is provided in the request
[1234]
description = Demo Room
secret = adminpwd
publishers = 6
bitrate = 128000
fir_freq = 10
;audiocodec = opus
;videocodec = vp8
record = false
;rec_dir = /tmp/janus-videoroom

View File

@ -0,0 +1,8 @@
; path = where to place recordings in the file system (should be in a
; properly configured web server, if you want the demo to work)
; base = base path to use when returning the recording URI (use this
; to make sure the file in the path you chose is reachable via HTTP)
[general]
path = /tmp/voicemail/
base = /voicemail/

View File

@ -0,0 +1,53 @@
; Web server stuff: whether any should be enabled, which ports they
; should use, whether security should be handled directly or demanded to
; an external application (e.g., web frontend) and what should be the
; base path for the Janus API protocol. You can also specify the
; threading model to use for the HTTP webserver: by default this is
; 'unlimited' (which means a thread per connection, as specified by the
; libmicrohttpd documentation), using a number will make use of a thread
; pool instead. Since long polls are involved, make sure you choose a
; value that doesn't keep new connections waiting.
[general]
json = indented ; Whether the JSON messages should be indented (default),
; plain (no indentation) or compact (no indentation and no spaces)
base_path = /janus ; Base path to bind to in the web server (plain HTTP only)
threads = unlimited ; unlimited=thread per connection, number=thread pool
http = yes ; Whether to enable the plain HTTP interface
port = 8088 ; Web server HTTP port
;interface = eth0 ; Whether we should bind this server to a specific interface only
;ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address (v4 or v6) only
https = no ; Whether to enable HTTPS (default=no)
;secure_port = 8089 ; Web server HTTPS port, if enabled
;secure_interface = eth0 ; Whether we should bind this server to a specific interface only
;secure_ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address (v4 or v6) only
;acl = 127.,192.168.0. ; Only allow requests coming from this comma separated list of addresses
; Janus can also expose an admin/monitor endpoint, to allow you to check
; which sessions are up, which handles they're managing, their current
; status and so on. This provides a useful aid when debugging potential
; issues in Janus. The configuration is pretty much the same as the one
; already presented above for the webserver stuff, as the API is very
; similar: choose the base bath for the admin/monitor endpoint (/admin
; by default), ports, threading model, etc. Besides, you can specify
; a secret that must be provided in all requests as a crude form of
; authorization mechanism, and partial or full source IPs if you want to
; limit access basing on IP addresses. For security reasons, this
; endpoint is disabled by default, enable it by setting admin_http=yes.
[admin]
admin_base_path = /admin ; Base path to bind to in the admin/monitor web server (plain HTTP only)
admin_threads = unlimited ; unlimited=thread per connection, number=thread pool
admin_http = no ; Whether to enable the plain HTTP interface
admin_port = 7088 ; Admin/monitor web server HTTP port
;admin_interface = eth0 ; Whether we should bind this server to a specific interface only
;admin_ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address (v4 or v6) only
admin_https = no ; Whether to enable HTTPS (default=no)
;admin_secure_port = 7889 ; Admin/monitor web server HTTPS port, if enabled
;admin_secure_interface = eth0 ; Whether we should bind this server to a specific interface only
;admin_secure_ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address (v4 or v6) only
;admin_acl = 127.,192.168.0. ; Only allow requests coming from this comma separated list of addresses
; Certificate and key to use for HTTPS.
[certificates]
cert_pem = /opt/janus/share/janus/certs/mycert.pem
cert_key = /opt/janus/share/janus/certs/mycert.key

View File

@ -0,0 +1,19 @@
; You can also control a Janus instance using Unix Sockets. The only
; aspect you need to configure here is the path of the Unix Sockets
; server.
[general]
enabled = yes ; Whether to enable the Unix Sockets interface
; for Janus API clients
json = indented ; Whether the JSON messages should be indented (default),
; plain (no indentation) or compact (no indentation and no spaces)
path = /tmp/ux-janusapi ; Path to bind to (Janus API)
;type = SOCK_SEQPACKET ; SOCK_SEQPACKET (default) or SOCK_DGRAM?
; As with other transport plugins, you can use Unix Sockets to interact
; with the Admin API as well: in case you're interested in it, a different
; path needs to be provided.
[admin]
admin_enabled = no ; Whether to enable the Unix Sockets interface
; for Admin API clients
admin_path = /tmp/ux-janusadmin ; Path to bind to (Admin API)
;admin_type = SOCK_SEQPACKET ; SOCK_SEQPACKET (default) or SOCK_DGRAM?

View File

@ -0,0 +1,35 @@
; WebSockets stuff: whether they should be enabled, which ports they
; should use, and so on.
[general]
json = indented ; Whether the JSON messages should be indented (default),
; plain (no indentation) or compact (no indentation and no spaces)
ws = yes ; Whether to enable the WebSockets API
ws_port = 8188 ; WebSockets server port
;ws_interface = eth0 ; Whether we should bind this server to a specific interface only
;ws_ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address only
wss = no ; Whether to enable secure WebSockets
;wss_port = 8989; ; WebSockets server secure port, if enabled
;wss_interface = eth0 ; Whether we should bind this server to a specific interface only
;wss_ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address only
;ws_logging = 7 ; libwebsockets debugging level (0 by default)
;ws_acl = 127.,192.168.0. ; Only allow requests coming from this comma separated list of addresses
; If you want to expose the Admin API via WebSockets as well, you need to
; specify a different server instance, as you cannot mix Janus API and
; Admin API messaging. Notice that by default the Admin API support via
; WebSockets is disabled.
[admin]
admin_ws = no ; Whether to enable the Admin API WebSockets API
admin_ws_port = 7188 ; Admin API WebSockets server port, if enabled
;admin_ws_interface = eth0 ; Whether we should bind this server to a specific interface only
;admin_ws_ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address only
admin_wss = no ; Whether to enable the Admin API secure WebSockets
;admin_wss_port = 7989 ; Admin API WebSockets server secure port, if enabled
;admin_wss_interface = eth0 ; Whether we should bind this server to a specific interface only
;admin_wss_ip = 192.168.0.1 ; Whether we should bind this server to a specific IP address only
;admin_ws_acl = 127.,192.168.0. ; Only allow requests coming from this comma separated list of addresses
; Certificate and key to use for any secure WebSocket server, if needed.
[certificates]
cert_pem = /opt/janus/share/janus/certs/mycert.pem
cert_key = /opt/janus/share/janus/certs/mycert.key

View File

@ -10,3 +10,26 @@ services:
ports:
- 127.0.0.1:9999:9999
ipc: host
janus:
image: mcroth/docker-janus
volumes:
- ./config/janus/:/opt/janus/etc/janus/
- ./janus.log:/var/log/janus.log
ports:
- 8088:8088
- 8188:8188
- 8004:8004
- 8004:8004/udp
- 8005:8005/udp
janus-feed:
build: .
volumes:
- ./tools:/tools
command: /tools/janus-feed
restart: unless-stopped
frontend:
image: nginx:alpine
volumes:
- ./html:/usr/share/nginx/html:ro
ports:
- 8080:80

1
html/index.html Symbolic link
View File

@ -0,0 +1 @@
minimal-streaming.html

3092
html/janus.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Janus WebRTC Gateway: Streaming Demo</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/webrtc-adapter/6.0.3/adapter.min.js" ></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js" ></script>
<!--<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.2/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.1.0/bootbox.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js"></script>-->
<script type="text/javascript" src="janus.js" ></script>
<script type="text/javascript" src="minimal-streaming.js"></script>
</head>
<body>
<button class="btn btn-default" autocomplete="off" id="start">Start</button>
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Stream
<span class="label label-info hide" id="status"></span>
<span class="label label-primary hide" id="curres"></span>
<span class="label label-info hide" id="curbitrate"></span>
</h3>
</div>
<div class="panel-body" id="stream">
<video id="targetVideo"></video>
</div>
</div>
</div>
</body>
</html>

186
html/minimal-streaming.js Normal file
View File

@ -0,0 +1,186 @@
var server = null;
if(window.location.protocol === 'http:')
server = "http://" + window.location.hostname + ":8088/janus";
else
server = "https://" + window.location.hostname + ":8089/janus";
var janus = null;
var streaming = null;
var opaqueId = "streamingtest-"+Janus.randomString(12);
var bitrateTimer = null;
var spinner = null;
var selectedStream = null;
$(function() {
$('#start').click(function() {
startVideo(document.getElementById('targetVideo'), 10)
});
})
function startVideo(videoNode, videoId) {
// Initialize the library (all console debuggers enabled)
Janus.init({debug: "all", callback: function() {
if(!Janus.isWebrtcSupported()) {
bootbox.alert("No WebRTC support... ");
return;
}
// Create session
janus = new Janus({
server: server,
success: function() {
// Attach to streaming plugin
janus.attach({
plugin: "janus.plugin.streaming",
opaqueId: opaqueId,
success: function(pluginHandle) {
streaming = pluginHandle;
Janus.log("Plugin attached! (" + streaming.getPlugin() + ", id=" + streaming.getId() + ")");
// Setup streaming session
startStream(videoId);
},
error: function(error) {
Janus.error(" -- Error attaching plugin... ", error);
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message :::");
Janus.debug(msg);
var result = msg["result"];
if(result !== null && result !== undefined) {
if(result["status"] !== undefined && result["status"] !== null) {
var status = result["status"];
console.info('Status:', status);
if(status === 'stopped')
stopStream();
}
} else if(msg["error"] !== undefined && msg["error"] !== null) {
console.error(msg['error'])
stopStream();
return;
}
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
// Offer from the plugin, let's answer
streaming.createAnswer({
jsep: jsep,
media: { audioSend: false, videoSend: false }, // We want recvonly audio/video
success: function(jsep) {
Janus.debug("Got SDP!");
Janus.debug(jsep);
var body = { "request": "start" };
streaming.send({"message": body, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error:", error);
}
});
}
},
onremotestream: function(stream) {
Janus.debug(" ::: Got a remote stream :::");
Janus.debug(stream);
/*
if($('#remotevideo').length === 0) {
addButtons = true;
$('#stream').append('<video class="rounded centered hide" id="remotevideo" width=320 height=240 autoplay/>');
// Show the stream and hide the spinner when we get a playing event
$("#remotevideo").bind("playing", function () {
$('#waitingvideo').remove();
if(this.videoWidth)
$('#remotevideo').removeClass('hide').show();
if(spinner !== null && spinner !== undefined)
spinner.stop();
spinner = null;
var videoTracks = stream.getVideoTracks();
if(videoTracks === null || videoTracks === undefined || videoTracks.length === 0)
return;
var width = this.videoWidth;
var height = this.videoHeight;
$('#curres').removeClass('hide').text(width+'x'+height).show();
if(Janus.webRTCAdapter.browserDetails.browser === "firefox") {
// Firefox Stable has a bug: width and height are not immediately available after a playing
setTimeout(function() {
var width = $("#remotevideo").get(0).videoWidth;
var height = $("#remotevideo").get(0).videoHeight;
$('#curres').removeClass('hide').text(width+'x'+height).show();
}, 2000);
}
});
}*/
Janus.attachMediaStream(videoNode, stream);
videoNode.play();
var videoTracks = stream.getVideoTracks();
if(videoTracks === null || videoTracks === undefined || videoTracks.length === 0) {
// No remote video
console.warning('No video')
}
if(videoTracks && videoTracks.length &&
(Janus.webRTCAdapter.browserDetails.browser === "chrome" ||
Janus.webRTCAdapter.browserDetails.browser === "firefox" ||
Janus.webRTCAdapter.browserDetails.browser === "safari")) {
$('#curbitrate').removeClass('hide').show();
bitrateTimer = setInterval(function() {
// Display updated bitrate, if supported
var bitrate = streaming.getBitrate();
//~ Janus.debug("Current bitrate is " + streaming.getBitrate());
$('#curbitrate').text(bitrate);
// Check if the resolution changed too
var width = videoNode.videoWidth;
var height = videoNode.videoHeight;
if(width > 0 && height > 0)
$('#curres').removeClass('hide').text(width+'x'+height).show();
}, 1000);
}
},
oncleanup: function() {
Janus.log(" ::: Got a cleanup notification :::");
if(bitrateTimer !== null && bitrateTimer !== undefined)
clearInterval(bitrateTimer);
bitrateTimer = null;
}
});
},
error: function(error) {
Janus.error(error);
},
destroyed: function() {
window.location.reload();
}
});
}});
}
function startStream(selectedStream) {
Janus.log("Selected video id #" + selectedStream);
var body = { "request": "watch", id: parseInt(selectedStream) };
streaming.send({"message": body});
}
function stopStream() {
$('#watch').attr('disabled', true).unbind('click');
var body = { "request": "stop" };
streaming.send({"message": body});
streaming.hangup();
$('#streamset').removeAttr('disabled');
$('#streamslist').removeAttr('disabled');
$('#watch').html("Watch or Listen").removeAttr('disabled').click(startStream);
$('#status').empty().hide();
$('#bitrate').attr('disabled', true);
$('#bitrateset').html('Bandwidth<span class="caret"></span>');
$('#curbitrate').hide();
if(bitrateTimer !== null && bitrateTimer !== undefined)
clearInterval(bitrateTimer);
bitrateTimer = null;
$('#curres').empty().hide();
$('#simulcast').remove();
simulcastStarted = false;
}

7
tools/janus-feed Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
exec gst-launch-1.0 -v \
videotestsrc pattern=ball ! clockoverlay ! \
x264enc bitrate=5000 key-int-max=30 bframes=0 ! \
video/x-h264,profile=high,framerate=30/1,width=1280,height=720 ! \
rtph264pay config-interval=1 pt=96 ! udpsink host=janus port=8004