npm package: @slyoldfox/rtsp-stream
Description: A serial multiplexer for encoding or decoding RTSP streams
Author: Thomas Watson Steen
Latest version: 1.0.1

# rtsp-stream

A transport agnostic RTSP serial multiplexer module for Node. Use it to
encode or decode RTSP data streams.

This project aims for 100% compliance with [RFC
2326](https://tools.ietf.org/html/rfc2326). If you find something
missing, please [open an
issue](https://github.com/watson/rtsp-stream/issues).

Protocol features currently supported:

- Client to server requests/responses
- Server to client requests/responses
- Persistent transport connections
- Connectionless mode (this is just data stream parsing, so sessions
  must be handled elsewhere)
- Pipelining

Protocol features that are out of scope for this module:

- Session handling

[![Build status](https://travis-ci.org/watson/rtsp-stream.svg?branch=master)](https://travis-ci.org/watson/rtsp-stream)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)

## Installation

```
npm install rtsp-stream
```

## Usage

Let's set up a TCP server, listen on port 5000 and have it respond to
RTSP requests:

```js
var net = require('net')
var rtsp = require('rtsp-stream')

var server = net.createServer(function (socket) {
  var decoder = new rtsp.Decoder()
  var encoder = new rtsp.Encoder()

  decoder.on('request', function (req) {
    console.log(req.method, req.uri)

    // output the request body
    req.pipe(process.stdout)

    req.on('end', function () {
      // prepare a new response to the client
      var res = encoder.response()

      res.setHeader('CSeq', req.headers['cseq'])
      res.end('Hello World!')
    })
  })

  // pipe the data from the client into the decoder
  socket.pipe(decoder)

  // ...and pipe the response back to the client from the encoder
  encoder.pipe(socket)
})

server.listen(5000)
```

### Server -> Client request

In some scenarios the server will make a request to the client. Here is
what the RFC [have to say](https://tools.ietf.org/html/rfc2326#page-28)
about that:

> Unlike HTTP, RTSP allows the media server to send requests to the
> media client. However, this is only supported for persistent
> connections, as the media server otherwise has no reliable way of
> reaching the client. Also, this is the only way that requests from
> media server to client are likely to traverse firewalls.

In the example below, the server sends two request to the client using
the `Encoder` object:

```js
decoder.on('response', function (res) {
  console.log('Response to CSeq %s (code %s)', res.headers['cseq'], res.statusCode)

  // output the response body
  res.pipe(process.stdout)
})

var body = 'Hello World!'
var options = {
  method: 'OPTIONS',
  uri: '*',
  headers: {
    CSeq: 1,
    'Content-Length': Buffer.byteLength(body)
  }
  body: body
}

encoder.request(options, function () {
  console.log('done sending request 1 to client')
})

var req = encoder.request({ method: 'OPTIONS', uri: '*' })
req.setHeader('CSeq', 2)
req.setHeader('Content-Length', Buffer.byteLength(body))
req.end(body)
```

## API

The rtsp-stream module exposes the following:

- `STATUS_CODES` - List of valid RTSP status codes
- `Decoder` - The decoder object
- `Encoder` - The encoder object
- `IncomingMessage` - A readable stream representing an incoming RTSP
  message. Can be either a request or a response. Given as the first
  argument to the `Decoder` request and response event
- `OutgoingMessage` - A writable stream representing an outgoing RTSP
  message. Can be either a request or a response
- `Request` - A writable stream of type `OutgoingMessage` representing
  an outgoing RTSP request. Generated by `encoder.request()`
- `Response` - A writable stream of type `OutgoingMessage` representing
  an outgoing RTSP response. Generated by `encoder.response()`

### `Decoder`

A writable stream used to parse incoming RTSP data. Emits the following
events:

#### Event: request

Emitted every time a new request header is found. The event listener is
called with a single arguemnt:

- `req` - An `rtspStream.IncomingMessage` object

#### Event: response

Emitted every time a new response header is found. The event listener is
called with a single arguemnt:

- `res` - An `rtspStream.IncomingMessage` object

### `Encoder`

A readable stream. Outputs valid RTSP responses.

#### `Encoder.response()`

Returns a writable stream of type `Response`.

#### `Encoder.request()`

Returns a writable stream of type `Request`.

### `IncomingMessage`

Exposes the body of the incoming RTSP message by implementing a readable
stream interface.

Also exposes the RTSP start-line using the following properties:

#### `IncomingMessage.rtspVersion`

The RTSP protocol version used in the message. By all intents and
purposes you can expect this to always be `1.0`.

#### `IncomingMessage.method`

*Only used if the message is a request*

The RTSP request method used in the request. The following are
standardized in [RFC 2326](https://tools.ietf.org/html/rfc2326), but
others are also used in the wild:

- `DESCRIBE`
- `ANNOUNCE`
- `GET_PARAMETER`
- `OPTIONS`
- `PAUSE`
- `PLAY`
- `RECORD`
- `SETUP`
- `SET_PARAMETER`
- `TEARDOWN`

#### `IncomingMessage.uri`

*Only used if the message is a request*

The RTSP request URI used.

#### `IncomingMessage.statusCode`

*Only used if the message is a response*

The RTSP response code used.

#### `IncomingMessage.statusMessage`

*Only used if the message is a response*

The message matching the RTSP response code used.

#### `IncomingMessage.headers`

An object containing the headers used on the RTSP request. Object keys
represent header fields and the object values the header values.

All header field names are lowercased for your convenience.

Values from repeating header fields are joined in an array.

### `OutgoingMessage`

A writable stream representing an outgoing RTSP message. Can be either a
request or a response.

#### `OutgoingMessage.headersSent`

A boolean. `true` if the response headers have flushed.

#### `OutgoingMessage.setHeader(name, value)`

Set a header to be sent along with the RTSP response body. Throws an
error if called after the headers have been flushed.

#### `OutgoingMessage.getHeader(name)`

Get a header value. Case insensitive.

#### `OutgoingMessage.removeHeader(name)`

Remove a header so it is not sent to the client. Case insensitive.
Throws an error if called after the headers have been flushed.

### `Request`

A writable stream of type `OutgoingMessage` representing an outgoing
RTSP request. Generated by `encoder.request()`.

### `Response`

A writable stream of type `OutgoingMessage` representing an outgoing
RTSP response. Generated by `encoder.response()`.

#### `Response.statusCode`

The status code used in the response. Defaults to `200`. For alist of
valid status codes see the `rtspStream.STATUS_CODES` object.

#### `Response.writeHead([statusCode[, statusMessage][, headers]])`

Force writing of the RTSP response headers to the client. Will be called
automatically on the first to call to either `response.write()` or
`response.end()`.

Throws an error if called after the headers have been flushed.

Arguments:

- `statusCode` - Set a custom status code (overrides the
  `response.statusCode` property)
- `statusMessage` - Set a custom status message related to the status
  code (e.g. the default status message for the status code `200` is
  `OK`)
- `headers` - A key/value headers object used to set extra headers to be
  sent along with the RTSP response. This will augment the headers
  already set using the `response.setHeader()` function

## License

MIT