Janus Gateway (2) :: Video room plugin을 위한 config 세팅

Eon Kim·2021년 11월 2일
2

Janus Gateway

목록 보기
2/3
post-thumbnail

안녕하세요, 주니어 개발자 Eon입니다.

이전 포스트는 Janus Gateway 설치 과정과 Docker로 실행하고 싶으신 분들을 위해 Dockerfile을 포함해서 올렸습니다.
이번 포스트는 Janus Gateway config 세팅을 해보려고 합니다.
Docker를 사용하지 않을 분은 config나 설정 값 모두 로컬 Janus나 웹 서버에 적용하시면 됩니다.

Janus 실행 먼저 보도록 하겠습니다.

Janus Gateway의 실행

이전 포스트의 Dockerfile 마지막 부분이 실행하는 파트입니다.

/opt/janus/bin/janus --v
/opt/janus/bin/janus

janus binary를 --v 옵션과 함께 실행하면 version을 출력합니다.
그리고 옵션 없이 실행하면 janus가 실행됩니다.

이렇게 하면 Janus가 실행됩니다.
실행은 시켰으나, 제대로 동작되고 있는지 알려면 config 세팅을 끝마친 후에 실행해야 합니다.
지금 실행한 것은 default값으로만 설정되어 있어, 사용이 어렵습니다.


Janus configs

Janus config를 보겠습니다.
Dockerfile의 순서대로 진행하셨다면 아래의 경로에 config 파일이 있습니다.

/opt/janus/etc/janus

Videoroom plugin을 사용한 화상회의 세팅을 위해 우리가 봐야 할 것은 아래 리스트입니다.

janus.jcfg
janus.plugin.videoroom.jcfg
janus.transport.http.jcfg
janus.transport.websocket.jcfg

위에서부터 아래의 설정을 위한 config 파일들입니다.

  • Janus 전반적인 general config
  • videoroom을 위한 config
  • http 관련 설정을 위한 config
  • websocket 관련 설정을 위한 config

janus.jcfg


# Janus 메인 설정입니다.

# 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: {

# folder path는 default 세팅을 따르겠습니다.

	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
	events_folder = "/opt/janus/lib/janus/events"			# Event handlers folder
	loggers_folder = "/opt/janus/lib/janus/loggers"			# External loggers folder


# logging 관련 세팅입니다.
# log_to_file : log를 file로 남기기 위해, logfile의 경로를 지정합니다.
# debug_level : level 5로 설정하여, Verbose mode로 설정합니다.
# debug.h File Reference
# debug_timestamps : timestamp를 같이 출력하여, 로그를 보기 쉽게 합니다.
# 로그 세팅은 본인이 편한대로 옵션을 지정하시면 됩니다.

		# The next settings configure logging
	#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
	debug_level = 5							# Debug/logging level, valid values are 0-7
	debug_timestamps = true				# Whether to show a timestamp for each log line
	#debug_colors = false					# Whether colors should be disabled in the log
	#debug_locks = true						# Whether to enable debugging of locks (very verbose!)
	#log_prefix = "[janus] "				# In case you want log lines to be prefixed by some
											# custom text, you can use the 'log_prefix' property.
											# It supports terminal colors, meaning something like
											# "[\x1b[32mjanus\x1b[0m] " would show a green "janus"
											# string in square brackets (assuming debug_colors=true).


# demonize는 실행할 때 옵션으로 설정할 수 있으니, default로 두겠습니다.

		# This is what you configure if you want to launch Janus as a daemon
	#daemonize = true						# Whether Janus should run as a daemon
											# or not (default=run in foreground)
	#pid_file = "/path/to/janus.pid"		# PID file to create when Janus has been
											# started, and to destroy at shutdown


# authenticate는 default로 사용하겠습니다. (설정해서 사용하는 것은 따로 포스팅하도록 하겠습니다.)
# api_secret : 모든 API request에 해당 string을 인증 수단의 하나로써 포함시켜야 합니다.
# token_auth : token 기반의 인증을 활성화합니다. 모든 request에 유효한 token을 포함해야 합니다. 이는 비밀번호 관리하듯이 관리할 수 있어 보안 수준이 아주 높진 않습니다.
# token_auth_secret : HMAC-SHA1 서명 token을 인증 수단으로 사용합니다. HMAC은 단방향 해시 암호화 알고리즘으로, 해독이 불가합니다. 따라서, 굉장히 높은 보안 수준을 자랑합니다. 물론 이 또한 token의 형태이므로, 탈취 자체에는 취약합니다.
# admin_secret : Admin API를 사용하기 위한 암호를 설정합니다. Admin API를 이용한 모니터링을 활용하기 위해서 필요합니다.

		# There are different ways you can authenticate the Janus and Admin APIs
	#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 = true				# 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.
	#token_auth_secret = "janus"	# Use HMAC-SHA1 signed tokens (with token_auth). Note that
									# without this, 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.


# 일반 설정 파트입니다.
# interface : SDP에 사용될 인터페이스를 정의합니다. Docker로 올릴 경우, Docker network interface가 설정되어, 로컬 네트워크 인터페이스로 설정하더라도 자동으로 변경됩니다. 이를 원치 않을 경우, Docker network를 수정해야 합니다. 이 포스트에서는 다루지 않도록 합니다.
# session_timeout : 아무 요청이 없을 때 세션이 자동 만료되는 시간을 설정합니다. 기본값이 60이며, 초 단위입니다. timeout을 짧게 잡게 되면 세션을 유지하기 위해 많은 횟수의 keepalive 요청이 필요합니다. 이는 퍼포먼스 저하로 이어질 수 있습니다. 따라서 timeout은 너무 부족하지 않게 설정하는 것이 좋습니다. 이 포스트에서는 default 값을 사용하겠습니다.
# candidates_timeout : ICE trickle 하는 과정에 대한 timeout입니다. 비동기 프로세스로 진행되기 때문에 큰 차이는 없겠지만 Janus가 candidates 정보를 가지고 있는 시간을 설정하는 것이므로, 너무 길면 퍼포먼스에 영향을 줄 수 있습니다. 이 포스트에서는 default 값을 사용하겠습니다.
# reclaim_session_timeout : 통신이 끝난 세션이 회수될 때까지의 시간을 설정합니다. timeout을 길게 잡으면 Janus가 세션 정보를 유지하고 있어야 합니다. 이 역시 퍼포먼스 저하로 이어질 수 있습니다. default는 0이며, 통신이 끝난 세션은 바로 회수됩니다. 이 포스트에서는 default 값을 사용하겠습니다.
# 나머지 설명이 없는 부분은 default 세팅을 사용하시면 됩니다. 세팅을 하고 싶으신 분은 주석의 설명을 읽고 설정하시기 바랍니다.

        # Generic settings
	#interface = "1.2.3.4"			# Interface to use (will be used in SDP)
	#server_name = "MyJanusInstance"# Public name of this Janus instance
									# as it will appear in an info request
	#session_timeout = 60			# How long (in seconds) we should wait before
									# deciding a Janus session has timed out. A
									# session times out when no request is received
									# for session_timeout seconds (default=60s).
									# Setting this to 0 will disable the timeout
									# mechanism, which is NOT suggested as it may
									# risk having orphaned sessions (sessions not
									# controlled by any transport and never freed).
									# To avoid timeouts, keep-alives can be used.
	#candidates_timeout = 45		# How long (in seconds) we should keep hold of
									# pending (trickle) candidates before discarding
									# them (default=45s). Notice that setting this
									# to 0 will NOT disable the timeout, but will
									# be considered an invalid value and ignored.
	#reclaim_session_timeout = 0	# How long (in seconds) we should wait for a
									# janus session to be reclaimed after the transport
									# is gone. After the transport is gone, a session
									# times out when no request is received for
									# reclaim_session_timeout seconds (default=0s).
									# Setting this to 0 will disable the timeout
									# mechanism, and sessions will be destroyed immediately
									# if the transport is gone.
	#recordings_tmp_ext = "tmp"		# The extension for recordings, in Janus, is
									# .mjr, a custom format we devised ourselves.
									# By default, we save to .mjr directly. If you'd
									# rather the recording filename have a temporary
									# extension while it's being saved, and only
									# have the .mjr extension when the recording
									# is over (e.g., to automatically trigger some
									# external scripts), then uncomment and set the
									# recordings_tmp_ext property to the extension
									# to add to the base (e.g., tmp --> .mjr.tmp).
	#event_loops = 8				# By default, Janus handles each have their own
									# event loop and related thread for all the media
									# routing and management. If for some reason you'd
									# rather limit the number of loop/threads, and
									# you want handles to share those, you can do that
									# configuring the event_loops property: this will
									# spawn the specified amount of threads at startup,
									# run a separate event loop on each of them, and
									# add new handles to one of them when attaching.
									# Notice that, while cutting the number of threads
									# and possibly reducing context switching, this
									# might have an impact on the media delivery,
									# especially if the available loops can't take
									# care of all the handles and their media in time.
									# As such, if you want to use this you should
									# provision the correct value according to the
									# available resources (e.g., CPUs available).
	#opaqueid_in_api = true			# Opaque IDs set by applications are typically
									# only passed to event handlers for correlation
									# purposes, but not sent back to the user or
									# application in the related Janus API responses
									# or events; in case you need them to be in the
									# Janus API too, set this property to 'true'.
	#hide_dependencies = true		# By default, a call to the "info" endpoint of
									# either the Janus or Admin API now also returns
									# the versions of the main dependencies (e.g.,
									# libnice, libsrtp, which crypto library is in
									# use and so on). Should you want that info not
									# to be disclose, set 'hide_dependencies' to true.
		# The following is ONLY useful when debugging RTP/RTCP packets,
		# e.g., to look at unencrypted live traffic with a browser. By
		# default it is obviously disabled, as WebRTC mandates encryption.
	#no_webrtc_encryption = true
		# Janus provides ways via its API to specify custom paths to save
		# files to (e.g., recordings, pcap captures and the like). In order
		# to avoid people can mess with folders they're not supposed to,
		# you can configure an array of folders that Janus should prevent
		# creating files in. If the 'protected_folder' property below is
		# commented, no folder is protected.
		# Notice that at the moment this only covers attempts to start
		# an .mjr recording and pcap/text2pcap packet captures.
	protected_folders = [
		"/bin",
		"/boot",
		"/dev",
		"/etc",
		"/initrd",
		"/lib",
		"/lib32",
		"/lib64",
		"/proc",
		"/sbin",
		"/sys",
		"/usr",
		"/var",
			# We add what are usually the folders Janus is installed to
			# as well: we don't just put "/opt/janus" because that would
			# include folders like "/opt/janus/share" that is where
			# recordings might be saved to by some plugins
		"/opt/janus/bin",
		"/opt/janus/etc",
		"/opt/janus/include",
		"/opt/janus/lib",
		"/opt/janus/lib32",
		"/opt/janus/lib64",
		"/opt/janus/sbin"
	]
}


# 인증서 파트입니다.
# 인증서를 사용해서 DTLS를 사용하고 싶으신 분은 설정을 진행하시면 됩니다.
# Janus는 기본적으로 DTLS를 지원합니다. 인증서가 없더라도 self-signed cert를 통해 DTLS를 사용할 수 있습니다.
# 이 포스트에서는 default 세팅을 사용하겠습니다.

# Certificate and key to use for DTLS (and passphrase if needed). If missing,
# Janus will autogenerate a self-signed certificate to use. Notice that
# self-signed certificates are fine for the purpose of WebRTC DTLS
# connectivity, for the time being, at least until Identity Providers
# are standardized and implemented in browsers. If for some reason you
# want to enforce the DTLS stack in Janus to enforce valid certificates
# from peers, though, you can do that setting 'dtls_accept_selfsigned' to
# 'false' below: DO NOT TOUCH THAT IF YOU DO NOT KNOW WHAT YOU'RE DOING!
# You can also configure the DTLS ciphers to offer: the default if not
# set is "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK"
# Finally, by default NIST P-256 certificates are generated (see #1997),
# but RSA generation is still supported if you set 'rsa_private_key' to 'true'.
certificates: {
	#cert_pem = "/path/to/certificate.pem"
	#cert_key = "/path/to/key.pem"
	#cert_pwd = "secretpassphrase"
	#dtls_accept_selfsigned = false
	#dtls_ciphers = "your-desired-openssl-ciphers"
	#rsa_private_key = false
}


# 미디어 관련 세팅입니다.
# ipv6 : ipv6를 지원할 것인지에 대한 세팅입니다. 아직까지 ipv6가 꼭 필요한 경우는 거의 없다고 봐도 무방합니다. 또한, 이 포스트에서는 demo 서비스까지만 다룰 것이므로, ipv6는 지원하지 않도록 false로 세팅합니다.
# rtp_port_range : RTP와 RTCP를 위해 사용될 포트 범위를 지정합니다. 포트를 많이 사용할수록 Janus 리소스가 많이 사용됩니다. demo 서비스에서 개인이 테스트할 정도만 필요하니, 30개 포트만 사용하겠습니다. video, audio 모두 RTP 통신을 하므로 Peer 2개가 연결됐을 때, 총 4개의 RTP 포트가 사용됩니다. Peer 3개가 연결됐을 때는 각 3개씩 총 9개의 RTP 포트가 사용됩니다.
# 나머지 세팅은 default 값을 사용하겠습니다.

# Media-related stuff: you can configure whether if you want
# to enable IPv6 support, the minimum size of the NACK queue (in ms,
# defaults to 200ms) for retransmissions no matter the RTT, the range of
# ports to use for RTP and RTCP (by default, no range is envisaged), the
# starting MTU for DTLS (1200 by default, it adapts automatically),
# how much time, in seconds, should pass with no media (audio or
# video) being received before Janus notifies you about this (default=1s,
# 0 disables these events entirely), how many lost packets should trigger
# a 'slowlink' event to users (default=4), and how often, in milliseconds,
# to send the Transport Wide Congestion Control feedback information back
# to senders, if negotiated (default=200ms). Finally, if you're using BoringSSL
# you can customize the frequency of retransmissions: OpenSSL has a fixed
# value of 1 second (the default), while BoringSSL can override that. Notice
# that lower values (e.g., 100ms) will typically get you faster connection
# times, but may not work in case the RTT of the user is high: as such,
# you should pick a reasonable trade-off (usually 2*max expected RTT).
media: {
	ipv6 = false
	#min_nack_queue = 500
	rtp_port_range = "10000-10030"
	#dtls_mtu = 1200
	#no_media_timer = 1
	#slowlink_threshold = 4
	#twcc_period = 100
	#dtls_timeout = 500
	# If you need DSCP packet marking and prioritization, you can configure
	# the 'dscp' property to a specific values, and Janus will try to
	# set it on all outgoing packets using libnice. Normally, the specs
	# suggest to use different values depending on whether audio, video
	# or data are used, but since all PeerConnections in Janus are bundled,
	# we can only use one. You can refer to this document for more info:
	# https://tools.ietf.org/html/draft-ietf-tsvwg-rtcweb-qos-18#page-6
	# That said, DON'T TOUCH THIS IF YOU DON'T KNOW WHAT IT MEANS!
	#dscp = 46
}


# NAT 관련 세팅입니다. 로컬에서만 테스트할 때는 설정이 필요없습니다. NAT를 통하는 경우에는 설정을 해야 합니다.
# stun_server : stun 서버를 지정합니다. default stun 서버가 사용 가능한 상태이므로, 주석만 해제하여 사용하도록 하겠습니다.
# stun_port : public으로 열어둔 stun 서버의 포트는 대부분 3478입니다. IANA에 지정돼 있는 well-known port로, 표준입니다. 마찬가지로 주석을 해제하여 사용하도록 하겠습니다.
# nice_debug : libnice를 설치했다면 사용이 가능합니다. true로 설정할 경우, debug 모드가 활성화되어 candidate 관련 로그가 debug level로 출력됩니다. default 값이 주석이 해제된 상태로 false 설정되어 있습니다. default 값을 사용하도록 하겠습니다.
# nat_1_1_mapping : NAT 맵핑을 설정합니다. 머신의 public IP address를 맵핑 값으로 설정합니다.
# 해당 파트 다음으로 오는 설정들은 모두 default 값을 사용합니다.

# 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 do full-trickle (Janus also trickles its candidates to
# users) rather than the default half-trickle (Janus supports trickle
# candidates from users, but sends its own within the SDP), and whether
# it should work in ICE-Lite mode (by default it doesn't). Finally,
# you can also enable ICE-TCP support (beware that this may lead to problems
# if you do not 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
	#full_trickle = true
	#ice_lite = true
	#ice_tcp = true
	# By default Janus tries to resolve mDNS (.local) candidates: even
	# though this is now done asynchronously and shouldn't keep the API
	# busy, even in case mDNS resolution takes a long time to timeout,
	# you can choose to drop all .local candidates instead, which is
	# helpful in case you know clients will never be in the same private
	# network as the one the Janus instance is running from. Notice that
	# this will cause ICE to fail if mDNS is the only way to connect!
	#ignore_mdns = 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.
	# Make sure you keep ICE Lite disabled, though, as it's not strictly
	# speaking a publicly reachable server, and a NAT is still involved.
	# If you'd rather keep the private IP address in place, rather than
	# replacing it (and so have both of them as advertised candidates),
	# then set the 'keep_private_host' property to true.
	# Multiple public IP addresses can be specified as a comma separated list
	# if the Janus is deployed in a DMZ between two 1-1 NAT for internal and
	# external users.
	nat_1_1_mapping = "1.2.3.4"  # The machine's public IP address
	#keep_private_host = true
	# 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. Notice that the 'opaque_id' provided via Janus API will be
	# used as the username for a specific PeerConnection by default; if that one
	# is missing, the 'session_id' will be used as the username instead.
	#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"
	# In case you want to allow Janus to start even if the configured STUN or TURN
	# server is unreachable, you can set 'ignore_unreachable_ice_server' to true.
	# WARNING: We do not recommend to ignore reachability problems, particularly
	# if you run Janus in the cloud. Before enabling this flag, make sure your
	# system is correctly configured and Janus starts after the network layer of
	# your machine is ready. Note that Linux distributions offer such directives.
	# You could use the following directive in systemd: 'After=network-online.target'
	# https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before=
	#ignore_unreachable_ice_server = true
}
# 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"
}
# As a core feature, Janus can log either on the standard output, or to
# a local file. Should you need more advanced logging functionality, you
# can make use of one of the custom loggers, or write one yourself. Use the
# 'disable' directive to prevent Janus from loading one or more loggers:
# use a comma separated list of logger file names to identify the loggers
# to disable. By default all available loggers are enabled and loaded at startup.
loggers: {
	#disable = "libjanus_jsonlog.so"
}
# Event handlers allow you to receive live events from Janus happening
# in core and/or plugins. Since this can require some more resources,
# the feature is disabled by default. Setting broadcast to yes will
# enable them. You can then choose which of the available event handlers
# should be loaded or not. Use the 'disable' directive to prevent Janus
# from loading one or more event handlers: use a comma separated list of
# file names to identify the event handlers to disable. By default, if
# broadcast is set to yes all available event handlers are enabled and
# loaded at startup. Finally, you can choose how often media statistics
# (packets sent/received, losses, etc.) should be sent: by default it's
# once per second (audio and video statistics sent separately), but may
# considered too verbose, or you may want to limit the number of events,
# especially if you have many PeerConnections active. To change this,
# just set 'stats_period' to the number of seconds that should pass in
# between statistics for each handle. Setting it to 0 disables them (but
# not other media-related events).
events: {
	#broadcast = true
	#disable = "libjanus_sampleevh.so"
	#stats_period = 5
}

janus.plugin.videoroom.jcfg

이 파트에서는 두 개의 방을 생성해두고 사용하는 sample을 보여줍니다.
방을 구성하는 속성들을 설정해보고 테스트할 수 있습니다.
이 방들은 사전에 Janus에서 이와 같이 config 설정으로 만들어야만 하는 것은 아닙니다.
Janus에 REST-API로 방 생성 요청을 할 수 있고, 원하는 옵션을 선택해서 방을 생성할 수 있습니다.
따로 설정을 바꾸어 테스트하는 것은 포스트에 포함하지 않겠습니다.

# room-<unique room ID>: {
# description = This is my awesome room
# is_private = true|false (whether this room should be in the public list, default=true)
# secret = <optional password needed for manipulating (e.g. destroying) the room>
# pin = <optional password needed for joining the room>
# require_pvtid = true|false (whether subscriptions are required to provide a valid private_id 
#			to associate with a publisher, default=false)
# 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)
# bitrate_cap = true|false (whether the above cap should act as a hard limit to
#			dynamic bitrate changes by publishers; default=false, publishers can go beyond that)
# fir_freq = <send a FIR to publishers every fir_freq seconds> (0=disable)
# audiocodec = opus|g722|pcmu|pcma|isac32|isac16 (audio codec(s) to force on publishers, default=opus
#			can be a comma separated list in order of preference, e.g., opus,pcmu)
# videocodec = vp8|vp9|h264|av1|h265 (video codec(s) to force on publishers, default=vp8
#			can be a comma separated list in order of preference, e.g., vp9,vp8,h264)
# vp9_profile = VP9-specific profile to prefer (e.g., "2" for "profile-id=2")
# h264_profile = H.264-specific profile to prefer (e.g., "42e01f" for "profile-level-id=42e01f")
# opus_fec = true|false (whether inband FEC must be negotiated; only works for Opus, default=false)
# video_svc = true|false (whether SVC support must be enabled; only works for VP9, default=false)
# audiolevel_ext = true|false (whether the ssrc-audio-level RTP extension must
#		be negotiated/used or not for new publishers, default=true)
# audiolevel_event = true|false (whether to emit event to other users or not, default=false)
# audio_active_packets = 100 (number of packets with audio level, default=100, 2 seconds)
# audio_level_average = 25 (average value of audio level, 127=muted, 0='too loud', default=25)
# videoorient_ext = true|false (whether the video-orientation RTP extension must
#		be negotiated/used or not for new publishers, default=true)
# playoutdelay_ext = true|false (whether the playout-delay RTP extension must
#		be negotiated/used or not for new publishers, default=true)
# transport_wide_cc_ext = true|false (whether the transport wide CC RTP extension must be
#		negotiated/used or not for new publishers, default=true)
# record = true|false (whether this room should be recorded, default=false)
# rec_dir = <folder where recordings should be stored, when enabled>
# lock_record = true|false (whether recording can only be started/stopped if the secret
#            is provided, or using the global enable_recording request, default=false)
# notify_joining = true|false (optional, whether to notify all participants when a new
#               participant joins the room. The Videoroom plugin by design only notifies
#               new feeds (publishers), and enabling this may result extra notification
#               traffic. This flag is particularly useful when enabled with require_pvtid
#               for admin to manage listening only participants. default=false)
# require_e2ee = true|false (whether all participants are required to publish and subscribe
#             using end-to-end media encryption, e.g., via Insertable Streams; default=false)
#}
general: {
	#admin_key = "supersecret"		# If set, rooms can be created via API only
									# if this key is provided in the request
	#lock_rtp_forward = true		# Whether the admin_key above should be
									# enforced for RTP forwarding requests too
	#events = false					# Whether events should be sent to event
									# handlers (default=true)
	# By default, integers are used as a unique ID for both rooms and participants.
	# In case you want to use strings instead (e.g., a UUID), set string_ids to true.
	#string_ids = true
}
room-1234: {
	description = "Demo Room"
	secret = "adminpwd"
	publishers = 6
	bitrate = 128000
	fir_freq = 10
	#audiocodec = "opus"
	#videocodec = "vp8"
	record = false
	#rec_dir = "/path/to/recordings-folder"
}
# This other demo room here is only there in case you want to play with
# the VP9 SVC support. Notice that you'll need a Chrome launched with
# the flag that enables that support, or otherwise you'll be using just
# plain VP9 (which is good if you want to test how this indeed affect
# what receivers will get, whether they're encoding SVC or not).
room-5678: {
	description = "VP9-SVC Demo Room"
	secret = "adminpwd"
	publishers = 6
	bitrate = 512000
	fir_freq = 10
	videocodec = "vp9"
	video_svc = true
}

janus.transport.http.jcfg


# Janus에 http request를 보낼 때의 설정입니다.
# admin_http : Janus Admin / Monitor API를 위해 true로 설정합니다. Janus에 생성된 세션과 핸들 정보를 모두 볼 수 있습니다.
# 나머지 설정은 default로 두겠습니다. cors, 인증서 파트는 Janus 앞에 Web Server를 두어 설정할 수도 있습니다.

# 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. Notice that by default
# all the web servers will try and bind on both IPv4 and IPv6: if you
# want to only bind to IPv4 addresses (e.g., because your system does not
# support IPv6), you should set the web server 'ip' property to '0.0.0.0'.
general: {
	#events = true					# Whether to notify event handlers about transport events (default=true)
	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)
	http = true						# 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 = false					# Whether to enable HTTPS (default=false)
	#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, 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=true.
admin: {
	admin_base_path = "/admin"			# Base path to bind to in the admin/monitor web server (plain HTTP only)
	admin_http = true					# 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 = false					# Whether to enable HTTPS (default=false)
	#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
}
# The HTTP servers created in Janus support CORS out of the box, but by
# default they return a wildcard (*) in the 'Access-Control-Allow-Origin'
# header. This works fine in most situations, except when we have to
# respond to a credential request (withCredentials=true in the XHR). If
# you need that, uncomment and set the 'allow_origin' below to specify
# what must be returned in 'Access-Control-Allow-Origin'. More details:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
cors: {
	#allow_origin = "http://foo.example"
}
# Certificate and key to use for HTTPS, if enabled (and passphrase if needed).
# You can also disable insecure protocols and ciphers by configuring the
# 'ciphers' property accordingly (no limitation by default).
certificates: {
	#cert_pem = "/path/to/cert.pem"
	#cert_key = "/path/to/key.pem"
	#cert_pwd = "secretpassphrase"
	#ciphers = "PFS:-VERS-TLS1.0:-VERS-TLS1.1:-3DES-CBC:-ARCFOUR-128"
}

janus.transport.websocket.jcfg


# 웹 소켓 관련 설정입니다.
# Admin 관련 API는 http를 통해서만 request하겠습니다.
# 모두 default 값으로 설정하겠습니다.

# WebSockets stuff: whether they should be enabled, which ports they
# should use, and so on.
general: {
	#events = true					# Whether to notify event handlers about transport events (default=true)
	json = "indented"				# Whether the JSON messages should be indented (default),
									# plain (no indentation) or compact (no indentation and no spaces)
	#pingpong_trigger = 30			# After how many seconds of idle, a PING should be sent
	#pingpong_timeout = 10			# After how many seconds of not getting a PONG, a timeout should be detected
	ws = true						# 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 = false						# 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 = "err,warn"		# libwebsockets debugging level as a comma separated list of things
									# to debug, supported values: err, warn, notice, info, debug, parser,
									# header, ext, client, latency, user, count (plus 'none' and 'all')
	#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 = false					# 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 = false					# 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 enabled (and passphrase if needed).
# You can also disable insecure protocols and ciphers by configuring the
# 'ciphers' property accordingly (no limitation by default).
# Examples of recommended cipher strings at https://cheatsheetseries.owasp.org/cheatsheets/TLS_Cipher_String_Cheat_Sheet.html
certificates: {
	#cert_pem = "/etc/letsencrypt/live/nimbus-cert/fullchain.pem"
	#cert_key = "/etc/letsencrypt/live/nimbus-cert/privkey.pem"
	#cert_pwd = "nimbus0425"
	#ciphers = "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"
}

이로써 Janus Gateway Video room config 설정이 끝났습니다.
다음 포스팅에서는 Janus Gateway Server와 Janus demo page의 연동을 다루겠습니다.
감사합니다.👍

profile
주니어 개발자

8개의 댓글

comment-user-thumbnail
2022년 1월 4일

상세한 설명 너무 감사드립니다!

답글 달기
comment-user-thumbnail
2022년 1월 14일

너무 좋은 포스팅입니다! 잘봤습니다.
저는 제 컴터에 웹캠 1~2개정도 달아서 rtp 영상 스트리밍을 하려하는데요.
폰에서 제 집을 cctv 처럼 보고싶은데 진짜 리얼타임으로 레이턴씨 100m 정도로 나올수있을까요?
영상 스트리밍 용량이 커져도 빠른게 우선이라 h264 정도의 코덱을 사용하면 될지 아직 모르겠네요.
자바를 좀 할줄알아서 이미지 한장한장 15fps 로 안드로이드 폰에서 이미지 보여주는(동영상처럼 보임) 거를 해봤는데 1분정도 보면 수십메가바이트를 사용해서 ㅠ 인코딩된 영상으로 바꾸려고요!!

가능할까요?! 동접자도 10명정도까지 커버가 될지 모르겠습니다 ㅠ

1개의 답글
comment-user-thumbnail
2024년 1월 28일

실례가 안된다면 질문가능할까요...?
ICE failed for component 1 in stream 1, but let's give it some time... (trickle received, answer received, alert not set)
[ERR][ice.c:janus_ice_check_failed:2079] [4395137508794770] ICE failed for component 1 in stream 1..
이런식으로 ice관련하여 뭔가 문제가 있습니다

콘솔로그에도
End of candidates.
ICE state changed to checking
janus.js:2505 Remote description accepted!
VideoChat.js:114 Janus says our WebRTC PeerConnection is down now

ice state가 연결안되고 피어커넥션이 다운됩니다..

nat: {
stun_server = "stun.l.google.com"
stun_port = 19302

    ...

nat_1_1_mapping = "제 nignx로 열어놓은 ip를" 설정해놨습니다 ..
}
\
janus.jcfg에서는 이런식으로 설정햇는데도 문제입니다 ㅠㅠ

답글 달기