Publishes incoming KMP tracks to an upstream server using the RTMP protocol.
Dependencies: nginx-common, nginx-kmp-in-module.
-
Input
- Protocol: KMP
- Codecs:
- Video: h264 / AVC
- Audio: AAC, MP3
-
Output protocol: RTMP
-
Dynamic configuration - passed in the data of the KMP
connect
packet - see Connect Data JSON for more details -
Support for publishing multiple tracks and multiple streams on a single RTMP connection - incoming KMP tracks are grouped according the
upstream_id
that is set in the KMP connect data. -
Support for sending RTMP
onFI
messages (containing absolute timestamps) -
Support for HTTP notifications (sent on RTMP connection close)
-
Management API
-
track - a single rendition of video/audio.
-
stream - an RTMP message stream, created using the RTMP
createStream
command, published using the RTMPpublish
command, etc. An RTMP stream can contain at most one video track and one audio track. An RTMP stream is automatically created when the first track is connected to the stream, and automatically destroyed when the last track disconnects. -
upstream - an RTMP connection to an upstream server. Multiple streams/tracks can be sent on a single upstream connection. An RTMP upstream object is created automatically when the first track is connected to it, and destroyed when the last track disconnects.
Important: this module assumes that the upstream RTMP server allocates stream ids in incremental numbers starting from 1.
To put it differently, this module does not parse the response of the createStream
command (or anything else returned from the upstream, following the RTMP handshake).
If this assumption does not hold for the specific upstream server to which the stream is published, the stream is likely to be rejected.
stream {
server {
listen 8005;
resolver 8.8.8.8;
kmp_rtmp;
}
}
http {
server {
listen 8001;
location /kmp_rtmp_api/ {
kmp_rtmp_api write=on;
}
}
}
- syntax:
kmp_rtmp_api [write=on|off];
- default:
none
- context:
location
Enables the API interface of this module in the surrounding location block. Access to this location should be limited.
The optional write
parameter determines whether the API is read-only or read-write. By default, the API is read-only.
- syntax:
kmp_rtmp;
- default: ``
- context:
server
Enables the media interface of this module in the surrounding server block.
- syntax:
kmp_rtmp_in_read_timeout msec;
- default:
20s
- context:
stream
,server
Defines a timeout for reading from the client connection. The timeout is set only between two successive read operations, not for the transmission of the whole stream. If the client does not transmit anything within this time, the connection is closed.
- syntax:
kmp_rtmp_in_send_timeout msec;
- default:
10s
- context:
stream
,server
Sets a timeout for sending acks back to the client. The timeout is set only between two successive write operations. If the client does not receive anything within this time, the connection is closed.
- syntax:
kmp_rtmp_in_mem_limit size;
- default:
256k
- context:
stream
,server
Sets the maximum total size of the buffers used to receive from the client.
If the limit is hit, the module drops the KMP connection.
This memory limit applies until the KMP connect
data is read from the client,
at this point, the KMP connection is linked to an upstream object,
and the memory usage tracking moves to the upstream level (kmp_rtmp_out_mem_limit
)
- syntax:
kmp_rtmp_in_buffer_size size;
- default:
64k
- context:
stream
,server
Sets the size of the buffers used to read video / audio data from the client connection.
- syntax:
kmp_rtmp_in_buffer_bin_count num;
- default:
8
- context:
stream
,server
Sets the number of bins that are used to group the input video / audio buffers. The buffers are grouped in bins according to the number of allocated blocks they contain. When allocating a block, the allocator prefers to use buffers that are more utilized. This is done in order to concentrate the allocated blocks in fewer buffers, and enable the allocator to free unused buffers.
- syntax:
kmp_rtmp_in_max_free_buffers num;
- default:
4
- context:
stream
,server
Sets the maximum number of free input buffers that are kept after they are copied. A large value may save some memory alloc/free operations, but can also increase memory usage.
- syntax:
kmp_rtmp_in_log_frames all | key | off;
- default:
off
- context:
stream
,server
When enabled, the module logs the metadata of every frame that is received -
- KMP frame header - created, dts, flags, pts delay
- Data size and MD5 hash
The value key
can be used to log only the metadata of video keyframes.
- syntax:
kmp_rtmp_in_dump_folder path;
- default: ``
- context:
stream
,server
When set to a non-empty string, the module saves all incoming KMP data to files under the specified folder.
The file names have the following structure: ngx_live_kmp_dump_{date}_{pid}_{connection}.dat
.
- syntax:
kmp_rtmp_out_notif_url url;
- default: ``
- context:
stream
,server
Sets an HTTP notification callback. The callback is invoked when the RTMP upstream is destroyed.
Sample request body:
{
"event_type": "rtmp_close",
"reason": "done",
"upstream_id": "id1",
"url": "rtmp://127.0.0.1:1935/app/stream",
"header": "",
"opaque": ""
}
The field event_type
always has the string value rtmp_close
.
The fields upstream_id
, url
, header
, opaque
have the values specified in the connect data JSON.
The reason
field in the request can have the following values -
done
- the upstream no longer contains any active streams, and all pending data was sentapi_delete
- the upstream was deleted via the management APIstart_resolve_failed
- a hostname was used in the url, and no resolver was configured / error allocating resolver contextresolve_failed
- failed to resolve the hostname of the upstream URLhandshake_failed
- RTMP handshake error, can be due to TCP connect error / receive error / receive timeout / invalid response received from upstreamsend_failed
- error sending to the RTMP upstreamrecv_failed
- error receiving from the RTMP upstreamget_buf_failed
- error allocating an input buffer / input memory limit reachedalloc_chain_failed
- error allocating a chain for for holding an input bufferadd_media_info_failed
- error allocating the extra data of the codecstart_connect_failed
- error creating / setting up a socket or nginx connectionalloc_failed
- error copying connect data fields (url
,header
etc.) to the upstream objectflush_failed
- error allocating / sending buffercreate_stream_failed
- error allocating stream object / buffers for stream publish commandsunpublish_stream_failed
- error allocating buffers for stream unpublish commandswrite_connect_failed
- error allocating buffers for RTMP connect messagewrite_meta_failed
- error allocating buffers for RTMP stream metadata (media info)create_track_failed
- error allocating track object / initial frame list partmem_limit_exceeded
- track could not be added to the upstream, as the memory used by its input buffers exceeds the available quota on the upstreampush_frame_failed
- error pushing a frame to the pending queue of the trackprocess_frame_failed
- error allocating output buffer / chain, possibly due to upstream memory limit
- syntax:
kmp_rtmp_out_notif_add_header name value;
- default: ``
- context:
stream
,server
Adds a request header to notification requests.
There could be several kmp_rtmp_out_notif_add_header
directives.
These directives are inherited from the previous level if and only if there are no kmp_rtmp_out_notif_add_header
directives defined on the current level.
- syntax:
kmp_rtmp_out_notif_timeout msec;
- default:
2s
- context:
stream
,server
Sets a timeout for sending notification requests. The timeout includes both the connection establishment as well as the sending of the request.
- syntax:
kmp_rtmp_out_notif_read_timeout msec;
- default:
20s
- context:
stream
,server
Sets a timeout for reading the response of notification requests.
- syntax:
kmp_rtmp_out_notif_buffer_size size;
- default:
4k
- context:
stream
,server
Sets the size of the buffer that holds the response of the notification requests.
- syntax:
kmp_rtmp_out_mem_limit size;
- default:
16m
- context:
stream
,server
Sets the maximum size of memory used by each upstream.
The value should be large enough to hold the pending input frames until they are processed (see min_process_delay
),
as well as the RTMP output buffers until they are sent.
If the limit is hit, the module drops the upstream RTMP connection and all its input KMP connections.
- syntax:
kmp_rtmp_out_max_free_buffers num;
- default:
4
- context:
stream
,server
Sets the maximum number of free output buffers that are kept after being sent to the upstream server. A large value may save some memory alloc/free operations, but can also increase memory usage.
- syntax:
kmp_rtmp_out_timeout msec;
- default:
10s
- context:
stream
,server
Sets the timeout for sending data to the upstream RTMP server. The timeout is set only between two successive write operations.
- syntax:
kmp_rtmp_out_flush_timeout msec;
- default:
500ms
- context:
stream
,server
Sets the timeout for flushing buffered data to the upstream RTMP server.
RTMP output data is kept in buffers of size kmp_rtmp_out_buffer_size
, a buffer is sent when it becomes full, or when the flush timeout expires.
- syntax:
kmp_rtmp_out_buffer_size size;
- default: ``
- context:
stream
,server
Sets the size of the buffers used to send data to the upstream server. A large value can be more efficient, but increases the latency (a buffer is sent either when it's full or the flush timeout expires).
- syntax:
kmp_rtmp_out_buffer_bin_count num;
- default: ``
- context:
stream
,server
Sets the number of bins that are used to group the output buffers. The buffers are grouped in bins according to the number of allocated blocks they contain. When allocating a block, the allocator prefers to use buffers that are more utilized. This is done in order to concentrate the allocated blocks in fewer buffers, and enable the allocator to free unused buffers.
- syntax:
kmp_rtmp_out_flash_ver str;
- default:
FMLE/3.0 (compatible; KalturaLive/{version})
- context:
stream
,server
Sets the default flashVer
value that is sent in the RTMP connect command.
This default can be overridden per-upstream by supplying the flash_ver
field in the connect data JSON.
- syntax:
kmp_rtmp_out_chunk_size size;
- default:
64k
- context:
stream
,server
Sets the size of the RTMP chunks sent to the upstream server. The value must be in the range 128 .. 16777215.
- syntax:
kmp_rtmp_out_write_meta_timeout msec;
- default:
3s
- context:
stream
,server
Sets the timeout for sending the RTMP @onMetaData
packet for an RTMP stream.
The metadata of the stream includes both video and audio parameters.
When a stream has both video and audio data, the metadata is sent immediately.
However, if a stream gets only video data, for example, the module will wait, in order to give the audio a chance to arrive.
If the audio arrives after the metadata was already sent, the module will reject the incoming KMP connection.
- syntax:
kmp_rtmp_out_min_process_delay msec;
- default:
500ms
- context:
stream
,server
Sets the minimum amount of time an incoming frame waits in queue before being processed. When a stream has both video and audio tracks, the respective RTMP packets are multiplexed according to their timestamps, each packet reports the delta from the previous video / audio packet. Delaying the processing of input frames enables the module to sort the frames according to their timestamps. To put it differently - the fact that video frame X has a timestamp lower than audio frame Y, doesn't necessarily mean that frame X will be read by this module before frame Y.
- syntax:
kmp_rtmp_out_max_process_delay msec;
- default:
1s
- context:
stream
,server
Sets the maximum amount of time an incoming frame waits in queue before being processed. Normally, the module processes the frame that has the lowest timestamp out of the frames pending in the queue. This behavior creates a risk of starvation - if the timestamps (both audio and video) jump backwards, one of the tracks will get to the timestamp jump first. From that point on, that track will always be chosen, since its top frame has a lower timestamp. Capping the processing delay prevents this starvation - at some point the track that did not reach the jump will exceed the max processing delay, and will be chosen. This enables the track to reach the jump, and once that happens, processing will continue normally.
- syntax:
kmp_rtmp_out_onfi_period msec;
- default:
5s
- context:
stream
,server
Sets the period for sending RTMP onFI
messages, containing the absolute KMP created
timestamp.
This can be useful since RTMP timestamps wrap around every ~49 days.
If the period is set to zero, no onFI
messages are sent.
- syntax:
kmp_rtmp_out_dump_folder path;
- default: ``
- context:
stream
,server
When set to a non-empty string, the module saves the raw data received from the RTMP upstream to a file under the specified folder.
The file names have the following structure: ngx_kmp_rtmp_dump_{date}_{upstream_id}_{connection}.dat
.
This can be used in order to inspect error messages returned from the upstream.
{
"upstream_id": "ch1-twitch",
"url": "rtmp://live.twitch.tv:1935/app/live_123456789_abcdefABCDEF12345",
"opaque": "{\"remote_id\":\"123456789\"}"
}
The KMP connect data of incoming connections must be a JSON object containing the following fields:
upstream_id
- string, required, identifies the RTMP upstream. All incoming KMP tracks that have the sameupstream_id
share a single RTMP connection.url
- string, required, the upstream RTMP URL. The URL has the format:rtmp://{host}:{port}/{app}/{stream}
, thertmp://
prefix is optional.header
- string, optional, sent on the upstream TCP connection upon establishment. Can be used to send additional parameters when the RTMP connection goes through a proxy. One sample use case, is pushing to a local nginx stream proxy, in order to publish usingRTMPS
.opaque
- string, optional, can be used to store arbitrary data on the upstream object.app
- string, optional, the RTMP application name. By default, the application name is extracted from theurl
.name
- string, optional, the RTMP stream name. By default, the stream name is extracted from theurl
.flash_ver
- string, optional, sets the value of theflashVer
field of the RTMPconnect
message. By default, the module uses the value set using thekmp_rtmp_out_flash_ver
directive.swf_url
- string, optional, sets the value of theswfUrl
field of the RTMPconnect
message. By default, an empty string is sent.tc_url
- string, optional, sets the value of thetcUrl
field of the RTMPconnect
message. By default, the module uses the value ofurl
, excluding the stream name part (=up to the application name).page_url
- string, optional, sets the value of thepageUrl
field of the RTMPconnect
message. By default, an empty string is sent.
If an upstream with the id upstream_id
exists when the track is added, most of the fields listed above are ignored.
The only fields that are used in this case (other than upstream_id
) are:
name
- if specified, or -url
- ifname
is not specified (note that only the{stream}
part of theurl
is used)
The sections below list the possible fields in each type of API object.
version
- string, nginx-kmp-rtmp-module versionnginx_version
- string, nginx versioncompiler
- string, the compiler used to build nginx-kmp-rtmp-modulebuilt
- string, the time nginx-kmp-rtmp-module was builtpid
- integer, the nginx process iduptime
- integer, the time since the nginx worker was started, in secondsupstreams
- object, the keys are upstream ids, the values are Upstream Objects
url
- string, the url of the upstream RTMP connectionheader
- string, theheader
value that was set on the connect data JSONopaque
- string, theopaque
value that was set on the connect data JSONremote_addr
- string, the ip + port of the remote peerlocal_addr
- string, the local ip + port of the connectionconnection
- integer, the nginx connection identifier, unique per nginx worker processmem_limit
- integer, maximum number of memory bytes the upstream object is allowed to consumemem_left
- integer, number of memory bytes left out of themem_limit
quotawritten_bytes
- integer, the total number of bytes written to the output queue of the upstreamsent_bytes
- integer, the total number of bytes that were sent to the RTMP upstreamreceived_bytes
- integer, the total number of bytes that were received from the RTMP upstreamstreams
- object, the keys are RTMP stream names, the values are Stream Objects
id
- integer, the RTMP message stream id (msid) of the streamuptime
- integer, the time that passed since the stream was created, in secondstracks
- object, the keys hold the media type (video
/audio
), the values are Track Objects
pending_frames
- integer, the number of frames in the pending queue of the trackmem_used
- integer, the number of used bytes in the input buffer queue of the trackinput
- object | null, returns statistics about the KMP input currently connected to the track. See Input Object for more details.null
is returned if no input connection is currently connected to the track.
Get the full status JSON.
Possible status codes:
- 200 - Success, returns a JSON object
Get the status of all active upstreams.
Possible status codes:
- 200 - Success, returns a JSON object
Get the ids of all active upstreams.
Possible status codes:
- 200 - Success, returns a JSON array of strings
Get the status of the specified upstream.
Possible status codes:
- 200 - Success, returns a JSON object
- 404 - No upstream matching the provided id was found
Drop an upstream by id, including all the associated KMP input connections.
Possible status codes:
- 204 - Success, connection was dropped
- 404 - No upstream matching the provided id was found
Get the status of the RTMP streams of the specified upstream.
Possible status codes:
- 200 - Success, returns a JSON object
- 404 - No upstream matching the provided id was found
Get the ids of the RTMP streams of the specified upstream.
Possible status codes:
- 200 - Success, returns a JSON array of strings
- 404 - No upstream matching the provided id was found
Drop an incoming KMP connection by id.
Possible status codes:
- 204 - Success, connection was dropped
- 400 - The provided connection id is not a number
- 404 - No upstream / connection matching the provided ids were found