8.76 KB
Newer Older
# Brave
Matthew Clark's avatar
Matthew Clark committed
2 3 4
![Python 3.6]( "Python 3.6")

5 6 7 8

_This project is an open-source prototype. See 'Project status' and 'License' below for more._

Brave is a *B*asic *r*eal-time (remote) *audio/video* *e*ditor.
It allows *LIVE* video (and/or audio) to be received, manipulated, and sent elsewhere.
10 11 12 13 14 15 16 17 18 19 20 21
It is API driven and is designed to work remotely, such as on the cloud.

Example usage includes:

* Forwarding RTMP from one place to another
* Changing the size of video, and having a holding slate if the input disappears
* Mixing two or more inputs
* Adding basic graphics (images, text, etc)
* Previewing video streams using WebRTC

Brave is based on GStreamer. It is, in one sense, a RESTful API for GStreamer (for live audio/video handling).

Matthew Clark's avatar
Matthew Clark committed
To learn more, read below, or see the [FAQ](docs/, [API guide](docs/, [How-to guide](docs/ and [Config file guide](docs/
Matthew Clark's avatar
Matthew Clark committed

### Architecture diagram
Matthew Clark's avatar
Matthew Clark committed
![Architecture diagram](docs/assets/arch.png "Architecture diagram")
26 27

### Web interface screenshot
Dispatch's avatar
Dispatch committed
![Web interface screenshot](docs/assets/brave-screenshot.png "Web interface screenshot")
29 30 31 32 33 34 35 36 37 38 39 40

This web interface is optional; Brave can be controlled via the API or startup config file.

### Alternatives to consider
Similar open-source projects to this include:

* [OBS](
* [Voctomix](
* [Snowmix](
* [FFdynamic](

## Capabilities
Matthew Clark's avatar
Matthew Clark committed
Brave allows you to configure *inputs*, *outputs*, *mixers* and *overlays*. You can have any number of each (subject to the limitations of your server). They can be created at startup using a [config file](./docs/, or created and changed dynamically via [REST API](docs/
42 43

### Inputs
Matthew Clark's avatar
Matthew Clark committed
An input is a source of audio or video. There can be any number of inputs, added or removed at any time, which can then be sent to mixers and outputs. Input types include:

* Live and non-live streams, through protocols such as RTMP, RTSP, and HLS
Matthew Clark's avatar
Matthew Clark committed
47 48
* Files (e.g. mp4 or mp3) - either local or downloaded remotely
* Images (PNG/SVG/JPEG)
* MPEG or OGG retrieved via a TCP connection
Matthew Clark's avatar
Matthew Clark committed
50 51 52
* Test audio / video streams

[Read more about input types.](docs/
53 54

### Outputs
Matthew Clark's avatar
Matthew Clark committed
55 56 57 58 59 60 61
An output is how the constructed audio/video is then sent, served or saved. There can be any number of outputs, added or removed at any time. Output types include:

* RTMP - which can then send to Facebook Live and YouTube Live
* TCP Server - which clients such as VLC can connect to
* Local file - writing an mp4 file
* Image - writing a JPEG file of the video periodically
* WebRTC - for near-realtime previewing of the video (and audio)
* [AWS Kinesis Video Stream](
Matthew Clark's avatar
Matthew Clark committed
* Local - for playback on a local machine

Matthew Clark's avatar
Matthew Clark committed
[Read more about output types.](docs/
66 67

### Overlays
Matthew Clark's avatar
Matthew Clark committed
An overlay is something that can overlay the video from an input or mixer. (Overlays do not exist for audio.) There can be any number of overlays.
69 70 71 72 73

Supported overlay types:

* Clock (place a clock over the video)
* Text (write text over the video)
Matthew Clark's avatar
Matthew Clark committed
74 75 76
* Effects

[Read more about overlay types.](docs/

Matthew Clark's avatar
Matthew Clark committed
### Mixers
There can be any number of mixers. They can take any number of inputs (including the output from another mixer). It can send to any number of outputs. [Read more about mixers.](docs/
80 81

## Project status
Dispatch's avatar
Dispatch committed
82 83 84
This project is still work in progress, and has not been thoroughly tested ~~or used any any production environments~~.

This project breaks *a lot* and is mid process of a nearly complete overhaul to fix, upgrade, and improve all areas of this project to make it semi viable in a production environment.
85 86 87 88 89 90 91

## Installation
First, install the dependencies, and then clone this repo.

### Dependencies
* Python 3.6 (or higher)
* GStreamer 1.14.3 or higher (including the good/bad/ugly packages)
* Multiple Python libraries (installed by pipenv)

94 95 96 97
### Install guides
* [How to install on MacOS](./docs/
* [How to install on Ubuntu](./docs/
* [How to install on CentOS 7](./docs/

Dispatch's avatar
Dispatch committed
99 100 101 102 103 104 105 106 107
### Docker build and install and use
`docker build`

Then get the package id from the end of the build process:
`Successfully built PackageHashNumber`

Then run the new docker image:
`docker run --name brave --rm -t -i -p 5000:5000 PackageHashNumber`

Dispatch's avatar
Dispatch committed
Optionally you can also mount a local directory integral to the docker instance:
Dispatch's avatar
Dispatch committed
109 110
`-v /path/in/host:/videos`

111 112 113 114 115 116 117
## How to use
To start:


Matthew Clark's avatar
Matthew Clark committed
Brave has an [API](docs/ and web interface, which by default is on port 5000. So if running locally, access by pointing your web browser at:
119 120 121 122 123 124 125 126 127 128 129 130


To change the port, either set the `PORT` environment variable, or set `api_port` in the config file.

### Configuring inputs, outputs, overlays and mixers
There are three ways to configure Brave:

1. Web interface
Matthew Clark's avatar
Matthew Clark committed
2. [REST API](docs/ (plus optional websocket)
3. [Config file](./docs/
133 134 135 136 137 138 139

#### Web interface
The web interface is a simple client-side interface. It uses the API to allow the user to view and control Brave's setup.

The web interface can be found at [http://localhost:5000/](). (If running on a remote server, replacing `localhost` with the name of your server.)

#### API
Matthew Clark's avatar
Matthew Clark committed
The API allows read/write access of the state of Brave, including being able to create new inputs, outputs, and overlays dynamically. See the [API documentation](docs/ for more.
141 142

#### Config file
143 144
Brave can be configured by config file.
This includes being able to have certain inputs, mixers, outputs and overlays created when Brave starts.
145 146 147 148 149 150 151

Provide another config with the `-c` parameter, e.g.

./ -c config/example_empty.yaml

Matthew Clark's avatar
Matthew Clark committed
See the [Config File documentation](./docs/ for more.

Matthew Clark's avatar
Matthew Clark committed
154 155 156 157
#### STUN and TURN servers for WebRTC
A STUN or TURN server is likely required for Brave's WebRTC to work between remote connections.
Brave defaults to Google's public STUN server; this can be overridden in the [config file](./docs/, or by setting the `STUN_SERVER` environment variable. Likewise, a `TURN_SERVER` environment variable can be set if a TURN server is required. Its value should be in the format `<usernane>:<credential>@<host>:<port>`.

158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
## Tests
Brave has functional black-box tests that ensure the config file and API is working correctly.
To run them:


A few useful `pytest` options:

* To see the output, add `-s`.
* To see the name of each test being run, add `-v`.
* To run only failing tests, add `--lf`.
* To filter to tests that match a string: `-k <string_to_match>`

All tests should pass.

### Code quality (linting)
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
To check code quality, [Flake8]( is used. To run:

flake8 --count brave

## Debugging
Brave is based on GStreamer, which is a complex beast. If you're experiencing errors or reliability issues, here's a guide on how to debug.

### Run the tests
Run the test framework.

### Logging
Brave outputs log messages, which should include all errors. To see finer grained logging, set `LOG_LEVEL=debug`, i.e.

LOG_LEVEL=debug ./

For even more, ask GStreamer to provide much more debug output with:


### Analyse the elements
Brave creates multiple GStreamer pipelines, each containing multiple linked elements.
Spotting which element has caused an error can help track down the problem.

To see, select 'Debug view' from the web interface. Or, visit the `/api/elements` API endpoint.
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228

Look out for:

* Elements not in the PLAYING state
* Elements with different caps

If there are situations where it work and where it doesn't, try capturing the two `/elements` responses, and diffing them.

### Switch off audio or video
If you're manipulating video that has audio, try disabling audio using `enable_audio: false` in the config file.

And then similarly, disabling video using `enable_video: false`.

This will help inform if it's the audio handling or video handling that's at fault.

### Divide and conquer
If you repeatably get an error, identify what's causing it by removing inputs/outputs/overlays until the problem goes away. Try and find the minimum required to cause the problem.

## License
Brave is licensed under the [Apache 2 license](blob/master/LICENSE).

Brave uses GStreamer which is licensed under the LGPL. GStreamer is dynamically linked, and is not distributed as part of the Brave codebase. [Here is the GStreamer license.]( [Here is the GStreamer licensing documentation.](

Matthew Clark's avatar
Matthew Clark committed
Copyright (c) 2019 BBC