Skip to content

Commit

Permalink
refactor(readme): Documentation made better
Browse files Browse the repository at this point in the history
  • Loading branch information
Roverr committed Nov 20, 2019
1 parent 489d752 commit 770dde9
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 137 deletions.
131 changes: 22 additions & 109 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,15 @@ rtsp-stream is an easy to use out of box solution that can be integrated into ex
## Table of contents
* [How does it work](#how-does-it-work)
* [Run with Docker](#run-with-docker)
* [Easy API](#easy-api)
* [Authentication](#authentication)
* [No Authentication](#no-authentication)
* [JWT](#jwt-authentication)
* [Easy API](#easy-api)
* [Configuration](#configuration)
* [Transcoding](#transcoding-related-configuration)
* [HTTP](#http-related-configuration)
* [CORS](#cors-related-configuration)
* [UI](#ui)
* [Debug](#debug)
* [Proven players](#proven-players)
* [Coming soon](#coming-soon)


## How does it work
It converts `RTSP` streams into `HLS` based on traffic. The idea behind this is that the application should not transcode anything until someone is actually watching the stream. This can help with network bottlenecks in systems where there are a lot of cameras installed.

Expand All @@ -36,16 +31,20 @@ The application has an offical [Docker repository](https://hub.docker.com/r/rove
```s
docker run -p 80:8080 roverr/rtsp-stream:1
```
## Easy API

There are 2 endpoint to call
* `/start` - to start transcoding of a stream
* `/stream/id/*fileId` - static endpoint to serve video files for your browser

[Read full documentation on API](docs/api/README.md).

## Authentication

The application offers different ways for authentication. There are situations when you can get away with no authentication, just
trusting requests because they are from reliable sources or just because they know how to use the API. In other cases, production cases, you definitely
want to protect the service. This application was not written to handle users and logins, so authentication is as lightweight as possible.


### No Authentication

**By default there is no authentication** what so ever. This can be useful if you have private subnets
where there is no real way to reach the service from the internet. (So every request is kind of trusted.) Also works great
if you just wanna try it out, maybe for home use.
Expand All @@ -70,109 +69,20 @@ The following environment variables are available for this setup:

You won't need the private key for it because no signing happens in this application.

<img src="./transcoder_auth.png"/>

## Easy API

API consisents of 2 main endpoints and one more extending them for debug purposes. [Read more](docs/api/README.md).
<img src="https://i.imgur.com/j2dfmzf.png"/>

## Configuration

You can configure the following settings in the application with environment variables:

### Transcoding related configuration:

The project uses [Lumberjack](https://github.com/natefinch/lumberjack) for the log rotation of the ffmpeg transcoding processes.

#### RTSP_STREAM_CLEANUP_TIME
Default: `2m0s`<br/>
Type: string<br/>
Description: Time period for the cleanup process [info on format here](https://golang.org/pkg/time/#ParseDuration)<br/>

#### RTSP_STREAM_STORE_DIR
Default: `./videos`<br/>
Type: string<br/>
Description: Sub directory to store the video chunks<br/>

#### RTSP_STREAM_KEEP_FILES
Default: `false`<br/>
Type: bool<br/>
Description: Option to keep the chunks for the stream being transcoded<br/>

#### RTSP_STREAM_PROCESS_LOGGING_ENABLED
Default: `false`<br/>
Type: bool<br/>
Description: Indicates if logging of transcoding ffmpeg processes is enabled or not<br/>

#### RTSP_STREAM_PROCESS_LOGGING_DIR
Default: `/var/log/rtsp-stream`<br/>
Type: string<br/>
Description: Describes the directory where ffmpeg process logs are stored<br/>
The application tries to be as flexible as possible therefore there are a lot of configuration options available.
You can set the following information in the application:
* Sub directory where the application stores video chunks
* Time period for the cleanup process that stops streams if they are inactive
* Option to keep all video chunks forever instead of removing them when a stream becomes inactive
* Logging options for the underlying ffmpeg process
* CORS and other HTTP related options for the backend server itself
* Debug options for easier time when trying to find out what's wrong

#### RTSP_STREAM_PROCESS_LOGGING_MAX_SIZE
Default: `500`<br/>
Type: integer<br/>
Description: Maximum size of each log file in **megabytes** for retention<br/>

#### RTSP_STREAM_PROCESS_LOGGING_MAX_AGE
Default: `7`<br/>
Type: integer<br/>
Description: Maximum number of days that we store a given log file<br/>

#### RTSP_STREAM_PROCESS_LOGGING_MAX_BACKUPS
Default: `3`<br/>
Type: integer<br/>
Description: Maximum number of old log files to retain for each ffmpeg process<br/>

#### RTSP_STREAM_PROCESS_LOGGING_COMPRESS
Default: `true`<br/>
Type: bool<br/>
Description: Option to compress the rotated log file or not<br/>

<hr/>

### HTTP related configuration:

#### RTSP_STREAM_PORT
Default: `8080`<br/>
Type: integer<br/>
Description: Port where the application listens<br/>

#### RTSP_STREAM_DEBUG
Default: `false`<br/>
Type: bool<br/>
Description: Turns on / off debug features<br/>

#### RTSP_STREAM_LIST_ENDPOINT
Default: `false`<br/>
Type: bool<br/>
Description: Turns on / off the `/list` endpoint<br/>

<hr/>

### CORS related configuration

By default all origin is allowed to make requests to the server, but you might want to configure it for security reasons.

#### RTSP_STREAM_CORS_ENABLED
Default: `false`<br/>
Type: bool<br/>
Description: Indicates if cors should be handled as configured or as default (everything allowed)<br/>

#### RTSP_STREAM_CORS_ALLOWED_ORIGIN
Default: <br/>
Type: []string<br/>
Description: A list of origins a cross-domain request can be executed from<br/>

#### RTSP_STREAM_CORS_ALLOW_CREDENTIALS
Default: `false`<br/>
Type: bool<br/>
Description: Indicates whether the request can include user credentials like cookies, HTTP authentication or client side SSL certificates<br/>

#### RTSP_STREAM_CORS_MAX_AGE
Default: `0`<br/>
Type: integer<br/>
Description: Indicates how long (in seconds) the results of a preflight request can be cached<br/>
Check the full list of environment variables [here](docs/configuration/README.md)

## UI

Expand Down Expand Up @@ -202,13 +112,16 @@ The following list of players has been already tried out in production environme
* Angular - [videogular](http://www.videogular.com/)
* React - [ReactHLS](https://github.com/foxford/react-hls)

## Contributions and reporting issues

See more information about [this here](docs/contribution/README.md).

## Coming soon
Codebase will be refactored as soon as I'll find some time to do it. 🙏
That will mean a major version bump. The goal is still the same. Keep it relatively simple and easy to integrate.
Solve the issue of not being able to play RTSP natively in browsers.

Plans for the future:
- Throw out URI based directory creation completely
- Add better logging and debug options
- Separate HTTP from Stream processing completely
- Add option to remove streams from the client (Could be tricky, gotta figure out if this should be an option even if non-authenticated mode is used)
Expand Down
45 changes: 17 additions & 28 deletions core/streaming/processor.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package streaming

import (
"errors"
"fmt"
"os"
"os/exec"
Expand All @@ -16,12 +15,6 @@ import (
"github.com/sirupsen/logrus"
)

// ErrInvalidHost describes an error for a hostname that is considered invalid if it's empty
var ErrInvalidHost = errors.New("Invalid hostname")

// ErrUnparsedURL describes an error that occours when the parsing process cannot be deemed as successful
var ErrUnparsedURL = errors.New("URL is not parsed correctly")

// IProcessor is an interface describing a processor service
type IProcessor interface {
NewProcess(path, URI string) *exec.Cmd
Expand Down Expand Up @@ -101,7 +94,9 @@ func (p Processor) NewProcess(path, URI string) *exec.Cmd {

// NewStream creates a new transcoding process for ffmpeg
func (p Processor) NewStream(URI string) (*Stream, string, string) {
id, path, err := createDirectoryForURI(p.storeDir)
id := uuid.New().String()
path := fmt.Sprintf("%s/%s", p.storeDir, id)
err := os.MkdirAll(path, os.ModePerm)
if err != nil {
logrus.Error(err)
return nil, "", ""
Expand Down Expand Up @@ -141,29 +136,23 @@ func (p Processor) NewStream(URI string) (*Stream, string, string) {
}

// Restart uses the processor to restart a given stream
func (p Processor) Restart(strm *Stream, path string) error {
strm.Mux.Lock()
defer strm.Mux.Unlock()
strm.CMD = p.NewProcess(strm.StorePath, strm.OriginalURI)
func (p Processor) Restart(stream *Stream, path string) error {
stream.Mux.Lock()
defer stream.Mux.Unlock()
stream.CMD = p.NewProcess(stream.StorePath, stream.OriginalURI)
if p.loggingOpts.Enabled {
strm.CMD.Stderr = strm.Logger
strm.CMD.Stdout = strm.Logger
stream.CMD.Stderr = stream.Logger
stream.CMD.Stdout = stream.Logger
}
strm.Streak.Activate()
go func() {
logrus.Infof("%s has been restarted", path)
err := strm.CMD.Run()
if err != nil {
logrus.Error(err)
}
}()
stream.Streak.Activate()
go p.spawnBackgroundRunProcess(stream.CMD)
logrus.Infof("%s has been restarted", path)
return nil
}

// createDirectoryForURI is to create a safe path based on the received URI
func createDirectoryForURI(storeDir string) (id, path string, err error) {
id = uuid.New().String()
path = fmt.Sprintf("%s/%s", storeDir, id)
err = os.MkdirAll(path, os.ModePerm)
return
func (p Processor) spawnBackgroundRunProcess(cmd *exec.Cmd) {
err := cmd.Run()
if err != nil {
logrus.Error(err)
}
}
97 changes: 97 additions & 0 deletions docs/configuration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
## Configuration

You can configure the following settings in the application with environment variables:

### Transcoding related configuration:

The project uses [Lumberjack](https://github.com/natefinch/lumberjack) for the log rotation of the ffmpeg transcoding processes.

#### RTSP_STREAM_CLEANUP_TIME
Default: `2m0s`<br/>
Type: string<br/>
Description: Time period for the cleanup process [info on format here](https://golang.org/pkg/time/#ParseDuration)<br/>

#### RTSP_STREAM_STORE_DIR
Default: `./videos`<br/>
Type: string<br/>
Description: Sub directory to store the video chunks<br/>

#### RTSP_STREAM_KEEP_FILES
Default: `false`<br/>
Type: bool<br/>
Description: Option to keep the chunks for the stream being transcoded<br/>

#### RTSP_STREAM_PROCESS_LOGGING_ENABLED
Default: `false`<br/>
Type: bool<br/>
Description: Indicates if logging of transcoding ffmpeg processes is enabled or not<br/>

#### RTSP_STREAM_PROCESS_LOGGING_DIR
Default: `/var/log/rtsp-stream`<br/>
Type: string<br/>
Description: Describes the directory where ffmpeg process logs are stored<br/>

#### RTSP_STREAM_PROCESS_LOGGING_MAX_SIZE
Default: `500`<br/>
Type: integer<br/>
Description: Maximum size of each log file in **megabytes** for retention<br/>

#### RTSP_STREAM_PROCESS_LOGGING_MAX_AGE
Default: `7`<br/>
Type: integer<br/>
Description: Maximum number of days that we store a given log file<br/>

#### RTSP_STREAM_PROCESS_LOGGING_MAX_BACKUPS
Default: `3`<br/>
Type: integer<br/>
Description: Maximum number of old log files to retain for each ffmpeg process<br/>

#### RTSP_STREAM_PROCESS_LOGGING_COMPRESS
Default: `true`<br/>
Type: bool<br/>
Description: Option to compress the rotated log file or not<br/>

<hr/>

### HTTP related configuration:

#### RTSP_STREAM_PORT
Default: `8080`<br/>
Type: integer<br/>
Description: Port where the application listens<br/>

#### RTSP_STREAM_DEBUG
Default: `false`<br/>
Type: bool<br/>
Description: Turns on / off debug features<br/>

#### RTSP_STREAM_LIST_ENDPOINT
Default: `false`<br/>
Type: bool<br/>
Description: Turns on / off the `/list` endpoint<br/>

<hr/>

### CORS related configuration

By default all origin is allowed to make requests to the server, but you might want to configure it for security reasons.

#### RTSP_STREAM_CORS_ENABLED
Default: `false`<br/>
Type: bool<br/>
Description: Indicates if cors should be handled as configured or as default (everything allowed)<br/>

#### RTSP_STREAM_CORS_ALLOWED_ORIGIN
Default: <br/>
Type: []string<br/>
Description: A list of origins a cross-domain request can be executed from<br/>

#### RTSP_STREAM_CORS_ALLOW_CREDENTIALS
Default: `false`<br/>
Type: bool<br/>
Description: Indicates whether the request can include user credentials like cookies, HTTP authentication or client side SSL certificates<br/>

#### RTSP_STREAM_CORS_MAX_AGE
Default: `0`<br/>
Type: integer<br/>
Description: Indicates how long (in seconds) the results of a preflight request can be cached<br/>
27 changes: 27 additions & 0 deletions docs/contribution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Reporting issues

Before reporting a new issue please be sure to check out the [debug guide](../debugging/README.md). If you are still sure that your issue requires developer attention please feel free to open it publicly in the following format:

* Summarise issue in couple of sentences
* Describe situation in which the error occoured (Environment, platform, context)
* Provide all logs and available resources for reproducation

I will try to provide support as fast as possible.

# Contributions

All contributions are welcomed but they have to be formatted correctly to keep up consistent administration.
Commit messages are following a really simple pattern:
- keyword(topic): Description

Following keywords are allowed for the repository:
- **feat**: feature describes something new that is now available
- **fix**: describes a bug fix
- **chore**: task that has to be done over time to time (like dependency version bumping)
- **test**: describe the addition of new tests / new edge cases

If your PR is not matching this style, it can still be merged but it will be squashed.

* Choose a name for the PR that reflects the modifications.
* Summarias modifications in bullet points
* Summarise in a couple of sentences why this repository needs this PR
Loading

0 comments on commit 770dde9

Please sign in to comment.