Knowledge Base

An example/template nginx.conf with descriptions

## ====================================================================================================== ##
## Visit this page for a list of all variables: https://github.com/arut/nginx-rtmp-module/wiki/Directives ##
## Visit this site for many more configuration examples: https://github.com/arut/nginx-rtmp-module	      ##
## This example file was put together by Andre "ustoopia" for useage on https://youtube.com/ustoopia      ##
## ====================================================================================================== ##

user www-data;            # Only used on linux. Nginx will run under this username.
worker_processes 1;				# Set this to how many processors/cores the CPU has. Relates to "worker_connections".
pid /run/nginx.pid;				# Sets the location of the process id file (used on linux only).
include /etc/nginx/modules-enabled/*.conf;	# Include all the optional configuration files stored in this folder.

events {
	worker_connections 768;		# Worker_processes * worker_connections = max clients. So in this setup: 1 * 768 = 768 max clients.
	# multi_accept on;		# "Off" will accept 1 new connection at a time. "On" will accept all new connections. Default is off.
	}

http {
	sendfile off;				# on|off. Toggles the use of sendfile. Default=off. For optimal HLS delivery disable this.
	tcp_nodelay on;				# on|off. Forces a socket to send the data in its buffer, whatever the packet size. Default=on.
	tcp_nopush on;				# on|off. Sends the response header and beginning of a file in one packet. Default=off.
	server_tokens off;			# on|off|build. Toggles showing nginx version in the response header field. Default=on.
	keepalive_timeout 65;			# A keep-alive client connection will stay open for .. on the server side. Use 0 to disable. Default=75s
	types_hash_max_size 2048;		# Sets the maximum size of the types hash tables. Default=1024.
	# server_name_in_redirect on;		# Toggles the use of the primary server name, specified by the server_name directive. Default=off.
	# server_names_hash_bucket_size 64;	# Sets the bucket size for the server names hash tables depending on processor's cache line, 32|64|128.
	default_type application/octet-stream;	# Emit this MIME type for all requests.
	
	## Include configuration files from these locations ##
	include /etc/nginx/mime.types;
	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*.conf;	# Holds symlinks to the actual config files in /etc/nginx/sites-available

	access_log /var/log/nginx/access.log;		# Set this here or in the virtual hosts config file in sites-available folder.
	error_log /var/log/nginx/error.log warn;	# Set this here or in the virtual hosts config file in sites-available folder.
 
	gzip on;			# on|off. Compresses responses using gzip method. Helps to reduce size of transmitted data by half or more. Default=off
	# gzip_vary on;			# More info on zip variables is found here: https://nginx.org/en/docs/http/ngx_http_gzip_module.html
	gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	gzip_http_version 1.1;
	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

## EITHER SET YOUR SERVER {} BLOCK HERE, OR RATHER IN A SEPERATE VIRTUAL HOST CONFIG FILE IN /sites-available/yourdomain.conf ##

## RTMP CONFIGURATION STARTS HERE ##
rtmp {
	server {
	listen 1935;		# The RTMP listening port. Open it in your router/firewall. Options: (addr[:port]|port|unix:path) [bind] [ipv6only=on|off] [so_keepalive=on|off|keepidle:keepintvl:keepcnt|proxy_protocol]

	application live {	# Name it whatever you prefer. You will need at least one application, you can have many more.
	live on;		# on|off. Enables this application and allowing live streaming to it. Default=on.
	# max_streams 32;	# Sets maximum number of RTMP streams. Default value is 32 which is usually ok for most cases. Default=32.
	# max_connections 100;	# Sets maximum number of connections for rtmp engine. Default=off. 
	meta on;		# on|copy|off. Receive metadata packets containing predefined fields like width, height etc. Default=on.
	interleave off;		# on|off. Audio and video data is transmitted on the same RTMP chunk stream. Default=off.
	wait_key on;		# on|off. Makes video stream start with a key frame. Default=off.
	wait_video off;		# on|off. Disable audio until first video frame is sent (can cause delay). Default=off.
	publish_notify off;	# on|off. Send "NetStream.Play.PublishNotify" and "NetStream.Play.UnpublishNotify" to subscribers. Default=off. 
	drop_idle_publisher 10s;# Drop publisher that has been idle for this time. Only works when connection is in publish mode. Default=off
	sync 300ms;		# When timestamp difference exceeds the value specifiedan absolute frame is sent fixing that. Default=300ms.
	play_restart off;	# on|off. If enabled sends "NetStream.Play.Start" and "NetStream.Play.Stop" every time publishing starts or stops. Default=off.
	idle_streams on;	# on|off. If disabled prevents viewers from connecting to idle/nonexistent streams and disconnects all. Default=on.

	## TRANSCODING USING FFMPEG EXEC ##
	## The following lines will take our incoming RTMP stream and transcode it to several different HLS streams with variable bitrates  ##
	## Once receive stream, transcode for adaptive streaming. This single ffmpeg command takes the input and transforms the source into ##
	## 4 or 5 different streams with different bitrate and quality. P.S. The scaling done here respects the aspect ratio of the input.  ##
	## EXEC - Many things are possible using exec. To learn more visit https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec   ##

	#exec ffmpeg -i rtmp://localhost/$app/$name  -async 1 -vsync -1
	#-c:v libx264 -acodec copy -b:v 256k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_low
	#-c:v libx264 -acodec copy -b:v 768k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_mid
	#-c:v libx264 -acodec copy -b:v 1024k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_high
	#-c:v libx264 -acodec copy -b:v 1920k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_higher
	#-c copy -f flv rtmp://localhost/hls/$name_src;

## SET ACCESS RULES FOR APPLICATION /live  ##
## PUBLISHING ##
	allow 127.0.0.1;		# If you decice to harden these rules, it is adviced to uncomment this line.
	# allow publish 192.168.2.0/24;	# Anybody from this local IP address range can stream to this application.
	# allow publish 192.168.2.50;	# Allow a single IP address to stream to this application (multiple lines with different ip's are possible)
	allow publish all;		# Anybody from any location can stream to this application. Comment this out if you want to use deny publish.
	# deny publish 10.0.0.50;	# Deny this specific IP address from streaming to this application. Can also be an IP address range.
	# deny publish all;		# Nobody can stream to the server except those that you've set in previous lines.
## PLAYING  ##
	allow play 127.0.0.1;		# Localhost can play the stream from this application. Must be set if you decide to use push later on!
	allow play 192.168.2.0/24;	# Anybody in this IP range can play the RTMP directly.
	allow play all;			# Anybody can play the RTMP livestream directly. Comment this out if you decide to use the next option.
	# deny play all;		# Nobody can play the RTMP stream except those that we've set in lines above it.

## RECORDING  ##
	record off;			# off|all|audio|video|keyframes|manual. These options speak for themselves.
	record_path /tmp/rec;		# Folder location that will be used to store the recordings. YOU SHOULD CHANGE THIS TO YOUR PREFERENCE!
	record_suffix -%d-%b-%y-%T.flv;	# Added to recorded filenames. Example uses 'strftime' format results: -24-Apr-13-18:23:38.flv. Default=.flv
	record_unique on;		# on|off. Appends timestamp to recorded files. Otherwise the same file is re-written each time. Default=-off
	record_append off;		# on|off. When turned on recorder appends new data to the old file with no gap. Default=off
	record_lock off;		# on|off. When turned on recorded file gets locked with 'fcntl' call. Default=off.
	record_notify off;		# on|off. Toggles sending "NetStream.Record.Start" and "NetStream.Record.Stop" status messages. Default=off.
	# record_max_size 128K;		# Set maximum file size of the recorded files. No default.
	# record_max_frames 200;	# Sets maximum number of video frames per recorded file. No default.
	# record_interval 15m;		# Restart recording after this number of (milli)seconds/minutes. Zero means no delay. Default=off.
	# recorder name	{}		# Create recorder{} block. Multiple recorders can be created withing single application. Example:
	recorder audio {
		record audio;
		record_suffix .audio.flv;
		record_path /tmp/rec/audio;
	}

## STREAM RELAYING LOCAL ##
	## For more info please visit:	https://github.com/arut/nginx-rtmp-module/wiki/Directives#relay ##
	## pull url [key=value]*	# Creates pull relay. A stream is pulled from remote machine and becomes available locally. ##
	## URL Syntax:			[rtmp://]host[:port][/app[/playpath]] ##
	# pull rtmp://cdn.example.com/live/ch?id=1234 name=channel_a;		# This is an example. Visit above url for more info.
	# session_relay off;		# on|off. On=relay is destroyed when connection is closed. Off=relay is destroyed when stream is closed. Default=off.

	## Push has the same syntax as pull. Unlike pull, push directive publishes stream to remote server. ##
	## This will push the stream from current application to these two applications to create a hls and/or dash stream automatically. ##

	push rtmp://localhost/hls;	# Remember to create the app hls! Disable it if you use transcoding using variable bitrates.
	push rtmp://localhost/dash;	# Remember to create the app dash! It is safe to disable this if you're not interested in using Dash.


## STREAM RELAYING TO EXTERNAL PARTY'S ##
	## Push can also be used to re-stream your stream to other platforms. You can do this directly or use an additional application for this. ##
	## Using an additional local application allows you to set up variables if you prefer. Or you can choose to push to 3rd party directly. ##

	## YOUTUBE PUSH OPTIONS ##
	# push rmtp://localhost/youtube;		# Uncomment this to use application on localhost (MUST BE SPECIFIED). OR simply use the following line:
	# push rtmp://a.rtmp.youtube.com/live2/YOUR-LIVE-STREAM-KEY;		# Your RTMP stream will be pushed as it is to Youtube as an RTMP stream.

	# TWITCH PUSH OPTIONS ##
	# push rmtp://localhost/twitch;			# Uncomment this to use application on localhost (MUST BE SPECIFIED). OR simply use the following line:
	# push rtmp://live-ams.twitch.tv/app/live_YOUR-LIVE-STREAM-KEY;		# Your RTMP stream will be pushed as it is to Twitch as an RTMP stream.
	}

## HLS APPLICATION ##
	application hls {		# (See line 121) We enabled pushing stream from 'live' application to 'hls' we need to define it of course.
	live on;			# on|off. Enables this application and allowing live streaming to it. Default=on.
	hls on;				# on|off. Toggles HLS on or off for this application.
	hls_type live;			# live|event. Live plays from the current live position. Event plays from the start of the playlist. Default=live.
	hls_path /tmp/hls;		# Location to store the video fragment files. Will be created if it doesn't exist.
	hls_fragment 5s;		# Sets HLS fragment length in seconds or minutes. Default=5s.
	hls_playlist_length 30s;	# Sets HLS playlist length in seconds or minutes. Default=30s.
	hls_sync 2ms;			# Timestamp sync threshold. Prevents crackling noise after conversion from low-res (1KHz) to high-res(90KHz). Default=2ms.
	hls_continuous off;		# on|off. In this mode HLS sequence number is started from where it stopped last time. Old fragments are kept. Default=off.
	hls_nested on;			# on|off. In this mode a subdirectory of hls_path is created for each stream. Default=off.
	hls_cleanup on;			# on|off. Nginx cache manager process removes old HLS fragments and playlist files from hls_path. Default=on.
	hls_fragment_naming system;	# system = use system time. sequential = use increasing integers. timestamp = use stream timestamp. Default=sequential.
	hls_fragment_slicing plain;	# plain|aligned. Plain: switch fragment when target duration is reached. Aligned: switch fragment when incoming timestamp is a
					# multiple of fragment duration. Makes it possible to generate identical fragments on different nginx instances. Default=plain.

	## ENCRYPTION KEYS	## !! Only works if you have certificates defined in your HTTP server block (Usually a seperate file in /sites-available/yourfile.conf)
	# hls_keys on;			# on|off. Enables HLS encryption. AES-128 method is used to encrypt the HLS fragments. Requires ssl module. Default=off.
	hls_key_path /tmp/keys;		# Sets the directory where auto-generated HLS keys are saved. Default= hls_path.
	hls_fragments_per_key 100;	# Sets the number of HLS fragments encrypted with the same key. 0 means only one key is created at the publish start and 
					# all fragments within the session are encrypted with this key. Default=0.
	#hls_key_url https://foo.bar/keys;	# Sets url for HLS key file entries. When empty it assumes hls_path. Default= empty.

	## HLS_VARIANT - Used for variable bitrate streaming. Please read: https://github.com/arut/nginx-rtmp-module/wiki/Directives#hls_variant ##
	## When hls_variant suffix is matched on stream name then variant playlist is created for the current stream with all entries specified by hls_variant
	## directives in current application. Stripped name without suffix is used as variant stream name. The original stream is processed as usual.
	## Optional parameters following the suffix are appended to EXT-X-STREAM-INF in m3u8 playlist. See HLS spec 3.3.10. EXT-X-STREAM-INF for full list.

		hls_variant _low BANDWIDTH=288000;		# Low bitrate, sub-SD resolution 	_low
		hls_variant _mid BANDWIDTH=448000;		# Medium bitrate, SD resolution 	_mid
		hls_variant _high BANDWIDTH=1152000;		# Higher-than-SD resolution 		_high 
		hls_variant _higher BANDWIDTH=2048000;		# High bitrate, HD 720p resolution 	_higher
		hls_variant _src BANDWIDTH=4096000;		# Source bitrate, source resolution 	_src
		}

## MPEG-DASH ##
	application dash {		# These variables will be used since we enabled pushing /live stream to this application (See line 122)
	live on;			# on|off. Enables this application and allowing live streaming to it. Default=on.
	dash on;			# on|off. Toggles MPEG-DASH on the current application.
	dash_path /tmp/dash;		# Location to store the video fragment files. Will be created if it doesn't exist.
	dash_fragment 5s;		# Sets DASH fragment length in seconds or minutes. Default= 5s.
	dash_playlist_length 30s;	# Sets MPEG-DASH playlist length. Defaults= 30s.
	dash_nested on;			# on|off. In this mode a subdirectory of dash_path is created for each stream. Default=off.
	dash_cleanup on;		# on|off. Nginx cache manager process removes old DASH fragments and playlist files from dash_path. Default=on.
	}

## TWITCH APPLICATION - Only required if you decide to re-stream using this application ##
        application twitch {		
		live on;
		record off;
		allow publish 127.0.0.1;
		deny publish all;
		push rtmp://ams02.contribute.live-video.net/app/YOUR_STREAM_KEY ## FIND YOUR OPTIMAL SERVER FIRST! (https://stream.twitch.tv/ingests/)
        }

## YOUTUBE - Only required if you decide to re-stream using this application ##
	application youtube {
		live on;
		record off;
		allow publish 127.0.0.1;
		deny publish all;
		push rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY; ## PLEASE REPLACE WITH SERVER CLOSEST TO YOU
	}

## LOGGING - This section has too many options to include. Please see https://github.com/arut/nginx-rtmp-module/wiki/Directives#access-log ##
	access_log /var/log/nginx/rtmp_access.log;	# off|path [format_name]. Default logging is done to same file as HTTP logger.


## NOTIFICATIONS  - This section has too many options to include. ##
	## Notifications use HTTP callback to inform subscribers that stream has started. You will need a website that can handle these. ##
	## These option go beyond the scope of this configuration file as it contains lots of info. Please visit this url for more info: ##
	## https://github.com/arut/nginx-rtmp-module/wiki/Directives#notify ##

	# publish_notify on;	# on|off. Send "NetStream.Play.PublishNotify" and "NetStream.Play.UnpublishNotify" to subscribers. Default=off.
	# on_connect http://www.example.com/plugin/Live/on_publish.php;			
	# on_play http://www.example.com/plugin/Live/on_play.php;
	# on_record_done http://www.example.com/plugin/Live/on_record_done.php';

	}	# CLOSING BRACKET SERVER BLOCK
}	# CLOSING BRACKET RTMP BLOCK
======================================================================================================
 Visit this page for a list of all variables: https://github.com/arut/nginx-rtmp-module/wiki/Directives
 Visit this site for many more configuration examples: https://github.com/arut/nginx-rtmp-module
 This example file was put together by Andre "ustoopia" for useage on https://youtube.com/ustoopia
 ======================================================================================================
 user www-data;            # Only used on linux. Nginx will run under this username.
 worker_processes 1;                # Set this to how many processors/cores the CPU has. Relates to "worker_connections".
 pid /run/nginx.pid;                # Sets the location of the process id file (used on linux only).
 include /etc/nginx/modules-enabled/*.conf;    # Include all the optional configuration files stored in this folder.
 events {
     worker_connections 768;     # Worker_processes * worker_connections = max clients. So in this setup: 1 * 768 = 768 max clients.
     # multi_accept on;      # "Off" will accept 1 new connection at a time. "On" will accept all new connections. Default is off.
     }
 http {
     sendfile off;               # on|off. Toggles the use of sendfile. Default=off. For optimal HLS delivery disable this.
     tcp_nodelay on;             # on|off. Forces a socket to send the data in its buffer, whatever the packet size. Default=on.
     tcp_nopush on;              # on|off. Sends the response header and beginning of a file in one packet. Default=off.
     server_tokens off;          # on|off|build. Toggles showing nginx version in the response header field. Default=on.
     keepalive_timeout 65;           # A keep-alive client connection will stay open for .. on the server side. Use 0 to disable. Default=75s
     types_hash_max_size 2048;       # Sets the maximum size of the types hash tables. Default=1024.
     # server_name_in_redirect on;       # Toggles the use of the primary server name, specified by the server_name directive. Default=off.
     # server_names_hash_bucket_size 64; # Sets the bucket size for the server names hash tables depending on processor's cache line, 32|64|128.
     default_type application/octet-stream;  # Emit this MIME type for all requests.
 ## Include configuration files from these locations ## include /etc/nginx/mime.types; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*.conf;    # Holds symlinks to the actual config files in /etc/nginx/sites-available access_log /var/log/nginx/access.log;       # Set this here or in the virtual hosts config file in sites-available folder. error_log /var/log/nginx/error.log warn;    # Set this here or in the virtual hosts config file in sites-available folder. gzip on;            # on|off. Compresses responses using gzip method. Helps to reduce size of transmitted data by half or more. Default=off # gzip_vary on;         # More info on zip variables is found here: https://nginx.org/en/docs/http/ngx_http_gzip_module.html gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
 }
 EITHER SET YOUR SERVER {} BLOCK HERE, OR RATHER IN A SEPERATE VIRTUAL HOST CONFIG FILE IN /sites-available/yourdomain.conf
 RTMP CONFIGURATION STARTS HERE
 rtmp {
     server {
     listen 1935;        # The RTMP listening port. Open it in your router/firewall. Options: (addr[:port]|port|unix:path) [bind] [ipv6only=on|off] [so_keepalive=on|off|keepidle:keepintvl:keepcnt|proxy_protocol]
 application live {  # Name it whatever you prefer. You will need at least one application, you can have many more. live on;        # on|off. Enables this application and allowing live streaming to it. Default=on. # max_streams 32;   # Sets maximum number of RTMP streams. Default value is 32 which is usually ok for most cases. Default=32. # max_connections 100;  # Sets maximum number of connections for rtmp engine. Default=off.  meta on;        # on|copy|off. Receive metadata packets containing predefined fields like width, height etc. Default=on. interleave off;     # on|off. Audio and video data is transmitted on the same RTMP chunk stream. Default=off. wait_key on;        # on|off. Makes video stream start with a key frame. Default=off. wait_video off;     # on|off. Disable audio until first video frame is sent (can cause delay). Default=off. publish_notify off; # on|off. Send "NetStream.Play.PublishNotify" and "NetStream.Play.UnpublishNotify" to subscribers. Default=off.  drop_idle_publisher 10s;# Drop publisher that has been idle for this time. Only works when connection is in publish mode. Default=off sync 300ms;     # When timestamp difference exceeds the value specifiedan absolute frame is sent fixing that. Default=300ms. play_restart off;   # on|off. If enabled sends "NetStream.Play.Start" and "NetStream.Play.Stop" every time publishing starts or stops. Default=off. idle_streams on;    # on|off. If disabled prevents viewers from connecting to idle/nonexistent streams and disconnects all. Default=on. ## TRANSCODING USING FFMPEG EXEC ## ## The following lines will take our incoming RTMP stream and transcode it to several different HLS streams with variable bitrates  ## ## Once receive stream, transcode for adaptive streaming. This single ffmpeg command takes the input and transforms the source into ## ## 4 or 5 different streams with different bitrate and quality. P.S. The scaling done here respects the aspect ratio of the input.  ## ## EXEC - Many things are possible using exec. To learn more visit https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec   ## #exec ffmpeg -i rtmp://localhost/$app/$name  -async 1 -vsync -1 #-c:v libx264 -acodec copy -b:v 256k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_low #-c:v libx264 -acodec copy -b:v 768k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_mid #-c:v libx264 -acodec copy -b:v 1024k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_high #-c:v libx264 -acodec copy -b:v 1920k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_higher #-c copy -f flv rtmp://localhost/hls/$name_src;
 SET ACCESS RULES FOR APPLICATION /live
 PUBLISHING
 allow 127.0.0.1;        # If you decice to harden these rules, it is adviced to uncomment this line. # allow publish 192.168.2.0/24; # Anybody from this local IP address range can stream to this application. # allow publish 192.168.2.50;   # Allow a single IP address to stream to this application (multiple lines with different ip's are possible) allow publish all;      # Anybody from any location can stream to this application. Comment this out if you want to use deny publish. # deny publish 10.0.0.50;   # Deny this specific IP address from streaming to this application. Can also be an IP address range. # deny publish all;     # Nobody can stream to the server except those that you've set in previous lines.
 PLAYING
 allow play 127.0.0.1;       # Localhost can play the stream from this application. Must be set if you decide to use push later on! allow play 192.168.2.0/24;  # Anybody in this IP range can play the RTMP directly. allow play all;         # Anybody can play the RTMP livestream directly. Comment this out if you decide to use the next option. # deny play all;        # Nobody can play the RTMP stream except those that we've set in lines above it.
 RECORDING
 record off;         # off|all|audio|video|keyframes|manual. These options speak for themselves. record_path /tmp/rec;       # Folder location that will be used to store the recordings. YOU SHOULD CHANGE THIS TO YOUR PREFERENCE! record_suffix -%d-%b-%y-%T.flv; # Added to recorded filenames. Example uses 'strftime' format results: -24-Apr-13-18:23:38.flv. Default=.flv record_unique on;       # on|off. Appends timestamp to recorded files. Otherwise the same file is re-written each time. Default=-off record_append off;      # on|off. When turned on recorder appends new data to the old file with no gap. Default=off record_lock off;        # on|off. When turned on recorded file gets locked with 'fcntl' call. Default=off. record_notify off;      # on|off. Toggles sending "NetStream.Record.Start" and "NetStream.Record.Stop" status messages. Default=off. # record_max_size 128K;     # Set maximum file size of the recorded files. No default. # record_max_frames 200;    # Sets maximum number of video frames per recorded file. No default. # record_interval 15m;      # Restart recording after this number of (milli)seconds/minutes. Zero means no delay. Default=off. # recorder name {}      # Create recorder{} block. Multiple recorders can be created withing single application. Example: recorder audio {     record audio;     record_suffix .audio.flv;     record_path /tmp/rec/audio; }
 STREAM RELAYING LOCAL
 ## For more info please visit:  https://github.com/arut/nginx-rtmp-module/wiki/Directives#relay ## ## pull url [key=value]*    # Creates pull relay. A stream is pulled from remote machine and becomes available locally. ## ## URL Syntax:          [rtmp://]host[:port][/app[/playpath]] ## # pull rtmp://cdn.example.com/live/ch?id=1234 name=channel_a;       # This is an example. Visit above url for more info. # session_relay off;        # on|off. On=relay is destroyed when connection is closed. Off=relay is destroyed when stream is closed. Default=off. ## Push has the same syntax as pull. Unlike pull, push directive publishes stream to remote server. ## ## This will push the stream from current application to these two applications to create a hls and/or dash stream automatically. ## push rtmp://localhost/hls;  # Remember to create the app hls! Disable it if you use transcoding using variable bitrates. push rtmp://localhost/dash; # Remember to create the app dash! It is safe to disable this if you're not interested in using Dash.
 STREAM RELAYING TO EXTERNAL PARTY'S
 ## Push can also be used to re-stream your stream to other platforms. You can do this directly or use an additional application for this. ## ## Using an additional local application allows you to set up variables if you prefer. Or you can choose to push to 3rd party directly. ## ## YOUTUBE PUSH OPTIONS ## # push rmtp://localhost/youtube;        # Uncomment this to use application on localhost (MUST BE SPECIFIED). OR simply use the following line: # push rtmp://a.rtmp.youtube.com/live2/YOUR-LIVE-STREAM-KEY;        # Your RTMP stream will be pushed as it is to Youtube as an RTMP stream. # TWITCH PUSH OPTIONS ## # push rmtp://localhost/twitch;         # Uncomment this to use application on localhost (MUST BE SPECIFIED). OR simply use the following line: # push rtmp://live-ams.twitch.tv/app/live_YOUR-LIVE-STREAM-KEY;     # Your RTMP stream will be pushed as it is to Twitch as an RTMP stream. }
 HLS APPLICATION
 application hls {       # (See line 121) We enabled pushing stream from 'live' application to 'hls' we need to define it of course. live on;            # on|off. Enables this application and allowing live streaming to it. Default=on. hls on;             # on|off. Toggles HLS on or off for this application. hls_type live;          # live|event. Live plays from the current live position. Event plays from the start of the playlist. Default=live. hls_path /tmp/hls;      # Location to store the video fragment files. Will be created if it doesn't exist. hls_fragment 5s;        # Sets HLS fragment length in seconds or minutes. Default=5s. hls_playlist_length 30s;    # Sets HLS playlist length in seconds or minutes. Default=30s. hls_sync 2ms;           # Timestamp sync threshold. Prevents crackling noise after conversion from low-res (1KHz) to high-res(90KHz). Default=2ms. hls_continuous off;     # on|off. In this mode HLS sequence number is started from where it stopped last time. Old fragments are kept. Default=off. hls_nested on;          # on|off. In this mode a subdirectory of hls_path is created for each stream. Default=off. hls_cleanup on;         # on|off. Nginx cache manager process removes old HLS fragments and playlist files from hls_path. Default=on. hls_fragment_naming system; # system = use system time. sequential = use increasing integers. timestamp = use stream timestamp. Default=sequential. hls_fragment_slicing plain; # plain|aligned. Plain: switch fragment when target duration is reached. Aligned: switch fragment when incoming timestamp is a                 # multiple of fragment duration. Makes it possible to generate identical fragments on different nginx instances. Default=plain. ## ENCRYPTION KEYS  ## !! Only works if you have certificates defined in your HTTP server block (Usually a seperate file in /sites-available/yourfile.conf) # hls_keys on;          # on|off. Enables HLS encryption. AES-128 method is used to encrypt the HLS fragments. Requires ssl module. Default=off. hls_key_path /tmp/keys;     # Sets the directory where auto-generated HLS keys are saved. Default= hls_path. hls_fragments_per_key 100;  # Sets the number of HLS fragments encrypted with the same key. 0 means only one key is created at the publish start and                  # all fragments within the session are encrypted with this key. Default=0. #hls_key_url https://foo.bar/keys;  # Sets url for HLS key file entries. When empty it assumes hls_path. Default= empty. ## HLS_VARIANT - Used for variable bitrate streaming. Please read: https://github.com/arut/nginx-rtmp-module/wiki/Directives#hls_variant ## ## When hls_variant suffix is matched on stream name then variant playlist is created for the current stream with all entries specified by hls_variant ## directives in current application. Stripped name without suffix is used as variant stream name. The original stream is processed as usual. ## Optional parameters following the suffix are appended to EXT-X-STREAM-INF in m3u8 playlist. See HLS spec 3.3.10. EXT-X-STREAM-INF for full list.     hls_variant _low BANDWIDTH=288000;      # Low bitrate, sub-SD resolution    _low     hls_variant _mid BANDWIDTH=448000;      # Medium bitrate, SD resolution     _mid     hls_variant _high BANDWIDTH=1152000;        # Higher-than-SD resolution         _high      hls_variant _higher BANDWIDTH=2048000;      # High bitrate, HD 720p resolution  _higher     hls_variant _src BANDWIDTH=4096000;     # Source bitrate, source resolution     _src     }
 MPEG-DASH
 application dash {      # These variables will be used since we enabled pushing /live stream to this application (See line 122) live on;            # on|off. Enables this application and allowing live streaming to it. Default=on. dash on;            # on|off. Toggles MPEG-DASH on the current application. dash_path /tmp/dash;        # Location to store the video fragment files. Will be created if it doesn't exist. dash_fragment 5s;       # Sets DASH fragment length in seconds or minutes. Default= 5s. dash_playlist_length 30s;   # Sets MPEG-DASH playlist length. Defaults= 30s. dash_nested on;         # on|off. In this mode a subdirectory of dash_path is created for each stream. Default=off. dash_cleanup on;        # on|off. Nginx cache manager process removes old DASH fragments and playlist files from dash_path. Default=on. }
 TWITCH APPLICATION - Only required if you decide to re-stream using this application
     application twitch {             live on;     record off;     allow publish 127.0.0.1;     deny publish all;     push rtmp://ams02.contribute.live-video.net/app/YOUR_STREAM_KEY ## FIND YOUR OPTIMAL SERVER FIRST! (https://stream.twitch.tv/ingests/)     }
 YOUTUBE - Only required if you decide to re-stream using this application
 application youtube {     live on;     record off;     allow publish 127.0.0.1;     deny publish all;     push rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY; ## PLEASE REPLACE WITH SERVER CLOSEST TO YOU }
 LOGGING - This section has too many options to include. Please see https://github.com/arut/nginx-rtmp-module/wiki/Directives#access-log
 access_log /var/log/nginx/rtmp_access.log;  # off|path [format_name]. Default logging is done to same file as HTTP logger.
 NOTIFICATIONS  - This section has too many options to include.
 ## Notifications use HTTP callback to inform subscribers that stream has started. You will need a website that can handle these. ## ## These option go beyond the scope of this configuration file as it contains lots of info. Please visit this url for more info: ## ## https://github.com/arut/nginx-rtmp-module/wiki/Directives#notify ## # publish_notify on;    # on|off. Send "NetStream.Play.PublishNotify" and "NetStream.Play.UnpublishNotify" to subscribers. Default=off. # on_connect http://www.example.com/plugin/Live/on_publish.php;          # on_play http://www.example.com/plugin/Live/on_play.php; # on_record_done http://www.example.com/plugin/Live/on_record_done.php'; }   # CLOSING BRACKET SERVER BLOCK
 }    # CLOSING BRACKET RTMP BLOCK
## ====================================================================================================== ##
## Visit this page for a list of all variables: https://github.com/arut/nginx-rtmp-module/wiki/Directives ##
## Visit this site for many more configuration examples: https://github.com/arut/nginx-rtmp-module	      ##
## This example file was put together by Andre "ustoopia" for useage on https://youtube.com/ustoopia      ##
## ====================================================================================================== ##

user www-data;            # Only used on linux. Nginx will run under this username.
worker_processes 1;				# Set this to how many processors/cores the CPU has. Relates to "worker_connections".
pid /run/nginx.pid;				# Sets the location of the process id file (used on linux only).
include /etc/nginx/modules-enabled/*.conf;	# Include all the optional configuration files stored in this folder.

events {
	worker_connections 768;		# Worker_processes * worker_connections = max clients. So in this setup: 1 * 768 = 768 max clients.
	# multi_accept on;		# "Off" will accept 1 new connection at a time. "On" will accept all new connections. Default is off.
	}

http {
	sendfile off;				# on|off. Toggles the use of sendfile. Default=off. For optimal HLS delivery disable this.
	tcp_nodelay on;				# on|off. Forces a socket to send the data in its buffer, whatever the packet size. Default=on.
	tcp_nopush on;				# on|off. Sends the response header and beginning of a file in one packet. Default=off.
	server_tokens off;			# on|off|build. Toggles showing nginx version in the response header field. Default=on.
	keepalive_timeout 65;			# A keep-alive client connection will stay open for .. on the server side. Use 0 to disable. Default=75s
	types_hash_max_size 2048;		# Sets the maximum size of the types hash tables. Default=1024.
	# server_name_in_redirect on;		# Toggles the use of the primary server name, specified by the server_name directive. Default=off.
	# server_names_hash_bucket_size 64;	# Sets the bucket size for the server names hash tables depending on processor's cache line, 32|64|128.
	default_type application/octet-stream;	# Emit this MIME type for all requests.
	
	## Include configuration files from these locations ##
	include /etc/nginx/mime.types;
	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*.conf;	# Holds symlinks to the actual config files in /etc/nginx/sites-available

	access_log /var/log/nginx/access.log;		# Set this here or in the virtual hosts config file in sites-available folder.
	error_log /var/log/nginx/error.log warn;	# Set this here or in the virtual hosts config file in sites-available folder.
 
	gzip on;			# on|off. Compresses responses using gzip method. Helps to reduce size of transmitted data by half or more. Default=off
	# gzip_vary on;			# More info on zip variables is found here: https://nginx.org/en/docs/http/ngx_http_gzip_module.html
	gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	gzip_http_version 1.1;
	gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}

## EITHER SET YOUR SERVER {} BLOCK HERE, OR RATHER IN A SEPERATE VIRTUAL HOST CONFIG FILE IN /sites-available/yourdomain.conf ##

## RTMP CONFIGURATION STARTS HERE ##
rtmp {
	server {
	listen 1935;		# The RTMP listening port. Open it in your router/firewall. Options: (addr[:port]|port|unix:path) [bind] [ipv6only=on|off] [so_keepalive=on|off|keepidle:keepintvl:keepcnt|proxy_protocol]

	application live {	# Name it whatever you prefer. You will need at least one application, you can have many more.
	live on;		# on|off. Enables this application and allowing live streaming to it. Default=on.
	# max_streams 32;	# Sets maximum number of RTMP streams. Default value is 32 which is usually ok for most cases. Default=32.
	# max_connections 100;	# Sets maximum number of connections for rtmp engine. Default=off. 
	meta on;		# on|copy|off. Receive metadata packets containing predefined fields like width, height etc. Default=on.
	interleave off;		# on|off. Audio and video data is transmitted on the same RTMP chunk stream. Default=off.
	wait_key on;		# on|off. Makes video stream start with a key frame. Default=off.
	wait_video off;		# on|off. Disable audio until first video frame is sent (can cause delay). Default=off.
	publish_notify off;	# on|off. Send "NetStream.Play.PublishNotify" and "NetStream.Play.UnpublishNotify" to subscribers. Default=off. 
	drop_idle_publisher 10s;# Drop publisher that has been idle for this time. Only works when connection is in publish mode. Default=off
	sync 300ms;		# When timestamp difference exceeds the value specifiedan absolute frame is sent fixing that. Default=300ms.
	play_restart off;	# on|off. If enabled sends "NetStream.Play.Start" and "NetStream.Play.Stop" every time publishing starts or stops. Default=off.
	idle_streams on;	# on|off. If disabled prevents viewers from connecting to idle/nonexistent streams and disconnects all. Default=on.

	## TRANSCODING USING FFMPEG EXEC ##
	## The following lines will take our incoming RTMP stream and transcode it to several different HLS streams with variable bitrates  ##
	## Once receive stream, transcode for adaptive streaming. This single ffmpeg command takes the input and transforms the source into ##
	## 4 or 5 different streams with different bitrate and quality. P.S. The scaling done here respects the aspect ratio of the input.  ##
	## EXEC - Many things are possible using exec. To learn more visit https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec   ##

	#exec ffmpeg -i rtmp://localhost/$app/$name  -async 1 -vsync -1
	#-c:v libx264 -acodec copy -b:v 256k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_low
	#-c:v libx264 -acodec copy -b:v 768k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_mid
	#-c:v libx264 -acodec copy -b:v 1024k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_high
	#-c:v libx264 -acodec copy -b:v 1920k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 60 -hls_list_size 0 -f flv rtmp://localhost/hls/$name_higher
	#-c copy -f flv rtmp://localhost/hls/$name_src;

## SET ACCESS RULES FOR APPLICATION /live  ##
## PUBLISHING ##
	allow 127.0.0.1;		# If you decice to harden these rules, it is adviced to uncomment this line.
	# allow publish 192.168.2.0/24;	# Anybody from this local IP address range can stream to this application.
	# allow publish 192.168.2.50;	# Allow a single IP address to stream to this application (multiple lines with different ip's are possible)
	allow publish all;		# Anybody from any location can stream to this application. Comment this out if you want to use deny publish.
	# deny publish 10.0.0.50;	# Deny this specific IP address from streaming to this application. Can also be an IP address range.
	# deny publish all;		# Nobody can stream to the server except those that you've set in previous lines.
## PLAYING  ##
	allow play 127.0.0.1;		# Localhost can play the stream from this application. Must be set if you decide to use push later on!
	allow play 192.168.2.0/24;	# Anybody in this IP range can play the RTMP directly.
	allow play all;			# Anybody can play the RTMP livestream directly. Comment this out if you decide to use the next option.
	# deny play all;		# Nobody can play the RTMP stream except those that we've set in lines above it.

## RECORDING  ##
	record off;			# off|all|audio|video|keyframes|manual. These options speak for themselves.
	record_path /tmp/rec;		# Folder location that will be used to store the recordings. YOU SHOULD CHANGE THIS TO YOUR PREFERENCE!
	record_suffix -%d-%b-%y-%T.flv;	# Added to recorded filenames. Example uses 'strftime' format results: -24-Apr-13-18:23:38.flv. Default=.flv
	record_unique on;		# on|off. Appends timestamp to recorded files. Otherwise the same file is re-written each time. Default=-off
	record_append off;		# on|off. When turned on recorder appends new data to the old file with no gap. Default=off
	record_lock off;		# on|off. When turned on recorded file gets locked with 'fcntl' call. Default=off.
	record_notify off;		# on|off. Toggles sending "NetStream.Record.Start" and "NetStream.Record.Stop" status messages. Default=off.
	# record_max_size 128K;		# Set maximum file size of the recorded files. No default.
	# record_max_frames 200;	# Sets maximum number of video frames per recorded file. No default.
	# record_interval 15m;		# Restart recording after this number of (milli)seconds/minutes. Zero means no delay. Default=off.
	# recorder name	{}		# Create recorder{} block. Multiple recorders can be created withing single application. Example:
	recorder audio {
		record audio;
		record_suffix .audio.flv;
		record_path /tmp/rec/audio;
	}

## STREAM RELAYING LOCAL ##
	## For more info please visit:	https://github.com/arut/nginx-rtmp-module/wiki/Directives#relay ##
	## pull url [key=value]*	# Creates pull relay. A stream is pulled from remote machine and becomes available locally. ##
	## URL Syntax:			[rtmp://]host[:port][/app[/playpath]] ##
	# pull rtmp://cdn.example.com/live/ch?id=1234 name=channel_a;		# This is an example. Visit above url for more info.
	# session_relay off;		# on|off. On=relay is destroyed when connection is closed. Off=relay is destroyed when stream is closed. Default=off.

	## Push has the same syntax as pull. Unlike pull, push directive publishes stream to remote server. ##
	## This will push the stream from current application to these two applications to create a hls and/or dash stream automatically. ##

	push rtmp://localhost/hls;	# Remember to create the app hls! Disable it if you use transcoding using variable bitrates.
	push rtmp://localhost/dash;	# Remember to create the app dash! It is safe to disable this if you're not interested in using Dash.


## STREAM RELAYING TO EXTERNAL PARTY'S ##
	## Push can also be used to re-stream your stream to other platforms. You can do this directly or use an additional application for this. ##
	## Using an additional local application allows you to set up variables if you prefer. Or you can choose to push to 3rd party directly. ##

	## YOUTUBE PUSH OPTIONS ##
	# push rmtp://localhost/youtube;		# Uncomment this to use application on localhost (MUST BE SPECIFIED). OR simply use the following line:
	# push rtmp://a.rtmp.youtube.com/live2/YOUR-LIVE-STREAM-KEY;		# Your RTMP stream will be pushed as it is to Youtube as an RTMP stream.

	# TWITCH PUSH OPTIONS ##
	# push rmtp://localhost/twitch;			# Uncomment this to use application on localhost (MUST BE SPECIFIED). OR simply use the following line:
	# push rtmp://live-ams.twitch.tv/app/live_YOUR-LIVE-STREAM-KEY;		# Your RTMP stream will be pushed as it is to Twitch as an RTMP stream.
	}

## HLS APPLICATION ##
	application hls {		# (See line 121) We enabled pushing stream from 'live' application to 'hls' we need to define it of course.
	live on;			# on|off. Enables this application and allowing live streaming to it. Default=on.
	hls on;				# on|off. Toggles HLS on or off for this application.
	hls_type live;			# live|event. Live plays from the current live position. Event plays from the start of the playlist. Default=live.
	hls_path /tmp/hls;		# Location to store the video fragment files. Will be created if it doesn't exist.
	hls_fragment 5s;		# Sets HLS fragment length in seconds or minutes. Default=5s.
	hls_playlist_length 30s;	# Sets HLS playlist length in seconds or minutes. Default=30s.
	hls_sync 2ms;			# Timestamp sync threshold. Prevents crackling noise after conversion from low-res (1KHz) to high-res(90KHz). Default=2ms.
	hls_continuous off;		# on|off. In this mode HLS sequence number is started from where it stopped last time. Old fragments are kept. Default=off.
	hls_nested on;			# on|off. In this mode a subdirectory of hls_path is created for each stream. Default=off.
	hls_cleanup on;			# on|off. Nginx cache manager process removes old HLS fragments and playlist files from hls_path. Default=on.
	hls_fragment_naming system;	# system = use system time. sequential = use increasing integers. timestamp = use stream timestamp. Default=sequential.
	hls_fragment_slicing plain;	# plain|aligned. Plain: switch fragment when target duration is reached. Aligned: switch fragment when incoming timestamp is a
					# multiple of fragment duration. Makes it possible to generate identical fragments on different nginx instances. Default=plain.

	## ENCRYPTION KEYS	## !! Only works if you have certificates defined in your HTTP server block (Usually a seperate file in /sites-available/yourfile.conf)
	# hls_keys on;			# on|off. Enables HLS encryption. AES-128 method is used to encrypt the HLS fragments. Requires ssl module. Default=off.
	hls_key_path /tmp/keys;		# Sets the directory where auto-generated HLS keys are saved. Default= hls_path.
	hls_fragments_per_key 100;	# Sets the number of HLS fragments encrypted with the same key. 0 means only one key is created at the publish start and 
					# all fragments within the session are encrypted with this key. Default=0.
	#hls_key_url https://foo.bar/keys;	# Sets url for HLS key file entries. When empty it assumes hls_path. Default= empty.

	## HLS_VARIANT - Used for variable bitrate streaming. Please read: https://github.com/arut/nginx-rtmp-module/wiki/Directives#hls_variant ##
	## When hls_variant suffix is matched on stream name then variant playlist is created for the current stream with all entries specified by hls_variant
	## directives in current application. Stripped name without suffix is used as variant stream name. The original stream is processed as usual.
	## Optional parameters following the suffix are appended to EXT-X-STREAM-INF in m3u8 playlist. See HLS spec 3.3.10. EXT-X-STREAM-INF for full list.

		hls_variant _low BANDWIDTH=288000;		# Low bitrate, sub-SD resolution 	_low
		hls_variant _mid BANDWIDTH=448000;		# Medium bitrate, SD resolution 	_mid
		hls_variant _high BANDWIDTH=1152000;		# Higher-than-SD resolution 		_high 
		hls_variant _higher BANDWIDTH=2048000;		# High bitrate, HD 720p resolution 	_higher
		hls_variant _src BANDWIDTH=4096000;		# Source bitrate, source resolution 	_src
		}

## MPEG-DASH ##
	application dash {		# These variables will be used since we enabled pushing /live stream to this application (See line 122)
	live on;			# on|off. Enables this application and allowing live streaming to it. Default=on.
	dash on;			# on|off. Toggles MPEG-DASH on the current application.
	dash_path /tmp/dash;		# Location to store the video fragment files. Will be created if it doesn't exist.
	dash_fragment 5s;		# Sets DASH fragment length in seconds or minutes. Default= 5s.
	dash_playlist_length 30s;	# Sets MPEG-DASH playlist length. Defaults= 30s.
	dash_nested on;			# on|off. In this mode a subdirectory of dash_path is created for each stream. Default=off.
	dash_cleanup on;		# on|off. Nginx cache manager process removes old DASH fragments and playlist files from dash_path. Default=on.
	}

## TWITCH APPLICATION - Only required if you decide to re-stream using this application ##
        application twitch {		
		live on;
		record off;
		allow publish 127.0.0.1;
		deny publish all;
		push rtmp://ams02.contribute.live-video.net/app/YOUR_STREAM_KEY ## FIND YOUR OPTIMAL SERVER FIRST! (https://stream.twitch.tv/ingests/)
        }

## YOUTUBE - Only required if you decide to re-stream using this application ##
	application youtube {
		live on;
		record off;
		allow publish 127.0.0.1;
		deny publish all;
		push rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY; ## PLEASE REPLACE WITH SERVER CLOSEST TO YOU
	}

## LOGGING - This section has too many options to include. Please see https://github.com/arut/nginx-rtmp-module/wiki/Directives#access-log ##
	access_log /var/log/nginx/rtmp_access.log;	# off|path [format_name]. Default logging is done to same file as HTTP logger.


## NOTIFICATIONS  - This section has too many options to include. ##
	## Notifications use HTTP callback to inform subscribers that stream has started. You will need a website that can handle these. ##
	## These option go beyond the scope of this configuration file as it contains lots of info. Please visit this url for more info: ##
	## https://github.com/arut/nginx-rtmp-module/wiki/Directives#notify ##

	# publish_notify on;	# on|off. Send "NetStream.Play.PublishNotify" and "NetStream.Play.UnpublishNotify" to subscribers. Default=off.
	# on_connect http://www.example.com/plugin/Live/on_publish.php;			
	# on_play http://www.example.com/plugin/Live/on_play.php;
	# on_record_done http://www.example.com/plugin/Live/on_record_done.php';

	}	# CLOSING BRACKET SERVER BLOCK
}	# CLOSING BRACKET RTMP BLOCK

Table of Contents