# Technical Documentation: ossrs/srs

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/ossrs/srs)

### Overview (README.md)

# SRS(Simple Realtime Server)


[](https://github.com/ossrs/srs/actions?query=workflow%3ACodeQL+branch%3A4.0release)
[](https://github.com/ossrs/srs/actions/workflows/release.yml?query=workflow%3ARelease)
[](https://github.com/ossrs/srs/actions?query=workflow%3ATest+branch%3A4.0release)
[](https://codecov.io/gh/ossrs/srs/branch/4.0release)
[](../../wikis/Contact#wechat)
[](https://github.com/ossrs/srs/issues/2716)
[](http://mulanos.cn)
[](https://alternativeto.net/software/srs/about/)
[](https://www.youtube.com/channel/UCP6ZblCL_fIJoEyUzZxC1ng)
[](https://discord.gg/yZ4BnPmHAd)
[](https://opencollective.com/srs-server/contribute)
[](https://stackoverflow.com/questions/tagged/simple-realtime-server)
[](https://hub.docker.com/r/ossrs/srs/tags)

SRS/4.0，[Leo](https://github.com/ossrs/srs/wiki/Product#release40)，是一个简单高效的实时视频服务器，支持RTMP/WebRTC/HLS/HTTP-FLV/SRT。

SRS is a simple, high efficiency and realtime video server, supports RTMP/WebRTC/HLS/HTTP-FLV/SRT.

[](https://ossrs.net/wiki/images/SRS-SingleNode-4.0-hd.png)

> Note:  The single node architecture for SRS, for detail please see [here](https://www.figma.com/file/333POxVznQ8Wz1Rxlppn36/SRS-4.0-Server-Arch).

SRS is licenced under [MIT][LICENSE], but some depended libraries are distributed using their [own licenses][LicenseMixing].

<a name="product"></a>
<a name="usage-docker"></a>
## Usage

Build SRS from source:

```
git clone -b 4.0release https://gitee.com/ossrs/srs.git &&
cd srs/trunk && ./configure && make && ./objs/srs -c conf/srs.conf
```

Open [http://localhost:8080/](http://localhost:8080/) to check it, then publish
by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) as:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv -y rtmp://localhost/live/livestream
```

Play the following streams by [players](https://ossrs.net):

* RTMP (by [VLC](https://www.videolan.org/)): rtmp://localhost/live/livestream
* H5(HTTP-FLV): [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)
* H5(HLS): [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.m3u8&port=8080&schema=http)

Note that if convert RTMP to WebRTC, please use [`rtmp2rtc.conf`](https://github.com/ossrs/srs/issues/2728#issuecomment-964686152):

* H5(WebRTC): [webrtc://localhost/live/livestream](http://localhost:8080/players/rtc_player.html?autostart=true)

> Note: Besides of FFmpeg or OBS, it's also able to [publish by H5](http://localhost:8080/players/rtc_publisher.html?autostart=true) 
> if [WebRTC](https://github.com/ossrs/srs/issues/307) is enabled.

> Highly recommend that directly run SRS by
> **docker([CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#docker) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#docker))**,
> **Cloud Virtual Machine([CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#cloud-virtual-machine) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#cloud-virtual-machine))**,
> or **K8s([CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#k8s) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#k8s))**,
> however it's also easy to build SRS from source code, for detail please see
> **Getting Started([CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started))**.

> Note: If need HTTPS, by which WebRTC and modern browsers require, please read
> **HTTPS API([CN](https://github.com/ossrs/srs/wiki/v4_CN_HTTPApi#https-api) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_HTTPApi#https-api))**
> and **HTTPS Callback([CN](https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback#https-callback) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_HTTPCallback#https-callback))**
> and **HTTPS Live Streaming([CN](https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream#https-flv-live-stream) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream#https-flv-live-stream))**,
> however HTTPS proxy also works perfect with SRS such as Nginx.

<a name="srs-40-wiki"></a>
<a name="wiki"></a>

From here, please read wikis:

* [Getting Started](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started), please read Wiki first.
* [中文文档：起步](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started)，不读Wiki一定扑街，不读文档请不要提Issue，不读文档请不要提问题，任何文档中明确说过的疑问都不会解答。

Fast index for Wikis:

* Overview? ([CN][v4_CN_Home], [EN][v4_EN_Home])
* How to deliver RTMP streaming?([CN][v4_CN_SampleRTMP], [EN][v4_EN_SampleRTMP])
* How to build RTMP Edge-Cluster?([CN][v4_CN_SampleRTMPCluster], [EN][v4_EN_SampleRTMPCluster])
* How to build RTMP Origin-Cluster?([CN][v4_CN_SampleOriginCluster], [EN][v4_EN_SampleOriginCluster])
* How to deliver HTTP-FLV streaming?([CN][v4_CN_SampleHttpFlv], [EN][v4_EN_SampleHttpFlv])
* How to deliver HLS streaming?([CN][v4_CN_SampleHLS], [EN][v4_EN_SampleHLS])
* How to deliver low-latency streaming?([CN][v4_CN_SampleRealtime], [EN][v4_EN_SampleRealtime])
* How to use WebRTC? ([CN][v4_CN_WebRTC], [EN][v4_EN_WebRTC])

Other important wiki:

* Usage: How to delivery DASH(Experimental)?([CN][v4_CN_SampleDASH], [EN][v4_EN_SampleDASH])
* Usage: How to transode RTMP stream by FFMPEG?([CN][v4_CN_SampleFFMPEG], [EN][v4_EN_SampleFFMPEG])
* Usage: How to delivery HTTP FLV Live Streaming Cluster?([CN][v4_CN_SampleHttpFlvCluster], [EN][v4_EN_SampleHttpFlvCluster])
* Usage: How to ingest file/stream/device to RTMP?([CN][v4_CN_SampleIngest], [EN][v4_EN_SampleIngest])
* Usage: How to forward stream to other servers?([CN][v4_CN_SampleForward], [EN][v4_EN_SampleForward])
* Usage: How to improve edge performance for multiple CPUs? ([CN][v4_CN_REUSEPORT], [EN][v4_EN_REUSEPORT])
* Usage: How to file a bug or contact us? ([CN][v4_CN_Contact], [EN][v4_EN_Contact])

## AUTHORS

Thank you to all our contributors! 🙏

[](https://opencollective.com/srs-server/contribute)

> Note: You may provide financial support for this project by donating [via Open Collective](https://opencollective.com/srs-server/contribute). Thank you for your support!

There are two types of people that have contributed code to the SRS project:

* Maintainers: Contribute and maintain important features. SRS always remembers and thanks you by writing your names in stream metadata.
* [Contributors][authors]: Submit patches, report bugs, add translations, help answer newbie questions, and generally make SRS much better.

Maintainers of SRS project:

* [Winlin](https://github.com/winlinvip): Focus on [issues/PR](https://github.com/ossrs/srs/issues) and tests now.
* [ZhaoWenjie](https://github.com/wenjiegit): Focus on [HDS](https://github.com/simple-rtmp-server/srs/wiki/v4_CN_DeliveryHDS) module.
* [ShiWei](https://github.com/runner365): Focus on [SRT](https://github.com/simple-rtmp-server/srs/wiki/v4_CN_SRTWiki) module.
* [XiaoZhihong](https://github.com/xiaozhihong): Focus on [WebRTC](https://github.com/simple-rtmp-server/srs/wiki/v4_CN_WebRTC) module.
* [WuPengqiang](https://github.com/Bepartofyou): Focus on [WebRTC](https://github.com/simple-rtmp-server/srs/wiki/v4_CN_WebRTC) module.
* [XiaLixin](https://github.com/xialixin): Focus on [GB28181](https://github.com/ossrs/srs/issues/1500) module.
* [LiPeng](https://github.com/lipeng19811218): Focus on [WebRTC](https://github.com/simple-rtmp-server/srs/wiki/v4_CN_WebRTC) module.
* [ChenGuanghua](https://github.com/chen-guanghua): Focus on [WebRTC](https://github.com/simple-rtmp-server/srs/wiki/v4_CN_WebRTC) module.
* [ChenHaibo](https://github.com/duiniuluantanqin): Focus on [GB28181](https://github.com/ossrs/srs/issues/1500) and [API](https://github.com/ossrs/srs/issues/1657) module.

A big THANK YOU goes to:

* All friends of SRS for [big supports][bigthanks].
* Genes amd Mabbott for creating [st][st]([state-threads][st2]).
* [Michael Talyanksy](https://github.com/michaeltalyansky) for introducing ST to us.

## Releases

* 2022-06-29, Release [v4.0-r1](https://github.com/ossrs/srs/releases/tag/v4.0-r1), v4.0-r1, 4.0 release1, v4.0.253, 144680 lines.
* 2022-06-11, Release [v4.0-r0](https://github.com/ossrs/srs/releases/tag/v4.0-r0), v4.0-r0, 4.0 release0, v4.0.252, 144680 lines.
* 2022-03-19, Release [v4.0-b10](https://github.com/ossrs/srs/releases/tag/v4.0-b10), v4.0-b10, 4.0 beta10, v4.0.251, 144665 lines.
* 2022-02-15, Release [v4.0-b9](https://github.com/ossrs/srs/releases/tag/v4.0-b9), v4.0-b9, 4.0 beta9, v4.0.245, 144474 lines.
* 2022-02-11, Release [v4.0-b8](https://github.com/ossrs/srs/releases/tag/v4.0-b8), v4.0-b8, 4.0 beta8, v4.0.241, 144445 lines.
* 2022-02-09, Release [v4.0-b7](https://github.com/ossrs/srs/releases/tag/v4.0-b7), v4.0-b7, 4.0 beta7, v4.0.240, 144437 lines.
* 2022-02-04, Release [v4.0-b6](https://github.com/ossrs/srs/releases/tag/v4.0-b6), v4.0-b6, 4.0 beta6, v4.0.238, 144437 lines.
* 2022-01-30, Release [v4.0-b5](https://github.com/ossrs/srs/releases/tag/v4.0-b5), v4.0-b5, 4.0 beta5, v4.0.236, 144416 lines.
* 2022-01-17, Release [v4.0-b4](https://github.com/ossrs/srs/releases/tag/v4.0-b4), v4.0-b4, 4.0 beta4, v4.0.230, 144393 lines.
* 2022-01-13, Release [v4.0-b3](https://github.com/ossrs/srs/releases/tag/v4.0-b3), v4.0-b3, 4.0 beta3, v4.0.229, 144393 lines.
* 2022-01-03, Release [v4.0-b2](https://github.com/ossrs/srs/releases/tag/v4.0-b2), v4.0-b2, 4.0 beta2, v4.0.215, 144278 lines.
* 2021-12-19, Release [v4.0-b1](https://github.com/ossrs/srs/releases/tag/v4.0-b1), v4.0-b1, 4.0 beta1, v4.0.206, 144126 lines.
* 2021-12-01, Release [v4.0-b0](https://github.com/ossrs/srs/releases/tag/v4.0-b0), v4.0-b0, 4.0 beta0, v4.0.201, 144022 lines.
* 2021-11-15, Release [v4.0.198](https://github.com/ossrs/srs/releases/tag/v4.0.198), 4.0 dev8, v4.0.198, 144010 lines.
* 2021-11-02, Release [v4.0.191](https://github.com/ossrs/srs/releases/tag/v4.0.191), 4.0 dev7, v4.0.191, 143890 lines.
* 2021-10-12, Release [v4.0.177](https://github.com/ossrs/srs/releases/tag/v4.0.177), 4.0 dev6, v4.0.177, 143686 lines.
* 2021-09-05, Release [v4.0.161](https://github.com/ossrs/srs/releases/tag/v4.0.161), 4.0 dev5, v4.0.161, 145865 lines.
* 2021-08-15, Release [v4.0.156](https://github.com/ossrs/srs/releases/tag/v4.0.156), 4.0 dev4, v4.0.156, 145490 lines.
* 2021-08-14, Release [v4.0.153](https://github.com/ossrs/srs/releases/tag/v4.0.153), 4.0 dev3, v4.0.153, 145506 lines.
* 2021-08-07, Release [v4.0.150](https://github.com/ossrs/srs/releases/tag/v4.0.150), 4.0 dev2, v4.0.150, 145289 lines.
* 2021-07-25, Release [v4.0.146](https://github.com/ossrs/srs/releases/tag/v4.0.146), 4.0 dev1, v4.0.146, 144026 lines.
* 2021-07-04, Release [v4.0.139](https://github.com/ossrs/srs/releases/tag/v4.0.139), 4.0 dev0, v4.0.139, 143245 lines.
* 2020-06-27, [Release v3.0-r0][r3.0r0], 3.0 release0, 3.0.141, 122674 lines.
* 2020-02-02, [Release v3.0-b0][r3.0b0], 3.0 beta0, 3.0.112, 121709 lines.
* 2019-10-04, [Release v3.0-a0][r3.0a0], 3.0 alpha0, 3.0.56, 107946 lines.
* 2017-03-03, [Release v2.0-r0][r2.0r0], 2.0 release0, 2.0.234, 86373 lines.
* 2016-08-06, [Release v2.0-b0][r2.0b0], 2.0 beta0, 2.0.210, 89704 lines.
* 2015-08-23, [Release v2.0-a0][r2.0a0], 2.0 alpha0, 2.0.185, 89022 lines.
* 2014-12-05, [Release v1.0-r0][r1.0r0], all bug fixed, 1.0.10, 59391 lines.
* 2014-10-09, [Release v0.9.8][r1.0b0], all bug fixed, 1.0.0, 59316 lines.
* 2014-04-07, [Release v0.9.1][r1.0a0], live streaming. 30000 lines.
* 2013-10-23, [Release v0.1.0][r0.1], rtmp. 8287 lines.
* 2013-10-17, Created.

## Features

Please read [FEATURES](trunk/doc/Features.md#features).

<a name="history"></a>
<a name="change-logs"></a>

## Changelog

Please read [CHANGELOG](trunk/doc/CHANGELOG.md#changelog).

## Compare

Comparing with other media servers, SRS is much better and stronger, for details please 
read Product([CN][v4_CN_Compare]/[EN][v4_EN_Compare]).

## Performance

Please read [PERFORMANCE](trunk/doc/PERFORMANCE.md#performance).

## Architecture

Please read [ARCHITECTURE](trunk/doc/Architecture.md#architecture).

## Ports

Please read [PORTS](trunk/doc/Resources.md#ports).

## APIs

Please read [APIS](trunk/doc/Resources.md#apis).

## Mirrors

Please read [MIRRORS](trunk/doc/Resources.md#mirrors).

Beijing, 2013.10<br/>
Winlin

[authors]: https://github.com/ossrs/srs/blob/4.0release/trunk/AUTHORS.txt
[bigthanks]: https://github.com/ossrs/srs/wiki/Product#release40
[st]: https://github.com/ossrs/state-threads
[st2]: https://github.com/ossrs/state-threads/tree/srs
[state-threads]: https://github.com/ossrs/state-threads/tree/srs
[nginx]: http://nginx.org/
[srs]: https://github.com/ossrs/srs
[gitee]: https://gitee.com/ossrs/srs
[srs-bench]: https://github.com/ossrs/srs-bench
[srs-ngb]: https://github.com/ossrs/srs-console
[srs-librtmp]: https://github.com/ossrs/srs-librtmp
[gitlab]: https://gitlab.com/winlinvip/srs-gitlab
[console]: http://ossrs.net:8080/console
[docker-srs3]: https://github.com/ossrs/srs-docker/tree/v3#usage
[docker-srs4]: https://github.com/ossrs/srs-docker/tree/v4#usage
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage

[v4_CN_Git]: https://github.com/ossrs/srs/wiki/v4_CN_Git
[v4_EN_Git]: https://github.com/ossrs/srs/wiki/v4_EN_Git
[v4_CN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMP
[v4_EN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMP
[v4_CN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMPCluster
[v4_EN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMPCluster
[v4_CN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleOriginCluster
[v4_EN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleOriginCluster
[v4_CN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHLS
[v4_EN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHLS
[v4_CN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleTranscode2HLS
[v4_EN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleTranscode2HLS
[v4_CN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_SampleFFMPEG
[v4_EN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_SampleFFMPEG
[v4_CN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_CN_SampleForward
[v4_EN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_EN_SampleForward
[v4_CN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRealtime
[v4_EN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRealtime
[v4_CN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC
[v4_EN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC
[v4_CN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
[v4_EN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC#config-candidate
[v4_CN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_CN_SampleARM
[v4_EN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_EN_SampleARM
[v4_CN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_CN_SampleIngest
[v4_EN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_EN_SampleIngest
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_OriginCluster
[v4_EN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_OriginCluster
[v4_CN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_CN_REUSEPORT
[v4_EN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_EN_REUSEPORT
[v4_CN_Sample]: https://github.com/ossrs/srs/wiki/v4_CN_Sample
[v4_EN_Sample]: https://github.com/ossrs/srs/wiki/v4_EN_Sample
[v4_CN_Product]: https://github.com/ossrs/srs/wiki/v4_CN_Product
[v4_EN_Product]: https://github.com/ossrs/srs/wiki/v4_EN_Product
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home

[v4_CN_Compare]: https://github.com/ossrs/srs/wiki/v4_CN_Compare
[v4_EN_Compare]: https://github.com/ossrs/srs/wiki/v4_EN_Compare
[v4_CN_Build]: https://github.com/ossrs/srs/wiki/v4_CN_Build
[v4_EN_Build]: https://github.com/ossrs/srs/wiki/v4_EN_Build
[v4_CN_Performance]: https://github.com/ossrs/srs/wiki/v4_CN_Performance
[v4_EN_Performance]: https://github.com/ossrs/srs/wiki/v4_EN_Performance
[v4_CN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryRTMP
[v4_EN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryRTMP
[v4_CN_Edge]: https://github.com/ossrs/srs/wiki/v4_CN_Edge
[v4_EN_Edge]: https://github.com/ossrs/srs/wiki/v4_EN_Edge
[v4_CN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_CN_RtmpUrlVhost
[v4_EN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_EN_RtmpUrlVhost
[v4_CN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_CN_RTMPHandshake
[v4_EN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_EN_RTMPHandshake
[v4_CN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPServer
[v4_EN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPServer
[v4_CN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS
[v4_EN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS
[v4_CN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS#hlsaudioonly
[v4_EN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS#hlsaudioonly
[v4_CN_Reload]: https://github.com/ossrs/srs/wiki/v4_CN_Reload
[v4_EN_Reload]: https://github.com/ossrs/srs/wiki/v4_EN_Reload
[v4_CN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#gop-cache
[v4_EN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#gop-cache
[v4_CN_Forward]: https://github.com/ossrs/srs/wiki/v4_CN_Forward
[v4_EN_Forward]: https://github.com/ossrs/srs/wiki/v4_EN_Forward
[v4_CN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_FFMPEG
[v4_EN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_FFMPEG
[v4_CN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback
[v4_EN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPCallback
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLinuxArm
[v4_EN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLinuxArm
[v4_CN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_CN_LinuxService
[v4_EN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_EN_LinuxService
[v4_CN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_CN_RTMP-ATC
[v4_EN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_EN_RTMP-ATC
[v4_CN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPApi
[v4_EN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPApi
[v4_CN_Ingest]: https://github.com/ossrs/srs/wiki/v4_CN_Ingest
[v4_EN_Ingest]: https://github.com/ossrs/srs/wiki/v4_EN_Ingest
[v4_CN_DVR]: https://github.com/ossrs/srs/wiki/v4_CN_DVR
[v4_EN_DVR]: https://github.com/ossrs/srs/wiki/v4_EN_DVR
[v4_CN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLog
[v4_EN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLog
[v4_CN_DRM2]: https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse
[v4_EN_DRM2]: https://github.com/ossrs/srs/wiki/v4_EN_DRM#tokentraverse
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_CN_FlvVodStream
[v4_EN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_EN_FlvVodStream
[v4_CN_Security]: https://github.com/ossrs/srs/wiki/v4_CN_Security
[v4_EN_Security]: https://github.com/ossrs/srs/wiki/v4_EN_Security
[v4_CN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHttpStream
[v4_EN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream
[v4_CN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHDS
[v4_EN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHDS
[v4_CN_Streamer]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer
[v4_EN_Streamer]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer
[v4_CN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-http-flv-to-srs
[v4_EN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer#push-http-flv-to-srs
[v4_CN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlv
[v4_EN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlv
[v4_CN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlvCluster
[v4_EN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlvCluster
[v4_CN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_CN_SampleDASH
[v4_EN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_EN_SampleDASH

[bug #547]: https://github.com/ossrs/srs/issues/547
[bug #301]: https://github.com/ossrs/srs/issues/301
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #367]: https://github.com/ossrs/srs/issues/367
[bug #257]: https://github.com/ossrs/srs/issues/257
[bug #904]: https://github.com/ossrs/srs/issues/904
[bug #913]: https://github.com/ossrs/srs/issues/913
[bug #1059]: https://github.com/ossrs/srs/issues/1059
[bug #92]: https://github.com/ossrs/srs/issues/92
[bug #464]: https://github.com/ossrs/srs/issues/464
[bug #460]: https://github.com/ossrs/srs/issues/460
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #307]: https://github.com/ossrs/srs/issues/307
[bug #2324]: https://github.com/ossrs/srs/issues/2324
[bug #1657]: https://github.com/ossrs/srs/issues/1657
[bug #1500]: https://github.com/ossrs/srs/issues/1500
[bug #738]: https://github.com/ossrs/srs/issues/738
[bug #299]: https://github.com/ossrs/srs/issues/299
[bug #250]: https://github.com/ossrs/srs/issues/250
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #470]: https://github.com/ossrs/srs/issues/470
[bug #319]: https://github.com/ossrs/srs/issues/319
[bug #1147]: https://github.com/ossrs/srs/issues/1147
[bug #2304]: https://github.com/ossrs/srs/issues/2304
[bug #1535]: https://github.com/ossrs/srs/issues/1535
[bug #1342]: https://github.com/ossrs/srs/issues/1342
[bug #1193]: https://github.com/ossrs/srs/issues/1193
[bug #2093]: https://github.com/ossrs/srs/issues/2093
[bug #465]: https://github.com/ossrs/srs/issues/465
[bug #2091]: https://github.com/ossrs/srs/issues/2091
[bug #2188]: https://github.com/ossrs/srs/issues/2188
[bug #413]: https://github.com/ossrs/srs/issues/413
[bug #1111]: https://github.com/ossrs/srs/issues/1111
[bug #463]: https://github.com/ossrs/srs/issues/463
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #257-c0]: https://github.com/ossrs/srs/issues/257#issuecomment-66864413

[r3.0r5]: https://github.com/ossrs/srs/releases/tag/v3.0-r5
[r3.0r4]: https://github.com/ossrs/srs/releases/tag/v3.0-r4
[r3.0r3]: https://github.com/ossrs/srs/releases/tag/v3.0-r3
[r3.0r2]: https://github.com/ossrs/srs/releases/tag/v3.0-r2
[r3.0r1]: https://github.com/ossrs/srs/releases/tag/v3.0-r1
[r3.0r0]: https://github.com/ossrs/srs/releases/tag/v3.0-r0
[r3.0b4]: https://github.com/ossrs/srs/releases/tag/v3.0-b4
[r3.0b3]: https://github.com/ossrs/srs/releases/tag/v3.0-b3
[r3.0b2]: https://github.com/ossrs/srs/releases/tag/v3.0-b2
[r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7
[r3.0a6]: https://github.com/ossrs/srs/releases/tag/v3.0-a6
[r3.0a5]: https://github.com/ossrs/srs/releases/tag/v3.0-a5
[r3.0a4]: https://github.com/ossrs/srs/releases/tag/v3.0-a4
[r3.0a3]: https://github.com/ossrs/srs/releases/tag/v3.0-a3
[r3.0a2]: https://github.com/ossrs/srs/releases/tag/v3.0-a2
[r3.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
[r2.0r8]: https://github.com/ossrs/srs/releases/tag/v2.0-r8
[r2.0r7]: https://github.com/ossrs/srs/releases/tag/v2.0-r7
[r2.0r6]: https://github.com/ossrs/srs/releases/tag/v2.0-r6
[r2.0r5]: https://github.com/ossrs/srs/releases/tag/v2.0-r5
[r2.0r4]: https://github.com/ossrs/srs/releases/tag/v2.0-r4
[r2.0r3]: https://github.com/ossrs/srs/releases/tag/v2.0-r3
[r2.0r2]: https://github.com/ossrs/srs/releases/tag/v2.0-r2
[r2.0r1]: https://github.com/ossrs/srs/releases/tag/v2.0-r1
[r2.0r0]: https://github.com/ossrs/srs/releases/tag/v2.0-r0
[r2.0b4]: https://github.com/ossrs/srs/releases/tag/v2.0-b4
[r2.0b3]: https://github.com/ossrs/srs/releases/tag/v2.0-b3
[r2.0b2]: https://github.com/ossrs/srs/releases/tag/v2.0-b2
[r2.0b1]: https://github.com/ossrs/srs/releases/tag/v2.0-b1
[r2.0b0]: https://github.com/ossrs/srs/releases/tag/v2.0-b0
[r2.0a3]: https://github.com/ossrs/srs/releases/tag/v2.0-a3
[r2.0a2]: https://github.com/ossrs/srs/releases/tag/v2.0-a2
[r2.0a1]: https://github.com/ossrs/srs/releases/tag/v2.0-a1
[r2.0a0]: https://github.com/ossrs/srs/releases/tag/v2.0-a0
[r1.0r4]: https://github.com/ossrs/srs/releases/tag/v1.0-r4
[r1.0r3]: https://github.com/ossrs/srs/releases/tag/v1.0-r3
[r1.0r2]: https://github.com/ossrs/srs/releases/tag/v1.0-r2
[r1.0r1]: https://github.com/ossrs/srs/releases/tag/v1.0-r1
[r1.0r0]: https://github.com/ossrs/srs/releases/tag/v1.0-r0
[r1.0b0]: https://github.com/ossrs/srs/releases/tag/v0.9.8
[r1.0a7]: https://github.com/ossrs/srs/releases/tag/v0.9.7
[r1.0a6]: https://github.com/ossrs/srs/releases/tag/v0.9.6
[r1.0a5]: https://github.com/ossrs/srs/releases/tag/v0.9.5
[r1.0a4]: https://github.com/ossrs/srs/releases/tag/v0.9.4
[r1.0a3]: https://github.com/ossrs/srs/releases/tag/v0.9.3
[r1.0a2]: https://github.com/ossrs/srs/releases/tag/v0.9.2
[r1.0a0]: https://github.com/ossrs/srs/releases/tag/v0.9.1
[r0.9]: https://github.com/ossrs/srs/releases/tag/v0.9.0
[r0.8]: https://github.com/ossrs/srs/releases/tag/v0.8.0
[r0.7]: https://github.com/ossrs/srs/releases/tag/v0.7.0
[r0.6]: https://github.com/ossrs/srs/releases/tag/v0.6.0
[r0.5]: https://github.com/ossrs/srs/releases/tag/v0.5.0
[r0.4]: https://github.com/ossrs/srs/releases/tag/v0.4.0
[r0.3]: https://github.com/ossrs/srs/releases/tag/v0.3.0
[r0.2]: https://github.com/ossrs/srs/releases/tag/v0.2.0
[r0.1]: https://github.com/ossrs/srs/releases/tag/v0.1.0


[v4_CN_Contact]: https://github.com/ossrs/srs/wiki/v4_CN_Contact
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

[LICENSE]: https://github.com/ossrs/srs/blob/4.0release/LICENSE
[LicenseMixing]: https://ossrs.net/lts/zh-cn/license

---

### Trunk Doc README (`trunk/doc/README.md`)

# Doc

The reference docs.

> Note: Please read **Wiki: Gettting Started( [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started) / [CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) )** first.

## Live Streaming

1. [amf0_spec_121207.pdf](http://github.com/ossrs/srs/wiki/doc/amf0_spec_121207.pdf), adobe amf0标准
1. [amf3_spec_121207.pdf](http://github.com/ossrs/srs/wiki/doc/amf3_spec_121207.pdf), adobe amf3标准。
1. [hls-m3u8-draft-pantos-http-live-streaming-12.txt](http://github.com/ossrs/srs/wiki/doc/hls-m3u8-draft-pantos-http-live-streaming-12.txt), [hls-m3u8-draft-pantos-http-live-streaming-12.pdf](http://github.com/ossrs/srs/wiki/doc/hls-m3u8-draft-pantos-http-live-streaming-12.pdf), m3u8标准。
1. [hls-mpeg-ts-iso13818-1.pdf](http://github.com/ossrs/srs/wiki/doc/hls-mpeg-ts-iso13818-1.pdf), ts标准。
1. [hls-mpeg-ts-VB_WhitePaper_TransportStreamVSProgramStream_rd2.pdf](http://github.com/ossrs/srs/wiki/doc/hls-mpeg-ts-VB_WhitePaper_TransportStreamVSProgramStream_rd2.pdf), ts的介绍。
1. [rtmp.part1.Chunk-Stream.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp.part1.Chunk-Stream.pdf), [rtmp.part2.Message-Formats.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp.part2.Message-Formats.pdf), [rtmp.part3.Commands-Messages.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp.part3.Commands-Messages.pdf), [rtmp_specification_1.0.pdf](http://github.com/ossrs/srs/wiki/doc/rtmp_specification_1.0.pdf), adobe rtmp标准。
1. [flv_v10_1.pdf](http://github.com/ossrs/srs/wiki/doc/flv_v10_1.pdf), adobe flv。
1. [video_file_format_spec_v10_1.pdf](http://github.com/ossrs/srs/wiki/doc/video_file_format_spec_v10_1.pdf) flv/f4v.

## Codec

1. [mp3.id3v2.3.0.pdf](http://github.com/ossrs/srs/wiki/doc/mp3.id3v2.3.0.pdf), http://id3.org/id3v2.3.0
1. [aac-iso-13818-7.pdf, ISO_IEC_13818-7-AAC-2004.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_13818-7-AAC-2004.pdf), aac标准，aac的编码等。
1. [aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, ISO_IEC_14496-3-AAC-2001.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-3-AAC-2001.pdf), aac的封装标准，即ts/flv里面的aac raw data标准。
1. [ISO_IEC_14496-1-System-2010.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-1-System-2010.pdf) mp4 base box.
1. [H.264-AVC-ISO_IEC_14496-10.pdf, ISO_IEC_14496-10-AVC-2003.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-10-AVC-2003.pdf), avc标准，编码部分。
1. [H.264-AVC-ISO_IEC_14496-12_2012-mp4.pdf, ISO_IEC_14496-12-base-format-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-12-base-format-2012.pdf), mp4标准。
1. [ISO_14496-14_2003_mp4-file-format.pdf, ISO_IEC_14496-14-MP4-2003.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-14-MP4-2003.pdf), mp4文件格式。
1. [H.264-AVC-ISO_IEC_14496-10-2012.pdf, ISO_IEC_14496-10-AVC-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-10-AVC-2012.pdf), avc标准，编码部分。上面的标准是2003年的，和下面的15是2010年的对不上。http://www.itu.int/ITU-T/recommendations/rec.aspx?rec=11466
1. [H.264-AVC-ISO_IEC_14496-15.pdf, ISO_IEC_14496-15-AVC-format-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_14496-15-AVC-format-2012.pdf), avc标准，封装部分。
1. [H.264_MPEG-4-Part-10-White-Paper.pdf](http://github.com/ossrs/srs/wiki/doc/H.264_MPEG-4-Part-10-White-Paper.pdf), h264简介。

## HTTP

1. [http1.0-rfc1945.txt, rfc1945-1996-http1.0.txt](http://github.com/ossrs/srs/wiki/doc/rfc1945-1996-http1.0.txt), http://www.rfc-editor.org/rfc/rfc1945.txt
1. [http1.1-rfc2616.txt, rfc2616-1999-http1.1.txt](http://github.com/ossrs/srs/wiki/doc/rfc2616-1999-http1.1.txt), http://www.rfc-editor.org/rfc/rfc2616.txt
1. [arpa-internet-text-messages-rfc822.txt, rfc822-1982-arpa-internet-text-messages.txt](http://github.com/ossrs/srs/wiki/doc/rfc822-1982-arpa-internet-text-messages.txt), http://www.rfc-editor.org/rfc/rfc822.txt

## RTC

1. [STUN, rfc5389-2008-stun.pdf](http://github.com/ossrs/srs/wiki/doc/rfc5389-2008-stun.pdf): https://tools.ietf.org/html/rfc5389
1. [TURN, rfc5766-2010-turn.pdf](http://github.com/ossrs/srs/wiki/doc/rfc5766-2010-turn.pdf): https://tools.ietf.org/html/rfc5766
1. [ICE, rfc5245-2010-ice.pdf](http://github.com/ossrs/srs/wiki/doc/rfc5245-2010-ice.pdf): https://tools.ietf.org/html/rfc5245
1. [SIP, rfc3261-2002-sip.pdf](http://github.com/ossrs/srs/wiki/doc/rfc3261-2002-sip.pdf): https://tools.ietf.org/html/rfc3261

## SRT

1. [Haivision_SRT_Open_Source_White_Paper.pdf](http://github.com/ossrs/srs/wiki/doc/Haivision_SRT_Open_Source_White_Paper.pdf)
1. [SRT_Alliance_Deployment_Guide.pdf](http://github.com/ossrs/srs/wiki/doc/SRT_Alliance_Deployment_Guide.pdf)
1. [SRT_Protocol_TechnicalOverview_DRAFT_2018-10-17.pdf](http://github.com/ossrs/srs/wiki/doc/SRT_Protocol_TechnicalOverview_DRAFT_2018-10-17.pdf)

## Others

1. [kafka-160915-0553-82964.pdf](http://github.com/ossrs/srs/wiki/doc/kafka-160915-0553-82964.pdf), https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol
1. [rtmfp-rfc7016.pdf, rfc7016-2013-rtmfp.pdf](http://github.com/ossrs/srs/wiki/doc/rfc7016-2013-rtmfp.pdf), adobe RTMFP, http://tools.ietf.org/html/rfc7016.
1. [rtmfp-tsvarea-1.pdf](http://github.com/ossrs/srs/wiki/doc/rtmfp-tsvarea-1.pdf), http://www.ietf.org/proceedings/10mar/slides/tsvarea-1.pdf
1. [MPEG-DASH-ISO_IEC_23009-1_2012.pdf, ISO_IEC_23009-1-DASH-2012.pdf](http://github.com/ossrs/srs/wiki/doc/ISO_IEC_23009-1-DASH-2012.pdf), MPEG-DASH标准。
1. [rfc2326-1998-rtsp.pdf](http://github.com/ossrs/srs/wiki/doc/rfc2326-1998-rtsp.pdf)
1. [rfc3550-2003-rtp.pdf](http://github.com/ossrs/srs/wiki/doc/rfc3550-2003-rtp.pdf)
1. [adobe-hds-specification.pdf](http://github.com/ossrs/srs/wiki/doc/adobe-hds-specification.pdf)
1. [adobe-media-manifest-specification.pdf](http://github.com/ossrs/srs/wiki/doc/adobe-media-manifest-specification.pdf)
1. [HTTPDynamicStreamingSpecificationErrataMay2014.pdf](http://github.com/ossrs/srs/wiki/doc/HTTPDynamicStreamingSpecificationErrataMay2014.pdf)
1. [FlashMediaManifestFormatSpecificationErrataMay2014.pdf](http://github.com/ossrs/srs/wiki/doc/FlashMediaManifestFormatSpecificationErrataMay2014.pdf)

## Files

1. ffmpeg-logo.png, ffmpeg-min.png, ffmpeg的logo。
1. source.flv, source.200kbps.768x320.flv, avatar预告片，400kbps。

Winlin

---

### Skills Internal Docs For Srs References Cpp Docs Doc Getting Started (`skills/internal-docs-for-srs/references/cpp-docs/doc/getting-started.md`)

---
title: Docker
sidebar_label: Docker
hide_title: false
hide_table_of_contents: false
---

# Docker

Please run SRS with docker.

## Live Streaming

SRS supports live streaming.

Run SRS using docker:

```bash
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 ossrs/srs:5
```

> Note: The available images is [here](https://hub.docker.com/r/ossrs/srs/tags).

Use docker of FFmpeg to publish:

```bash
docker run --rm -it ossrs/srs:encoder ffmpeg -stream_loop -1 -re -i doc/source.flv \
  -c copy -f flv rtmp://host.docker.internal/live/livestream
```

Or publish stream by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) :

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

> Note: The file `./doc/source.flv` is under the source repository of SRS.

Play stream by:

* RTMP (by [VLC](https://www.videolan.org/)): `rtmp://localhost/live/livestream`
* H5(HTTP-FLV): [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)
* H5(HLS): [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.m3u8&port=8080&schema=http)

## WebRTC

SRS supports WebRTC for video chat.

Run SRS using docker:

```bash
CANDIDATE="192.168.1.10"
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 1990:1990 -p 8088:8088 \
    --env CANDIDATE=$CANDIDATE -p 8000:8000/udp \
    ossrs/srs:5
```

> Note: Please replace the IP with your server IP.

> Note: About CANDIDATE, please read [CANDIDATE](./webrtc.md#config-candidate)

If SRS runs on localhost, push stream to SRS by [WebRTC: Publish](http://localhost:8080/players/rtc_publisher.html?autostart=true&stream=livestream&port=8080&schema=http)

> Note: If not localhost, browser(WebRTC) requires HTTPS, please see [WebRTC using HTTPS](./getting-started.md#webrtc-using-https) for detail.

Play stream of SRS by [WebRTC: Play](http://localhost:8080/players/rtc_player.html?autostart=true&stream=livestream&schema=http)

> Note: If use different streams, you're able to do video chat application.

## WebRTC for Live Streaming

SRS supports coverting live streaming to WebRTC.

Run SRS using docker:

```bash
CANDIDATE="192.168.1.10"
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8000:8000/udp \
    --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
    --env SRS_RTC_SERVER_ENABLED=on --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE \
    --env SRS_VHOST_RTC_ENABLED=on --env SRS_VHOST_RTC_RTMP_TO_RTC=on --env SRS_VHOST_RTC_RTC_TO_RTMP=on \
    --env SRS_VHOST_HTTP_REMUX_ENABLED=on --env SRS_VHOST_HLS_ENABLED=on \
    ossrs/srs:8 ./objs/srs -e
```

> Note: Please replace the IP with your server IP.

> Note: About CANDIDATE, please read [CANDIDATE](./webrtc.md#config-candidate)

> Note: If convert RTMP to WebRTC, you can also use the config file [`rtmp2rtc.conf`](https://github.com/ossrs/srs/issues/2728#rtmp2rtc-en-guide)

Use docker of FFmpeg to publish:

```bash
docker run --rm -it ossrs/srs:encoder ffmpeg -stream_loop -1 -re -i doc/source.flv \
  -c copy -f flv rtmp://host.docker.internal/live/livestream
```

Or publish stream by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) :

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

> Note: The file `./doc/source.flv` is under the source repository of SRS.

Play stream by:

* WebRTC: [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html?autostart=true)
* H5(HTTP-FLV): [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)
* H5(HLS): [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.m3u8&port=8080&schema=http)

## WebRTC using HTTPS

When pushing stream to SRS, if not localhost, for example, to view WebRTC on pad or mobile phone, when SRS is running on remote server.

> Note: If only need to play WebRTC stream, HTTP is ok. If wants to push stream, and not localhost, you need HTTPS.

Run SRS using docker:

```bash
CANDIDATE="192.168.1.10"
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 1990:1990 -p 8088:8088 -p 8000:8000/udp \
    --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_API_HTTPS_ENABLED=on \
    --env SRS_HTTP_SERVER_ENABLED=on --env SRS_HTTP_SERVER_HTTPS_ENABLED=on \
    --env SRS_RTC_SERVER_ENABLED=on --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE --env SRS_VHOST_RTC_ENABLED=on \
    --env SRS_VHOST_HTTP_REMUX_ENABLED=on --env SRS_VHOST_HLS_ENABLED=on \
    ossrs/srs:8 ./objs/srs -e
```

> Note: Please replace the IP with your server IP.

> Note: About CANDIDATE, please read [CANDIDATE](./webrtc.md#config-candidate)

> Remark: Please use your HTTPS key and cert file, please read
> **[HTTPS API](./http-api.md#https-api)**
> and **[HTTPS Callback](./http-callback.md#https-callback)**
> and **[HTTPS Live Streaming](./flv.md#https-flv-live-stream)**,
> however HTTPS proxy also works perfect with SRS such as Nginx.

Push stream to SRS by [WebRTC: Publish](https://192.168.3.82:8088/players/rtc_publisher.html?autostart=true&stream=livestream&api=1990&schema=https)

Play stream of SRS by [WebRTC: Play](https://192.168.3.82:8088/players/rtc_player.html?autostart=true&stream=livestream&api=1990&schema=https)

> Note: For self-sign certificate, please type `thisisunsafe` to accept it.

> Note: If use different streams, you're able to do video chat application.

## SRT for Live Streaming

SRS supports publishing by SRT for live streaming, and play by SRT or other protocols.

First, start SRS with Docker:

```bash
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 10080:10080/udp \
    --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
    --env SRS_SRT_SERVER_ENABLED=on --env SRS_VHOST_SRT_ENABLED=on --env SRS_VHOST_SRT_SRT_TO_RTMP=on \
    --env SRS_SRT_SERVER_LATENCY=0 --env SRS_SRT_SERVER_RECVLATENCY=0 --env SRS_SRT_SERVER_TSBPDMODE=off \
    --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
    ossrs/srs:8 ./objs/srs -e
```

Publish stream by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) :

```bash
ffmpeg -re -i ./doc/source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
```

Play stream by [ffplay](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download)

```bash
ffplay 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request'
```

## Multiple Streams

You can send multiple streams to SRS by using different URLs. There's no need to change any settings; 
just change the URL for the stream you're publishing and playing. It's very easy and straightforward.

* `rtmp://ip/live/livesteam`
* `rtmp://ip/live/livesteamN`
* `rtmp://ip/liveN/livestreamN`
* `rtmp://ip/whatever/doesnotmatter`
* `srt://ip:10080?streamid=#!::r=anyM/streamN,m=publish`
* `http://ip:1985/rtc/v1/whip/?app=anyM&stream=streamN`
* `http://ip:1985/rtc/v1/whep/?app=anyM&stream=streamN`
* `http://ip:8080/anyM/streamN.flv`
* `http://ip:8080/anyM/streamN.m3u8`
* `https://ip:8080/anyM/streamN.flv`
* `https://ip:8080/anyM/streamN.m3u8`

SRS uses a configuration at the virtual host (vhost) level. All applications(app) and streams within the 
same vhost share this configuration. For more information, please refer to the [RTMP URL](./rtmp-url-vhost.md) 
documentation.

---

### Trunk Doc Architecture (`trunk/doc/Architecture.md`)

# Architecture

The architecture of SRS.

> Note: Please read **Wiki: Gettting Started( [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started) / [CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) )** first.

## Architecture

The stream architecture of SRS.

```
/* Detailed source-code truncated for AI context efficiency. */
```

Remark:

1. Encoder: Encoder pushs RTMP stream to SRS.
1. MediaSource: Supports any media source, ingesting by ffmpeg.
1. Ingester: Forks a ffmpeg(or other tools) to ingest as rtmp to SRS, please read [Ingest][v4_CN_Ingest].
1. Streamer: Remuxs other protocols to RTMP, please read [Streamer][v4_CN_Streamer].
1. EXEC: Like NGINX-RTMP, EXEC forks external tools for events, please read [ng-exec][v4_CN_NgExec].
1. SRTModule: A isolate module which run in [hybrid](https://github.com/ossrs/srs/issues/1147#issuecomment-577574883) model.

## System Requirements

Supported operating systems and hardware:

* Linux, with x86, x86-64 or arm.
* Mac, with intel chip.
* Other OS, such as Windows, please use [docker][docker-srs4].

[authors]: https://github.com/ossrs/srs/blob/4.0release/trunk/AUTHORS.txt
[bigthanks]: https://github.com/ossrs/srs/wiki/Product#release40
[st]: https://github.com/ossrs/state-threads
[st2]: https://github.com/ossrs/state-threads/tree/srs
[state-threads]: https://github.com/ossrs/state-threads/tree/srs
[nginx]: http://nginx.org/
[srs]: https://github.com/ossrs/srs
[gitee]: https://gitee.com/ossrs/srs
[srs-bench]: https://github.com/ossrs/srs-bench
[srs-ngb]: https://github.com/ossrs/srs-console
[srs-librtmp]: https://github.com/ossrs/srs-librtmp
[gitlab]: https://gitlab.com/winlinvip/srs-gitlab
[console]: http://ossrs.net:8080/console
[docker-srs3]: https://github.com/ossrs/srs-docker/tree/v3#usage
[docker-srs4]: https://github.com/ossrs/srs-docker/tree/v4#usage
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage

[v4_CN_Git]: https://github.com/ossrs/srs/wiki/v4_CN_Git
[v4_EN_Git]: https://github.com/ossrs/srs/wiki/v4_EN_Git
[v4_CN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMP
[v4_EN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMP
[v4_CN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMPCluster
[v4_EN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMPCluster
[v4_CN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleOriginCluster
[v4_EN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleOriginCluster
[v4_CN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHLS
[v4_EN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHLS
[v4_CN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleTranscode2HLS
[v4_EN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleTranscode2HLS
[v4_CN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_SampleFFMPEG
[v4_EN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_SampleFFMPEG
[v4_CN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_CN_SampleForward
[v4_EN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_EN_SampleForward
[v4_CN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRealtime
[v4_EN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRealtime
[v4_CN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC
[v4_EN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC
[v4_CN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
[v4_EN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC#config-candidate
[v4_CN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_CN_SampleARM
[v4_EN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_EN_SampleARM
[v4_CN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_CN_SampleIngest
[v4_EN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_EN_SampleIngest
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_OriginCluster
[v4_EN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_OriginCluster
[v4_CN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_CN_REUSEPORT
[v4_EN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_EN_REUSEPORT
[v4_CN_Sample]: https://github.com/ossrs/srs/wiki/v4_CN_Sample
[v4_EN_Sample]: https://github.com/ossrs/srs/wiki/v4_EN_Sample
[v4_CN_Product]: https://github.com/ossrs/srs/wiki/v4_CN_Product
[v4_EN_Product]: https://github.com/ossrs/srs/wiki/v4_EN_Product
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home

[v4_CN_Compare]: https://github.com/ossrs/srs/wiki/v4_CN_Compare
[v4_EN_Compare]: https://github.com/ossrs/srs/wiki/v4_EN_Compare
[v4_CN_Build]: https://github.com/ossrs/srs/wiki/v4_CN_Build
[v4_EN_Build]: https://github.com/ossrs/srs/wiki/v4_EN_Build
[v4_CN_Performance]: https://github.com/ossrs/srs/wiki/v4_CN_Performance
[v4_EN_Performance]: https://github.com/ossrs/srs/wiki/v4_EN_Performance
[v4_CN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryRTMP
[v4_EN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryRTMP
[v4_CN_Edge]: https://github.com/ossrs/srs/wiki/v4_CN_Edge
[v4_EN_Edge]: https://github.com/ossrs/srs/wiki/v4_EN_Edge
[v4_CN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_CN_RtmpUrlVhost
[v4_EN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_EN_RtmpUrlVhost
[v4_CN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_CN_RTMPHandshake
[v4_EN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_EN_RTMPHandshake
[v4_CN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPServer
[v4_EN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPServer
[v4_CN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS
[v4_EN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS
[v4_CN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS#hlsaudioonly
[v4_EN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS#hlsaudioonly
[v4_CN_Reload]: https://github.com/ossrs/srs/wiki/v4_CN_Reload
[v4_EN_Reload]: https://github.com/ossrs/srs/wiki/v4_EN_Reload
[v4_CN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#gop-cache
[v4_EN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#gop-cache
[v4_CN_Forward]: https://github.com/ossrs/srs/wiki/v4_CN_Forward
[v4_EN_Forward]: https://github.com/ossrs/srs/wiki/v4_EN_Forward
[v4_CN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_FFMPEG
[v4_EN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_FFMPEG
[v4_CN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback
[v4_EN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPCallback
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLinuxArm
[v4_EN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLinuxArm
[v4_CN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_CN_LinuxService
[v4_EN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_EN_LinuxService
[v4_CN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_CN_RTMP-ATC
[v4_EN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_EN_RTMP-ATC
[v4_CN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPApi
[v4_EN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPApi
[v4_CN_Ingest]: https://github.com/ossrs/srs/wiki/v4_CN_Ingest
[v4_EN_Ingest]: https://github.com/ossrs/srs/wiki/v4_EN_Ingest
[v4_CN_DVR]: https://github.com/ossrs/srs/wiki/v4_CN_DVR
[v4_EN_DVR]: https://github.com/ossrs/srs/wiki/v4_EN_DVR
[v4_CN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLog
[v4_EN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLog
[v4_CN_DRM2]: https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse
[v4_EN_DRM2]: https://github.com/ossrs/srs/wiki/v4_EN_DRM#tokentraverse
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_CN_FlvVodStream
[v4_EN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_EN_FlvVodStream
[v4_CN_Security]: https://github.com/ossrs/srs/wiki/v4_CN_Security
[v4_EN_Security]: https://github.com/ossrs/srs/wiki/v4_EN_Security
[v4_CN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHttpStream
[v4_EN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream
[v4_CN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHDS
[v4_EN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHDS
[v4_CN_Streamer]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer
[v4_EN_Streamer]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer
[v4_CN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-http-flv-to-srs
[v4_EN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer#push-http-flv-to-srs
[v4_CN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlv
[v4_EN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlv
[v4_CN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlvCluster
[v4_EN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlvCluster
[v4_CN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_CN_SampleDASH
[v4_EN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_EN_SampleDASH

[bug #547]: https://github.com/ossrs/srs/issues/547
[bug #301]: https://github.com/ossrs/srs/issues/301
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #367]: https://github.com/ossrs/srs/issues/367
[bug #257]: https://github.com/ossrs/srs/issues/257
[bug #904]: https://github.com/ossrs/srs/issues/904
[bug #913]: https://github.com/ossrs/srs/issues/913
[bug #1059]: https://github.com/ossrs/srs/issues/1059
[bug #92]: https://github.com/ossrs/srs/issues/92
[bug #464]: https://github.com/ossrs/srs/issues/464
[bug #460]: https://github.com/ossrs/srs/issues/460
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #307]: https://github.com/ossrs/srs/issues/307
[bug #2324]: https://github.com/ossrs/srs/issues/2324
[bug #1657]: https://github.com/ossrs/srs/issues/1657
[bug #1500]: https://github.com/ossrs/srs/issues/1500
[bug #738]: https://github.com/ossrs/srs/issues/738
[bug #299]: https://github.com/ossrs/srs/issues/299
[bug #250]: https://github.com/ossrs/srs/issues/250
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #470]: https://github.com/ossrs/srs/issues/470
[bug #319]: https://github.com/ossrs/srs/issues/319
[bug #1147]: https://github.com/ossrs/srs/issues/1147
[bug #2304]: https://github.com/ossrs/srs/issues/2304
[bug #1535]: https://github.com/ossrs/srs/issues/1535
[bug #1342]: https://github.com/ossrs/srs/issues/1342
[bug #1193]: https://github.com/ossrs/srs/issues/1193
[bug #2093]: https://github.com/ossrs/srs/issues/2093
[bug #465]: https://github.com/ossrs/srs/issues/465
[bug #2091]: https://github.com/ossrs/srs/issues/2091
[bug #2188]: https://github.com/ossrs/srs/issues/2188
[bug #413]: https://github.com/ossrs/srs/issues/413
[bug #1111]: https://github.com/ossrs/srs/issues/1111
[bug #463]: https://github.com/ossrs/srs/issues/463
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #257-c0]: https://github.com/ossrs/srs/issues/257#issuecomment-66864413

[r3.0r5]: https://github.com/ossrs/srs/releases/tag/v3.0-r5
[r3.0r4]: https://github.com/ossrs/srs/releases/tag/v3.0-r4
[r3.0r3]: https://github.com/ossrs/srs/releases/tag/v3.0-r3
[r3.0r2]: https://github.com/ossrs/srs/releases/tag/v3.0-r2
[r3.0r1]: https://github.com/ossrs/srs/releases/tag/v3.0-r1
[r3.0r0]: https://github.com/ossrs/srs/releases/tag/v3.0-r0
[r3.0b4]: https://github.com/ossrs/srs/releases/tag/v3.0-b4
[r3.0b3]: https://github.com/ossrs/srs/releases/tag/v3.0-b3
[r3.0b2]: https://github.com/ossrs/srs/releases/tag/v3.0-b2
[r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7
[r3.0a6]: https://github.com/ossrs/srs/releases/tag/v3.0-a6
[r3.0a5]: https://github.com/ossrs/srs/releases/tag/v3.0-a5
[r3.0a4]: https://github.com/ossrs/srs/releases/tag/v3.0-a4
[r3.0a3]: https://github.com/ossrs/srs/releases/tag/v3.0-a3
[r3.0a2]: https://github.com/ossrs/srs/releases/tag/v3.0-a2
[r3.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
[r2.0r8]: https://github.com/ossrs/srs/releases/tag/v2.0-r8
[r2.0r7]: https://github.com/ossrs/srs/releases/tag/v2.0-r7
[r2.0r6]: https://github.com/ossrs/srs/releases/tag/v2.0-r6
[r2.0r5]: https://github.com/ossrs/srs/releases/tag/v2.0-r5
[r2.0r4]: https://github.com/ossrs/srs/releases/tag/v2.0-r4
[r2.0r3]: https://github.com/ossrs/srs/releases/tag/v2.0-r3
[r2.0r2]: https://github.com/ossrs/srs/releases/tag/v2.0-r2
[r2.0r1]: https://github.com/ossrs/srs/releases/tag/v2.0-r1
[r2.0r0]: https://github.com/ossrs/srs/releases/tag/v2.0-r0
[r2.0b4]: https://github.com/ossrs/srs/releases/tag/v2.0-b4
[r2.0b3]: https://github.com/ossrs/srs/releases/tag/v2.0-b3
[r2.0b2]: https://github.com/ossrs/srs/releases/tag/v2.0-b2
[r2.0b1]: https://github.com/ossrs/srs/releases/tag/v2.0-b1
[r2.0b0]: https://github.com/ossrs/srs/releases/tag/v2.0-b0
[r2.0a3]: https://github.com/ossrs/srs/releases/tag/v2.0-a3
[r2.0a2]: https://github.com/ossrs/srs/releases/tag/v2.0-a2
[r2.0a1]: https://github.com/ossrs/srs/releases/tag/v2.0-a1
[r2.0a0]: https://github.com/ossrs/srs/releases/tag/v2.0-a0
[r1.0r4]: https://github.com/ossrs/srs/releases/tag/v1.0-r4
[r1.0r3]: https://github.com/ossrs/srs/releases/tag/v1.0-r3
[r1.0r2]: https://github.com/ossrs/srs/releases/tag/v1.0-r2
[r1.0r1]: https://github.com/ossrs/srs/releases/tag/v1.0-r1
[r1.0r0]: https://github.com/ossrs/srs/releases/tag/v1.0-r0
[r1.0b0]: https://github.com/ossrs/srs/releases/tag/v0.9.8
[r1.0a7]: https://github.com/ossrs/srs/releases/tag/v0.9.7
[r1.0a6]: https://github.com/ossrs/srs/releases/tag/v0.9.6
[r1.0a5]: https://github.com/ossrs/srs/releases/tag/v0.9.5
[r1.0a4]: https://github.com/ossrs/srs/releases/tag/v0.9.4
[r1.0a3]: https://github.com/ossrs/srs/releases/tag/v0.9.3
[r1.0a2]: https://github.com/ossrs/srs/releases/tag/v0.9.2
[r1.0a0]: https://github.com/ossrs/srs/releases/tag/v0.9.1
[r0.9]: https://github.com/ossrs/srs/releases/tag/v0.9.0
[r0.8]: https://github.com/ossrs/srs/releases/tag/v0.8.0
[r0.7]: https://github.com/ossrs/srs/releases/tag/v0.7.0
[r0.6]: https://github.com/ossrs/srs/releases/tag/v0.6.0
[r0.5]: https://github.com/ossrs/srs/releases/tag/v0.5.0
[r0.4]: https://github.com/ossrs/srs/releases/tag/v0.4.0
[r0.3]: https://github.com/ossrs/srs/releases/tag/v0.3.0
[r0.2]: https://github.com/ossrs/srs/releases/tag/v0.2.0
[r0.1]: https://github.com/ossrs/srs/releases/tag/v0.1.0


[v4_CN_Contact]: https://github.com/ossrs/srs/wiki/v4_CN_Contact
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

[LICENSE]: https://github.com/ossrs/srs/blob/4.0release/LICENSE
[LicenseMixing]: https://ossrs.net/lts/zh-cn/license

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
[release4]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release40

---

### Trunk Doc CHANGELOG (`trunk/doc/CHANGELOG.md`)

# Changelog

The changelog for SRS.

> Note: Please read **Wiki: Gettting Started( [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started) / [CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) )** first.

<a name="v4-changes"></a>

## SRS 4.0 Changelog

* v4.0, 2022-06-29, Update SRS image for r.ossrs.net. v4.0.253
* v4.0, 2022-06-11, For [#3058](https://github.com/ossrs/srs/pull/3058): Docker: Support x86_64, armv7 and aarch64 docker image (#3058). v4.0.252
* v4.0, 2022-03-19, For [#2893](https://github.com/ossrs/srs/pull/2893): SRT: Decouple publish with play url (#2893). v4.0.251
* v4.0, 2022-03-19, Merge [#2908](https://github.com/ossrs/srs/pull/2908): SRT: url supports multiple QueryStrings (#2908). v4.0.250
* v4.0, 2022-03-17, SRT: Support debug and run with CLion. v4.0.249
* v4.0, 2022-03-15, Merge [#2966](https://github.com/ossrs/srs/pull/2966): Bugfix: Fix rtcp nack blp encode bug (#2966). v4.0.248
* v4.0, 2022-03-07, RTC: Identify the WebRTC publisher in param for hooks. v4.0.247
* v4.0, 2022-03-07, SRT: Append vhost to stream, not app. v4.0.246
* v4.0, 2022-02-15, Fix warnings for uuid. v4.0.245
* v4.0, 2022-02-15, Merge [#2917](https://github.com/ossrs/srs/pull/2917): SRT: Close connection if RTMP failed. (#2917). v4.0.244
* v4.0, 2022-02-15, Refine build script for SRT to avoid warnings. v4.0.243
* v4.0, 2022-02-11, Support new fields for feature query. v4.0.241
* v4.0, 2022-02-09, Mirror docker images in TCR Singapore. v4.0.240
* v4.0, 2022-02-08, Refine the error for WebRTC H5 publisher. v4.0.239
* v4.0, 2022-02-04, Push docker to docker, acr and tcr. v4.0.238
* v4.0, 2022-02-03, Merge [#2888](https://github.com/ossrs/srs/pull/2888): Fix bug when the value of http header is empty. (#2888). v4.0.237
* v4.0, 2022-01-30, Refine docker console, preview by players at the same server. v4.0.236
* v4.0, 2022-01-30, For docker, always use the console for logging. v4.0.235
* v4.0, 2022-01-29, Merge [#2896](https://github.com/ossrs/srs/pull/2896): SRT: Reduce the SRT bug by limit the max times for retry. (#2896). v4.0.234
* v4.0, 2022-01-23, Merge [#2886](https://github.com/ossrs/srs/pull/2886): Fix bug when free addrinfo. (#2886). v4.0.233
* v4.0, 2022-01-22, Merge [#2887](https://github.com/ossrs/srs/pull/2887): Fix memory leak in SrsMetaCache. (#2887). v4.0.232
* v4.0, 2022-01-21, Support docker image for [lighthouse](https://hub.docker.com/r/ossrs/lighthouse). v4.0.231
* v4.0, 2022-01-17, Enable rtmp2rtc and rtc2rtmp for docker.conf
* v4.0, 2022-01-17, Support docker image for [droplet](https://hub.docker.com/r/ossrs/droplet). v4.0.230
* v4.0, 2022-01-16, Update README for **Cloud Virtual Machine([CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#cloud-virtual-machine) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#cloud-virtual-machine))**
* v4.0, 2022-01-13, Merge [#2872](https://github.com/ossrs/srs/pull/2872): RTC: fix play rtc judge for config rtc2rtmp on. (#2872). v4.0.229
* v4.0, 2022-01-13, Support configure with --config as default config file. v4.0.227
* v4.0, 2022-01-13, For [#2880](https://github.com/ossrs/srs/pull/2880): Add SrsAutoFreeH to release ptr with hooks. (#2880). v4.0.226
* v4.0, 2022-01-13, Support api_port to specify the WebRTC API port. v4.0.224
* v4.0, 2022-01-13, Merge [#2873](https://github.com/ossrs/srs/pull/2873): LiveSource: Refine fetch for external exposed interface. (#2873). v4.0.223
* v4.0, 2022-01-13, Add conf/vm.conf for cloud virtual machine. v4.0.222
* v4.0, 2022-01-12, Refine the running homepage. v4.0.221
* v4.0, 2022-01-12, Merge [#2863](https://github.com/ossrs/srs/pull/2863): RTC: fix play crash or no stream for rtmp2rtc tips. (#2863). v4.0.220
* v4.0, 2022-01-05, For [#2717](https://github.com/ossrs/srs/issues/2717): When reopening segment, never update the duration. (#2717). v4.0.219
* v4.0, 2022-01-04, Discover api server and ip as candidates. v4.0.218
* v4.0, 2022-01-04, Install test-on self-sign certificate. v4.0.217
* v4.0, 2022-01-03, For [#2824](https://github.com/ossrs/srs/issues/2824): Support config in_docker to fix the detect fail. (#2824). v4.0.216
* v4.0, 2021-12-31, For [#2728](https://github.com/ossrs/srs/issues/2728): Refine error log for rtmp2rtc. (#2728). v4.0.215
* v4.0, 2021-12-29, Merge [#2770](https://github.com/ossrs/srs/pull/2770), [#2820](https://github.com/ossrs/srs/pull/2820): Bugs fixed. (#2770)(#2820). v4.0.214
* v4.0, 2021-12-27, Fix [#2811](https://github.com/ossrs/srs/issues/2811): Fix ulimit issue by detecting epoll on Ubuntu. (#2811). v4.0.213
* v4.0, 2021-12-26, Fix [#2247](https://github.com/ossrs/srs/pull/2247): Cleanup server for GMC, by WaitGroup to destroy. (#2247). v4.0.212
* v4.0, 2021-12-25, For [#2809](https://github.com/ossrs/srs/issues/2809), HTTP: Fix 2GB+ mp4/flv file downloading error. (#2809)(#2780)(#2781). v4.0.211
* v4.0, 2021-12-23, For [#2800](https://github.com/ossrs/srs/issues/2800), Fix bug for large mp4(5G+) offset. (#2800). v4.0.210
* v4.0, 2021-12-23, For [#2807](https://github.com/ossrs/srs/issues/2807), Fix bug for HLS log printing. (#2807). v4.0.209
* v4.0, 2021-12-23, For [#2711](https://github.com/ossrs/srs/pull/2711), Refine the default config file. (#2711). v4.0.208
* v4.0, 2021-12-20, Merge [#2784](https://github.com/ossrs/srs/pull/2784): RTC: Support payload name AV1X/AV1. (#2784)(#2760). v4.0.207
* v4.0, 2021-12-07, Merge [#2771](https://github.com/ossrs/srs/pull/2771): RTC: Fix memory leak when replace rtp packet in cache. (#2771). v4.0.205
* v4.0, 2021-12-06, Merge [#2766](https://github.com/ossrs/srs/pull/2766): RTC: Fix nack encode seqnum. (#2766). v4.0.204
* v4.0, 2021-12-04, Merge [#2768](https://github.com/ossrs/srs/pull/2768): RTC: Fix bugs for RTC2RTMP. (#2768). v4.0.203
* v4.0, 2021-12-04, Merge [#2757](https://github.com/ossrs/srs/pull/2757): RTC: Ignore empty audio packet when transcoding (#2757). v4.0.202
* v4.0, 2021-12-01, Fix [#2762](https://github.com/ossrs/srs/pull/2762): RTC: Refine publish security error message (#2762). v4.0.200
* v4.0, 2021-11-25, Merge [#2751](https://github.com/ossrs/srs/pull/2751): RTC: Fix crash when pkt->payload() if pkt is nullptr (#2751). v4.0.199
* v4.0, 2021-11-15, For [#1708](https://github.com/ossrs/srs/pull/1708): ST: Print log when multiple thread stop one coroutine. (#1708). v4.0.198
* v4.0, 2021-11-14, Merge [#2732](https://github.com/ossrs/srs/pull/2732): WebRTC: Fail to publish RTC automatically for HTML5. (#2732). v4.0.197
* v4.0, 2021-11-13, Merge [#2729](https://github.com/ossrs/srs/pull/2729): RTC: check audio track exist when negotiate (#2729). v4.0.196
* v4.0, 2021-11-09, Merge [#2721](https://github.com/ossrs/srs/pull/2721): Rtc2Rtmp: Use RTP timestamp to identify video frames. v4.0.195
* v4.0, 2021-11-07, Merge [#2711](https://github.com/ossrs/srs/pull/2711): Config: Guess config files by [FHS](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard). v4.0.194
* v4.0, 2021-11-07, Merge [#2714](https://github.com/ossrs/srs/pull/2714): DVR: copy req from publish. v4.0.193
* v4.0, 2021-11-04, Merge [#2707](https://github.com/ossrs/srs/pull/2707): Refuse edge request when state is stopping. v4.0.192
* v4.0, 2021-11-02, Auto create package by github actions. v4.0.191
* v4.0, 2021-10-30, Merge [#2552](https://github.com/ossrs/srs/pull/2552): Script: Refine CentOS7 service script to restart SRS. v4.0.190
* v4.0, 2021-10-30, Merge [#2397](https://github.com/ossrs/srs/pull/2397): SRTP: Patch libsrtp2 to fix GCC10 build fail. v4.0.189
* v4.0, 2021-10-30, Merge [#2284](https://github.com/ossrs/srs/pull/2284): Forward: Fast quit when cycle fail. v4.0.188
* v4.0, 2021-10-28, Merge [#2186](https://github.com/ossrs/srs/pull/2186): Gop: Ignore zero timestamp when shrinking. v4.0.187
* v4.0, 2021-10-27, Merge [#1963](https://github.com/ossrs/srs/pull/1963): Cluster: Origin server shouldn't be it's own coworker. v4.0.186
* v4.0, 2021-10-25, Merge [#2692](https://github.com/ossrs/srs/pull/2692): API: Add server_id into http_hooks. v4.0.185
* v4.0, 2021-10-22, Merge [#2687](https://github.com/ossrs/srs/pull/2687): API: Always stat client event if auth fail. v4.0.183
* v4.0, 2021-10-20, Merge [#1758](https://github.com/ossrs/srs/pull/1758): JSON: Support escape special chars. v4.0.182
* v4.0, 2021-10-19, Merge [#1754](https://github.com/ossrs/srs/pull/1754): RTMP: If port is explicity set to 0, use default 1935. v4.0.181
* v4.0, 2021-10-18, Merge [#2670](https://github.com/ossrs/srs/pull/2670): SRT: Solve mpegts demux assert bug. v4.0.180
* v4.0, 2021-10-16, Merge [#2665](https://github.com/ossrs/srs/pull/2665): API: Fix the same 'client_id' error when asynchronous call. v4.0.179
* v4.0, 2021-10-13, Merge [#2671](https://github.com/ossrs/srs/pull/2671): SRT: Pes error when mpegts demux in srt. v4.0.178
* v4.0, 2021-10-12, Merge [#2550](https://github.com/ossrs/srs/pull/2550): API use publish params. v4.0.177
* v4.0, 2021-10-12, Merge [#2549](https://github.com/ossrs/srs/pull/2549): Fix duration issue for HLS on_hls. v4.0.176
* v4.0, 2021-10-11, Fix [#1641](https://github.com/ossrs/srs/issues/1641), HLS/RTC picture corrupt for SPS/PPS lost. v4.0.175
* v4.0, 2021-10-11, RTC: Refine config, aac to rtmp_to_rtc, bframe to keep_bframe. v4.0.174
* v4.0, 2021-10-10, For [#1641](https://github.com/ossrs/srs/issues/1641), Support RTMP publish and play regression test. v4.0.173
* v4.0, 2021-10-10, RTC: Change rtc.aac to discard by default. v4.0.172
* v4.0, 2021-10-10, Fix [#2304](https://github.com/ossrs/srs/issues/2304) Remove Push RTSP feature. v4.0.171
* v4.0, 2021-10-10, Fix [#2653](https://github.com/ossrs/srs/issues/2653) Remove HTTP RAW API. v4.0.170
* v4.0, 2021-10-08, Merge [#2654](https://github.com/ossrs/srs/pull/2654): Parse width and width from SPS/PPS. v4.0.169
* v4.0, 2021-10-08, Default to log to console for docker. v4.0.168
* v4.0, 2021-10-07, Fix bugs #2648, #2415. v4.0.167
* v4.0, 2021-10-03, Support --arch and --cross-prefix for cross compile. 4.0.166
* v4.0, 2021-10-03, Actions: Create source tar file srs-server-4.0.165.tar.gz
* v4.0, 2021-09-23, Merge [#2578](https://github.com/ossrs/srs/pull/2578) Support http callback on_play/stop. 4.0.163
* v4.0, 2021-09-23, Merge [#2618](https://github.com/ossrs/srs/pull/2618) to fix FUA bug.
* v4.0, 2021-09-05, RTC: Merge [#2581](https://github.com/ossrs/srs/pull/2581), Fix listen ipv6 and port. 4.0.161
* v4.0, 2021-09-04, For [#2282](https://github.com/ossrs/srs/pull/2282), [#2181](https://github.com/ossrs/srs/issues/2181), Move DVR async worker from SrsDvrPlan to global.
* v4.0, 2021-09-04, For [#2282](https://github.com/ossrs/srs/pull/2282), [#2181](https://github.com/ossrs/srs/issues/2181), Remove reload for dvr_apply. 4.0.160
* v4.0, 2021-08-28, RTC: Merge [#1859](https://github.com/ossrs/srs/pull/1859), Enhancement: Add param and stream to on_connect. 4.0.159
* v4.0, 2021-08-27, RTC: Merge [#2544](https://github.com/ossrs/srs/pull/2544), Support for multiple SPS/PPS, then pick the first one. 4.0.158
* v4.0, 2021-08-17, RTC: Merge [#2470](https://github.com/ossrs/srs/pull/2470), RTC: Fix rtc to rtmp sync timestamp using sender report. 4.0.157
* v4.0, 2021-08-14, Support Github Actions to publish SRS. 4.0.155
* v4.0, 2021-08-14, RTC: Merge [#2533](https://github.com/ossrs/srs/pull/2533), fix SDP comparison bug. 4.0.154
* v4.0, 2021-08-13, RTC: Merge [#2526](https://github.com/ossrs/srs/pull/2526), fix codec issue for G.711 or H.263. 4.0.152
* v4.0, 2021-08-10, RTC: Merge [#2509](https://github.com/ossrs/srs/pull/2514), support http hooks n_play/stop/publish/unpublish. 4.0.151
* v4.0, 2021-08-07, Merge [#2514](https://github.com/ossrs/srs/pull/2514), Get original client ip instead of proxy ip, for rtc api #2514. 4.0.150
* v4.0, 2021-08-07, Fix [#2508](https://github.com/ossrs/srs/pull/2508), Support features query by API. 4.0.149
* v4.0, 2021-07-25, Fix build failed. 4.0.146
* v4.0, 2021-07-24, Merge [#2373](https://github.com/ossrs/srs/pull/2373), RTC: Fix NACK negotiation bug for Firefox. 4.0.145
* v4.0, 2021-07-24, Merge [#2483](https://github.com/ossrs/srs/pull/2483), RTC: Support statistic for HTTP-API, HTTP-Callback and Security. 4.0.144
* v4.0, 2021-07-21, Merge [#2474](https://github.com/ossrs/srs/pull/2474), SRT: Use thread-safe log for multiple-threading SRT module. 4.0.143
* v4.0, 2021-07-17, Fix bugs and enhance code. 4.0.142
* v4.0, 2021-07-16, Support [CLion and cmake](https://github.com/ossrs/srs/wiki/v4_CN_IDE#clion) to build and debug SRS. 4.0.141
* v4.0, 2021-07-08, For [#2403](https://github.com/ossrs/srs/issues/2403), fix padding packets for RTMP2RTC. 4.0.140
* v4.0, 2021-07-04, For [#2424](https://github.com/ossrs/srs/issues/2424), use srandom/random to generate. 4.0.139
* v4.0, 2021-07-01, Merge [#2452](https://github.com/ossrs/srs/pull/2452), fix FFmpeg bug by updating channel_layout. 4.0.138
* v4.0, 2021-06-30, Merge [#2440](https://github.com/ossrs/srs/pull/2440), fix [#2390](https://github.com/ossrs/srs/issues/2390), SRT bug for zerolatency. 4.0.137
* v4.0, 2021-06-28, Merge [#2435](https://github.com/ossrs/srs/pull/2435), fix bug for HTTP-RAW-API to check vhost. 4.0.136
* v4.0, 2021-06-28, Fix [#2431](https://github.com/ossrs/srs/issues/2431), configure FFmpeg bug. 4.0.135 
* v4.0, 2021-06-28, Merge [#2444](https://github.com/ossrs/srs/pull/2444), add libavcodec/crystalhd.c for FFmpeg. 4.0.134
* v4.0, 2021-06-28, Merge [#2438](https://github.com/ossrs/srs/pull/2438), fix losing of last HLS ts file 4.0.133
* v4.0, 2021-06-27, Squash for [#2424](https://github.com/ossrs/srs/issues/2424), query the latest available version. 4.0.132
* v4.0, 2021-06-24, Merge [#2429](https://github.com/ossrs/srs/pull/2429) to fix SRT bug. 4.0.131
* v4.0, 2021-06-21, Fix [#2413](https://github.com/ossrs/srs/issues/2413), fix RTMP to RTC bug 4.0.130
* v4.0, 2021-06-20, Guess where FFmpeg is. 4.0.129
* v4.0, 2021-06-20, Fix [#1685](https://github.com/ossrs/srs/issues/1685), support RTC cross-build for armv7/armv8(aarch64). 4.0.128
* v4.0, 2021-06-17, Fix [#2214](https://github.com/ossrs/srs/issues/2214), remove detection for gmc and gmp.
* v4.0, 2021-06-16, Change [GB28181](https://github.com/ossrs/srs/issues/1500) to [feature/gb28181](https://github.com/ossrs/srs/tree/feature/gb28181). 4.0.127
* v4.0, 2021-06-01, Support --shared-ffmpeg to link with *.so for LGPL license. 4.0.126
* v4.0, 2021-06-01, Support --shared-srt to link with *.so for MPL license. 4.0.125
* v4.0, 2021-05-31, Use [SPDX-License-Identifier: MIT](https://spdx.dev/ids/). 4.0.124
* v4.0, 2021-05-21, Fix [#2370](https://github.com/ossrs/srs/issues/2370) bug for Firefox play stream(published by Chrome). 4.0.121
* v4.0, 2021-05-21, RTC: Refine sdk, migrate from onaddstream to ontrack. 4.0.120
* v4.0, 2021-05-21, Tools: Refine configure options. 4.0.119
* v4.0, 2021-05-20, Fix build fail when disable RTC by --rtc=off. 4.0.118
* v4.0, 2021-05-15, SRT: Build SRT from source by SRS. 4.0.115
* v4.0, 2021-05-15, Rename SrsConsumer* to SrsLiveConsumer*. 4.0.114
* v4.0, 2021-05-15, Rename SrsRtcStream* to SrsRtcSource*. 4.0.113
* v4.0, 2021-05-15, Rename SrsSource* to SrsLiveSource*. 4.0.112
* v4.0, 2021-05-15, Rename SrsRtpPacket2 to SrsRtpPacket. 4.0.111
* v4.0, 2021-05-14, RTC: Remove [Object Cache Pool](https://github.com/ossrs/srs/commit/14bfc98122bba369572417c19ebb2a61b373fc45#commitcomment-47655008), no effect. 4.0.110
* v4.0, 2021-05-14, Change virtual public to public. 4.0.109
* v4.0, 2021-05-14, Refine id and vid for statistic. 4.0.108
* v4.0, 2021-05-09, Refine tid for sdk and demos. 4.0.106
* v4.0, 2021-05-08, Refine shared fast timer. 4.0.105
* v4.0, 2021-05-08, Refine global or thread-local variables initialize. 4.0.104
* v4.0, 2021-05-07, RTC: Support circuit breaker. 4.0.103
* v4.0, 2021-05-07, RTC: Refine play stream find track. 4.0.102
* v4.0, 2021-05-07, RTC: Refine FastTimer to fixed interval. 4.0.101
* v4.0, 2021-05-06, RTC: Fix config bug for nack and twcc. 4.0.99
* v4.0, 2021-05-04, Add video room demo. 4.0.98
* v4.0, 2021-05-03, Add RTC stream merging demo by FFmpeg. 4.0.97
* v4.0, 2021-05-02, Add one to one demo. 4.0.96
* v4.0, 2021-04-20, Support RTC2RTMP bridger and shared FastTimer. 4.0.95
* v4.0, 2021-04-20, Refine transcoder to support aac2opus and opus2aac. 4.0.94
* v4.0, 2021-05-01, Timer: Extract and apply shared FastTimer. 4.0.93
* v4.0, 2021-04-29, RTC: Support AV1 for Chrome M90. 4.0.91
* v4.0, 2021-04-24, Change push-RTSP as deprecated feature.
* v4.0, 2021-04-24, Player: Change the default from RTMP to HTTP-FLV.
* v4.0, 2021-04-24, Disable CherryPy by --cherrypy=off. 4.0.90
* v4.0, 2021-04-01, RTC: Refine TWCC and SDP exchange. 4.0.88
* v4.0, 2021-03-24, RTC: Support WebRTC re-publish stream. 4.0.87
* v4.0, 2021-03-24, RTC: Use fast parse TWCC-ID, ignore in packet parsing. 4.0.86
* v4.0, 2021-03-09, DTLS: Fix ARQ bug, use openssl timeout. 4.0.84
* v4.0, 2021-03-08, DTLS: Fix dead loop by duplicated Alert message. 4.0.83
* v4.0, 2021-03-08, Fix bug when client DTLS is passive. 4.0.82
* v4.0, 2021-03-03, Fix [#2106](https://github.com/ossrs/srs/issues/2106), [#2011](https://github.com/ossrs/srs/issues/2011), RTMP/AAC transcode to Opus bug. 4.0.81
* v4.0, 2021-03-02, Refine build script for FFmpeg and SRTP. 4.0.80
* v4.0, 2021-03-02, Upgrade libsrtp from 2.0.0 to 2.3.0, with source code. 4.0.79
* v4.0, 2021-03-01, Upgrade openssl from 1.1.0e to 1.1.1b, with source code. 4.0.78
* v4.0, 2021-03-01, Enable Object Cache and Zero Copy Nack by default. 4.0.77
* v4.0, 2021-02-28, RTC: Support high performance [Zero Copy NACK](https://github.com/ossrs/srs/commit/36ea67359e55c94ab044cee4b6a4ec901a83a287#commitcomment-47654868). 4.0.76
* v4.0, 2021-02-27, RTC: Support [Object Cache Pool](https://github.com/ossrs/srs/commit/14bfc98122bba369572417c19ebb2a61b373fc45#commitcomment-47655008) for performance. 4.0.75
* v4.0, 2021-02-12, RTC: Support [High Resolution(about 25ms) Timer](https://github.com/ossrs/srs/commit/c5d2027f9af77fc2d34a6b6ca941c0f0fbdd10c4#commitcomment-47655747). 4.0.72
* v4.0, 2021-02-10, RTC: [Improve performance about 700+](https://github.com/ossrs/srs/commit/b431ad738c39f34a5a0a39e81beb7854223db761#commitcomment-47655935) streams. 4.0.71
* v4.0, 2021-02-04, At least wait 1ms when <1ms, to avoid epoll_wait spin loop. 4.0.66
* v4.0, 2021-01-31, Enable -std=c++11 by default. 4.0.65
* v4.0, 2021-01-25, Enable --nasm and --srtp-asm by default for performance. 4.0.64
* v4.0, 2021-01-20, Support HTTP-FLV and HLS for srs-player by H5. 4.0.63
* v4.0, 2021-01-08, HTML5 video tag resolution adaptive. 4.0.59
* v4.0, 2021-01-08, Fix memory leak and bugs for RTC. 4.0.58
* v4.0, 2021-01-06, Merge #2109, Refine srs_string_split.
* v4.0, 2020-12-24, Support disable CherryPy. 4.0.57
* v4.0, 2020-11-12, For [#1998](https://github.com/ossrs/srs/issues/1998), Support Firefox, use PT in offer. 4.0.55
* v4.0, 2020-11-11, For [#1508](https://github.com/ossrs/srs/issues/1508), Transform http header name to upper camel case. 4.0.54
* v4.0, 2020-11-06, For [#1657](https://github.com/ossrs/srs/issues/1657), Read cached data first in SSL. 4.0.48
* v4.0, 2020-11-06, For [#1657](https://github.com/ossrs/srs/issues/1657#issuecomment-722971676), support HTTPS Streaming(HTTPS-FLV, etc). 4.0.47
* v4.0, 2020-11-06, For [#1657](https://github.com/ossrs/srs/issues/1657#issuecomment-722904004), support HTTPS API. 4.0.46
* v4.0, 2020-11-03, For [#1657](https://github.com/ossrs/srs/issues/1657#issuecomment-720889906), support HTTPS client, for http-callback. 4.0.45
* v4.0, 2020-10-31, Support gdb/srs.py to stat coroutines. 4.0.44
* v4.0, 2020-09-19, RTC: Extract resource manager. Use any UDP packet to keep alive. 4.0.43
* v4.0, 2020-09-09, RTC: Refine NACK RTT and efficiency. 4.0.42
* v4.0, 2020-09-08, Refine PLI/NACK/DTLS logs. 4.0.41
* v4.0, 2020-08-30, Fix serval bugs for RTC. Refine context API. 4.0.40
* v4.0, 2020-08-18, RTC: DTLS support ARQ, covered with utest. 4.0.39
* v4.0, 2020-08-06, RTC: Refine error check. 4.0.37
* v4.0, 2020-07-25, RTC: Support multiple address for client. 4.0.36
* v4.0, 2020-07-11, Refine log context with random string. 4.0.35
* v4.0, 2020-07-04, Fix some bugs for RTC. 4.0.34
* v4.0, 2020-06-24, Support static link c++ libraries. 4.0.32
* v4.0, 2020-06-23, Change log cid from int to string. 4.0.31
* v4.0, 2020-06-03, Support enable C++11. 4.0.29
* v4.0, 2020-05-31, Remove [srs-librtmp](https://github.com/ossrs/srs/issues/1535#issuecomment-633907655). 4.0.28
* v4.0, 2020-05-21, For [#307](https://github.com/ossrs/srs/issues/307), disable GSO and sendmmsg. 4.0.27
* v4.0, 2020-05-14, For [#307](https://github.com/ossrs/srs/issues/307), refine core structure, RTMP base on frame, RTC base on RTP. 4.0.26
* v4.0, 2020-05-11, For [#307](https://github.com/ossrs/srs/issues/307), refine RTC publisher structure. 4.0.25
* v4.0, 2020-04-30, For [#307](https://github.com/ossrs/srs/issues/307), support publish RTC with passing opus. 4.0.24
* v4.0, 2020-04-14, For [#307](https://github.com/ossrs/srs/issues/307), support sendmmsg, GSO and reuseport. 4.0.23
* v4.0, 2020-04-05, For [#307](https://github.com/ossrs/srs/issues/307), SRTP ASM only works with openssl-1.0, auto detect it. 4.0.22
* v4.0, 2020-04-04, For [#307](https://github.com/ossrs/srs/issues/307), refine RTC latency from 600ms to 200ms. 4.0.20
* v4.0, 2020-04-03, For [#307](https://github.com/ossrs/srs/issues/307), build SRTP with openssl to improve performance. 4.0.19
* v4.0, 2020-03-31, Play stream by WebRTC on iOS/Android/PC browser. 4.0.17
* v4.0, 2020-03-28, Support multiple OS/Platform build cache. 4.0.16
* v4.0, 2020-03-28, For [#1250](https://github.com/ossrs/srs/issues/1250), support macOS, OSX, MacbookPro, Apple Darwin.
* v4.0, 2020-03-22, Welcome maintainers [Runner365](https://github.com/runner365), [John](https://github.com/xiaozhihong) and [B.P.Y(Bepartofyou)](https://github.com/Bepartofyou). 4.0.15
* v4.0, 2020-03-22, For [#307](https://github.com/ossrs/srs/issues/307), support play with WebRTC. 4.0.14
* v4.0, 2020-03-13, For [#1636](https://github.com/ossrs/srs/issues/1636), fix bug for mux AAC to ADTS, never overwrite by RTMP sampling rate. 4.0.13
* v4.0, 2020-03-07, For [#1612](https://github.com/ossrs/srs/issues/1612), fix crash bug for RTSP. 4.0.12
* v4.0, 2020-03-07, For [#1631](https://github.com/ossrs/srs/issues/1631), support sei_filter for SRT. 4.0.11
* v4.0, 2020-03-01, For [#1621](https://github.com/ossrs/srs/issues/1621), support mix_correct for aggregate aac for SRT. 4.0.10
* v4.0, 2020-02-25, For [#1615](https://github.com/ossrs/srs/issues/1615), support default app(live) for vmix SRT. 4.0.9
* v4.0, 2020-02-21, For [#1598](https://github.com/ossrs/srs/issues/1598), support SLB health checking by TCP. 4.0.8
* v4.0, 2020-02-19, For [#1579](https://github.com/ossrs/srs/issues/1579), support rolling update of k8s. 4.0.7
* v4.0, 2020-02-18, For [#1579](https://github.com/ossrs/srs/issues/1579), support start/final wait for gracefully quit. 4.0.6
* v4.0, 2020-02-18, For [#1579](https://github.com/ossrs/srs/issues/1579), support gracefully quit and force to. 4.0.5
* v4.0, 2020-02-13, SRT supports detail config for [DynamicEncoding](https://github.com/runner365/srt_encoder). 4.0.4
* v4.0, 2020-02-04, Update project code. 4.0.3
* v4.0, 2020-01-26, Allow use libsrt.so for SRT is MPL license. 4.0.2
* v4.0, 2020-01-24, Fix [#1147](https://github.com/ossrs/srs/issues/1147), support SRT(Secure Reliable Transport). 4.0.1

<a name="v3-changes"></a>

## SRS 3.0 Changelog

* v3.0, 2021-05-12, Fix [#2311](https://github.com/ossrs/srs/issues/2311), Copy the request for stat client. 3.0.162
* <strong>v3.0, 2021-04-28, [3.0 release5(3.0.161)](https://github.com/ossrs/srs/releases/tag/v3.0-r5) released. 122750 lines.</strong>
* v3.0, 2021-04-28, Upgrade players. 3.0.161
* <strong>v3.0, 2021-04-24, [3.0 release4(3.0.160)](https://github.com/ossrs/srs/releases/tag/v3.0-r4) released. 122750 lines.</strong>
* v3.0, 2021-04-24, Package players and console to zip and docker. 3.0.160
* v3.0, 2021-04-24, Add srs-console to research/console. 3.0.159
* v3.0, 2021-03-05, Refine usage to docker by default. 3.0.158
* v3.0, 2021-01-07, Change id from int to string for the statistics. 3.0.157
* <strong>v3.0, 2021-01-02, [3.0 release3(3.0.156)](https://github.com/ossrs/srs/releases/tag/v3.0-r3) released. 122736 lines.</strong>
* v3.0, 2020-12-26, For RTMP edge/forward, pass vhost in tcUrl, not in stream. 3.0.156
* v3.0, 2020-12-17, Fix [#1694](https://github.com/ossrs/srs/issues/1694), Support DVR 2GB+ MP4 file. 3.0.155
* v3.0, 2020-12-17, Fix [#1548](https://github.com/ossrs/srs/issues/1548), Add edts in MP4 for Windows10. 3.0.154
* <strong>v3.0, 2020-10-31, [3.0 release2(3.0.153)](https://github.com/ossrs/srs/releases/tag/v3.0-r2) released. 122663 lines.</strong>
* v3.0, 2020-10-31, Fix [#509](https://github.com/ossrs/srs/issues/509), Always malloc stack on heap. 3.0.153
* v3.0, 2020-10-31, Remove some global elements for debugging. 3.0.152
* v3.0, 2020-10-31, Use global _srs_server for debugging. 3.0.151
* v3.0, 2020-10-31, Refine source cid, track previous one. 3.0.150
* v3.0, 2020-10-25, Add hls.realtime.conf for low-latency HLS. 3.0.149
* v3.0, 2020-10-24, Refine script and startup logs. 3.0.148
* v3.0, 2020-10-23, Allow FFmpeg if exists at /usr/local/bin/ffmpeg. 3.0.147
* v3.0, 2020-10-23, Refine build script, use libssl in docker. 3.0.146
* v3.0, 2020-10-14, Fix [#1987](https://github.com/ossrs/srs/issues/1987), Fix Kbps resample bug. 3.0.145
* <strong>v3.0, 2020-10-10, [3.0 release1(3.0.144)](https://github.com/ossrs/srs/releases/tag/v3.0-r1) released. 122674 lines.</strong>
* v3.0, 2020-10-10, Fix [#1780](https://github.com/ossrs/srs/issues/1780), build fail on Ubuntu20(focal). 3.0.144
* v3.0, 2020-09-14, Prevent stop ingest for multiple times. 3.0.143
* v3.0, 2020-09-10, RTC: Change SO_REUSEPORT fail to warning. 3.0.142
* <strong>v3.0, 2020-06-27, [3.0 release0(3.0.141)](https://github.com/ossrs/srs/releases/tag/v3.0-r0) released. 122674 lines.</strong>
* v3.0, 2020-03-30, For [#1672](https://github.com/ossrs/srs/issues/1672), fix dvr close file failed bug. 3.0.140
* <strong>v3.0, 2020-03-29, [3.0 beta4(3.0.139)](https://github.com/ossrs/srs/releases/tag/v3.0-b4) released. 122674 lines.</strong>
* v3.0, 2020-03-28, Support multiple OS/Platform build cache. 3.0.139
* v3.0, 2020-03-28, For [#1250](https://github.com/ossrs/srs/issues/1250), support macOS, OSX, MacbookPro, Apple Darwin. 3.0.138
* v3.0, 2020-03-21, For [#1629](https://github.com/ossrs/srs/issues/1629), fix kickoff FLV client bug. 3.0.137
* v3.0, 2020-03-21, For [#1619](https://github.com/ossrs/srs/issues/1619), configure without utest by default. 3.0.136
* v3.0, 2020-03-21, For [#1651](https://github.com/ossrs/srs/issues/1651), fix return pnwrite of srs_write_large_iovs. 3.0.135
* <strong>v3.0, 2020-03-18, [3.0 beta3(3.0.134)](https://github.com/ossrs/srs/releases/tag/v3.0-b3) released. 122509 lines.</strong>
* v3.0, 2020-03-12, For [#1635](https://github.com/ossrs/srs/issues/1635), inotify watch ConfigMap for reload. 3.0.134
* v3.0, 2020-03-12, For [#1635](https://github.com/ossrs/srs/issues/1635), support auto reaload config by inotify. 3.0.129
* v3.0, 2020-03-12, For [#1630](https://github.com/ossrs/srs/issues/1630), disable cache for stream changing, and drop dup header. 3.0.128
* v3.0, 2020-03-12, For [#1594](https://github.com/ossrs/srs/issues/1594), detect and disable daemon for docker. 3.0.127
* v3.0, 2020-03-12, For [#1634](https://github.com/ossrs/srs/issues/1634), always check status in thread loop. 3.0.126
* v3.0, 2020-03-11, For [#1634](https://github.com/ossrs/srs/issues/1634), refactor output with datetime for ingest/encoder/exec. 3.0.125
* v3.0, 2020-03-11, For [#1634](https://github.com/ossrs/srs/issues/1634), fix quit by accident SIGTERM while killing FFMPEG. 3.0.124
* <strong>v3.0, 2020-03-05, [3.0 beta2(3.0.123)](https://github.com/ossrs/srs/releases/tag/v3.0-b2) released. 122170 lines.</strong>
* v3.0, 2020-02-21, For [#1598](https://github.com/ossrs/srs/issues/1598), support SLB health checking by TCP. 3.0.123
* v3.0, 2020-02-21, Fix bug for librtmp client ipv4/ipv6 socket. 3.0.122
* v3.0, 2020-02-18, For [#1579](https://github.com/ossrs/srs/issues/1579), support start/final wait for gracefully quit. 3.0.121
* v3.0, 2020-02-18, For [#1579](https://github.com/ossrs/srs/issues/1579), support force gracefully quit. 3.0.120
* v3.0, 2020-02-18, For [#1579](https://github.com/ossrs/srs/issues/1579), support gracefully quit. 3.0.119
* v3.0, 2020-02-17, For [#1601](https://github.com/ossrs/srs/issues/1601), flush async on_dvr/on_hls events before stop. 3.0.118
* <strong>v3.0, 2020-02-14, [3.0 beta1(3.0.117)](https://github.com/ossrs/srs/releases/tag/v3.0-b1) released. 121964 lines.</strong>
* v3.0, 2020-02-14, For [#1595](https://github.com/ossrs/srs/issues/1595), migrating streaming from ossrs.net to r.ossrs.net. 3.0.117
* v3.0, 2020-02-05, For [#665](https://github.com/ossrs/srs/issues/665), fix HTTP-FLV reloading bug. 3.0.116
* v3.0, 2020-02-05, For [#1592](https://github.com/ossrs/srs/issues/1592), fix terminal echo off by redirect process stdin. 3.0.115
* v3.0, 2020-02-04, For [#1186](https://github.com/ossrs/srs/issues/1186), refactor security check. 3.0.114
* v3.0, 2020-02-04, Fix [#939](https://github.com/ossrs/srs/issues/939), response right A/V flag in FLV header. 3.0.113
* v3.0, 2020-02-04, For [#939](https://github.com/ossrs/srs/issues/939), always enable fast FLV streaming.
* <strong>v3.0, 2020-02-02, [3.0 beta0(3.0.112)](https://github.com/ossrs/srs/releases/tag/v3.0-b0) released. 121709 lines.</strong>
* v3.0, 2020-01-29, Support isolate version file. 3.0.112
* v3.0, 2020-01-29, Fix [#1206](https://github.com/ossrs/srs/issues/1206), dispose ingester while server quiting. 3.0.111
* v3.0, 2020-01-28, Fix [#1230](https://github.com/ossrs/srs/issues/1230), racing condition in source fetch or create. 3.0.110
* v3.0, 2020-01-27, Fix [#1303](https://github.com/ossrs/srs/issues/1303), do not dispatch previous meta when not publishing. 3.0.109
* v3.0, 2020-01-26, Allow use libst.so for ST is MPL license.
* v3.0, 2020-01-26, Fix [#607](https://github.com/ossrs/srs/issues/607), set RTMP identifying recursive depth to 3.
* v3.0, 2020-01-25, Fix [#878](https://github.com/ossrs/srs/issues/878), remove deprecated #EXT-X-ALLOW-CACHE for HLS. 3.0.108
* v3.0, 2020-01-25, Fix [#703](https://github.com/ossrs/srs/issues/703), drop video data util sps/pps. 3.0.107
* v3.0, 2020-01-25, Fix [#1108](https://github.com/ossrs/srs/issues/1108), reap DVR tmp file when unpublish. 3.0.106
* <strong>v3.0, 2020-01-21, [3.0 alpha9(3.0.105)](https://github.com/ossrs/srs/releases/tag/v3.0-a9) released. 121577 lines.</strong>
* v3.0, 2020-01-21, Fix [#1221](https://github.com/ossrs/srs/issues/1221), remove complex configure options. 3.0.104
* v3.0, 2020-01-21, Fix [#1547](https://github.com/ossrs/srs/issues/1547), support crossbuild for ARM/MIPS.
* v3.0, 2020-01-21, For [#1547](https://github.com/ossrs/srs/issues/1547), support setting cc/cxx/ar/ld/randlib tools. 3.0.103
* v3.0, 2020-01-19, For [#1580](https://github.com/ossrs/srs/issues/1580), fix cid range problem. 3.0.102
* v3.0, 2020-01-19, For [#1070](https://github.com/ossrs/srs/issues/1070), define FLV CodecID for [AV1](https://github.com/ossrs/srs/issues/1070) and [opus](https://github.com/ossrs/srs/issues/307). 3.0.101
* v3.0, 2020-01-16, For [#1575](https://github.com/ossrs/srs/issues/1575), correct RTMP redirect as tcUrl, add redirect2 as RTMP URL. 3.0.100
* v3.0, 2020-01-15, For [#1509](https://github.com/ossrs/srs/issues/1509), decrease the fast vector init size from 64KB to 64B. 3.0.99
* v3.0, 2020-01-15, For [#1509](https://github.com/ossrs/srs/issues/1509), release coroutine when source is idle. 3.0.98
* <strong>v3.0, 2020-01-10, [3.0 alpha8(3.0.97)](https://github.com/ossrs/srs/releases/tag/v3.0-a8) released. 121555 lines.</strong>
* v3.0, 2020-01-09, For [#1042](https://github.com/ossrs/srs/issues/1042), improve test coverage for service. 3.0.97
* v3.0, 2020-01-08, Merge [#1554](https://github.com/ossrs/srs/issues/1554), support logrotate copytruncate. 3.0.96
* v3.0, 2020-01-05, Always use string instance to avoid crash risk. 3.0.95
* v3.0, 2020-01-05, For [#460](https://github.com/ossrs/srs/issues/460), fix ipv6 hostport parsing bug. 3.0.94
* v3.0, 2020-01-05, For [#460](https://github.com/ossrs/srs/issues/460), fix ipv6 intranet address filter bug. 3.0.93
* v3.0, 2020-01-05, For [#1543](https://github.com/ossrs/srs/issues/1543), use getpeername to retrieve client ip. 3.0.92
* v3.0, 2020-01-02, For [#1042](https://github.com/ossrs/srs/issues/1042), improve test coverage for config. 3.0.91
* v3.0, 2019-12-30, Fix mp4 security issue, check buffer when required size is variable.
* <strong>v3.0, 2019-12-29, [3.0 alpha7(3.0.90)](https://github.com/ossrs/srs/releases/tag/v3.0-a7) released. 116356 lines.</strong>
* v3.0, 2019-12-29, For [#1255](https://github.com/ossrs/srs/issues/1255), support vhost/domain in query string for HTTP streaming. 3.0.90
* v3.0, 2019-12-29, For [#299](https://github.com/ossrs/srs/issues/299), increase dash segment size for avsync issue. 3.0.89
* v3.0, 2019-12-27, For [#299](https://github.com/ossrs/srs/issues/299), fix some bugs in dash, it works now. 3.0.88
* v3.0, 2019-12-27, For [#1544](https://github.com/ossrs/srs/issues/1544), fix memory leaking for complex error. 3.0.87
* v3.0, 2019-12-27, Add links for flv.js, hls.js and dash.js.
* v3.0, 2019-12-26, For [#1105](https://github.com/ossrs/srs/issues/1105), http server support mp4 range.
* v3.0, 2019-12-26, For [#1105](https://github.com/ossrs/srs/issues/1105), dvr mp4 supports playing on Chrome/Safari/Firefox. 3.0.86
* <strong>v3.0, 2019-12-26, [3.0 alpha6(3.0.85)](https://github.com/ossrs/srs/releases/tag/v3.0-a6) released. 116056 lines.</strong>
* v3.0, 2019-12-26, For [#1488](https://github.com/ossrs/srs/issues/1488), pass client ip to http callback. 3.0.85
* v3.0, 2019-12-25, For [#1537](https://github.com/ossrs/srs/issues/1537), [#1282](https://github.com/ossrs/srs/issues/1282), support aarch64 for armv8. 3.0.84
* v3.0, 2019-12-25, For [#1538](https://github.com/ossrs/srs/issues/1538), fresh chunk allow fmt=0 or fmt=1. 3.0.83
* v3.0, 2019-12-25, Remove FFMPEG and NGINX, please use [srs-docker](https://github.com/ossrs/srs-docker) instead. 3.0.82
* v3.0, 2019-12-25, For [#1537](https://github.com/ossrs/srs/issues/1537), remove cross-build, not used patches, directly build st.
* v3.0, 2019-12-24, For [#1508](https://github.com/ossrs/srs/issues/1508), support chunk length and content in multiple parts.
* v3.0, 2019-12-23, Merge SRS2 for running srs-librtmp on Windows. 3.0.80
* v3.0, 2019-12-23, For [#1535](https://github.com/ossrs/srs/issues/1535), deprecate Adobe FMS/AMS edge token traversing([CN](https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse), [EN](https://github.com/ossrs/srs/wiki/v4_EN_DRM#tokentraverse)) authentication. 3.0.79
* v3.0, 2019-12-23, For [#1535](https://github.com/ossrs/srs/issues/1535), deprecate BWT(bandwidth testing). 3.0.78
* v3.0, 2019-12-23, For [#1535](https://github.com/ossrs/srs/issues/1535), deprecate Adobe HDS(f4m)([CN](https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHDS), [EN](https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHDS)). 3.0.77
* v3.0, 2019-12-20, Fix [#1508](https://github.com/ossrs/srs/issues/1508), http-client support read chunked response. 3.0.76
* v3.0, 2019-12-20, For [#1508](https://github.com/ossrs/srs/issues/1508), refactor srs_is_digital, support all zeros.
* <strong>v3.0, 2019-12-19, [3.0 alpha5(3.0.75)](https://github.com/ossrs/srs/releases/tag/v3.0-a5) released. 115362 lines.</strong>
* v3.0, 2019-12-19, Refine the RTMP iovs cache increasing to much faster.
* v3.0, 2019-12-19, Fix [#1524](https://github.com/ossrs/srs/issues/1524), memory leak for amf0 strict array. 3.0.75
* v3.0, 2019-12-19, Fix random build failed bug for modules.
* v3.0, 2019-12-19, Fix [#1520](https://github.com/ossrs/srs/issues/1520) and [#1223](https://github.com/ossrs/srs/issues/1223), bug for origin cluster 3+ servers. 3.0.74
* v3.0, 2019-12-18, For [#1042](https://github.com/ossrs/srs/issues/1042), add test for RAW AVC protocol.
* v3.0, 2019-12-18, Detect whether flash enabled for srs-player. 3.0.73
* v3.0, 2019-12-17, Fix HTTP CORS bug when sending response for OPTIONS. 3.0.72
* v3.0, 2019-12-17, Enhance HTTP response write for final_request.
* v3.0, 2019-12-17, Refactor HTTP stream to disconnect client when unpublish.
* v3.0, 2019-12-17, Fix HTTP-FLV and VOD-FLV conflicting bug.
* v3.0, 2019-12-17, Refactor HttpResponseWriter.write, default to single text mode.
* v3.0, 2019-12-16, For [#1042](https://github.com/ossrs/srs/issues/1042), add test for HTTP protocol.
* <strong>v3.0, 2019-12-13, [3.0 alpha4(3.0.71)](https://github.com/ossrs/srs/releases/tag/v3.0-a4) released. 112928 lines.</strong>
* v3.0, 2019-12-12, For [#547](https://github.com/ossrs/srs/issues/547), [#1506](https://github.com/ossrs/srs/issues/1506), default hls_dts_directly to on. 3.0.71
* v3.0, 2019-12-12, SrsPacket supports converting to message, so can be sent by one API.
* v3.0, 2019-12-11, For [#1042](https://github.com/ossrs/srs/issues/1042), cover RTMP client/server protocol.
* v3.0, 2019-12-11, Fix [#1445](https://github.com/ossrs/srs/issues/1445), limit the createStream recursive depth. 3.0.70
* v3.0, 2019-12-11, For [#1042](https://github.com/ossrs/srs/issues/1042), cover RTMP handshake protocol.
* v3.0, 2019-12-11, Fix [#1229](https://github.com/ossrs/srs/issues/1229), fix the security risk in logger. 3.0.69
* v3.0, 2019-12-11, For [#1229](https://github.com/ossrs/srs/issues/1229), fix the security risk in HDS. 3.0.69
* v3.0, 2019-12-05, Fix [#1506](https://github.com/ossrs/srs/issues/1506), support directly turn FLV timestamp to TS DTS. 3.0.68
* <strong>v3.0, 2019-11-30, [3.0 alpha3(3.0.67)](https://github.com/ossrs/srs/releases/tag/v3.0-a3) released. 110864 lines.</strong>
* v3.0, 2019-12-01, Fix [#1501](https://github.com/ossrs/srs/issues/1501), use request coworker for origin cluster. 3.0.67
* <strong>v3.0, 2019-11-30, [3.0 alpha2(3.0.66)](https://github.com/ossrs/srs/releases/tag/v3.0-a2) released. 110831 lines.</strong>
* v3.0, 2019-11-30, Fix [#1501](https://github.com/ossrs/srs/issues/1501), use request coworker for origin cluster. 3.0.66
* v3.0, 2019-11-30, Random tid for docker. 3.0.65
* v3.0, 2019-11-30, Refine debug info for edge. 3.0.64
* v3.0, 2019-10-30, Cover protocol stack RTMP. 3.0.63
* v3.0, 2019-10-23, Cover JSON codec. 3.0.62
* v3.0, 2019-10-13, Use http://ossrs.net as homepage.
* v3.0, 2019-10-10, Cover AMF0 codec. 3.0.61
* <strong>v3.0, 2019-10-07, [3.0 alpha1(3.0.60)](https://github.com/ossrs/srs/releases/tag/v3.0-a1) released. 107962 lines.</strong>
* v3.0, 2019-10-06, Support log rotate by init.d command. 3.0.60
* v3.0, 2019-10-06, We prefer ipv4, only use ipv6 if ipv4 is disabled. 3.0.59
* v3.0, 2019-10-05, Support systemctl service for CentOS7. 3.0.58
* v3.0, 2019-10-04, Disable SO_REUSEPORT if not supported. 3.0.57
* <strong>v3.0, 2019-10-04, [3.0 alpha0(3.0.56)](https://github.com/ossrs/srs/releases/tag/v3.0-a0) released. 107946 lines.</strong>
* v3.0, 2019-10-04, Support go-oryx rtmplb with [proxy protocol](https://github.com/ossrs/go-oryx/wiki/RtmpProxy). 3.0.56
* v3.0, 2019-10-03, Fix [#775](https://github.com/ossrs/srs/issues/775), Support SO_REUSEPORT to improve edge performance. 3.0.54
* v3.0, 2019-10-03, For [#467](https://github.com/ossrs/srs/issues/467), Remove KAFKA producer. 3.0.53
* v3.0, 2019-05-14, Covert Kernel File reader/writer. 3.0.52
* v3.0, 2019-04-30, Refine typo in files. 3.0.51
* v3.0, 2019-04-25, Upgrade http-parser from 2.1 to 2.9.2 and cover it. 3.0.50
* v3.0, 2019-04-22, Refine in time unit. 3.0.49
* v3.0, 2019-04-07, Cover ST Coroutine and time unit. 3.0.48
* v3.0, 2019-04-06, Merge [#1304](https://github.com/ossrs/srs/issues/1304), Fix ST coroutine pull error. 3.0.47
* v3.0, 2019-04-05, Merge [#1339](https://github.com/ossrs/srs/issues/1339), Support HTTP-FLV params. 3.0.46
* v3.0, 2018-11-11, Merge [#1261](https://github.com/ossrs/srs/issues/1261), Support `_definst_` for Wowza. 3.0.44
* v3.0, 2018-08-26, SRS [console](https://github.com/ossrs/srs-ngb) support both [Chinese](http://ossrs.net:1985/console/ng_index.html) and [English](http://ossrs.net:1985/console/en_index.html).
* v3.0, 2018-08-25, Fix [#1093](https://github.com/ossrs/srs/issues/1093), Support HLS encryption. 3.0.42
* v3.0, 2018-08-25, Fix [#1051](https://github.com/ossrs/srs/issues/1051), Drop ts when republishing stream. 3.0.41
* v3.0, 2018-08-12, For [#1202](https://github.com/ossrs/srs/issues/1202), Support edge/forward to Aliyun CDN. 3.0.40
* v3.0, 2018-08-11, For [#910](https://github.com/ossrs/srs/issues/910), Support HTTP FLV with HTTP callback. 3.0.39
* v3.0, 2018-08-05, Refine HTTP-FLV latency, support realtime mode.3.0.38
* v3.0, 2018-08-05, Fix [#1087](https://github.com/ossrs/srs/issues/1087), Ignore iface without address. 3.0.37
* v3.0, 2018-08-04, For [#1110](https://github.com/ossrs/srs/issues/1110), Support params in http callback. 3.0.36
* v3.0, 2018-08-02, Always use vhost in stream query, the unify uri. 3.0.35
* v3.0, 2018-08-02, For [#1031](https://github.com/ossrs/srs/issues/1031), SRS edge support douyu.com. 3.0.34
* v3.0, 2018-07-22, Replace hex to string to match MIT license. 3.0.33
* v3.0, 2018-07-22, Replace base64 to match MIT license. 3.0.32
* v3.0, 2018-07-22, Replace crc32 IEEE and MPEG by pycrc to match MIT license. 3.0.31
* v3.0, 2018-07-21, Replace crc32 IEEE by golang to match MIT license. 3.0.30
* v3.0, 2018-02-16, Fix [#464](https://github.com/ossrs/srs/issues/464), support RTMP origin cluster. 3.0.29
* v3.0, 2018-02-13, Fix [#1057](https://github.com/ossrs/srs/issues/1057), switch to simple handshake. 3.0.28
* v3.0, 2018-02-13, Fix [#1059](https://github.com/ossrs/srs/issues/1059), merge from 2.0, supports url with vhost in stream. 3.0.27
* v3.0, 2018-01-01, Fix [#913](https://github.com/ossrs/srs/issues/913), support complex error. 3.0.26
* v3.0, 2017-06-04, Fix [#299](https://github.com/ossrs/srs/issues/299), support experimental MPEG-DASH. 3.0.25
* v3.0, 2017-05-30, Fix [#821](https://github.com/ossrs/srs/issues/821), support MP4 file parser. 3.0.24
* v3.0, 2017-05-30, Fix [#904](https://github.com/ossrs/srs/issues/904), replace NXJSON(LGPL) with json-parser(BSD). 3.0.23
* v3.0, 2017-04-16, Fix [#547](https://github.com/ossrs/srs/issues/547), support HLS audio in TS. 3.0.22
* v3.0, 2017-03-26, Fix [#820](https://github.com/ossrs/srs/issues/820), extract service for modules. 3.0.21
* v3.0, 2017-03-02, Fix [#786](https://github.com/ossrs/srs/issues/786), simply don't reuse object. 3.0.20
* v3.0, 2017-03-01, For [#110](https://github.com/ossrs/srs/issues/110), refine thread object. 3.0.19
* v3.0, 2017-02-12, Fix [#301](https://github.com/ossrs/srs/issues/301), user must config the codec in right way for HLS. 3.0.18
* v3.0, 2017-02-07, fix [#738](https://github.com/ossrs/srs/issues/738), support DVR general mp4. 3.0.17
* v3.0, 2017-01-19, for [#742](https://github.com/ossrs/srs/issues/742), refine source, meta and origin hub. 3.0.16
* v3.0, 2017-01-17, for [#742](https://github.com/ossrs/srs/issues/742), refine source, timeout, live cycle. 3.0.15
* v3.0, 2017-01-11, fix [#735](https://github.com/ossrs/srs/issues/735), config transform refer_publish invalid. 3.0.14
* v3.0, 2017-01-06, for [#730](https://github.com/ossrs/srs/issues/730), support config in/out ack size. 3.0.13
* v3.0, 2017-01-06, for [#711](https://github.com/ossrs/srs/issues/711), support perfile for transcode. 3.0.12
* v3.0, 2017-01-05, Fix [#727](https://github.com/ossrs/srs/issues/727), patch ST for valgrind and ARM. 3.0.11
* v3.0, 2017-01-05, for [#324](https://github.com/ossrs/srs/issues/324), always enable hstrs. 3.0.10
* v3.0, 2016-12-15, fix [#717](https://github.com/ossrs/srs/issues/717), [#691](https://github.com/ossrs/srs/issues/691), http api/static/stream support cors. 3.0.9
* v3.0, 2016-12-08, Fix [#105](https://github.com/ossrs/srs/issues/105), support log rotate signal SIGUSR1. 3.0.8
* v3.0, 2016-12-07, fix typo and refine grammar. 3.0.7
* v3.0, 2015-10-20, fix [#502](https://github.com/ossrs/srs/issues/502), support snapshot with http-callback or transcoder. 3.0.5
* v3.0, 2015-09-19, support amf0 and json to convert with each other.
* v3.0, 2015-09-19, json objects support dumps to string.
* v3.0, 2015-09-14, fix [#459](https://github.com/ossrs/srs/issues/459), support dvr raw api. 3.0.4
* v3.0, 2015-09-14, fix [#459](https://github.com/ossrs/srs/issues/459), dvr support apply filter for ng-control dvr module.
* v3.0, 2015-09-14, fix [#319](https://github.com/ossrs/srs/issues/319), http raw api support update global and vhost. 3.0.3
* v3.0, 2015-08-31, fix [#319](https://github.com/ossrs/srs/issues/319), http raw api support query global and vhost.
* v3.0, 2015-08-28, fix [#471](https://github.com/ossrs/srs/issues/471), api response the width and height. 3.0.2
* v3.0, 2015-08-25, fix [#367](https://github.com/ossrs/srs/issues/367), support nginx-rtmp exec. 3.0.1

<a name="v2-changes"></a>

## SRS 2.0 Changelog

* <strong>v2.0, 2020-01-25, [2.0 release8(2.0.272)](https://github.com/ossrs/srs/releases/tag/v2.0-r8) released. 87292 lines.</strong>
* v2.0, 2020-01-08, Merge [#1554](https://github.com/ossrs/srs/issues/1554), support logrotate copytruncate. 2.0.272
* v2.0, 2020-01-05, Merge [#1551](https://github.com/ossrs/srs/issues/1551), fix memory leak in RTSP stack. 2.0.270
* v2.0, 2019-12-26, For [#1488](https://github.com/ossrs/srs/issues/1488), pass client ip to http callback. 2.0.269
* v2.0, 2019-12-23, Fix [srs-librtmp #22](https://github.com/ossrs/srs-librtmp/issues/22), parse vhost splited by single seperator. 2.0.268
* v2.0, 2019-12-23, Fix [srs-librtmp #25](https://github.com/ossrs/srs-librtmp/issues/25), build srs-librtmp on windows. 2.0.267
* v2.0, 2019-12-13, Support openssl versions greater than 1.1.0. 2.0.266
* <strong>v2.0, 2019-11-29, [2.0 release7(2.0.265)](https://github.com/ossrs/srs/releases/tag/v2.0-r7) released. 86994 lines.</strong>
* v2.0, 2019-11-29, For [srs-docker](https://github.com/ossrs/srs-docker/tree/master/2.0), install Cherrypy without sudo. 2.0.265
* v2.0, 2019-04-06, For [#1304](https://github.com/ossrs/srs/issues/1304), Default HSTRS to on. 2.0.264
* <strong>v2.0, 2019-04-05, [2.0 release6(2.0.263)](https://github.com/ossrs/srs/releases/tag/v2.0-r6) released. 86994 lines.</strong>
* v2.0, 2019-04-05, Merge [#1312](https://github.com/ossrs/srs/issues/1312), Fix GCC7 build error, this statement may fall through. 2.0.263
* v2.0, 2019-04-05, Merge [#1339](https://github.com/ossrs/srs/issues/1339), Support HTTP-FLV params. 2.0.262
* v2.0, 2018-12-01, Merge [#1274](https://github.com/ossrs/srs/issues/1274), Upgrade to FFMPEG 4.1 and X264 157. 2.0.261
* v2.0, 2018-11-11, Merge [#1261](https://github.com/ossrs/srs/issues/1261), Support `_definst_` for Wowza. 2.0.260
* v2.0, 2018-11-11, Merge [#1263](https://github.com/ossrs/srs/issues/1263), Fix string trim bug. 2.0.259
* <strong>v2.0, 2018-10-28, [2.0 release5(2.0.258)](https://github.com/ossrs/srs/releases/tag/v2.0-r5) released. 86916 lines.</strong>
* v2.0, 2018-10-28, Fix [#1250](https://github.com/ossrs/srs/issues/1250), Support build on OSX10.14 Mojave. 2.0.258
* v2.0, 2018-10-08, Merge [#1236](https://github.com/ossrs/srs/issues/1236), Fix sleep bug in us. 2.0.257
* v2.0, 2018-10-08, Merge [#1237](https://github.com/ossrs/srs/issues/1237), Support param for transcoder. 2.0.256
* <strong>v2.0, 2018-08-12, [2.0 release4(2.0.255)](https://github.com/ossrs/srs/releases/tag/v2.0-r4) released. 86915 lines.</strong>
* v2.0, 2018-08-12, For [#1202](https://github.com/ossrs/srs/issues/1202), Support edge/forward to Aliyun CDN. 2.0.255
* v2.0, 2018-08-11, For [#910](https://github.com/ossrs/srs/issues/910), Support HTTP FLV with HTTP callback. 2.0.254
* v2.0, 2018-08-11, For [#1110](https://github.com/ossrs/srs/issues/1110), Refine params in http callback. 2.0.253
* v2.0, 2018-08-05, Refine HTTP-FLV latency, support realtime mode. 2.0.252
* v2.0, 2018-08-04, For [#1110](https://github.com/ossrs/srs/issues/1110), Support params in http callback. 2.0.251
* v2.0, 2018-08-02, For [#1031](https://github.com/ossrs/srs/issues/1031), SRS edge support douyu.com. 2.0.250
* v2.0, 2018-07-21, Merge [#1119](https://github.com/ossrs/srs/issues/1119), fix memory leak. 2.0.249
* <strong>v2.0, 2018-07-18, [2.0 release3(2.0.248)](https://github.com/ossrs/srs/releases/tag/v2.0-r3) released. 86775 lines.</strong>
* v2.0, 2018-07-17, Merge [#1176](https://github.com/ossrs/srs/issues/1176), fix scaned issues. 2.0.248
* v2.0, 2018-02-28, Merge [#1077](https://github.com/ossrs/srs/issues/1077), fix crash for edge HLS. 2.0.247
* v2.0, 2018-02-13, Fix [#1059](https://github.com/ossrs/srs/issues/1059), support vhost in stream parameters. 2.0.246
* v2.0, 2018-01-07, Merge [#1045](https://github.com/ossrs/srs/issues/1045), fix [#1044](https://github.com/ossrs/srs/issues/1044), TCP connection alive detection. 2.0.245
* v2.0, 2018-01-04, Merge [#1039](https://github.com/ossrs/srs/issues/1039), fix bug of init.d script.
* v2.0, 2018-01-01, Merge [#1033](https://github.com/ossrs/srs/issues/1033), allow user to add some specific flags. 2.0.244
* <strong>v2.0, 2017-06-10, [2.0 release2(2.0.243)](https://github.com/ossrs/srs/releases/tag/v2.0-r2) released. 86670 lines.</strong>
* v2.0, 2017-05-29, Merge [#899](https://github.com/ossrs/srs/issues/899) to fix [#893](https://github.com/ossrs/srs/issues/893), ts PES ext length. 2.0.243
* v2.0, 2017-05-01, Fix [#865](https://github.com/ossrs/srs/issues/865), shouldn't remove ts/m3u8 when hls_dispose disabled. 2.0.242
* v2.0, 2017-04-30, Fix [#636](https://github.com/ossrs/srs/issues/636), FD leak for requesting empty HTTP stream. 2.0.241
* v2.0, 2017-04-23, Fix [#851](https://github.com/ossrs/srs/issues/851), HTTP API support number of video frames for FPS. 2.0.240
* <strong>v2.0, 2017-04-18, [2.0 release1(2.0.239)](https://github.com/ossrs/srs/releases/tag/v2.0-r1) released. 86515 lines.</strong>
* v2.0, 2017-04-18, Fix [#848](https://github.com/ossrs/srs/issues/848), crash at HTTP fast buffer grow. 2.0.239
* v2.0, 2017-04-15, Fix [#844](https://github.com/ossrs/srs/issues/844), support Haivision encoder. 2.0.238
* v2.0, 2017-04-15, Merge [#846](https://github.com/ossrs/srs/issues/846), fix fd leak for FLV stream caster. 2.0.237
* v2.0, 2017-04-15, Merge [#841](https://github.com/ossrs/srs/issues/841), avoid the duplicated sps/pps in ts. 2.0.236
* v2.0, 2017-04-09, Fix [#834](https://github.com/ossrs/srs/issues/834), crash for TS context corrupt. 2.0.235
* <strong>v2.0, 2017-03-03, [2.0 release0(2.0.234)](https://github.com/ossrs/srs/releases/tag/v2.0-r0) released. 86373 lines.</strong>
* v2.0, 2017-02-25, for [#730](https://github.com/ossrs/srs/issues/730), remove the test code. 2.0.234
* v2.0, 2017-02-09, fix [#503](https://github.com/ossrs/srs/issues/503] disable utilities when reload a source. 2.0.233
* v2.0, 2017-01-22, for [#752](https://github.com/ossrs/srs/issues/752] release the io then free it for kbps. 2.0.232
* v2.0, 2017-01-18, fix [#750](https://github.com/ossrs/srs/issues/750] use specific error code for dns resolve. 2.0.231
* <strong>v2.0, 2017-01-18, [2.0 beta4(2.0.230)](https://github.com/ossrs/srs/releases/tag/v2.0-b4) released. 86334 lines.</strong>
* v2.0, 2017-01-18, fix [#749](https://github.com/ossrs/srs/issues/749), timestamp overflow for ATC. 2.0.230
* v2.0, 2017-01-11, fix [#740](https://github.com/ossrs/srs/issues/740), convert ts aac audio private stream 1 to common. 2.0.229
* v2.0, 2017-01-11, fix [#588](https://github.com/ossrs/srs/issues/588), kbps interface error. 2.0.228
* v2.0, 2017-01-11, fix [#736](https://github.com/ossrs/srs/issues/736), recovery the hls dispose. 2.0.227
* v2.0, 2017-01-10, refine hls html5 video template.
* v2.0, 2017-01-10, fix [#635](https://github.com/ossrs/srs/issues/635), hls support NonIDR(open gop). 2.0.226
* v2.0, 2017-01-06, for [#730](https://github.com/ossrs/srs/issues/730), reset ack follow flash player rules. 2.0.225
* v2.0, 2016-12-15, for [#513](https://github.com/ossrs/srs/issues/513), remove hls ram from srs2 to srs3+. 2.0.224
* <strong>v2.0, 2016-12-13, [2.0 beta3(2.0.223)](https://github.com/ossrs/srs/releases/tag/v2.0-b3) released. 86685 lines.</strong>
* v2.0, 2016-12-13, fix [#713](https://github.com/ossrs/srs/issues/713), disable the source cleanup. 2.0.223
* v2.0, 2016-12-13, fix [#713](https://github.com/ossrs/srs/issues/713), refine source to avoid critical fetch and create. 2.0.222
* <strong>v2.0, 2016-11-09, [2.0 beta2(2.0.221)](https://github.com/ossrs/srs/releases/tag/v2.0-b2) released. 86691 lines.</strong>
* v2.0, 2016-11-05, fix [#654](https://github.com/ossrs/srs/issues/654), crash when source cleanup for edge. 2.0.221
* v2.0, 2016-10-26, fix [#666](https://github.com/ossrs/srs/issues/666), crash when source cleanup for http-flv. 2.0.220
* v2.0, 2016-10-10, fix [#661](https://github.com/ossrs/srs/issues/661), close fd after thread stopped. 2.0.219
* v2.0, 2016-09-23, support asprocess for oryx. 2.0.218
* v2.0, 2016-09-23, support change work_dir for oryx.
* v2.0, 2016-09-15, fix [#640](https://github.com/ossrs/srs/issues/640), typo for rtmp type. 2.0.217
* v2.0, 2016-09-12, fix fast stream error bug. 2.0.216
* <strong>v2.0, 2016-09-09, [2.0 beta1(2.0.215)](https://github.com/ossrs/srs/releases/tag/v2.0-b1) released. 89941 lines.</strong>
* v2.0, 2016-09-09, refine librtmp comments about NALUs. 2.0.215
* v2.0, 2016-09-05, fix memory leak at source. 2.0.214
* v2.0, 2016-09-05, fix memory leak at handshake. 2.0.213
* v2.0, 2016-09-04, support valgrind for [patched st](https://github.com/ossrs/state-threads/issues/2).
* v2.0, 2016-09-03, support all arm for [patched st](https://github.com/ossrs/state-threads/issues/1). 2.0.212
* v2.0, 2016-09-01, workaround [#511](https://github.com/ossrs/srs/issues/511) the fly stfd in close. 2.0.211
* v2.0, 2016-08-30, comment the pcr.
* v2.0, 2016-08-18, fix [srs-librtmp#4](https://github.com/ossrs/srs-librtmp/issues/4) filter frame.
* v2.0, 2016-08-10, fix socket timeout for librtmp.
* v2.0, 2016-08-08, fix the crash by srs_info log.
* <strong>v2.0, 2016-08-06, [2.0 beta0(2.0.210)](https://github.com/ossrs/srs/releases/tag/v2.0-b0) released. 89704 lines.</strong>
* v2.0, 2016-05-17, fix the sps pps parse bug.
* v2.0, 2016-01-13, fix http reader bug, support infinite chunked. 2.0.209
* v2.0, 2016-01-09, merge [#559](https://github.com/ossrs/srs/pull/559) fix memory leak bug. 2.0.208
* v2.0, 2016-01-09, merge [#558](https://github.com/ossrs/srs/pull/558) add tcUrl for on_publish.
* v2.0, 2016-01-05, add keyword XCORE for coredump to identify the version. 2.0.207
* <strong>v2.0, 2015-12-23, [2.0 alpha3(2.0.205)](https://github.com/ossrs/srs/releases/tag/v2.0-a3) released. 89544 lines.</strong>
* v2.0, 2015-12-22, for [#509](https://github.com/ossrs/srs/issues/509) always alloc big object at heap. 2.0.205
* v2.0, 2015-12-22, for [#418](https://github.com/ossrs/srs/issues/418) ignore null connect props to make RED5 happy. 2.0.204
* v2.0, 2015-12-22, for [#546](https://github.com/ossrs/srs/issues/546) thread terminate normally dispose bug. 2.0.203
* v2.0, 2015-12-22, for [#541](https://github.com/ossrs/srs/issues/541) failed when chunk size too small. 2.0.202
* v2.0, 2015-12-15, default hls_on_error to continue. 2.0.201
* v2.0, 2015-11-16, for [#518](https://github.com/ossrs/srs/issues/518) fix fd leak bug when fork. 2.0.200
* v2.0, 2015-11-05, for [#511](https://github.com/ossrs/srs/issues/511) fix bug for restart thread. 2.0.199
* v2.0, 2015-11-02, for [#515](https://github.com/ossrs/srs/issues/515) use srs_freepa and SrsAutoFreeA for array. 2.0.198
* v2.0, 2015-10-28, for [ExoPlayer #828](https://github.com/google/ExoPlayer/pull/828), remove duration for live.
* v2.0, 2015-10-28, for [ExoPlayer #828](https://github.com/google/ExoPlayer/pull/828), add av tag in flv header. 2.0.197
* v2.0, 2015-10-27, for [#512](https://github.com/ossrs/srs/issues/512) partial hotfix the hls pure audio. 2.0.196
* <strong>v2.0, 2015-10-08, [2.0 alpha2(2.0.195)](https://github.com/ossrs/srs/releases/tag/v2.0-a2) released. 89358 lines.</strong>
* v2.0, 2015-10-04, for [#448](https://github.com/ossrs/srs/issues/448) fix the bug of response of http hooks. 2.0.195
* v2.0, 2015-10-01, for [#497](https://github.com/ossrs/srs/issues/497) response error when client not found to kickoff. 2.0.194
* v2.0, 2015-10-01, for [#495](https://github.com/ossrs/srs/issues/495) decrease the srs-librtmp size. 2.0.193
* v2.0, 2015-09-23, for [#485](https://github.com/ossrs/srs/issues/485) error when arm glibc 2.15+ or not i386/x86_64/amd64. 2.0.192
* v2.0, 2015-09-23, for [#485](https://github.com/ossrs/srs/issues/485) srs for respberrypi and cubieboard. 2.0.191
* v2.0, 2015-09-21, fix [#484](https://github.com/ossrs/srs/issues/484) hotfix the openssl build script 2.0.190
* <strong>v2.0, 2015-09-14, [2.0 alpha1(2.0.189)](https://github.com/ossrs/srs/releases/tag/v2.0-a1) released. 89269 lines.</strong>
* v2.0, 2015-09-14, fix [#474](https://github.com/ossrs/srs/issues/474) config to donot parse width/height from sps. 2.0.189
* v2.0, 2015-09-14, for [#474](https://github.com/ossrs/srs/issues/474) always release publish for source.
* v2.0, 2015-09-14, for [#458](https://github.com/ossrs/srs/issues/458) http hooks use source thread cid. 2.0.188
* v2.0, 2015-09-14, for [#475](https://github.com/ossrs/srs/issues/475) fix http hooks crash for st context switch. 2.0.187
* v2.0, 2015-09-09, support reload utc_time. 2.0.186
* <strong>v2.0, 2015-08-23, [2.0 alpha0(2.0.185)](https://github.com/ossrs/srs/releases/tag/v2.0-a0) released. 89022 lines.</strong>
* v2.0, 2015-08-22, HTTP API support JSONP by specifies the query string callback=xxx.
* v2.0, 2015-08-20, fix [#380](https://github.com/ossrs/srs/issues/380), srs-librtmp send sequence header when sps or pps changed.
* v2.0, 2015-08-18, close [#454](https://github.com/ossrs/srs/issues/454), support obs restart publish. 2.0.184
* v2.0, 2015-08-14, use reduce_sequence_header for stream control.
* v2.0, 2015-08-14, use send_min_interval for stream control. 2.0.183
* v2.0, 2015-08-12, enable the SRS_PERF_TCP_NODELAY and add config tcp_nodelay. 2.0.182
* v2.0, 2015-08-11, for [#442](https://github.com/ossrs/srs/issues/442) support kickoff connected client. 2.0.181
* v2.0, 2015-07-21, for [#169](https://github.com/ossrs/srs/issues/169) support default values for transcode. 2.0.180
* v2.0, 2015-07-21, fix [#435](https://github.com/ossrs/srs/issues/435) add pageUrl for HTTP callback on_play.
* v2.0, 2015-07-20, refine the hls, ignore packet when no sequence header. 2.0.179
* v2.0, 2015-07-16, for [#441](https://github.com/ossrs/srs/issues/441) use 30s timeout for first msg. 2.0.178
* v2.0, 2015-07-14, refine hls disable the time jitter, support not mix monotonically increase. 2.0.177
* v2.0, 2015-07-01, fix [#433](https://github.com/ossrs/srs/issues/433) fix the sps parse bug. 2.0.176
* v2.0, 2015-06-10, fix [#425](https://github.com/ossrs/srs/issues/425) refine the time jitter, correct (-inf,-250)+(250,+inf) to 10ms. 2.0.175
* v2.0, 2015-06-10, fix [#424](https://github.com/ossrs/srs/issues/424) fix aggregate timestamp bug. 2.0.174
* v2.0, 2015-06-06, fix [#421](https://github.com/ossrs/srs/issues/421) drop video for unkown RTMP header.
* v2.0, 2015-06-05, fix [#420](https://github.com/ossrs/srs/issues/420) remove ts for hls ram mode.
* v2.0, 2015-05-30, fix [#209](https://github.com/ossrs/srs/issues/209) cleanup hls when stop and timeout. 2.0.173.
* v2.0, 2015-05-29, fix [#409](https://github.com/ossrs/srs/issues/409) support pure video hls. 2.0.172.
* v2.0, 2015-05-28, support [srs-dolphin](https://github.com/ossrs/srs-dolphin), the multiple-process SRS.
* v2.0, 2015-05-24, fix [#404](https://github.com/ossrs/srs/issues/404) register handler then start http thread. 2.0.167.
* v2.0, 2015-05-23, refine the thread, protocol, kbps code. 2.0.166
* v2.0, 2015-05-23, fix [#391](https://github.com/ossrs/srs/issues/391) copy request for async call.
* v2.0, 2015-05-22, fix [#397](https://github.com/ossrs/srs/issues/397) the USER_HZ maybe not 100. 2.0.165
* v2.0, 2015-05-22, for [#400](https://github.com/ossrs/srs/issues/400), parse when got entire http header, by feilong. 2.0.164.
* v2.0, 2015-05-19, merge from bravo system, add the rtmfp to bms(commercial srs). 2.0.163.
* v2.0, 2015-05-10, support push flv stream over HTTP POST to SRS.
* v2.0, 2015-04-20, support ingest hls live stream to RTMP.
* v2.0, 2015-04-15, for [#383](https://github.com/ossrs/srs/issues/383), support mix_correct algorithm. 2.0.161.
* v2.0, 2015-04-13, for [#381](https://github.com/ossrs/srs/issues/381), support reap hls/ts by gop or not. 2.0.160.
* v2.0, 2015-04-10, enhanced on_hls_notify, support HTTP GET when reap ts.
* v2.0, 2015-04-10, refine the hls deviation for floor algorithm.
* v2.0, 2015-04-08, for [#375](https://github.com/ossrs/srs/issues/375), fix hls bug, keep cc continous between ts files. 2.0.159.
* v2.0, 2015-04-04, for [#304](https://github.com/ossrs/srs/issues/304), rewrite annexb mux for ts, refer to apple sample. 2.0.157.
* v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156.
* v2.0, 2015-04-03, for [#372](https://github.com/ossrs/srs/issues/372), support transform vhost of edge 2.0.155.
* v2.0, 2015-03-30, for [#366](https://github.com/ossrs/srs/issues/366), config hls to disable cleanup of ts. 2.0.154.
* v2.0, 2015-03-31, support server cycle handler. 2.0.153.
* v2.0, 2015-03-31, support on_hls for http hooks. 2.0.152.
* v2.0, 2015-03-31, enhanced hls, support deviation for duration. 2.0.151.
* v2.0, 2015-03-30, for [#351](https://github.com/ossrs/srs/issues/351), support config the m3u8/ts path for hls. 2.0.149.
* v2.0, 2015-03-17, for [#155](https://github.com/ossrs/srs/issues/155), osx(darwin) support demo with nginx and ffmpeg. 2.0.143.
* v2.0, 2015-03-15, start [2.0release branch](https://github.com/ossrs/srs/tree/2.0release), 80773 lines.
* v2.0, 2015-03-14, fix [#324](https://github.com/ossrs/srs/issues/324), support hstrs(http stream trigger rtmp source) edge mode. 2.0.140.
* v2.0, 2015-03-14, for [#324](https://github.com/ossrs/srs/issues/324), support hstrs(http stream trigger rtmp source) origin mode. 2.0.139.
* v2.0, 2015-03-12, fix [#328](https://github.com/ossrs/srs/issues/328), support adobe hds. 2.0.138.
* v2.0, 2015-03-10, fix [#155](https://github.com/ossrs/srs/issues/155), support osx(darwin) for mac pro. 2.0.137.
* v2.0, 2015-03-08, fix [#316](https://github.com/ossrs/srs/issues/316), http api provides stream/vhost/srs/server bytes, codec and count. 2.0.136.
* v2.0, 2015-03-08, fix [#310](https://github.com/ossrs/srs/issues/310), refine aac LC, support aac HE/HEv2. 2.0.134.
* v2.0, 2015-03-06, for [#322](https://github.com/ossrs/srs/issues/322), fix http-flv stream bug, support multiple streams. 2.0.133.
* v2.0, 2015-03-06, refine http request parse. 2.0.132.
* v2.0, 2015-03-01, for [#179](https://github.com/ossrs/srs/issues/179), revert dvr http api. 2.0.128.
* v2.0, 2015-02-24, for [#304](https://github.com/ossrs/srs/issues/304), fix hls bug, write pts/dts error. 2.0.124
* v2.0, 2015-02-19, refine dvr, append file when dvr file exists. 2.0.122.
* v2.0, 2015-02-19, refine pithy print to more easyer to use. 2.0.121.
* v2.0, 2015-02-18, fix [#2304](https://github.com/ossrs/srs/issues/2304#issuecomment-826009290), support push rtsp to srs. 2.0.120.
* v2.0, 2015-02-17, the join maybe failed, should use a variable to ensure thread terminated. 2.0.119.
* v2.0, 2015-02-15, for [#304](https://github.com/ossrs/srs/issues/304), support config default acodec/vcodec. 2.0.118.
* v2.0, 2015-02-15, for [#304](https://github.com/ossrs/srs/issues/304), rewrite hls/ts code, support h.264+mp3 for hls. 2.0.117.
* v2.0, 2015-02-12, for [#304](https://github.com/ossrs/srs/issues/304), use stringstream to generate m3u8, add hls_td_ratio. 2.0.116.
* v2.0, 2015-02-11, dev code ZhouGuowen for 2.0.115.
* v2.0, 2015-02-10, for [#311](https://github.com/ossrs/srs/issues/311), set pcr_base to dts. 2.0.114.
* v2.0, 2015-02-10, fix [the bug](https://github.com/ossrs/srs/commit/87519aaae835199e5adb60c0ae2c1cd24939448c) of ibmf format which decoded in annexb.
* v2.0, 2015-02-10, for [#310](https://github.com/ossrs/srs/issues/310), downcast aac SSR to LC. 2.0.113
* v2.0, 2015-02-03, fix [#136](https://github.com/ossrs/srs/issues/136), support hls without io(in ram). 2.0.112
* v2.0, 2015-01-31, for [#250](https://github.com/ossrs/srs/issues/250), support push MPEGTS over UDP to SRS. 2.0.111
* v2.0, 2015-01-29, build libfdk-aac in ffmpeg. 2.0.108
* v2.0, 2015-01-25, for [#301](https://github.com/ossrs/srs/issues/301), hls support h.264+mp3, ok for vlc. 2.0.107
* v2.0, 2015-01-25, for [#301](https://github.com/ossrs/srs/issues/301), http ts stream support h.264+mp3. 2.0.106
* v2.0, 2015-01-25, hotfix [#268](https://github.com/ossrs/srs/issues/268), refine the pcr start at 0, dts/pts plus delay. 2.0.105
* v2.0, 2015-01-25, hotfix [#151](https://github.com/ossrs/srs/issues/151), refine pcr=dts-800ms and use dts/pts directly. 2.0.104
* v2.0, 2015-01-23, hotfix [#151](https://github.com/ossrs/srs/issues/151), use absolutely overflow to make jwplayer happy. 2.0.103
* v2.0, 2015-01-22, for [#293](https://github.com/ossrs/srs/issues/293), support http live ts stream. 2.0.101.
* v2.0, 2015-01-19, for [#293](https://github.com/ossrs/srs/issues/293), support http live flv/aac/mp3 stream with fast cache. 2.0.100.
* v2.0, 2015-01-18, for [#293](https://github.com/ossrs/srs/issues/293), support rtmp remux to http flv live stream. 2.0.99.
* v2.0, 2015-01-17, fix [#277](https://github.com/ossrs/srs/issues/277), refine http server refer to go http-framework. 2.0.98
* v2.0, 2015-01-17, for [#277](https://github.com/ossrs/srs/issues/277), refine http api refer to go http-framework. 2.0.97
* v2.0, 2015-01-17, hotfix [#290](https://github.com/ossrs/srs/issues/290), use iformat only for rtmp input. 2.0.95
* v2.0, 2015-01-08, hotfix [#281](https://github.com/ossrs/srs/issues/281), fix hls bug ignore type-9 send aud. 2.0.93
* v2.0, 2015-01-03, fix [#274](https://github.com/ossrs/srs/issues/274), http-callback support on_dvr when reap a dvr file. 2.0.89
* v2.0, 2015-01-03, hotfix to remove the pageUrl for http callback. 2.0.88
* v2.0, 2015-01-03, fix [#179](https://github.com/ossrs/srs/issues/179), dvr support custom filepath by variables. 2.0.87
* v2.0, 2015-01-02, fix [#211](https://github.com/ossrs/srs/issues/211), support security allow/deny publish/play all/ip. 2.0.86
* v2.0, 2015-01-02, hotfix [#207](https://github.com/ossrs/srs/issues/207), trim the last 0 of log. 2.0.85
* v2.0, 2014-01-02, fix [#158](https://github.com/ossrs/srs/issues/158), http-callback check http status code ok(200). 2.0.84
* v2.0, 2015-01-02, hotfix [#216](https://github.com/ossrs/srs/issues/216), http-callback post in application/json content-type. 2.0.83
* v2.0, 2014-01-02, fix [#263](https://github.com/ossrs/srs/issues/263), srs-librtmp flv read tag should init size. 2.0.82
* v2.0, 2015-01-01, hotfix [#270](https://github.com/ossrs/srs/issues/270), memory leak for http client post. 2.0.81
* v2.0, 2014-12-12, fix [#266](https://github.com/ossrs/srs/issues/266), aac profile is object id plus one. 2.0.80
* v2.0, 2014-12-29, hotfix [#267](https://github.com/ossrs/srs/issues/267), the forward dest ep should use server. 2.0.79
* v2.0, 2014-12-29, hotfix [#268](https://github.com/ossrs/srs/issues/268), the hls pcr is negative when startup. 2.0.78
* v2.0, 2014-12-22, hotfix [#264](https://github.com/ossrs/srs/issues/264), ignore NALU when sequence header to make HLS happy. 2.0.76
* v2.0, 2014-12-20, hotfix [#264](https://github.com/ossrs/srs/issues/264), support disconnect publish connect when hls error. 2.0.75
* v2.0, 2014-12-12, fix [#257](https://github.com/ossrs/srs/issues/257), support 0.1s+ latency. 2.0.70
* v2.0, 2014-12-08, update wiki for mr([EN](https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#merged-read), [CN](https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#merged-read)) and mw([EN](https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#merged-write), [CN](https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#merged-write)).
* v2.0, 2014-12-07, fix [#251](https://github.com/ossrs/srs/issues/251), 10k+ clients, use queue cond wait and fast vector. 2.0.67
* v2.0, 2014-12-05, fix [#251](https://github.com/ossrs/srs/issues/251), 9k+ clients, use fast cache for msgs queue. 2.0.57
* v2.0, 2014-12-04, fix [#241](https://github.com/ossrs/srs/issues/241), add mw(merged-write) config. 2.0.53
* v2.0, 2014-12-04, for [#241](https://github.com/ossrs/srs/issues/241), support mr(merged-read) config and reload. 2.0.52.
* v2.0, 2014-12-04, enable [#241](https://github.com/ossrs/srs/issues/241) and [#248](https://github.com/ossrs/srs/issues/248), +25% performance, 2.5k publisher. 2.0.50
* v2.0, 2014-12-04, fix [#248](https://github.com/ossrs/srs/issues/248), improve about 15% performance for fast buffer. 2.0.49
* v2.0, 2014-12-03, fix [#244](https://github.com/ossrs/srs/issues/244), conn thread use cond to wait for recv thread error. 2.0.47.
* v2.0, 2014-12-02, merge [#239](https://github.com/ossrs/srs/pull/239), traverse the token before response connect. 2.0.45.
* v2.0, 2014-12-02, srs-librtmp support hijack io apis for st-load. 2.0.42.
* v2.0, 2014-12-01, for [#237](https://github.com/ossrs/srs/issues/237), refine syscall for recv, supports 1.5k clients. 2.0.41.
* v2.0, 2014-11-30, add qtcreate project file trunk/src/qt/srs/srs-qt.pro. 2.0.39.
* v2.0, 2014-11-29, fix [#235](https://github.com/ossrs/srs/issues/235), refine handshake, replace union with template method. 2.0.38.
* v2.0, 2014-11-28, fix [#215](https://github.com/ossrs/srs/issues/215), add srs_rtmp_dump tool. 2.0.37.
* v2.0, 2014-11-25, update PRIMARY, AUTHORS, CONTRIBUTORS rule. 2.0.32.
* v2.0, 2014-11-24, fix [#212](https://github.com/ossrs/srs/issues/212), support publish aac adts raw stream. 2.0.31.
* v2.0, 2014-11-22, fix [#217](https://github.com/ossrs/srs/issues/217), remove timeout recv, support 7.5k+ 250kbps clients. 2.0.30.
* v2.0, 2014-11-21, srs-librtmp add rtmp prefix for rtmp/utils/human apis. 2.0.29.
* v2.0, 2014-11-21, refine examples of srs-librtmp, add srs_print_rtmp_packet. 2.0.28.
* v2.0, 2014-11-20, fix [#212](https://github.com/ossrs/srs/issues/212), support publish audio raw frames. 2.0.27
* v2.0, 2014-11-19, fix [#213](https://github.com/ossrs/srs/issues/213), support compile [srs-librtmp on windows](https://github.com/winlinvip/srs.librtmp), [bug #213](https://github.com/ossrs/srs/issues/213). 2.0.26
* v2.0, 2014-11-18, all wiki translated to English. 2.0.23.
* v2.0, 2014-11-15, fix [#204](https://github.com/ossrs/srs/issues/204), srs-librtmp drop duplicated sps/pps(sequence header). 2.0.22.
* v2.0, 2014-11-15, fix [#203](https://github.com/ossrs/srs/issues/203), srs-librtmp drop any video before sps/pps(sequence header). 2.0.21.
* v2.0, 2014-11-15, fix [#202](https://github.com/ossrs/srs/issues/202), fix memory leak of h.264 raw packet send in srs-librtmp. 2.0.20.
* v2.0, 2014-11-13, fix [#200](https://github.com/ossrs/srs/issues/200), deadloop when read/write 0 and ETIME. 2.0.16.
* v2.0, 2014-11-13, fix [#194](https://github.com/ossrs/srs/issues/194), writev multiple msgs, support 6k+ 250kbps clients. 2.0.15.
* v2.0, 2014-11-12, fix [#194](https://github.com/ossrs/srs/issues/194), optmized st for timeout recv. pulse to 500ms. 2.0.14.
* v2.0, 2014-11-11, fix [#195](https://github.com/ossrs/srs/issues/195), remove the confuse code st_usleep(0). 2.0.13.
* v2.0, 2014-11-08, fix [#191](https://github.com/ossrs/srs/issues/191), configure --export-librtmp-project and --export-librtmp-single. 2.0.11.
* v2.0, 2014-11-08, fix [#66](https://github.com/ossrs/srs/issues/66), srs-librtmp support write h264 raw packet. 2.0.9.
* v2.0, 2014-10-25, fix [#185](https://github.com/ossrs/srs/issues/185), AMF0 support 0x0B the date type codec. 2.0.7.
* v2.0, 2014-10-24, fix [#186](https://github.com/ossrs/srs/issues/186), hotfix for bug #186, drop connect args when not object. 2.0.6.
* v2.0, 2014-10-24, rename wiki/xxx to wiki/v4_CN_xxx. 2.0.3.
* v2.0, 2014-10-19, fix [#184](https://github.com/ossrs/srs/issues/184), support AnnexB in RTMP body for HLS. 2.0.2
* v2.0, 2014-10-18, remove supports for OSX(darwin). 2.0.1.
* v2.0, 2014-10-16, revert github srs README to English. 2.0.0.

<a name="v1-changes"></a>

## SRS 1.0 Changelog

* <strong>v1.0, 2014-12-05, [1.0 release(1.0.10)](https://github.com/ossrs/srs/releases/tag/v1.0-r0) released. 59391 lines.</strong>
* <strong>v1.0, 2014-10-09, [1.0 beta(1.0.0)](https://github.com/ossrs/srs/releases/tag/v0.9.8) released. 59316 lines.</strong>
* v1.0, 2014-10-08, fix [#151](https://github.com/ossrs/srs/issues/151), always reap ts whatever audio or video packet. 0.9.223.
* v1.0, 2014-10-08, fix [#162](https://github.com/ossrs/srs/issues/162), failed if no epoll. 0.9.222.
* v1.0, 2014-09-30, fix [#180](https://github.com/ossrs/srs/issues/180), crash for multiple edge publishing the same stream. 0.9.220.
* v1.0, 2014-09-26, fix hls bug, refine config and log, according to clion of jetbrains. 0.9.216.
* v1.0, 2014-09-25, fix [#177](https://github.com/ossrs/srs/issues/177), dvr segment add config dvr_wait_keyframe. 0.9.213.
* v1.0, 2014-08-28, fix [#167](https://github.com/ossrs/srs/issues/167), add openssl includes to utest. 0.9.209.
* v1.0, 2014-08-27, max connections is 32756, for st use mmap default. 0.9.209
* v1.0, 2014-08-24, fix [#150](https://github.com/ossrs/srs/issues/150), forward should forward the sequence header when retry. 0.9.208.
* v1.0, 2014-08-22, for [#165](https://github.com/ossrs/srs/issues/165), refine dh wrapper, ensure public key is 128bytes. 0.9.206.
* v1.0, 2014-08-19, for [#160](https://github.com/ossrs/srs/issues/160), support forward/edge to flussonic, disable debug_srs_upnode to make flussonic happy. 0.9.201.
* v1.0, 2014-08-17, for [#155](https://github.com/ossrs/srs/issues/155), refine for osx, with ssl/http, disable statistics. 0.9.198.
* v1.0, 2014-08-06, fix [#148](https://github.com/ossrs/srs/issues/148), simplify the RTMP handshake key generation. 0.9.191.
* v1.0, 2014-08-06, fix [#147](https://github.com/ossrs/srs/issues/147), support identify the srs edge. 0.9.190.
* <strong>v1.0, 2014-08-03, [1.0 mainline7(0.9.189)](https://github.com/ossrs/srs/releases/tag/v0.9.7) released. 57432 lines.</strong>
* v1.0, 2014-08-03, fix [#79](https://github.com/ossrs/srs/issues/79), fix the reload remove edge assert bug. 0.9.189.
* v1.0, 2014-08-03, fix [#57](https://github.com/ossrs/srs/issues/57), use lock(acquire/release publish) to avoid duplicated publishing. 0.9.188.
* v1.0, 2014-08-03, fix [#85](https://github.com/ossrs/srs/issues/85), fix the segment-dvr sequence header missing. 0.9.187.
* v1.0, 2014-08-03, fix [#145](https://github.com/ossrs/srs/issues/145), refine ffmpeg log, check abitrate for libaacplus. 0.9.186.
* v1.0, 2014-08-03, fix [#143](https://github.com/ossrs/srs/issues/143), fix retrieve sys stat bug for all linux. 0.9.185.
* v1.0, 2014-08-02, fix [#138](https://github.com/ossrs/srs/issues/138), fix http hooks bug, regression bug. 0.9.184.
* v1.0, 2014-08-02, fix [#142](https://github.com/ossrs/srs/issues/142), fix tcp stat slow bug, use /proc/net/sockstat instead, refer to 'ss -s'. 0.9.183.
* v1.0, 2014-07-31, fix [#141](https://github.com/ossrs/srs/issues/141), support tun0(vpn network device) ip retrieve. 0.9.179.
* v1.0, 2014-07-27, support partially build on OSX(Darwin). 0.9.177
* v1.0, 2014-07-27, api connections add udp, add disk iops. 0.9.176
* v1.0, 2014-07-26, complete config utest. 0.9.173
* v1.0, 2014-07-26, fix [#124](https://github.com/ossrs/srs/issues/124), gop cache support disable video in publishing. 0.9.171.
* v1.0, 2014-07-23, fix [#121](https://github.com/ossrs/srs/issues/121), srs_info detail log compile failed. 0.9.168.
* v1.0, 2014-07-19, fix [#119](https://github.com/ossrs/srs/issues/119), use iformat and oformat for ffmpeg transcode. 0.9.163.
* <strong>v1.0, 2014-07-13, [1.0 mainline6(0.9.160)](https://github.com/ossrs/srs/releases/tag/v0.9.6) released. 50029 lines.</strong>
* v1.0, 2014-07-13, refine the bandwidth check/test, add as/js library, use srs-librtmp for linux tool. 0.9.159
* v1.0, 2014-07-12, complete rtmp stack utest. 0.9.156
* v1.0, 2014-07-06, fix [#81](https://github.com/ossrs/srs/issues/81), fix HLS codec info, IOS ok. 0.9.153.
* v1.0, 2014-07-06, fix [#103](https://github.com/ossrs/srs/issues/103), support all aac sample rate. 0.9.150.
* v1.0, 2014-07-05, complete kernel utest. 0.9.149
* v1.0, 2014-06-30, fix [#111](https://github.com/ossrs/srs/issues/111), always use 31bits timestamp. 0.9.143.
* v1.0, 2014-06-28, response the call message with null. 0.9.137
* v1.0, 2014-06-28, fix [#110](https://github.com/ossrs/srs/issues/110), thread start segment fault, thread cycle stop destroy thread. 0.9.136
* v1.0, 2014-06-27, fix [#109](https://github.com/ossrs/srs/issues/109), fix the system jump time, adjust system startup time. 0.9.135
* <strong>v1.0, 2014-06-27, [1.0 mainline5(0.9.134)](https://github.com/ossrs/srs/releases/tag/v0.9.5) released. 41573 lines.</strong>
* v1.0, 2014-06-27, SRS online 30days with RTMP/HLS.
* v1.0, 2014-06-25, fix [#108](https://github.com/ossrs/srs/issues/108), support config time jitter for encoder non-monotonical stream. 0.9.133
* v1.0, 2014-06-23, support report summaries in heartbeat. 0.9.132
* v1.0, 2014-06-22, performance refine, support [3k+](https://github.com/ossrs/srs/wiki/v4_CN_Performance#performancereport4k) connections(270kbps). 0.9.130
* v1.0, 2014-06-21, support edge [token traverse](https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse), fix [#104](https://github.com/ossrs/srs/issues/104). 0.9.129
* v1.0, 2014-06-19, add connections count to api summaries. 0.9.127
* v1.0, 2014-06-19, add srs bytes and kbps to api summaries. 0.9.126
* v1.0, 2014-06-18, add network bytes to api summaries. 0.9.125
* v1.0, 2014-06-14, fix [#98](https://github.com/ossrs/srs/issues/98), workaround for librtmp ping(fmt=1,cid=2 fresh stream). 0.9.124
* v1.0, 2014-05-29, support flv inject and flv http streaming with start=bytes. 0.9.122
* <strong>v1.0, 2014-05-28, [1.0 mainline4(0.9.120)](https://github.com/ossrs/srs/releases/tag/v0.9.4) released. 39200 lines.</strong>
* v1.0, 2014-05-27, fix [#87](https://github.com/ossrs/srs/issues/87), add source id for full trackable log. 0.9.120
* v1.0, 2014-05-27, fix [#84](https://github.com/ossrs/srs/issues/84), unpublish when edge disconnect. 0.9.119
* v1.0, 2014-05-27, fix [#89](https://github.com/ossrs/srs/issues/89), config to /dev/null to disable ffmpeg log. 0.9.117
* v1.0, 2014-05-25, fix [#76](https://github.com/ossrs/srs/issues/76), allow edge vhost to add or remove. 0.9.114
* v1.0, 2014-05-24, Johnny contribute [ossrs.net](http://ossrs.net). karthikeyan start to translate wiki to English.
* v1.0, 2014-05-22, fix [#78](https://github.com/ossrs/srs/issues/78), st joinable thread must be stop by other threads, 0.9.113
* v1.0, 2014-05-22, support amf0 StrictArray(0x0a). 0.9.111.
* v1.0, 2014-05-22, support flv parser, add amf0 to librtmp. 0.9.110
* v1.0, 2014-05-22, fix [#74](https://github.com/ossrs/srs/issues/74), add tcUrl for http callback on_connect, 0.9.109
* v1.0, 2014-05-19, support http heartbeat, 0.9.107
* <strong>v1.0, 2014-05-18, [1.0 mainline3(0.9.105)](https://github.com/ossrs/srs/releases/tag/v0.9.3) released. 37594 lines.</strong>
* v1.0, 2014-05-18, support http api json, to PUT/POST. 0.9.105
* v1.0, 2014-05-17, fix [#72](https://github.com/ossrs/srs/issues/72), also need stream_id for send_and_free_message. 0.9.101
* v1.0, 2014-05-17, rename struct to class. 0.9.100
* v1.0, 2014-05-14, fix [#67](https://github.com/ossrs/srs/issues/67] pithy print, stage must has a age. 0.9.98
* v1.0, 2014-05-13, fix mem leak for delete[] SharedPtrMessage array. 0.9.95
* v1.0, 2014-05-12, refine the kbps calc module. 0.9.93
* v1.0, 2014-05-12, fix bug [#64](https://github.com/ossrs/srs/issues/64): install_dir=DESTDIR+PREFIX
* v1.0, 2014-05-08, fix [#36](https://github.com/ossrs/srs/issues/36): never directly use \*(int32_t\*) for arm.
* v1.0, 2014-05-08, fix [#60](https://github.com/ossrs/srs/issues/60): support aggregate message
* v1.0, 2014-05-08, fix [#59](https://github.com/ossrs/srs/issues/59), edge support FMS origin server. 0.9.92
* v1.0, 2014-05-06, fix [#50](https://github.com/ossrs/srs/issues/50), ubuntu14 build error.
* v1.0, 2014-05-04, support mips linux.
* v1.0, 2014-04-30, fix bug [#34](https://github.com/ossrs/srs/issues/34): convert signal to io thread. 0.9.85
* v1.0, 2014-04-29, refine RTMP protocol completed, to 0.9.81
* <strong>v1.0, 2014-04-28, [1.0 mainline2(0.9.79)](https://github.com/ossrs/srs/releases/tag/v0.9.2) released. 35255 lines.</strong>
* v1.0, 2014-04-28, support full edge RTMP server. 0.9.79
* v1.0, 2014-04-27, support basic edge(play/publish) RTMP server. 0.9.78
* v1.0, 2014-04-25, add donation page. 0.9.76
* v1.0, 2014-04-21, support android app to start srs for internal edge. 0.9.72
* v1.0, 2014-04-19, support tool over srs-librtmp to ingest flv/rtmp. 0.9.71
* v1.0, 2014-04-17, support dvr(record live to flv file for vod). 0.9.69
* v1.0, 2014-04-11, add speex1.2 to transcode flash encoder stream. 0.9.58
* v1.0, 2014-04-10, support reload ingesters(add/remov/update). 0.9.57
* <strong>v1.0, 2014-04-07, [1.0 mainline(0.9.55)](https://github.com/ossrs/srs/releases/tag/v0.9.1) released. 30000 lines.</strong>
* v1.0, 2014-04-07, support [ingest](https://github.com/ossrs/srs/wiki/v4_CN_SampleIngest) file/stream/device.
* v1.0, 2014-04-05, support [http api](https://github.com/ossrs/srs/wiki/v4_CN_HTTPApi) and [http server](https://github.com/ossrs/srs/wiki/v4_CN_HTTPServer).
* v1.0, 2014-04-03, implements http framework and api/v1/version.
* v1.0, 2014-03-30, fix bug for st detecting epoll failed, force st to use epoll.
* v1.0, 2014-03-29, add wiki [Performance for RaspberryPi](https://github.com/ossrs/srs/wiki/v4_CN_RaspberryPi).
* v1.0, 2014-03-29, add release binary package for raspberry-pi.
* v1.0, 2014-03-26, support RTMP ATC for HLS/HDS to support backup(failover).
* v1.0, 2014-03-23, support daemon, default start in daemon.
* v1.0, 2014-03-22, support make install/install-api and uninstall.
* v1.0, 2014-03-22, add ./etc/init.d/srs, refine to support make clean then make.
* v1.0, 2014-03-21, write pid to ./objs/srs.pid.
* v1.0, 2014-03-20, refine hls code, support pure audio HLS.
* v1.0, 2014-03-19, add vn/an for FFMPEG to drop video/audio for radio stream.
* v1.0, 2014-03-19, refine handshake, client support complex handshake, add utest.
* v1.0, 2014-03-16, fix bug on arm of st, the sp change from 20 to 8, for respberry-pi, @see [commit](https://github.com/ossrs/srs/commit/5a4373d4835758188b9a1f03005cea0b6ddc62aa)
* v1.0, 2014-03-16, support ARM([debian armhf, v7cpu](https://github.com/ossrs/srs/wiki/v4_CN_SrsLinuxArm)) with rtmp/ssl/hls/librtmp.
* v1.0, 2014-03-12, finish utest for amf0 codec.
* v1.0, 2014-03-06, add gperftools for mem leak detect, mem/cpu profile.
* v1.0, 2014-03-04, add gest framework for utest, build success.
* v1.0, 2014-03-02, srs-librtmp, client publish/play library like librtmp.
* v1.0, 2014-03-01, modularity, extract core/kernel/rtmp/app/main module.
* v1.0, 2014-02-28, support arm build(SRS/ST), add ssl to 3rdparty package.
* v1.0, 2014-02-28, add wiki [BuildArm](https://github.com/ossrs/srs/wiki/v4_CN_Build), [FFMPEG](https://github.com/ossrs/srs/wiki/v4_CN_FFMPEG), [Reload](https://github.com/ossrs/srs/wiki/v4_CN_Reload)
* v1.0, 2014-02-27, add wiki [LowLatency](https://github.com/ossrs/srs/wiki/v4_CN_LowLatency), [HTTPCallback](https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback)
* v1.0, 2014-01-19, add wiki [DeliveryHLS](https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS)
* v1.0, 2014-01-12, add wiki [HowToAskQuestion](https://github.com/ossrs/srs/wiki/v4_CN_HowToAskQuestion), [RtmpUrlVhost](https://github.com/ossrs/srs/wiki/v4_CN_RtmpUrlVhost)
* v1.0, 2014-01-11, fix jw/flower player pause bug, which send closeStream actually.
* v1.0, 2014-01-05, add wiki [Build](https://github.com/ossrs/srs/wiki/v4_CN_Build), [Performance](https://github.com/ossrs/srs/wiki/v4_CN_Performance), [Forward](https://github.com/ossrs/srs/wiki/v4_CN_Forward)
* v1.0, 2014-01-01, change listen(512), chunk-size(60000), to improve performance.
* v1.0, 2013-12-27, merge from wenjie, the bandwidth test feature.
* <strong>v0.9, 2013-12-25, [v0.9](https://github.com/ossrs/srs/releases/tag/v0.9.0) released. 20926 lines.</strong>
* v0.9, 2013-12-25, fix the bitrate bug(in Bps), use enhanced microphone.
* v0.9, 2013-12-22, demo video meeting or chat(SRS+cherrypy+jquery+bootstrap).
* v0.9, 2013-12-22, merge from wenjie, support banwidth test.
* v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level
* v0.9, 2013-12-21, add [players](http://ossrs.net/players/srs_player.html) for play and publish.
* v0.9, 2013-12-15, ensure the HLS(ts) is continous when republish stream.
* v0.9, 2013-12-15, fix the hls reload bug, feed it the sequence header.
* v0.9, 2013-12-15, refine protocol, use int64_t timestamp for ts and jitter.
* v0.9, 2013-12-15, support set the live queue length(in seconds), drop when full.
* v0.9, 2013-12-15, fix the forwarder reconnect bug, feed it the sequence header.
* v0.9, 2013-12-15, support reload the hls/forwarder/transcoder.
* v0.9, 2013-12-14, refine the thread model for the retry threads.
* v0.9, 2013-12-10, auto install depends tools/libs on centos/ubuntu.
* <strong>v0.8, 2013-12-08, [v0.8](https://github.com/ossrs/srs/releases/tag/v0.8.0) released. 19186 lines.</strong>
* v0.8, 2013-12-08, support [http hooks](https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback): on_connect/close/publish/unpublish/play/stop.
* v0.8, 2013-12-08, support multiple http hooks for a event.
* v0.8, 2013-12-07, support http callback hooks, on_connect.
* v0.8, 2013-12-07, support network based cli and json result, add CherryPy 3.2.4.
* v0.8, 2013-12-07, update http/hls/rtmp load test tool [SB](https://github.com/ossrs/srs-bench), use SRS rtmp sdk.
* v0.8, 2013-12-06, support max_connections, drop if exceed.
* v0.8, 2013-12-05, support log_dir, write ffmpeg log to file.
* v0.8, 2013-12-05, fix the forward/hls/encoder bug.
* <strong>v0.7, 2013-12-03, [v0.7](https://github.com/ossrs/srs/releases/tag/v0.7.0) released. 17605 lines.</strong>
* v0.7, 2013-12-01, support dead-loop detect for forwarder and transcoder.
* v0.7, 2013-12-01, support all ffmpeg filters and params.
* v0.7, 2013-11-30, support live stream transcoder by ffmpeg.
* v0.7, 2013-11-30, support --with/without -ffmpeg, build ffmpeg-2.1.
* v0.7, 2013-11-30, add ffmpeg-2.1, x264-core138, lame-3.99.5, libaacplus-2.0.2.
* <strong>v0.6, 2013-11-29, [v0.6](https://github.com/ossrs/srs/releases/tag/v0.6.0) released. 16094 lines.</strong>
* v0.6, 2013-11-29, add performance summary, 1800 clients, 900Mbps, CPU 90.2%, 41MB.
* v0.6, 2013-11-29, support forward stream to other edge server.
* v0.6, 2013-11-29, support forward stream to other origin server.
* v0.6, 2013-11-28, fix memory leak bug, aac decode bug.
* v0.6, 2013-11-27, support --with or --without -hls and -ssl options.
* v0.6, 2013-11-27, support AAC 44100HZ sample rate for iphone, adjust the timestamp.
* <strong>v0.5, 2013-11-26, [v0.5](https://github.com/ossrs/srs/releases/tag/v0.5.0) released. 14449 lines.</strong>
* v0.5, 2013-11-24, support HLS(m3u8), fragment and window.
* v0.5, 2013-11-24, support record to ts file for HLS.
* v0.5, 2013-11-21, add ts_info tool to demux ts file.
* v0.5, 2013-11-16, add rtmp players(OSMF/jwplayer5/jwplayer6).
* <strong>v0.4, 2013-11-10, [v0.4](https://github.com/ossrs/srs/releases/tag/v0.4.0) released. 12500 lines.</strong>
* v0.4, 2013-11-10, support config and reload the pithy print.
* v0.4, 2013-11-09, support reload config(vhost and its detail).
* v0.4, 2013-11-09, support reload config(listen and chunk_size) by SIGHUP(1).
* v0.4, 2013-11-09, support longtime(>4.6hours) publish/play.
* v0.4, 2013-11-09, support config the chunk_size.
* v0.4, 2013-11-09, support pause for live stream.
* <strong>v0.3, 2013-11-04, [v0.3](https://github.com/ossrs/srs/releases/tag/v0.3.0) released. 11773 lines.</strong>
* v0.3, 2013-11-04, support refer/play-refer/publish-refer.
* v0.3, 2013-11-04, support vhosts specified config.
* v0.3, 2013-11-02, support listen multiple ports.
* v0.3, 2013-11-02, support config file in nginx-conf style.
* v0.3, 2013-10-29, support pithy print log message specified by stage.
* v0.3, 2013-10-28, support librtmp without extended-timestamp in 0xCX chunk packet.
* v0.3, 2013-10-27, support cache last gop for client fast startup.
* <strong>v0.2, 2013-10-25, [v0.2](https://github.com/ossrs/srs/releases/tag/v0.2.0) released. 10125 lines.</strong>
* v0.2, 2013-10-25, support flash publish.
* v0.2, 2013-10-25, support h264/avc codec by rtmp complex handshake.
* v0.2, 2013-10-24, support time jitter detect and correct algorithm
* v0.2, 2013-10-24, support decode codec type to cache the h264/avc sequence header.
* <strong>v0.1, 2013-10-23, [v0.1](https://github.com/ossrs/srs/releases/tag/v0.1.0) released. 8287 lines.</strong>
* v0.1, 2013-10-23, support basic amf0 codec, simplify the api using c-style api.
* v0.1, 2013-10-23, support shared ptr msg for zero memory copy.
* v0.1, 2013-10-22, support vp6 codec with rtmp protocol specified simple handshake.
* v0.1, 2013-10-20, support multiple flash client play live streaming.
* v0.1, 2013-10-20, support FMLE/FFMPEG publish live streaming.
* v0.1, 2013-10-18, support rtmp message2chunk protocol(send\_message).
* v0.1, 2013-10-17, support rtmp chunk2message protocol(recv\_message).

Winlin 2021

---

### Trunk Doc Dockers (`trunk/doc/Dockers.md`)

# Dockers

About SRS Dockerfile:

* Dockerfile: For release and test.
* trunk/Dockerfile.pkg: For package binary.
* trunk/Dockerfile.builds: For test.
* trunk/Dockerfile.test: For test.
* trunk/Dockerfile.cov: For test and coverage.

```bash
docker build -t srs -f Dockerfile .
```

## Dependency Tree

The dependency tree about Dockerfile:

* Dockerfile
  * [ossrs/srs:ubuntu20](https://github.com/ossrs/dev-docker/tree/ubuntu20)
    * [ossrs/srs:ubuntu20-base2](https://github.com/ossrs/dev-docker/blob/ubuntu20/Dockerfile.base2)
      * [ossrs/srs:ubuntu20-base](https://github.com/ossrs/dev-docker/blob/ubuntu20/Dockerfile.base)
        * ubuntu:focal
    * ubuntu:focal
  * [ossrs/srs:ubuntu20-cache](https://github.com/ossrs/dev-docker/tree/ubuntu20-cache)
    * [ossrs/srs:ubuntu20](https://github.com/ossrs/dev-docker/tree/ubuntu20)
      * ubuntu:focal
  * ubuntu:focal
* trunk/Dockerfile.test
  * [ossrs/srs:dev-gcc7-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev-gcc7-cache)
    * [ossrs/srs:dev-gcc7](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev-gcc7)
      * centos:7
* trunk/Dockerfile.cov
  * [ossrs/srs:dev-gcc7-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev-gcc7-cache)
      * [ossrs/srs:dev-gcc7](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev-gcc7)
          * centos:7
* trunk/Dockerfile.pkg
  * [ossrs/srs:dev](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev)
    * centos:7
* trunk/Dockerfile.builds
  * [ossrs/srs:dev-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev-cache)
    * [ossrs/srs:dev](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev)
      * centos:7
  * [ossrs/srs:dev6-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev6-cache)
    * [ossrs/srs:dev6](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev6)
      * centos:6
  * [ossrs/srs:ubuntu16-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16-cache)
      * [ossrs/srs:ubuntu16](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16)
          * ubuntu:xenial
  * [ossrs/srs:ubuntu18-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu18-cache)
      * [ossrs/srs:ubuntu18](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu18)
          * ubuntu:bionic
  * [ossrs/srs:ubuntu20-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20-cache)
      * [ossrs/srs:ubuntu20](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20)
          * ubuntu:focal
  * [ossrs/srs:ubuntu16-cache-cross-arm](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16-cache-cross-arm)
      * [ossrs/srs:ubuntu16](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16)
          * ubuntu:xenial
  * [ossrs/srs:ubuntu16-cache-cross-aarch64](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16-cache-cross-aarch64)
      * [ossrs/srs:ubuntu16](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16)
          * ubuntu:xenial
  * [ossrs/srs:ubuntu20-cache-cross-arm](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20-cache-cross-arm)
      * [ossrs/srs:ubuntu20](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20)
          * ubuntu:focal
  * [ossrs/srs:ubuntu20-cache-cross-aarch64](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20-cache-cross-aarch64)
      * [ossrs/srs:ubuntu20](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20)
          * ubuntu:focal

## Image for Cache

To speedup the test, we use a set of cache images. 

If need to reconfigure SRS, please update SRS, then update the images:

* [ossrs/srs:dev-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev-cache)
* [ossrs/srs:dev6-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:dev6-cache)
* [ossrs/srs:ubuntu16-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16-cache)
* [ossrs/srs:ubuntu18-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu18-cache)
* [ossrs/srs:ubuntu20-cache](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20-cache)
* [ossrs/srs:ubuntu16-cache-cross-arm](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16-cache-cross-arm)
* [ossrs/srs:ubuntu16-cache-cross-aarch64](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu16-cache-cross-aarch64)
* [ossrs/srs:ubuntu20-cache-cross-arm](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20-cache-cross-arm)
* [ossrs/srs:ubuntu20-cache-cross-aarch64](https://github.com/ossrs/dev-docker/tree/ossrs/srs:ubuntu20-cache-cross-aarch64)

For example, update the [release.yml](https://github.com/ossrs/dev-docker/blob/ubuntu20-cache/.github/workflows/release.yml) for ubuntu20-cache:

```bash
# Build SRS for cache, never install it.
#     SRS is 2d036c3fd Fix #2747: Support Apple Silicon M1(aarch64). v5.0.41
# Please update this comment, if need to refresh the cached dependencies, like st/openssl/ffmpeg/libsrtp/libsrt etc.
```

Then push to github and the image will be updated automatically.

---

### Trunk Doc Features (`trunk/doc/Features.md`)

# Features

The features of SRS.

> Note: Please read **Wiki: Gettting Started( [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started) / [CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) )** first.

- [x] Using coroutine by ST, it's really simple and stupid enough.
- [x] Support cluster which consists of origin ([CN][v4_CN_DeliveryRTMP],[EN][v4_EN_DeliveryRTMP]) and edge([CN][v4_CN_Edge], [EN][v4_EN_Edge]) server and uses RTMP as default transport protocol.
- [x] Origin server supports remuxing RTMP to HTTP-FLV([CN][v4_CN_SampleHttpFlv], [EN][v4_EN_SampleHttpFlv]) and HLS([CN][v4_CN_DeliveryHLS], [EN][v4_EN_DeliveryHLS]).
- [x] Edge server supports remuxing RTMP to HTTP-FLV([CN][v4_CN_SampleHttpFlv], [EN][v4_EN_SampleHttpFlv]). As for HLS([CN][v4_CN_DeliveryHLS], [EN][v4_EN_DeliveryHLS]) edge server, recomment to use HTTP edge server, such as [NGINX](http://nginx.org/).
- [x] Support HLS with audio-only([CN][v4_CN_DeliveryHLS2], [EN][v4_EN_DeliveryHLS2]), which need to build the timestamp from AAC samples, so we enhanced it please read [#547][bug #547].
- [x] Support HLS with mp3(h.264+mp3) audio codec, please read [bug #301][bug #301].
- [x] Support transmux RTMP to HTTP-FLV/MP3/AAC/TS, please read wiki([CN][v4_CN_DeliveryHttpStream], [EN][v4_CN_DeliveryHttpStream]).
- [x] Support ingesting([CN][v4_CN_Ingest], [EN][v4_EN_Ingest]) other protocols to SRS by FFMPEG.
- [x] Support RTMP long time(>4.6hours) publishing/playing, with the timestamp corrected.
- [x] Support native HTTP server([CN][v4_CN_SampleHTTP], [EN][v4_EN_SampleHTTP]) for http api and http live streaming.
- [x] Support HTTP CORS for js in http api and http live streaming.
- [x] Support HTTP API([CN][v4_CN_HTTPApi], [EN][v4_EN_HTTPApi]) for system management.
- [x] Support HTTP callback([CN][v4_CN_HTTPCallback], [EN][v4_EN_HTTPCallback]) for authentication and integration.
- [x] Support DVR([CN][v4_CN_DVR], [EN][v4_EN_DVR]) to record live streaming to FLV file.
- [x] Support DVR control module like NGINX-RTMP, please read [#459][bug #459].
- [x] Support EXEC like NGINX-RTMP, please read [bug #367][bug #367].
- [x] Support security strategy including allow/deny publish/play IP([CN][v4_CN_Security], [EN][v4_EN_Security]).
- [x] Support low latency(0.1s+) transport model, please read [bug #257][bug #257].
- [x] Support gop-cache([CN][v4_CN_LowLatency2], [EN][v4_EN_LowLatency2]) for player fast startup.
- [x] Support Vhost([CN][v4_CN_RtmpUrlVhost], [EN][v4_EN_RtmpUrlVhost]) and \_\_defaultVhost\_\_.
- [x] Support reloading([CN][v4_CN_Reload], [EN][v4_EN_Reload]) to apply changes of config.
- [x] Support listening at multiple ports.
- [x] Support forwarding([CN][v4_CN_Forward], [EN][v4_EN_Forward]) to other RTMP servers.
- [x] Support transcoding([CN][v4_CN_FFMPEG], [EN][v4_EN_FFMPEG]) by FFMPEG.
- [x] All wikis are writen in [Chinese][v4_CN_Home] and [English][v4_EN_Home].
- [x] Enhanced json, replace NXJSON(LGPL) with json-parser(BSD), read [#904][bug #904].
- [x] Support valgrind and latest ARM by patching ST, read [ST#1](https://github.com/ossrs/state-threads/issues/1) and [ST#2](https://github.com/ossrs/state-threads/issues/2).
- [x] Support traceable and session-based log([CN][v4_CN_SrsLog], [EN][v4_EN_SrsLog]).
- [x] High performance([CN][v4_CN_Performance], [EN][v4_EN_Performance]) RTMP/HTTP-FLV, 6000+ connections.
- [x] Enhanced complex error code with description and stack, read [#913][bug #913].
- [x] Enhanced RTMP url  which supports vhost in stream, read [#1059][bug #1059].
- [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92].
- [x] Support listen at IPv4 and IPv6, read [#460][bug #460].
- [x] Improve test coverage for core/kernel/protocol/service.
- [x] Support docker by [srs-docker](https://github.com/ossrs/srs-docker).
- [x] Support multiple processes by ReusePort([CN][v4_CN_REUSEPORT], [EN][v4_EN_REUSEPORT]), [#775][bug #775].
- [x] Support a simple [mgmt console][console], please read [srs-console][srs-ngb].
- [x] [Experimental] Support playing stream by WebRTC, [#307][bug #307].
- [x] [Experimental] Support publishing stream by WebRTC, [#307][bug #307].
- [x] [Experimental] Support mux RTP/RTCP/DTLS/SRTP on one port for WebRTC, [#307][bug #307].
- [x] [Experimental] Support client address changing for WebRTC, [#307][bug #307].
- [x] [Experimental] Support transcode RTMP/AAC to WebRTC/Opus, [#307][bug #307].
- [x] [Experimental] Support AV1 codec for WebRTC, [#2324][bug #2324].
- [x] [Experimental] Enhance HTTP Stream Server for HTTP-FLV, HTTPS, HLS etc. [#1657][bug #1657].
- [x] [Experimental] Support DVR in MP4 format, read [#738][bug #738].
- [x] [Experimental] Support MPEG-DASH, the future live streaming protocol, read [#299][bug #299].
- [x] [Experimental] Support pushing MPEG-TS over UDP, please read [bug #250][bug #250].
- [x] [Experimental] Support pushing FLV over HTTP POST, please read wiki([CN][v4_CN_Streamer2], [EN][v4_EN_Streamer2]).
- [x] [Experimental] Support SRT server, read [#1147][bug #1147].
- [x] [Experimental] Support transmux RTC to RTMP, [#2093][bug #2093].
- [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v4_CN_DeliveryHDS], [EN][v4_EN_DeliveryHDS]) and [#1535][bug #1535].
- [x] [Deprecated] Support bandwidth testing, please read [#1535][bug #1535].
- [x] [Deprecated] Support Adobe FMS/AMS token traverse([CN][v4_CN_DRM2], [EN][v4_EN_DRM2]) authentication, please read [#1535][bug #1535].
- [x] [Removed] Support pushing RTSP, please read [#2304](https://github.com/ossrs/srs/issues/2304#issuecomment-826009290).
- [x] [Removed] Support HTTP RAW API, please read [#2653](https://github.com/ossrs/srs/issues/2653).
- [x] [Removed] Support RTMP client library: [srs-librtmp][srs-librtmp].
- [ ] Support Windows/Cygwin 64bits, [#2532](https://github.com/ossrs/srs/issues/2532).
- [ ] Support push stream by GB28181, [#1500][bug #1500].
- [ ] Support IETF-QUIC for WebRTC Cluster, [#2091][bug #2091].
- [ ] Enhanced forwarding with vhost and variables, [#1342][bug #1342].
- [ ] Support DVR to Cloud Storage, [#1193][bug #1193].
- [ ] Support H.265 over RTMP and HLS, [#465][bug #465].
- [ ] Improve RTC performance to 5K by multiple threading, [#2188][bug #2188].
- [ ] Support source cleanup for idle streams, [#413][bug #413].
- [ ] Support change user to run SRS, [#1111][bug #1111].
- [ ] Support HLS variant, [#463][bug #463].

> Remark: About the milestone and product plan, please read ([CN][v4_CN_Product], [EN][v4_EN_Product]) wiki.

[authors]: https://github.com/ossrs/srs/blob/4.0release/trunk/AUTHORS.txt
[bigthanks]: https://github.com/ossrs/srs/wiki/Product#release40
[st]: https://github.com/ossrs/state-threads
[st2]: https://github.com/ossrs/state-threads/tree/srs
[state-threads]: https://github.com/ossrs/state-threads/tree/srs
[nginx]: http://nginx.org/
[srs]: https://github.com/ossrs/srs
[gitee]: https://gitee.com/ossrs/srs
[srs-bench]: https://github.com/ossrs/srs-bench
[srs-ngb]: https://github.com/ossrs/srs-console
[srs-librtmp]: https://github.com/ossrs/srs-librtmp
[gitlab]: https://gitlab.com/winlinvip/srs-gitlab
[console]: http://ossrs.net:8080/console
[docker-srs3]: https://github.com/ossrs/srs-docker/tree/v3#usage
[docker-srs4]: https://github.com/ossrs/srs-docker/tree/v4#usage
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage

[v4_CN_Git]: https://github.com/ossrs/srs/wiki/v4_CN_Git
[v4_EN_Git]: https://github.com/ossrs/srs/wiki/v4_EN_Git
[v4_CN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMP
[v4_EN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMP
[v4_CN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMPCluster
[v4_EN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMPCluster
[v4_CN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleOriginCluster
[v4_EN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleOriginCluster
[v4_CN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHLS
[v4_EN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHLS
[v4_CN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleTranscode2HLS
[v4_EN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleTranscode2HLS
[v4_CN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_SampleFFMPEG
[v4_EN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_SampleFFMPEG
[v4_CN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_CN_SampleForward
[v4_EN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_EN_SampleForward
[v4_CN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRealtime
[v4_EN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRealtime
[v4_CN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC
[v4_EN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC
[v4_CN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
[v4_EN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC#config-candidate
[v4_CN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_CN_SampleARM
[v4_EN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_EN_SampleARM
[v4_CN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_CN_SampleIngest
[v4_EN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_EN_SampleIngest
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_OriginCluster
[v4_EN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_OriginCluster
[v4_CN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_CN_REUSEPORT
[v4_EN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_EN_REUSEPORT
[v4_CN_Sample]: https://github.com/ossrs/srs/wiki/v4_CN_Sample
[v4_EN_Sample]: https://github.com/ossrs/srs/wiki/v4_EN_Sample
[v4_CN_Product]: https://github.com/ossrs/srs/wiki/v4_CN_Product
[v4_EN_Product]: https://github.com/ossrs/srs/wiki/v4_EN_Product
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home

[v4_CN_Compare]: https://github.com/ossrs/srs/wiki/v4_CN_Compare
[v4_EN_Compare]: https://github.com/ossrs/srs/wiki/v4_EN_Compare
[v4_CN_Build]: https://github.com/ossrs/srs/wiki/v4_CN_Build
[v4_EN_Build]: https://github.com/ossrs/srs/wiki/v4_EN_Build
[v4_CN_Performance]: https://github.com/ossrs/srs/wiki/v4_CN_Performance
[v4_EN_Performance]: https://github.com/ossrs/srs/wiki/v4_EN_Performance
[v4_CN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryRTMP
[v4_EN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryRTMP
[v4_CN_Edge]: https://github.com/ossrs/srs/wiki/v4_CN_Edge
[v4_EN_Edge]: https://github.com/ossrs/srs/wiki/v4_EN_Edge
[v4_CN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_CN_RtmpUrlVhost
[v4_EN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_EN_RtmpUrlVhost
[v4_CN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_CN_RTMPHandshake
[v4_EN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_EN_RTMPHandshake
[v4_CN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPServer
[v4_EN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPServer
[v4_CN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS
[v4_EN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS
[v4_CN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS#hlsaudioonly
[v4_EN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS#hlsaudioonly
[v4_CN_Reload]: https://github.com/ossrs/srs/wiki/v4_CN_Reload
[v4_EN_Reload]: https://github.com/ossrs/srs/wiki/v4_EN_Reload
[v4_CN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#gop-cache
[v4_EN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#gop-cache
[v4_CN_Forward]: https://github.com/ossrs/srs/wiki/v4_CN_Forward
[v4_EN_Forward]: https://github.com/ossrs/srs/wiki/v4_EN_Forward
[v4_CN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_FFMPEG
[v4_EN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_FFMPEG
[v4_CN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback
[v4_EN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPCallback
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLinuxArm
[v4_EN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLinuxArm
[v4_CN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_CN_LinuxService
[v4_EN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_EN_LinuxService
[v4_CN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_CN_RTMP-ATC
[v4_EN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_EN_RTMP-ATC
[v4_CN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPApi
[v4_EN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPApi
[v4_CN_Ingest]: https://github.com/ossrs/srs/wiki/v4_CN_Ingest
[v4_EN_Ingest]: https://github.com/ossrs/srs/wiki/v4_EN_Ingest
[v4_CN_DVR]: https://github.com/ossrs/srs/wiki/v4_CN_DVR
[v4_EN_DVR]: https://github.com/ossrs/srs/wiki/v4_EN_DVR
[v4_CN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLog
[v4_EN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLog
[v4_CN_DRM2]: https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse
[v4_EN_DRM2]: https://github.com/ossrs/srs/wiki/v4_EN_DRM#tokentraverse
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_CN_FlvVodStream
[v4_EN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_EN_FlvVodStream
[v4_CN_Security]: https://github.com/ossrs/srs/wiki/v4_CN_Security
[v4_EN_Security]: https://github.com/ossrs/srs/wiki/v4_EN_Security
[v4_CN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHttpStream
[v4_EN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream
[v4_CN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHDS
[v4_EN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHDS
[v4_CN_Streamer]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer
[v4_EN_Streamer]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer
[v4_CN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-http-flv-to-srs
[v4_EN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer#push-http-flv-to-srs
[v4_CN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlv
[v4_EN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlv
[v4_CN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlvCluster
[v4_EN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlvCluster
[v4_CN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_CN_SampleDASH
[v4_EN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_EN_SampleDASH

[bug #547]: https://github.com/ossrs/srs/issues/547
[bug #301]: https://github.com/ossrs/srs/issues/301
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #367]: https://github.com/ossrs/srs/issues/367
[bug #257]: https://github.com/ossrs/srs/issues/257
[bug #904]: https://github.com/ossrs/srs/issues/904
[bug #913]: https://github.com/ossrs/srs/issues/913
[bug #1059]: https://github.com/ossrs/srs/issues/1059
[bug #92]: https://github.com/ossrs/srs/issues/92
[bug #464]: https://github.com/ossrs/srs/issues/464
[bug #460]: https://github.com/ossrs/srs/issues/460
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #307]: https://github.com/ossrs/srs/issues/307
[bug #2324]: https://github.com/ossrs/srs/issues/2324
[bug #1657]: https://github.com/ossrs/srs/issues/1657
[bug #1500]: https://github.com/ossrs/srs/issues/1500
[bug #738]: https://github.com/ossrs/srs/issues/738
[bug #299]: https://github.com/ossrs/srs/issues/299
[bug #250]: https://github.com/ossrs/srs/issues/250
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #470]: https://github.com/ossrs/srs/issues/470
[bug #319]: https://github.com/ossrs/srs/issues/319
[bug #1147]: https://github.com/ossrs/srs/issues/1147
[bug #2304]: https://github.com/ossrs/srs/issues/2304
[bug #1535]: https://github.com/ossrs/srs/issues/1535
[bug #1342]: https://github.com/ossrs/srs/issues/1342
[bug #1193]: https://github.com/ossrs/srs/issues/1193
[bug #2093]: https://github.com/ossrs/srs/issues/2093
[bug #465]: https://github.com/ossrs/srs/issues/465
[bug #2091]: https://github.com/ossrs/srs/issues/2091
[bug #2188]: https://github.com/ossrs/srs/issues/2188
[bug #413]: https://github.com/ossrs/srs/issues/413
[bug #1111]: https://github.com/ossrs/srs/issues/1111
[bug #463]: https://github.com/ossrs/srs/issues/463
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #257-c0]: https://github.com/ossrs/srs/issues/257#issuecomment-66864413

[r3.0r5]: https://github.com/ossrs/srs/releases/tag/v3.0-r5
[r3.0r4]: https://github.com/ossrs/srs/releases/tag/v3.0-r4
[r3.0r3]: https://github.com/ossrs/srs/releases/tag/v3.0-r3
[r3.0r2]: https://github.com/ossrs/srs/releases/tag/v3.0-r2
[r3.0r1]: https://github.com/ossrs/srs/releases/tag/v3.0-r1
[r3.0r0]: https://github.com/ossrs/srs/releases/tag/v3.0-r0
[r3.0b4]: https://github.com/ossrs/srs/releases/tag/v3.0-b4
[r3.0b3]: https://github.com/ossrs/srs/releases/tag/v3.0-b3
[r3.0b2]: https://github.com/ossrs/srs/releases/tag/v3.0-b2
[r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7
[r3.0a6]: https://github.com/ossrs/srs/releases/tag/v3.0-a6
[r3.0a5]: https://github.com/ossrs/srs/releases/tag/v3.0-a5
[r3.0a4]: https://github.com/ossrs/srs/releases/tag/v3.0-a4
[r3.0a3]: https://github.com/ossrs/srs/releases/tag/v3.0-a3
[r3.0a2]: https://github.com/ossrs/srs/releases/tag/v3.0-a2
[r3.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
[r2.0r8]: https://github.com/ossrs/srs/releases/tag/v2.0-r8
[r2.0r7]: https://github.com/ossrs/srs/releases/tag/v2.0-r7
[r2.0r6]: https://github.com/ossrs/srs/releases/tag/v2.0-r6
[r2.0r5]: https://github.com/ossrs/srs/releases/tag/v2.0-r5
[r2.0r4]: https://github.com/ossrs/srs/releases/tag/v2.0-r4
[r2.0r3]: https://github.com/ossrs/srs/releases/tag/v2.0-r3
[r2.0r2]: https://github.com/ossrs/srs/releases/tag/v2.0-r2
[r2.0r1]: https://github.com/ossrs/srs/releases/tag/v2.0-r1
[r2.0r0]: https://github.com/ossrs/srs/releases/tag/v2.0-r0
[r2.0b4]: https://github.com/ossrs/srs/releases/tag/v2.0-b4
[r2.0b3]: https://github.com/ossrs/srs/releases/tag/v2.0-b3
[r2.0b2]: https://github.com/ossrs/srs/releases/tag/v2.0-b2
[r2.0b1]: https://github.com/ossrs/srs/releases/tag/v2.0-b1
[r2.0b0]: https://github.com/ossrs/srs/releases/tag/v2.0-b0
[r2.0a3]: https://github.com/ossrs/srs/releases/tag/v2.0-a3
[r2.0a2]: https://github.com/ossrs/srs/releases/tag/v2.0-a2
[r2.0a1]: https://github.com/ossrs/srs/releases/tag/v2.0-a1
[r2.0a0]: https://github.com/ossrs/srs/releases/tag/v2.0-a0
[r1.0r4]: https://github.com/ossrs/srs/releases/tag/v1.0-r4
[r1.0r3]: https://github.com/ossrs/srs/releases/tag/v1.0-r3
[r1.0r2]: https://github.com/ossrs/srs/releases/tag/v1.0-r2
[r1.0r1]: https://github.com/ossrs/srs/releases/tag/v1.0-r1
[r1.0r0]: https://github.com/ossrs/srs/releases/tag/v1.0-r0
[r1.0b0]: https://github.com/ossrs/srs/releases/tag/v0.9.8
[r1.0a7]: https://github.com/ossrs/srs/releases/tag/v0.9.7
[r1.0a6]: https://github.com/ossrs/srs/releases/tag/v0.9.6
[r1.0a5]: https://github.com/ossrs/srs/releases/tag/v0.9.5
[r1.0a4]: https://github.com/ossrs/srs/releases/tag/v0.9.4
[r1.0a3]: https://github.com/ossrs/srs/releases/tag/v0.9.3
[r1.0a2]: https://github.com/ossrs/srs/releases/tag/v0.9.2
[r1.0a0]: https://github.com/ossrs/srs/releases/tag/v0.9.1
[r0.9]: https://github.com/ossrs/srs/releases/tag/v0.9.0
[r0.8]: https://github.com/ossrs/srs/releases/tag/v0.8.0
[r0.7]: https://github.com/ossrs/srs/releases/tag/v0.7.0
[r0.6]: https://github.com/ossrs/srs/releases/tag/v0.6.0
[r0.5]: https://github.com/ossrs/srs/releases/tag/v0.5.0
[r0.4]: https://github.com/ossrs/srs/releases/tag/v0.4.0
[r0.3]: https://github.com/ossrs/srs/releases/tag/v0.3.0
[r0.2]: https://github.com/ossrs/srs/releases/tag/v0.2.0
[r0.1]: https://github.com/ossrs/srs/releases/tag/v0.1.0


[v4_CN_Contact]: https://github.com/ossrs/srs/wiki/v4_CN_Contact
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

[LICENSE]: https://github.com/ossrs/srs/blob/4.0release/LICENSE
[LicenseMixing]: https://ossrs.net/lts/zh-cn/license

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
[release4]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release40

---

### Trunk Doc PERFORMANCE (`trunk/doc/PERFORMANCE.md`)

# Performance

The performance benchmark data and corelative commits are listed here.

> Note: Please read **Wiki: Gettting Started( [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started) / [CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) )** first.

* See also: [Performance for x86/x64 Test Guide][v4_CN_Performance].
* See also: [Performance for RaspberryPi][v4_CN_RaspberryPi].
* For multiple processes performance, read [#775: REUSEPORT][bug #775] or OriginCluster([CN][v4_EN_OriginCluster]/[EN][v4_EN_OriginCluster]).
* For RTC benchmark, please use [srs-bench](https://github.com/ossrs/srs-bench/tree/feature/rtc#usage).

<a name="play-rtmp-benchmark"></a>
**Play RTMP benchmark**

The data for playing RTMP was benchmarked by [SB][srs-bench]:


|   Update      |    SRS    |    Clients    |     Type      |    CPU    |  Memory   | Commit        |
| ------------- | --------- | ------------- | ------------- | --------- | --------  | ------------  |
|   2014-12-07  |   2.0.67  |   10k(10000)  |   players     |   95%     |   656MB   |   [code][p12] |
|   2014-12-05  |   2.0.57  |   9.0k(9000)  |   players     |   90%     |   468MB   |   [code][p11] |
|   2014-12-05  |   2.0.55  |   8.0k(8000)  |   players     |   89%     |   360MB   |   [code][p10] |
|   2014-11-22  |   2.0.30  |   7.5k(7500)  |   players     |   87%     |   320MB   |   [code][p9]  |
|   2014-11-13  |   2.0.15  |   6.0k(6000)  |   players     |   82%     |   203MB   |   [code][p8]  |
|   2014-11-12  |   2.0.14  |   3.5k(3500)  |   players     |   95%     |   78MB    |   [code][p7]  |
|   2014-11-12  |   2.0.14  |   2.7k(2700)  |   players     |   69%     |   59MB    |   -           |
|   2014-11-11  |   2.0.12  |   2.7k(2700)  |   players     |   85%     |   66MB    |   -           |
|   2014-11-11  |   1.0.5   |   2.7k(2700)  |   players     |   85%     |   66MB    |   -           |
|   2014-07-12  |   0.9.156 |   2.7k(2700)  |   players     |   89%     |   61MB    |   [code][p6]  |
|   2014-07-12  |   0.9.156 |   1.8k(1800)  |   players     |   68%     |   38MB    |   -           |
|   2013-11-28  |   0.5.0   |   1.8k(1800)  |   players     |   90%     |   41M     |   -           |

| Update     |    SFU           |  Clients |     Type      |    CPU    |  Memory   | Threads | VM   |
| ---------- | ---------------- | -------- | ------------- | --------- | --------  | ------- | ---- |
| 2021-05-11 | SRS/v4.0.105     | 4000     |   players     |   ~94% x1 |   419MB   | 1       | G5 8CPU |
| 2021-05-11 | NginxRTMP/v1.2.1 | 2400     |   players     |   ~92% x1 |   173MB   | 1       | G5 8CPU |

> Note: CentOS7, 600Kbps, [ECS/G5-2.5GHZ(SkyLake)](https://help.aliyun.com/document_detail/25378.html),
> [SRS/v4.0.105](https://github.com/ossrs/srs/commit/2ad24b2313e88a85801deaea370204f225555939),
> [NginxRTMP/v1.2.1](https://github.com/arut/nginx-rtmp-module/releases/tag/v1.2.1).

<a name="publish-rtmp-benchmark"></a>
**Publish RTMP benchmark**

The data for publishing RTMP was benchmarked by [SB][srs-bench]:

|   Update      |    SRS    |    Clients    |     Type      |    CPU    |  Memory   | Commit        |
| ------------- | --------- | ------------- | ------------- | --------- | --------  | ------------  |
|   2014-12-04  |   2.0.52  |   4.0k(4000)  |   publishers  |   80%     |   331MB   |   [code][p5]  |
|   2014-12-04  |   2.0.51  |   2.5k(2500)  |   publishers  |   91%     |   259MB   |   [code][p4]  |
|   2014-12-04  |   2.0.49  |   2.5k(2500)  |   publishers  |   95%     |   404MB   |   [code][p3]  |
|   2014-12-04  |   2.0.49  |   1.4k(1400)  |   publishers  |   68%     |   144MB   |   -           |
|   2014-12-03  |   2.0.48  |   1.4k(1400)  |   publishers  |   95%     |   140MB   |   [code][p2]  |
|   2014-12-03  |   2.0.47  |   1.4k(1400)  |   publishers  |   95%     |   140MB   |   -           |
|   2014-12-03  |   2.0.47  |   1.2k(1200)  |   publishers  |   84%     |   76MB    |   [code][p1]  |
|   2014-12-03  |   2.0.12  |   1.2k(1200)  |   publishers  |   96%     |   43MB    |   -           |
|   2014-12-03  |   1.0.10  |   1.2k(1200)  |   publishers  |   96%     |   43MB    |   -           |

| Update     |    SFU           |  Clients |     Type      |    CPU    |  Memory   | Threads | VM   |
| ---------- | ---------------- | -------- | ------------- | --------- | --------  | ------- | ---- |
| 2021-05-11 | SRS/v4.0.105     | 2300     |   publishers  |   ~89% x1 |   1.1GB   | 1       | G5 8CPU |
| 2021-05-11 | NginxRTMP/v1.2.1 | 1300     |   publishers  |   ~84% x1 |   198MB   | 1       | G5 8CPU |

> Note: CentOS7, 600Kbps, [ECS/G5-2.5GHZ(SkyLake)](https://help.aliyun.com/document_detail/25378.html),
> [SRS/v4.0.105](https://github.com/ossrs/srs/commit/2ad24b2313e88a85801deaea370204f225555939),
> [NginxRTMP/v1.2.1](https://github.com/arut/nginx-rtmp-module/releases/tag/v1.2.1).

<a name="play-http-flv-benchmark"></a>
**Play HTTP FLV benchmark**

The data for playing HTTP FLV was benchmarked by [SB][srs-bench]:


|   Update      |    SRS    |    Clients    |     Type      |    CPU    |  Memory   | Commit        |
| ------------- | --------- | ------------- | ------------- | --------- | --------  | ------------  |
|   2014-05-25  |   2.0.171 |   6.0k(6000)  |   players     |   84%     |   297MB   |   [code][p20] |
|   2014-05-24  |   2.0.170 |   3.0k(3000)  |   players     |   89%     |   96MB    |   [code][p19] |
|   2014-05-24  |   2.0.169 |   3.0k(3000)  |   players     |   94%     |   188MB   |   [code][p18] |
|   2014-05-24  |   2.0.168 |   2.3k(2300)  |   players     |   92%     |   276MB   |   [code][p17] |
|   2014-05-24  |   2.0.167 |   1.0k(1000)  |   players     |   82%     |   86MB    |   -           |

<a name="rtc-benchmark"></a>
**RTC benchmark**

The RTC benchmark data, by [srs-bench](https://github.com/ossrs/srs-bench/tree/feature/rtc#usage):

| Update     |    SFU        |  Clients |     Type      |    CPU    |  Memory   | Threads | VM   |
| ---------- | ------------- | -------- | ------------- | --------- | --------  | ------- | ---- |
| 2021-05-10 | SRS/v4.0.105  | 2000     |   players     |   ~94% x1 |   462MB   | 1      | G7 2CPU |
| 2021-05-10 | SRS/v4.0.105  | 1000     |   players     |   ~90% x1 |   180MB   | 1      | G5 2CPU |
| 2021-03-31 | SRS/v4.0.87   | 800      |   players     |   ~94% x1 |   444MB   | 1      | G5 2CPU |
| 2021-05-10 | Janus/v0.11.1 | 700      |   players     |   ~93% x2 |   430MB   | 24     | G5 2CPU |
| 2021-05-10 | SRS/v4.0.105  | 1700     |   publishers  |   ~92% x1 |   334MB   | 1      | G7 2CPU |
| 2021-05-10 | SRS/v4.0.105  | 950      |   publishers  |   ~92% x1 |   132MB   | 1      | G5 2CPU |
| 2021-03-31 | SRS/v4.0.87   | 550      |   publishers  |   ~86% x1 |   1.3GB   | 1      | G5 2CPU |
| 2021-05-10 | Janus/v0.11.1 | 350      |   publishers  |   ~93% x2 |   405MB   | 23     | G5 2CPU |

> Note: CentOS7, 600Kbps, [ECS/G5-2.5GHZ(SkyLake)/G7-2.7GHZ(IceLake)](https://help.aliyun.com/document_detail/25378.html),
> [SRS/v4.0.87](https://github.com/ossrs/srs/commit/d6c16a7e236e03eba754c763e865464ec82d4516),
> [SRS/v4.0.105](https://github.com/ossrs/srs/commit/2ad24b2313e88a85801deaea370204f225555939),
> [Janus/v0.11.1](https://github.com/meetecho/janus-gateway/releases/tag/v0.11.1).

<a name="latency-benchmark"></a>
**Latency benchmark**

The latency between encoder and player with realtime config([CN][v4_CN_LowLatency], [EN][v4_EN_LowLatency]):

|   Update      |    SRS    | Protocol |    VP6    |  H.264    |  VP6+MP3  | H.264+MP3 |
| ------------- | --------- | --------- | --------- | --------- | --------- | --------  |
|   2014-12-16  |   2.0.72  | RTMP      |   0.1s    |   0.4s    |[0.8s][p15]|[0.6s][p16]|
|   2014-12-12  |   2.0.70  | RTMP      |[0.1s][p13]|[0.4s][p14]|   1.0s    |   0.9s    |
|   2014-12-03  |   1.0.10  | RTMP      |   0.4s    |   0.4s    |   0.9s    |   1.2s    |
|   2021-04-02  |   4.0.87  | WebRTC    |   x       |   80ms    |   x       |   x       |

> 2018-08-05, [c45f72e](https://github.com/ossrs/srs/commit/c45f72ef7bac9c7cf85b9125fc9e3aafd53f396f), Refine HTTP-FLV latency, support realtime mode. 2.0.252

We used FMLE as encoder for benchmark. The latency of server was 0.1s+,
and the bottleneck was the encoder. For more information, read
[bug #257][bug #257-c0].

Winlin 2021


[p1]: https://github.com/ossrs/srs/commit/787ab674e38734ea8e0678101614fdcd84645dc8
[p2]: https://github.com/ossrs/srs/commit/f35ec2155b1408d528a9f37da7904c9625186bcf
[p3]: https://github.com/ossrs/srs/commit/29324fab469e0f7cef9ad04ffdbce832ac7dd9ff
[p4]: https://github.com/ossrs/srs/commit/f57801eb46c16755b173984b915a4166922df6a6
[p5]: https://github.com/ossrs/srs/commit/5589b13d2e216b91f97afb78ee0c011b2fccf7da
[p6]: https://github.com/ossrs/srs/commit/1ae3e6c64cc5cee90e6050c26968ebc3c18281be
[p7]: https://github.com/ossrs/srs/commit/8acd143a7a152885b815999162660fd4e7a3f247
[p8]: https://github.com/ossrs/srs/commit/cc6aca9ad55342a06440ce7f3b38453776b2b2d1
[p9]: https://github.com/ossrs/srs/commit/58136ec178e3d47db6c90a59875d7e40946936e5
[p10]: https://github.com/ossrs/srs/commit/58136ec178e3d47db6c90a59875d7e40946936e5
[p11]: https://github.com/ossrs/srs/commit/9ee138746f83adc26f0e236ec017f4d68a300004
[p12]: https://github.com/ossrs/srs/commit/1311b6fe6576fd7b9c6d299b0f8f2e8d202f4bf8
[p13]: https://github.com/ossrs/srs/commit/10297fab519811845b549a8af40a6bcbd23411e8
[p14]: https://github.com/ossrs/srs/commit/10297fab519811845b549a8af40a6bcbd23411e8
[p15]: https://github.com/ossrs/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc
[p16]: https://github.com/ossrs/srs/commit/0d6b91039d408328caab31a1077d56a809b6bebc
[p17]: https://github.com/ossrs/srs/commit/fc995473eb02c7cf64b5b212b456e11f34aa7984
[p18]: https://github.com/ossrs/srs/commit/960341b9b2b9646270ccfd113b4dd784d9826c73
[p19]: https://github.com/ossrs/srs/commit/4df19ba99a4e4d80cd89b304f9298d343497bec9
[p20]: https://github.com/ossrs/srs/commit/d12fc7fcc5b2e9e3c8ee5c7da01d0e41c8f8ca4a
[p21]: https://github.com/ossrs/srs/commit/87519aaae835199e5adb60c0ae2c1cd24939448c
[p22]: https://github.com/ossrs/srs/commit/5a4373d4835758188b9a1f03005cea0b6ddc62aa
[p23]: https://github.com/ossrs/srs/pull/239

[authors]: https://github.com/ossrs/srs/blob/4.0release/trunk/AUTHORS.txt
[bigthanks]: https://github.com/ossrs/srs/wiki/Product#release40
[st]: https://github.com/ossrs/state-threads
[st2]: https://github.com/ossrs/state-threads/tree/srs
[state-threads]: https://github.com/ossrs/state-threads/tree/srs
[nginx]: http://nginx.org/
[srs]: https://github.com/ossrs/srs
[gitee]: https://gitee.com/ossrs/srs
[srs-bench]: https://github.com/ossrs/srs-bench
[srs-ngb]: https://github.com/ossrs/srs-console
[srs-librtmp]: https://github.com/ossrs/srs-librtmp
[gitlab]: https://gitlab.com/winlinvip/srs-gitlab
[console]: http://ossrs.net:8080/console
[docker-srs3]: https://github.com/ossrs/srs-docker/tree/v3#usage
[docker-srs4]: https://github.com/ossrs/srs-docker/tree/v4#usage
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage

[v4_CN_Git]: https://github.com/ossrs/srs/wiki/v4_CN_Git
[v4_EN_Git]: https://github.com/ossrs/srs/wiki/v4_EN_Git
[v4_CN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMP
[v4_EN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMP
[v4_CN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMPCluster
[v4_EN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMPCluster
[v4_CN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleOriginCluster
[v4_EN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleOriginCluster
[v4_CN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHLS
[v4_EN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHLS
[v4_CN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleTranscode2HLS
[v4_EN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleTranscode2HLS
[v4_CN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_SampleFFMPEG
[v4_EN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_SampleFFMPEG
[v4_CN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_CN_SampleForward
[v4_EN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_EN_SampleForward
[v4_CN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRealtime
[v4_EN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRealtime
[v4_CN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC
[v4_EN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC
[v4_CN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
[v4_EN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC#config-candidate
[v4_CN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_CN_SampleARM
[v4_EN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_EN_SampleARM
[v4_CN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_CN_SampleIngest
[v4_EN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_EN_SampleIngest
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_OriginCluster
[v4_EN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_OriginCluster
[v4_CN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_CN_REUSEPORT
[v4_EN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_EN_REUSEPORT
[v4_CN_Sample]: https://github.com/ossrs/srs/wiki/v4_CN_Sample
[v4_EN_Sample]: https://github.com/ossrs/srs/wiki/v4_EN_Sample
[v4_CN_Product]: https://github.com/ossrs/srs/wiki/v4_CN_Product
[v4_EN_Product]: https://github.com/ossrs/srs/wiki/v4_EN_Product
[v1-wiki-cn]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v1-wiki-en]: https://github.com/ossrs/srs/wiki/v4_EN_Home
[v2-wiki-cn]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v2-wiki-en]: https://github.com/ossrs/srs/wiki/v4_EN_Home
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home

[v4_CN_Compare]: https://github.com/ossrs/srs/wiki/v4_CN_Compare
[v4_EN_Compare]: https://github.com/ossrs/srs/wiki/v4_EN_Compare
[v4_CN_Build]: https://github.com/ossrs/srs/wiki/v4_CN_Build
[v4_EN_Build]: https://github.com/ossrs/srs/wiki/v4_EN_Build
[v4_CN_Performance]: https://github.com/ossrs/srs/wiki/v4_CN_Performance
[v4_EN_Performance]: https://github.com/ossrs/srs/wiki/v4_EN_Performance
[v4_CN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryRTMP
[v4_EN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryRTMP
[v4_CN_Edge]: https://github.com/ossrs/srs/wiki/v4_CN_Edge
[v4_EN_Edge]: https://github.com/ossrs/srs/wiki/v4_EN_Edge
[v4_CN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_CN_RtmpUrlVhost
[v4_EN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_EN_RtmpUrlVhost
[v4_CN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_CN_RTMPHandshake
[v4_EN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_EN_RTMPHandshake
[v4_CN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPServer
[v4_EN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPServer
[v4_CN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS
[v4_EN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS
[v4_CN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS#hlsaudioonly
[v4_EN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS#hlsaudioonly
[v4_CN_Reload]: https://github.com/ossrs/srs/wiki/v4_CN_Reload
[v4_EN_Reload]: https://github.com/ossrs/srs/wiki/v4_EN_Reload
[v4_CN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#gop-cache
[v4_EN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#gop-cache
[v4_CN_Forward]: https://github.com/ossrs/srs/wiki/v4_CN_Forward
[v4_EN_Forward]: https://github.com/ossrs/srs/wiki/v4_EN_Forward
[v4_CN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_FFMPEG
[v4_EN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_FFMPEG
[v4_CN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback
[v4_EN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPCallback
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLinuxArm
[v4_EN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLinuxArm
[v4_CN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_CN_LinuxService
[v4_EN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_EN_LinuxService
[v4_CN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_CN_RTMP-ATC
[v4_EN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_EN_RTMP-ATC
[v4_CN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPApi
[v4_EN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPApi
[v4_CN_Ingest]: https://github.com/ossrs/srs/wiki/v4_CN_Ingest
[v4_EN_Ingest]: https://github.com/ossrs/srs/wiki/v4_EN_Ingest
[v4_CN_DVR]: https://github.com/ossrs/srs/wiki/v4_CN_DVR
[v4_EN_DVR]: https://github.com/ossrs/srs/wiki/v4_EN_DVR
[v4_CN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLog
[v4_EN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLog
[v4_CN_DRM2]: https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse
[v4_EN_DRM2]: https://github.com/ossrs/srs/wiki/v4_EN_DRM#tokentraverse
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_CN_FlvVodStream
[v4_EN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_EN_FlvVodStream
[v4_CN_Security]: https://github.com/ossrs/srs/wiki/v4_CN_Security
[v4_EN_Security]: https://github.com/ossrs/srs/wiki/v4_EN_Security
[v4_CN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHttpStream
[v4_EN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream
[v4_CN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHDS
[v4_EN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHDS
[v4_CN_Streamer]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer
[v4_EN_Streamer]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer
[v4_CN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-http-flv-to-srs
[v4_EN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer#push-http-flv-to-srs
[v4_CN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlv
[v4_EN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlv
[v4_CN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlvCluster
[v4_EN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlvCluster
[v4_CN_LowLatency]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency
[v4_EN_LowLatency]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency
[v4_EN_LowLatency#merged-read]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#merged-read
[v4_CN_Performance#performancereport4k]: https://github.com/ossrs/srs/wiki/v4_CN_Performance#performancereport4k
[v4_CN_DRM#tokentraverse]: https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse
[v4_CN_RaspberryPi]: https://github.com/ossrs/srs/wiki/v4_CN_RaspberryPi
[v4_CN_Build]: https://github.com/ossrs/srs/wiki/v4_CN_Build
[v4_CN_LowLatency]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency
[v4_CN_HowToAskQuestion]: https://github.com/ossrs/srs/wiki/v4_CN_HowToAskQuestion
[v4_CN_Build]: https://github.com/ossrs/srs/wiki/v4_CN_Build
[v4_CN_Performance]: https://github.com/ossrs/srs/wiki/v4_CN_Performance
[v4_CN_RaspberryPi]: https://github.com/ossrs/srs/wiki/v4_CN_RaspberryPi
[v4_CN_LowLatency#merged-read]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#merged-read
[v4_CN_Product]: https://github.com/ossrs/srs/wiki/v4_CN_Product
[v4_EN_LowLatency#merged-write]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#merged-write
[v4_CN_LowLatency#merged-write]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#merged-write
[v4_CN_NgExec]:https://github.com/ossrs/srs/wiki/v4_CN_NgExec
[v4_EN_NgExec]:https://github.com/ossrs/srs/wiki/v4_EN_NgExec
[v4_CN_ReusePort]:https://github.com/ossrs/srs/wiki/v4_CN_ReusePort
[v4_EN_ReusePort]:https://github.com/ossrs/srs/wiki/v4_EN_ReusePort
[v4_CN_SampleSRT]:https://github.com/ossrs/srs/wiki/v4_CN_SampleSRT
[v4_EN_SampleSRT]:https://github.com/ossrs/srs/wiki/v4_EN_SampleSRT
[v4_CN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_CN_SampleDASH
[v4_EN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_EN_SampleDASH

[bug #547]: https://github.com/ossrs/srs/issues/547
[bug #301]: https://github.com/ossrs/srs/issues/301
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #367]: https://github.com/ossrs/srs/issues/367
[bug #257]: https://github.com/ossrs/srs/issues/257
[bug #904]: https://github.com/ossrs/srs/issues/904
[bug #913]: https://github.com/ossrs/srs/issues/913
[bug #1059]: https://github.com/ossrs/srs/issues/1059
[bug #92]: https://github.com/ossrs/srs/issues/92
[bug #464]: https://github.com/ossrs/srs/issues/464
[bug #460]: https://github.com/ossrs/srs/issues/460
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #307]: https://github.com/ossrs/srs/issues/307
[bug #2324]: https://github.com/ossrs/srs/issues/2324
[bug #1657]: https://github.com/ossrs/srs/issues/1657
[bug #1500]: https://github.com/ossrs/srs/issues/1500
[bug #738]: https://github.com/ossrs/srs/issues/738
[bug #299]: https://github.com/ossrs/srs/issues/299
[bug #250]: https://github.com/ossrs/srs/issues/250
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #470]: https://github.com/ossrs/srs/issues/470
[bug #319]: https://github.com/ossrs/srs/issues/319
[bug #1147]: https://github.com/ossrs/srs/issues/1147
[bug #2304]: https://github.com/ossrs/srs/issues/2304
[bug #1535]: https://github.com/ossrs/srs/issues/1535
[bug #1342]: https://github.com/ossrs/srs/issues/1342
[bug #1193]: https://github.com/ossrs/srs/issues/1193
[bug #2093]: https://github.com/ossrs/srs/issues/2093
[bug #465]: https://github.com/ossrs/srs/issues/465
[bug #2091]: https://github.com/ossrs/srs/issues/2091
[bug #2188]: https://github.com/ossrs/srs/issues/2188
[bug #413]: https://github.com/ossrs/srs/issues/413
[bug #1111]: https://github.com/ossrs/srs/issues/1111
[bug #463]: https://github.com/ossrs/srs/issues/463
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #257-c0]: https://github.com/ossrs/srs/issues/257#issuecomment-66864413

[r3.0r5]: https://github.com/ossrs/srs/releases/tag/v3.0-r5
[r3.0r4]: https://github.com/ossrs/srs/releases/tag/v3.0-r4
[r3.0r3]: https://github.com/ossrs/srs/releases/tag/v3.0-r3
[r3.0r2]: https://github.com/ossrs/srs/releases/tag/v3.0-r2
[r3.0r1]: https://github.com/ossrs/srs/releases/tag/v3.0-r1
[r3.0r0]: https://github.com/ossrs/srs/releases/tag/v3.0-r0
[r3.0b4]: https://github.com/ossrs/srs/releases/tag/v3.0-b4
[r3.0b3]: https://github.com/ossrs/srs/releases/tag/v3.0-b3
[r3.0b2]: https://github.com/ossrs/srs/releases/tag/v3.0-b2
[r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7
[r3.0a6]: https://github.com/ossrs/srs/releases/tag/v3.0-a6
[r3.0a5]: https://github.com/ossrs/srs/releases/tag/v3.0-a5
[r3.0a4]: https://github.com/ossrs/srs/releases/tag/v3.0-a4
[r3.0a3]: https://github.com/ossrs/srs/releases/tag/v3.0-a3
[r3.0a2]: https://github.com/ossrs/srs/releases/tag/v3.0-a2
[r3.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
[r2.0r8]: https://github.com/ossrs/srs/releases/tag/v2.0-r8
[r2.0r7]: https://github.com/ossrs/srs/releases/tag/v2.0-r7
[r2.0r6]: https://github.com/ossrs/srs/releases/tag/v2.0-r6
[r2.0r5]: https://github.com/ossrs/srs/releases/tag/v2.0-r5
[r2.0r4]: https://github.com/ossrs/srs/releases/tag/v2.0-r4
[r2.0r3]: https://github.com/ossrs/srs/releases/tag/v2.0-r3
[r2.0r2]: https://github.com/ossrs/srs/releases/tag/v2.0-r2
[r2.0r1]: https://github.com/ossrs/srs/releases/tag/v2.0-r1
[r2.0r0]: https://github.com/ossrs/srs/releases/tag/v2.0-r0
[r2.0b4]: https://github.com/ossrs/srs/releases/tag/v2.0-b4
[r2.0b3]: https://github.com/ossrs/srs/releases/tag/v2.0-b3
[r2.0b2]: https://github.com/ossrs/srs/releases/tag/v2.0-b2
[r2.0b1]: https://github.com/ossrs/srs/releases/tag/v2.0-b1
[r2.0b0]: https://github.com/ossrs/srs/releases/tag/v2.0-b0
[r2.0a3]: https://github.com/ossrs/srs/releases/tag/v2.0-a3
[r2.0a2]: https://github.com/ossrs/srs/releases/tag/v2.0-a2
[r2.0a1]: https://github.com/ossrs/srs/releases/tag/v2.0-a1
[r2.0a0]: https://github.com/ossrs/srs/releases/tag/v2.0-a0
[r1.0r4]: https://github.com/ossrs/srs/releases/tag/v1.0-r4
[r1.0r3]: https://github.com/ossrs/srs/releases/tag/v1.0-r3
[r1.0r2]: https://github.com/ossrs/srs/releases/tag/v1.0-r2
[r1.0r1]: https://github.com/ossrs/srs/releases/tag/v1.0-r1
[r1.0r0]: https://github.com/ossrs/srs/releases/tag/v1.0-r0
[r1.0b0]: https://github.com/ossrs/srs/releases/tag/v0.9.8
[r1.0a7]: https://github.com/ossrs/srs/releases/tag/v0.9.7
[r1.0a6]: https://github.com/ossrs/srs/releases/tag/v0.9.6
[r1.0a5]: https://github.com/ossrs/srs/releases/tag/v0.9.5
[r1.0a4]: https://github.com/ossrs/srs/releases/tag/v0.9.4
[r1.0a3]: https://github.com/ossrs/srs/releases/tag/v0.9.3
[r1.0a2]: https://github.com/ossrs/srs/releases/tag/v0.9.2
[r1.0a0]: https://github.com/ossrs/srs/releases/tag/v0.9.1
[r0.9]: https://github.com/ossrs/srs/releases/tag/v0.9.0
[r0.8]: https://github.com/ossrs/srs/releases/tag/v0.8.0
[r0.7]: https://github.com/ossrs/srs/releases/tag/v0.7.0
[r0.6]: https://github.com/ossrs/srs/releases/tag/v0.6.0
[r0.5]: https://github.com/ossrs/srs/releases/tag/v0.5.0
[r0.4]: https://github.com/ossrs/srs/releases/tag/v0.4.0
[r0.3]: https://github.com/ossrs/srs/releases/tag/v0.3.0
[r0.2]: https://github.com/ossrs/srs/releases/tag/v0.2.0
[r0.1]: https://github.com/ossrs/srs/releases/tag/v0.1.0


[v4_CN_Contact]: https://github.com/ossrs/srs/wiki/v4_CN_Contact
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

[LICENSE]: https://github.com/ossrs/srs/blob/4.0release/LICENSE
[LicenseMixing]: https://ossrs.net/lts/zh-cn/license

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
[release4]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release40

---

### Trunk Doc Resources (`trunk/doc/Resources.md`)

# Resources

The resources of SRS.

> Note: Please read **Wiki: Gettting Started( [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started) / [CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) )** first.

## Ports

The ports used by SRS, kernel services:

* `tcp://1935`, for RTMP live streaming server([CN][v4_CN_DeliveryRTMP],[EN][v4_EN_DeliveryRTMP]).
* `tcp://1985`, HTTP API server, for HTTP-API([CN][v4_CN_HTTPApi], [EN][v4_EN_HTTPApi]), WebRTC([CN][v4_CN_WebRTC], [EN][v4_EN_WebRTC]), etc.
* `tcp://8080`, HTTP live streaming server, HTTP-FLV([CN][v4_CN_SampleHttpFlv], [EN][v4_EN_SampleHttpFlv]), HLS([CN][v4_CN_SampleHLS], [EN][v4_EN_SampleHLS]) as such.
* `udp://8000`, WebRTC Media([CN][v4_CN_WebRTC], [EN][v4_EN_WebRTC]) server.

For optional HTTPS services, which might be provided by other web servers:

* `tcp://8088`, HTTPS live streaming server.
* `tcp://1990`, HTTPS API server.

For optional stream caster services, to push streams to SRS:

* `udp://8935`, Stream Caster: [Push MPEGTS over UDP](https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-mpeg-ts-over-udp) server.
* `tcp://554`, Stream Caster: [Push RTSP](https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-rtsp-to-srs) server.
* `tcp://8936`, Stream Caster: [Push HTTP-FLV](https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-http-flv-to-srs) server.
* `udp://10080`, Stream Caster: [Push SRT Media](https://github.com/ossrs/srs/issues/1147#issuecomment-577469119) server.

For external services to work with SRS:

* `udp://1989`, [WebRTC Signaling](https://github.com/ossrs/signaling#usage) server.

## APIs

The API used by SRS:

* `/api/v1/` The HTTP API path.
* `/rtc/v1/` The HTTP API path for RTC.
* `/sig/v1/` The [demo signaling](https://github.com/ossrs/signaling) API.

Other API used by [ossrs.net](https://ossrs.net):

* `/gif/v1` The statistic API.
* `/service/v1/` The latest available version API.
* `/ws-service/v1/` The latest available version API, by websocket.
* `/im-service/v1/` The latest available version API, by IM.
* `/code-service/v1/` The latest available version API, by Code verification.

The statistic path for [ossrs.net](https://ossrs.net):

* `/srs/xxx` The GitHub pages for [srs](https://github.com/ossrs/srs)
* `/wiki/xxx` The GitHub wiki for [srs](https://github.com/ossrs/srs/wiki)
* `/release/xxx` The pages for [ossrs.net](https://ossrs.net)
* `/console/xxx` The pages for [console](http://ossrs.net/console/)
* `/player/xxx` The pages for [players and publishers](http://ossrs.net/players/)
* `/k8s/xxx` The template and repository deploy by K8s, like [srs-k8s-template](https://github.com/ossrs/srs-k8s-template)

## Mirrors

Gitee: [https://gitee.com/ossrs/srs][gitee], the GIT usage([CN][v4_CN_Git], [EN][v4_EN_Git])

```
git clone https://gitee.com/ossrs/srs.git &&
cd srs && git remote set-url origin https://github.com/ossrs/srs.git && git pull
```

> Remark: For users in China, recomment to use mirror from CSDN or OSChina, because they are much faster.

Gitlab: [https://gitlab.com/winlinvip/srs-gitlab][gitlab], the GIT usage([CN][v4_CN_Git], [EN][v4_EN_Git])

```
git clone https://gitlab.com/winlinvip/srs-gitlab.git srs &&
cd srs && git remote set-url origin https://github.com/ossrs/srs.git && git pull
```

Github: [https://github.com/ossrs/srs][srs], the GIT usage([CN][v4_CN_Git], [EN][v4_EN_Git])

```
git clone https://github.com/ossrs/srs.git
```

| Branch | Cost | Size | CMD |
| --- | --- | --- | --- |
| 3.0release | 2m19.931s | 262MB | git clone -b 3.0release https://gitee.com/ossrs/srs.git |
| 3.0release | 0m56.515s | 95MB | git clone -b 3.0release --depth=1 https://gitee.com/ossrs/srs.git |
| develop | 2m22.430s | 234MB | git clone -b develop https://gitee.com/ossrs/srs.git |
| develop | 0m46.421s | 42MB | git clone -b develop --depth=1 https://gitee.com/ossrs/srs.git |
| min | 2m22.865s | 217MB | git clone -b min https://gitee.com/ossrs/srs.git |
| min | 0m36.472s | 11MB | git clone -b min --depth=1 https://gitee.com/ossrs/srs.git |

[authors]: https://github.com/ossrs/srs/blob/4.0release/trunk/AUTHORS.txt
[bigthanks]: https://github.com/ossrs/srs/wiki/Product#release40
[st]: https://github.com/ossrs/state-threads
[st2]: https://github.com/ossrs/state-threads/tree/srs
[state-threads]: https://github.com/ossrs/state-threads/tree/srs
[nginx]: http://nginx.org/
[srs]: https://github.com/ossrs/srs
[gitee]: https://gitee.com/ossrs/srs
[srs-bench]: https://github.com/ossrs/srs-bench
[srs-ngb]: https://github.com/ossrs/srs-console
[srs-librtmp]: https://github.com/ossrs/srs-librtmp
[gitlab]: https://gitlab.com/winlinvip/srs-gitlab
[console]: http://ossrs.net:8080/console
[docker-srs3]: https://github.com/ossrs/srs-docker/tree/v3#usage
[docker-srs4]: https://github.com/ossrs/srs-docker/tree/v4#usage
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage

[v4_CN_Git]: https://github.com/ossrs/srs/wiki/v4_CN_Git
[v4_EN_Git]: https://github.com/ossrs/srs/wiki/v4_EN_Git
[v4_CN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMP
[v4_EN_SampleRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMP
[v4_CN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRTMPCluster
[v4_EN_SampleRTMPCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRTMPCluster
[v4_CN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleOriginCluster
[v4_EN_SampleOriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleOriginCluster
[v4_CN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHLS
[v4_EN_SampleHLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHLS
[v4_CN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_CN_SampleTranscode2HLS
[v4_EN_SampleTranscode2HLS]: https://github.com/ossrs/srs/wiki/v4_EN_SampleTranscode2HLS
[v4_CN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_SampleFFMPEG
[v4_EN_SampleFFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_SampleFFMPEG
[v4_CN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_CN_SampleForward
[v4_EN_SampleForward]: https://github.com/ossrs/srs/wiki/v4_EN_SampleForward
[v4_CN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_CN_SampleRealtime
[v4_EN_SampleRealtime]: https://github.com/ossrs/srs/wiki/v4_EN_SampleRealtime
[v4_CN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC
[v4_EN_WebRTC]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC
[v4_CN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
[v4_EN_WebRTC#config-candidate]: https://github.com/ossrs/srs/wiki/v4_EN_WebRTC#config-candidate
[v4_CN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_CN_SampleARM
[v4_EN_SampleARM]: https://github.com/ossrs/srs/wiki/v4_EN_SampleARM
[v4_CN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_CN_SampleIngest
[v4_EN_SampleIngest]: https://github.com/ossrs/srs/wiki/v4_EN_SampleIngest
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_CN_OriginCluster
[v4_EN_OriginCluster]: https://github.com/ossrs/srs/wiki/v4_EN_OriginCluster
[v4_CN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_CN_REUSEPORT
[v4_EN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v4_EN_REUSEPORT
[v4_CN_Sample]: https://github.com/ossrs/srs/wiki/v4_CN_Sample
[v4_EN_Sample]: https://github.com/ossrs/srs/wiki/v4_EN_Sample
[v4_CN_Product]: https://github.com/ossrs/srs/wiki/v4_CN_Product
[v4_EN_Product]: https://github.com/ossrs/srs/wiki/v4_EN_Product
[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home
[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home

[v4_CN_Compare]: https://github.com/ossrs/srs/wiki/v4_CN_Compare
[v4_EN_Compare]: https://github.com/ossrs/srs/wiki/v4_EN_Compare
[v4_CN_Build]: https://github.com/ossrs/srs/wiki/v4_CN_Build
[v4_EN_Build]: https://github.com/ossrs/srs/wiki/v4_EN_Build
[v4_CN_Performance]: https://github.com/ossrs/srs/wiki/v4_CN_Performance
[v4_EN_Performance]: https://github.com/ossrs/srs/wiki/v4_EN_Performance
[v4_CN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryRTMP
[v4_EN_DeliveryRTMP]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryRTMP
[v4_CN_Edge]: https://github.com/ossrs/srs/wiki/v4_CN_Edge
[v4_EN_Edge]: https://github.com/ossrs/srs/wiki/v4_EN_Edge
[v4_CN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_CN_RtmpUrlVhost
[v4_EN_RtmpUrlVhost]: https://github.com/ossrs/srs/wiki/v4_EN_RtmpUrlVhost
[v4_CN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_CN_RTMPHandshake
[v4_EN_RTMPHandshake]: https://github.com/ossrs/srs/wiki/v4_EN_RTMPHandshake
[v4_CN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPServer
[v4_EN_HTTPServer]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPServer
[v4_CN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS
[v4_EN_DeliveryHLS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS
[v4_CN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHLS#hlsaudioonly
[v4_EN_DeliveryHLS2]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHLS#hlsaudioonly
[v4_CN_Reload]: https://github.com/ossrs/srs/wiki/v4_CN_Reload
[v4_EN_Reload]: https://github.com/ossrs/srs/wiki/v4_EN_Reload
[v4_CN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_CN_LowLatency#gop-cache
[v4_EN_LowLatency2]: https://github.com/ossrs/srs/wiki/v4_EN_LowLatency#gop-cache
[v4_CN_Forward]: https://github.com/ossrs/srs/wiki/v4_CN_Forward
[v4_EN_Forward]: https://github.com/ossrs/srs/wiki/v4_EN_Forward
[v4_CN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_CN_FFMPEG
[v4_EN_FFMPEG]: https://github.com/ossrs/srs/wiki/v4_EN_FFMPEG
[v4_CN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPCallback
[v4_EN_HTTPCallback]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPCallback
[v4_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_CN_SampleDemo
[v4_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v4_EN_SampleDemo
[v4_CN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLinuxArm
[v4_EN_SrsLinuxArm]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLinuxArm
[v4_CN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_CN_LinuxService
[v4_EN_LinuxService]: https://github.com/ossrs/srs/wiki/v4_EN_LinuxService
[v4_CN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_CN_RTMP-ATC
[v4_EN_RTMP-ATC]: https://github.com/ossrs/srs/wiki/v4_EN_RTMP-ATC
[v4_CN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_CN_HTTPApi
[v4_EN_HTTPApi]: https://github.com/ossrs/srs/wiki/v4_EN_HTTPApi
[v4_CN_Ingest]: https://github.com/ossrs/srs/wiki/v4_CN_Ingest
[v4_EN_Ingest]: https://github.com/ossrs/srs/wiki/v4_EN_Ingest
[v4_CN_DVR]: https://github.com/ossrs/srs/wiki/v4_CN_DVR
[v4_EN_DVR]: https://github.com/ossrs/srs/wiki/v4_EN_DVR
[v4_CN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_CN_SrsLog
[v4_EN_SrsLog]: https://github.com/ossrs/srs/wiki/v4_EN_SrsLog
[v4_CN_DRM2]: https://github.com/ossrs/srs/wiki/v4_CN_DRM#tokentraverse
[v4_EN_DRM2]: https://github.com/ossrs/srs/wiki/v4_EN_DRM#tokentraverse
[v4_CN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHTTP
[v4_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHTTP
[v4_CN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_CN_FlvVodStream
[v4_EN_FlvVodStream]: https://github.com/ossrs/srs/wiki/v4_EN_FlvVodStream
[v4_CN_Security]: https://github.com/ossrs/srs/wiki/v4_CN_Security
[v4_EN_Security]: https://github.com/ossrs/srs/wiki/v4_EN_Security
[v4_CN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHttpStream
[v4_EN_DeliveryHttpStream]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHttpStream
[v4_CN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_CN_DeliveryHDS
[v4_EN_DeliveryHDS]: https://github.com/ossrs/srs/wiki/v4_EN_DeliveryHDS
[v4_CN_Streamer]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer
[v4_EN_Streamer]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer
[v4_CN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_CN_Streamer#push-http-flv-to-srs
[v4_EN_Streamer2]: https://github.com/ossrs/srs/wiki/v4_EN_Streamer#push-http-flv-to-srs
[v4_CN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlv
[v4_EN_SampleHttpFlv]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlv
[v4_CN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_CN_SampleHttpFlvCluster
[v4_EN_SampleHttpFlvCluster]: https://github.com/ossrs/srs/wiki/v4_EN_SampleHttpFlvCluster
[v4_CN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_CN_SampleDASH
[v4_EN_SampleDASH]:https://github.com/ossrs/srs/wiki/v4_EN_SampleDASH

[bug #547]: https://github.com/ossrs/srs/issues/547
[bug #301]: https://github.com/ossrs/srs/issues/301
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #367]: https://github.com/ossrs/srs/issues/367
[bug #257]: https://github.com/ossrs/srs/issues/257
[bug #904]: https://github.com/ossrs/srs/issues/904
[bug #913]: https://github.com/ossrs/srs/issues/913
[bug #1059]: https://github.com/ossrs/srs/issues/1059
[bug #92]: https://github.com/ossrs/srs/issues/92
[bug #464]: https://github.com/ossrs/srs/issues/464
[bug #460]: https://github.com/ossrs/srs/issues/460
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #307]: https://github.com/ossrs/srs/issues/307
[bug #2324]: https://github.com/ossrs/srs/issues/2324
[bug #1657]: https://github.com/ossrs/srs/issues/1657
[bug #1500]: https://github.com/ossrs/srs/issues/1500
[bug #738]: https://github.com/ossrs/srs/issues/738
[bug #299]: https://github.com/ossrs/srs/issues/299
[bug #250]: https://github.com/ossrs/srs/issues/250
[bug #459]: https://github.com/ossrs/srs/issues/459
[bug #470]: https://github.com/ossrs/srs/issues/470
[bug #319]: https://github.com/ossrs/srs/issues/319
[bug #1147]: https://github.com/ossrs/srs/issues/1147
[bug #2304]: https://github.com/ossrs/srs/issues/2304
[bug #1535]: https://github.com/ossrs/srs/issues/1535
[bug #1342]: https://github.com/ossrs/srs/issues/1342
[bug #1193]: https://github.com/ossrs/srs/issues/1193
[bug #2093]: https://github.com/ossrs/srs/issues/2093
[bug #465]: https://github.com/ossrs/srs/issues/465
[bug #2091]: https://github.com/ossrs/srs/issues/2091
[bug #2188]: https://github.com/ossrs/srs/issues/2188
[bug #413]: https://github.com/ossrs/srs/issues/413
[bug #1111]: https://github.com/ossrs/srs/issues/1111
[bug #463]: https://github.com/ossrs/srs/issues/463
[bug #775]: https://github.com/ossrs/srs/issues/775
[bug #257-c0]: https://github.com/ossrs/srs/issues/257#issuecomment-66864413

[r3.0r5]: https://github.com/ossrs/srs/releases/tag/v3.0-r5
[r3.0r4]: https://github.com/ossrs/srs/releases/tag/v3.0-r4
[r3.0r3]: https://github.com/ossrs/srs/releases/tag/v3.0-r3
[r3.0r2]: https://github.com/ossrs/srs/releases/tag/v3.0-r2
[r3.0r1]: https://github.com/ossrs/srs/releases/tag/v3.0-r1
[r3.0r0]: https://github.com/ossrs/srs/releases/tag/v3.0-r0
[r3.0b4]: https://github.com/ossrs/srs/releases/tag/v3.0-b4
[r3.0b3]: https://github.com/ossrs/srs/releases/tag/v3.0-b3
[r3.0b2]: https://github.com/ossrs/srs/releases/tag/v3.0-b2
[r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7
[r3.0a6]: https://github.com/ossrs/srs/releases/tag/v3.0-a6
[r3.0a5]: https://github.com/ossrs/srs/releases/tag/v3.0-a5
[r3.0a4]: https://github.com/ossrs/srs/releases/tag/v3.0-a4
[r3.0a3]: https://github.com/ossrs/srs/releases/tag/v3.0-a3
[r3.0a2]: https://github.com/ossrs/srs/releases/tag/v3.0-a2
[r3.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
[r2.0r8]: https://github.com/ossrs/srs/releases/tag/v2.0-r8
[r2.0r7]: https://github.com/ossrs/srs/releases/tag/v2.0-r7
[r2.0r6]: https://github.com/ossrs/srs/releases/tag/v2.0-r6
[r2.0r5]: https://github.com/ossrs/srs/releases/tag/v2.0-r5
[r2.0r4]: https://github.com/ossrs/srs/releases/tag/v2.0-r4
[r2.0r3]: https://github.com/ossrs/srs/releases/tag/v2.0-r3
[r2.0r2]: https://github.com/ossrs/srs/releases/tag/v2.0-r2
[r2.0r1]: https://github.com/ossrs/srs/releases/tag/v2.0-r1
[r2.0r0]: https://github.com/ossrs/srs/releases/tag/v2.0-r0
[r2.0b4]: https://github.com/ossrs/srs/releases/tag/v2.0-b4
[r2.0b3]: https://github.com/ossrs/srs/releases/tag/v2.0-b3
[r2.0b2]: https://github.com/ossrs/srs/releases/tag/v2.0-b2
[r2.0b1]: https://github.com/ossrs/srs/releases/tag/v2.0-b1
[r2.0b0]: https://github.com/ossrs/srs/releases/tag/v2.0-b0
[r2.0a3]: https://github.com/ossrs/srs/releases/tag/v2.0-a3
[r2.0a2]: https://github.com/ossrs/srs/releases/tag/v2.0-a2
[r2.0a1]: https://github.com/ossrs/srs/releases/tag/v2.0-a1
[r2.0a0]: https://github.com/ossrs/srs/releases/tag/v2.0-a0
[r1.0r4]: https://github.com/ossrs/srs/releases/tag/v1.0-r4
[r1.0r3]: https://github.com/ossrs/srs/releases/tag/v1.0-r3
[r1.0r2]: https://github.com/ossrs/srs/releases/tag/v1.0-r2
[r1.0r1]: https://github.com/ossrs/srs/releases/tag/v1.0-r1
[r1.0r0]: https://github.com/ossrs/srs/releases/tag/v1.0-r0
[r1.0b0]: https://github.com/ossrs/srs/releases/tag/v0.9.8
[r1.0a7]: https://github.com/ossrs/srs/releases/tag/v0.9.7
[r1.0a6]: https://github.com/ossrs/srs/releases/tag/v0.9.6
[r1.0a5]: https://github.com/ossrs/srs/releases/tag/v0.9.5
[r1.0a4]: https://github.com/ossrs/srs/releases/tag/v0.9.4
[r1.0a3]: https://github.com/ossrs/srs/releases/tag/v0.9.3
[r1.0a2]: https://github.com/ossrs/srs/releases/tag/v0.9.2
[r1.0a0]: https://github.com/ossrs/srs/releases/tag/v0.9.1
[r0.9]: https://github.com/ossrs/srs/releases/tag/v0.9.0
[r0.8]: https://github.com/ossrs/srs/releases/tag/v0.8.0
[r0.7]: https://github.com/ossrs/srs/releases/tag/v0.7.0
[r0.6]: https://github.com/ossrs/srs/releases/tag/v0.6.0
[r0.5]: https://github.com/ossrs/srs/releases/tag/v0.5.0
[r0.4]: https://github.com/ossrs/srs/releases/tag/v0.4.0
[r0.3]: https://github.com/ossrs/srs/releases/tag/v0.3.0
[r0.2]: https://github.com/ossrs/srs/releases/tag/v0.2.0
[r0.1]: https://github.com/ossrs/srs/releases/tag/v0.1.0


[v4_CN_Contact]: https://github.com/ossrs/srs/wiki/v4_CN_Contact
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

[LICENSE]: https://github.com/ossrs/srs/blob/4.0release/LICENSE
[LicenseMixing]: https://ossrs.net/lts/zh-cn/license

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
[release4]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release40

---

### Trunk 3rdparty Gperftools 2 Fit Docs T Test1.Times (`trunk/3rdparty/gperftools-2-fit/docs/t-test1.times.txt`)

time.1.ptmalloc.64:0.56 user 0.02 system 0.57 elapsed 100% CPU
time.1.tcmalloc.64:0.38 user 0.02 system 0.40 elapsed 98% CPU
time.1.ptmalloc.128:0.61 user 0.01 system 0.61 elapsed 101% CPU
time.1.tcmalloc.128:0.35 user 0.00 system 0.35 elapsed 99% CPU
time.1.ptmalloc.256:0.59 user 0.01 system 0.60 elapsed 100% CPU
time.1.tcmalloc.256:0.27 user 0.02 system 0.28 elapsed 102% CPU
time.1.ptmalloc.512:0.57 user 0.00 system 0.57 elapsed 100% CPU
time.1.tcmalloc.512:0.25 user 0.01 system 0.25 elapsed 101% CPU
time.1.ptmalloc.1024:0.52 user 0.00 system 0.52 elapsed 99% CPU
time.1.tcmalloc.1024:0.22 user 0.02 system 0.24 elapsed 97% CPU
time.1.ptmalloc.2048:0.47 user 0.00 system 0.47 elapsed 99% CPU
time.1.tcmalloc.2048:0.22 user 0.02 system 0.25 elapsed 95% CPU
time.1.ptmalloc.4096:0.48 user 0.01 system 0.48 elapsed 100% CPU
time.1.tcmalloc.4096:0.25 user 0.01 system 0.25 elapsed 100% CPU
time.1.ptmalloc.8192:0.49 user 0.02 system 0.49 elapsed 102% CPU
time.1.tcmalloc.8192:0.27 user 0.02 system 0.28 elapsed 101% CPU
time.1.ptmalloc.16384:0.51 user 0.04 system 0.55 elapsed 99% CPU
time.1.tcmalloc.16384:0.35 user 0.02 system 0.37 elapsed 100% CPU
time.1.ptmalloc.32768:0.53 user 0.14 system 0.66 elapsed 100% CPU
time.1.tcmalloc.32768:0.67 user 0.02 system 0.69 elapsed 99% CPU
time.1.ptmalloc.65536:0.68 user 0.31 system 0.98 elapsed 100% CPU
time.1.tcmalloc.65536:0.71 user 0.01 system 0.72 elapsed 99% CPU
time.1.ptmalloc.131072:0.90 user 0.72 system 1.62 elapsed 99% CPU
time.1.tcmalloc.131072:0.94 user 0.03 system 0.97 elapsed 99% CPU
time.2.ptmalloc.64:1.05 user 0.00 system 0.53 elapsed 196% CPU
time.2.tcmalloc.64:0.66 user 0.03 system 0.37 elapsed 185% CPU
time.2.ptmalloc.128:1.77 user 0.01 system 0.89 elapsed 198% CPU
time.2.tcmalloc.128:0.53 user 0.01 system 0.29 elapsed 184% CPU
time.2.ptmalloc.256:1.14 user 0.01 system 0.62 elapsed 182% CPU
time.2.tcmalloc.256:0.45 user 0.02 system 0.26 elapsed 180% CPU
time.2.ptmalloc.512:1.26 user 0.40 system 1.79 elapsed 92% CPU
time.2.tcmalloc.512:0.43 user 0.02 system 0.27 elapsed 166% CPU
time.2.ptmalloc.1024:0.98 user 0.03 system 0.56 elapsed 179% CPU
time.2.tcmalloc.1024:0.44 user 0.02 system 0.34 elapsed 134% CPU
time.2.ptmalloc.2048:0.87 user 0.02 system 0.44 elapsed 199% CPU
time.2.tcmalloc.2048:0.49 user 0.02 system 0.34 elapsed 148% CPU
time.2.ptmalloc.4096:0.92 user 0.03 system 0.48 elapsed 196% CPU
time.2.tcmalloc.4096:0.50 user 0.02 system 0.49 elapsed 105% CPU
time.2.ptmalloc.8192:1.05 user 0.04 system 0.55 elapsed 196% CPU
time.2.tcmalloc.8192:0.59 user 0.01 system 0.51 elapsed 116% CPU
time.2.ptmalloc.16384:1.30 user 0.14 system 0.72 elapsed 198% CPU
time.2.tcmalloc.16384:0.63 user 0.03 system 0.68 elapsed 96% CPU
time.2.ptmalloc.32768:1.33 user 0.56 system 1.00 elapsed 189% CPU
time.2.tcmalloc.32768:1.16 user 0.01 system 1.17 elapsed 99% CPU
time.2.ptmalloc.65536:1.86 user 1.79 system 2.01 elapsed 181% CPU
time.2.tcmalloc.65536:1.35 user 0.01 system 1.35 elapsed 100% CPU
time.2.ptmalloc.131072:2.61 user 5.19 system 4.81 elapsed 162% CPU
time.2.tcmalloc.131072:1.86 user 0.04 system 1.90 elapsed 100% CPU
time.3.ptmalloc.64:1.79 user 0.03 system 0.67 elapsed 268% CPU
time.3.tcmalloc.64:1.58 user 0.04 system 0.62 elapsed 260% CPU
time.3.ptmalloc.128:2.77 user 1.34 system 3.07 elapsed 133% CPU
time.3.tcmalloc.128:1.19 user 0.01 system 0.50 elapsed 236% CPU
time.3.ptmalloc.256:2.14 user 0.02 system 0.85 elapsed 252% CPU
time.3.tcmalloc.256:0.96 user 0.01 system 0.41 elapsed 236% CPU
time.3.ptmalloc.512:3.37 user 1.31 system 3.33 elapsed 140% CPU
time.3.tcmalloc.512:0.93 user 0.04 system 0.39 elapsed 243% CPU
time.3.ptmalloc.1024:1.66 user 0.01 system 0.64 elapsed 260% CPU
time.3.tcmalloc.1024:0.81 user 0.02 system 0.44 elapsed 187% CPU
time.3.ptmalloc.2048:2.07 user 0.01 system 0.82 elapsed 252% CPU
time.3.tcmalloc.2048:1.10 user 0.04 system 0.59 elapsed 191% CPU
time.3.ptmalloc.4096:2.01 user 0.03 system 0.79 elapsed 258% CPU
time.3.tcmalloc.4096:0.87 user 0.03 system 0.65 elapsed 137% CPU
time.3.ptmalloc.8192:2.22 user 0.11 system 0.83 elapsed 280% CPU
time.3.tcmalloc.8192:0.96 user 0.06 system 0.75 elapsed 135% CPU
time.3.ptmalloc.16384:2.56 user 0.47 system 1.02 elapsed 295% CPU
time.3.tcmalloc.16384:0.99 user 0.04 system 1.03 elapsed 99% CPU
time.3.ptmalloc.32768:3.29 user 1.75 system 1.96 elapsed 256% CPU
time.3.tcmalloc.32768:1.67 user 0.02 system 1.69 elapsed 99% CPU
time.3.ptmalloc.65536:4.04 user 6.62 system 4.92 elapsed 216% CPU
time.3.tcmalloc.65536:1.91 user 0.02 system 1.98 elapsed 97% CPU
time.3.ptmalloc.131072:5.55 user 17.86 system 12.44 elapsed 188% CPU
time.3.tcmalloc.131072:2.78 user 0.02 system 2.82 elapsed 99% CPU
time.4.ptmalloc.64:3.42 user 1.36 system 3.20 elapsed 149% CPU
time.4.tcmalloc.64:2.42 user 0.02 system 0.71 elapsed 341% CPU
time.4.ptmalloc.128:3.98 user 1.79 system 3.89 elapsed 148% CPU
time.4.tcmalloc.128:1.87 user 0.02 system 0.58 elapsed 325% CPU
time.4.ptmalloc.256:4.06 user 2.14 system 4.12 elapsed 150% CPU
time.4.tcmalloc.256:1.69 user 0.02 system 0.51 elapsed 331% CPU
time.4.ptmalloc.512:4.48 user 2.15 system 4.39 elapsed 150% CPU
time.4.tcmalloc.512:1.62 user 0.03 system 0.52 elapsed 314% CPU
time.4.ptmalloc.1024:3.18 user 0.03 system 0.84 elapsed 381% CPU
time.4.tcmalloc.1024:1.53 user 0.02 system 0.56 elapsed 274% CPU
time.4.ptmalloc.2048:3.24 user 0.02 system 0.84 elapsed 384% CPU
time.4.tcmalloc.2048:1.44 user 0.04 system 0.66 elapsed 221% CPU
time.4.ptmalloc.4096:3.50 user 0.04 system 0.91 elapsed 389% CPU
time.4.tcmalloc.4096:1.31 user 0.01 system 0.89 elapsed 148% CPU
time.4.ptmalloc.8192:6.77 user 3.85 system 4.14 elapsed 256% CPU
time.4.tcmalloc.8192:1.20 user 0.05 system 0.97 elapsed 127% CPU
time.4.ptmalloc.16384:7.08 user 5.06 system 4.63 elapsed 262% CPU
time.4.tcmalloc.16384:1.27 user 0.03 system 1.25 elapsed 103% CPU
time.4.ptmalloc.32768:5.57 user 4.22 system 3.31 elapsed 295% CPU
time.4.tcmalloc.32768:2.17 user 0.03 system 2.25 elapsed 97% CPU
time.4.ptmalloc.65536:6.11 user 15.05 system 9.19 elapsed 230% CPU
time.4.tcmalloc.65536:2.51 user 0.02 system 2.57 elapsed 98% CPU
time.4.ptmalloc.131072:7.58 user 33.15 system 21.28 elapsed 191% CPU
time.4.tcmalloc.131072:3.57 user 0.07 system 3.66 elapsed 99% CPU
time.5.ptmalloc.64:4.44 user 2.08 system 4.37 elapsed 148% CPU
time.5.tcmalloc.64:2.87 user 0.02 system 0.79 elapsed 361% CPU
time.5.ptmalloc.128:4.77 user 2.77 system 5.14 elapsed 146% CPU
time.5.tcmalloc.128:2.65 user 0.03 system 0.72 elapsed 367% CPU
time.5.ptmalloc.256:5.82 user 2.88 system 5.49 elapsed 158% CPU
time.5.tcmalloc.256:2.33 user 0.01 system 0.66 elapsed 352% CPU
time.5.ptmalloc.512:6.27 user 3.11 system 5.34 elapsed 175% CPU
time.5.tcmalloc.512:2.14 user 0.03 system 0.70 elapsed 307% CPU
time.5.ptmalloc.1024:6.82 user 3.18 system 5.23 elapsed 191% CPU
time.5.tcmalloc.1024:2.20 user 0.02 system 0.70 elapsed 313% CPU
time.5.ptmalloc.2048:6.57 user 3.46 system 5.22 elapsed 192% CPU
time.5.tcmalloc.2048:2.15 user 0.03 system 0.82 elapsed 264% CPU
time.5.ptmalloc.4096:8.75 user 5.09 system 5.26 elapsed 263% CPU
time.5.tcmalloc.4096:1.68 user 0.03 system 1.08 elapsed 158% CPU
time.5.ptmalloc.8192:4.48 user 0.61 system 1.51 elapsed 335% CPU
time.5.tcmalloc.8192:1.47 user 0.07 system 1.18 elapsed 129% CPU
time.5.ptmalloc.16384:5.71 user 1.98 system 2.14 elapsed 358% CPU
time.5.tcmalloc.16384:1.58 user 0.03 system 1.52 elapsed 105% CPU
time.5.ptmalloc.32768:7.19 user 7.81 system 5.53 elapsed 270% CPU
time.5.tcmalloc.32768:2.63 user 0.05 system 2.72 elapsed 98% CPU
time.5.ptmalloc.65536:8.45 user 23.51 system 14.30 elapsed 223% CPU
time.5.tcmalloc.65536:3.12 user 0.05 system 3.21 elapsed 98% CPU
time.5.ptmalloc.131072:10.22 user 43.63 system 27.84 elapsed 193% CPU
time.5.tcmalloc.131072:4.42 user 0.07 system 4.51 elapsed 99% CPU
time.6.ptmalloc.64:5.57 user 2.56 system 5.08 elapsed 159% CPU
time.6.tcmalloc.64:3.20 user 0.01 system 0.89 elapsed 360% CPU
time.6.ptmalloc.128:5.98 user 3.52 system 5.71 elapsed 166% CPU
time.6.tcmalloc.128:2.76 user 0.02 system 0.78 elapsed 355% CPU
time.6.ptmalloc.256:4.61 user 0.02 system 1.19 elapsed 389% CPU
time.6.tcmalloc.256:2.65 user 0.02 system 0.74 elapsed 356% CPU
time.6.ptmalloc.512:8.28 user 3.88 system 6.61 elapsed 183% CPU
time.6.tcmalloc.512:2.60 user 0.02 system 0.72 elapsed 362% CPU
time.6.ptmalloc.1024:4.75 user 0.00 system 1.22 elapsed 387% CPU
time.6.tcmalloc.1024:2.56 user 0.02 system 0.79 elapsed 325% CPU
time.6.ptmalloc.2048:8.90 user 4.59 system 6.15 elapsed 219% CPU
time.6.tcmalloc.2048:2.37 user 0.06 system 0.96 elapsed 250% CPU
time.6.ptmalloc.4096:11.41 user 7.02 system 6.31 elapsed 291% CPU
time.6.tcmalloc.4096:1.82 user 0.03 system 1.19 elapsed 154% CPU
time.6.ptmalloc.8192:11.64 user 8.25 system 5.97 elapsed 332% CPU
time.6.tcmalloc.8192:1.83 user 0.07 system 1.38 elapsed 136% CPU
time.6.ptmalloc.16384:7.44 user 2.98 system 3.01 elapsed 345% CPU
time.6.tcmalloc.16384:1.83 user 0.08 system 1.80 elapsed 105% CPU
time.6.ptmalloc.32768:8.69 user 12.35 system 8.04 elapsed 261% CPU
time.6.tcmalloc.32768:3.14 user 0.06 system 3.24 elapsed 98% CPU
time.6.ptmalloc.65536:10.52 user 35.43 system 20.75 elapsed 221% CPU
time.6.tcmalloc.65536:3.62 user 0.03 system 3.72 elapsed 98% CPU
time.6.ptmalloc.131072:11.74 user 59.00 system 36.93 elapsed 191% CPU
time.6.tcmalloc.131072:5.33 user 0.04 system 5.42 elapsed 98% CPU
time.7.ptmalloc.64:6.60 user 3.45 system 6.01 elapsed 167% CPU
time.7.tcmalloc.64:3.50 user 0.04 system 0.94 elapsed 376% CPU
time.7.ptmalloc.128:7.09 user 4.25 system 6.69 elapsed 169% CPU
time.7.tcmalloc.128:3.13 user 0.03 system 0.84 elapsed 374% CPU
time.7.ptmalloc.256:9.28 user 4.85 system 7.20 elapsed 196% CPU
time.7.tcmalloc.256:3.06 user 0.02 system 0.82 elapsed 375% CPU
time.7.ptmalloc.512:9.13 user 4.78 system 6.79 elapsed 204% CPU
time.7.tcmalloc.512:2.99 user 0.03 system 0.83 elapsed 359% CPU
time.7.ptmalloc.1024:10.85 user 6.41 system 7.52 elapsed 229% CPU
time.7.tcmalloc.1024:3.05 user 0.04 system 0.89 elapsed 345% CPU
time.7.ptmalloc.2048:5.65 user 0.08 system 1.47 elapsed 388% CPU
time.7.tcmalloc.2048:3.01 user 0.01 system 0.98 elapsed 306% CPU
time.7.ptmalloc.4096:6.09 user 0.08 system 1.58 elapsed 389% CPU
time.7.tcmalloc.4096:2.25 user 0.03 system 1.32 elapsed 171% CPU
time.7.ptmalloc.8192:6.73 user 0.85 system 1.99 elapsed 379% CPU
time.7.tcmalloc.8192:2.22 user 0.08 system 1.61 elapsed 142% CPU
time.7.ptmalloc.16384:8.87 user 4.66 system 4.04 elapsed 334% CPU
time.7.tcmalloc.16384:2.07 user 0.07 system 2.07 elapsed 103% CPU
time.7.ptmalloc.32768:10.61 user 17.85 system 11.22 elapsed 253% CPU
time.7.tcmalloc.32768:3.68 user 0.06 system 3.79 elapsed 98% CPU
time.7.ptmalloc.65536:13.05 user 45.97 system 27.28 elapsed 216% CPU
time.7.tcmalloc.65536:4.16 user 0.07 system 4.31 elapsed 98% CPU
time.7.ptmalloc.131072:13.22 user 62.67 system 41.33 elapsed 183% CPU
time.7.tcmalloc.131072:6.10 user 0.06 system 6.25 elapsed 98% CPU
time.8.ptmalloc.64:7.31 user 3.92 system 6.39 elapsed 175% CPU
time.8.tcmalloc.64:4.00 user 0.01 system 1.04 elapsed 383% CPU
time.8.ptmalloc.128:9.40 user 5.41 system 7.67 elapsed 192% CPU
time.8.tcmalloc.128:3.61 user 0.02 system 0.94 elapsed 386% CPU
time.8.ptmalloc.256:10.61 user 6.35 system 7.96 elapsed 212% CPU
time.8.tcmalloc.256:3.30 user 0.02 system 0.99 elapsed 335% CPU
time.8.ptmalloc.512:12.42 user 7.10 system 8.79 elapsed 221% CPU
time.8.tcmalloc.512:3.35 user 0.04 system 0.94 elapsed 358% CPU
time.8.ptmalloc.1024:13.63 user 8.54 system 8.95 elapsed 247% CPU
time.8.tcmalloc.1024:3.44 user 0.02 system 0.96 elapsed 359% CPU
time.8.ptmalloc.2048:6.45 user 0.03 system 1.67 elapsed 386% CPU
time.8.tcmalloc.2048:3.55 user 0.05 system 1.09 elapsed 328% CPU
time.8.ptmalloc.4096:6.83 user 0.26 system 1.80 elapsed 393% CPU
time.8.tcmalloc.4096:2.78 user 0.06 system 1.53 elapsed 185% CPU
time.8.ptmalloc.8192:7.59 user 1.29 system 2.36 elapsed 376% CPU
time.8.tcmalloc.8192:2.57 user 0.07 system 1.84 elapsed 142% CPU
time.8.ptmalloc.16384:10.15 user 6.20 system 5.20 elapsed 314% CPU
time.8.tcmalloc.16384:2.40 user 0.05 system 2.42 elapsed 101% CPU
time.8.ptmalloc.32768:11.82 user 24.48 system 14.60 elapsed 248% CPU
time.8.tcmalloc.32768:4.37 user 0.05 system 4.47 elapsed 98% CPU
time.8.ptmalloc.65536:15.41 user 58.94 system 34.42 elapsed 215% CPU
time.8.tcmalloc.65536:4.90 user 0.04 system 4.96 elapsed 99% CPU
time.8.ptmalloc.131072:16.07 user 82.93 system 52.51 elapsed 188% CPU
time.8.tcmalloc.131072:7.13 user 0.04 system 7.19 elapsed 99% CPU
time.9.ptmalloc.64:8.44 user 4.59 system 6.92 elapsed 188% CPU
time.9.tcmalloc.64:4.00 user 0.02 system 1.05 elapsed 382% CPU
time.9.ptmalloc.128:10.92 user 6.14 system 8.31 elapsed 205% CPU
time.9.tcmalloc.128:3.88 user 0.02 system 1.01 elapsed 382% CPU
time.9.ptmalloc.256:13.01 user 7.75 system 9.12 elapsed 227% CPU
time.9.tcmalloc.256:3.89 user 0.01 system 1.00 elapsed 386% CPU
time.9.ptmalloc.512:14.96 user 8.89 system 9.73 elapsed 244% CPU
time.9.tcmalloc.512:3.80 user 0.03 system 1.01 elapsed 377% CPU
time.9.ptmalloc.1024:15.42 user 10.20 system 9.80 elapsed 261% CPU
time.9.tcmalloc.1024:3.86 user 0.03 system 1.19 elapsed 325% CPU
time.9.ptmalloc.2048:7.24 user 0.02 system 1.87 elapsed 388% CPU
time.9.tcmalloc.2048:3.98 user 0.05 system 1.26 elapsed 319% CPU
time.9.ptmalloc.4096:7.96 user 0.18 system 2.06 elapsed 394% CPU
time.9.tcmalloc.4096:3.27 user 0.04 system 1.69 elapsed 195% CPU
time.9.ptmalloc.8192:9.00 user 1.63 system 2.79 elapsed 380% CPU
time.9.tcmalloc.8192:3.00 user 0.06 system 2.05 elapsed 148% CPU
time.9.ptmalloc.16384:12.07 user 8.13 system 6.55 elapsed 308% CPU
time.9.tcmalloc.16384:2.85 user 0.05 system 2.75 elapsed 105% CPU
time.9.ptmalloc.32768:13.99 user 29.65 system 18.02 elapsed 242% CPU
time.9.tcmalloc.32768:4.98 user 0.06 system 5.13 elapsed 98% CPU
time.9.ptmalloc.65536:16.89 user 70.42 system 42.11 elapsed 207% CPU
time.9.tcmalloc.65536:5.55 user 0.04 system 5.65 elapsed 98% CPU
time.9.ptmalloc.131072:18.53 user 94.11 system 61.17 elapsed 184% CPU
time.9.tcmalloc.131072:8.06 user 0.04 system 8.16 elapsed 99% CPU
time.10.ptmalloc.64:9.81 user 5.70 system 7.42 elapsed 208% CPU
time.10.tcmalloc.64:4.43 user 0.03 system 1.20 elapsed 370% CPU
time.10.ptmalloc.128:12.69 user 7.81 system 9.02 elapsed 227% CPU
time.10.tcmalloc.128:4.27 user 0.02 system 1.13 elapsed 378% CPU
time.10.ptmalloc.256:15.04 user 9.53 system 9.92 elapsed 247% CPU
time.10.tcmalloc.256:4.23 user 0.02 system 1.09 elapsed 388% CPU
time.10.ptmalloc.512:17.30 user 10.46 system 10.61 elapsed 261% CPU
time.10.tcmalloc.512:4.14 user 0.05 system 1.10 elapsed 379% CPU
time.10.ptmalloc.1024:16.96 user 9.38 system 9.30 elapsed 283% CPU
time.10.tcmalloc.1024:4.27 user 0.06 system 1.18 elapsed 366% CPU
time.10.ptmalloc.2048:8.07 user 0.03 system 2.06 elapsed 393% CPU
time.10.tcmalloc.2048:4.49 user 0.07 system 1.33 elapsed 342% CPU
time.10.ptmalloc.4096:8.66 user 0.25 system 2.25 elapsed 394% CPU
time.10.tcmalloc.4096:3.61 user 0.05 system 1.78 elapsed 205% CPU
time.10.ptmalloc.8192:21.52 user 17.43 system 10.41 elapsed 374% CPU
time.10.tcmalloc.8192:3.59 user 0.10 system 2.33 elapsed 158% CPU
time.10.ptmalloc.16384:20.55 user 24.85 system 12.55 elapsed 361% CPU
time.10.tcmalloc.16384:3.29 user 0.04 system 3.22 elapsed 103% CPU
time.10.ptmalloc.32768:15.23 user 38.13 system 22.49 elapsed 237% CPU
time.10.tcmalloc.32768:5.62 user 0.05 system 5.72 elapsed 99% CPU
time.10.ptmalloc.65536:19.80 user 85.42 system 49.98 elapsed 210% CPU
time.10.tcmalloc.65536:6.23 user 0.09 system 6.36 elapsed 99% CPU
time.10.ptmalloc.131072:20.91 user 106.97 system 69.08 elapsed 185% CPU
time.10.tcmalloc.131072:8.94 user 0.09 system 9.09 elapsed 99% CPU
time.11.ptmalloc.64:10.82 user 6.34 system 7.92 elapsed 216% CPU
time.11.tcmalloc.64:4.80 user 0.03 system 1.24 elapsed 387% CPU
time.11.ptmalloc.128:14.58 user 8.61 system 9.81 elapsed 236% CPU
time.11.tcmalloc.128:4.65 user 0.03 system 1.21 elapsed 384% CPU
time.11.ptmalloc.256:17.38 user 10.98 system 10.75 elapsed 263% CPU
time.11.tcmalloc.256:4.51 user 0.03 system 1.18 elapsed 384% CPU
time.11.ptmalloc.512:19.18 user 11.71 system 10.95 elapsed 282% CPU
time.11.tcmalloc.512:4.57 user 0.02 system 1.19 elapsed 384% CPU
time.11.ptmalloc.1024:19.94 user 12.41 system 10.48 elapsed 308% CPU
time.11.tcmalloc.1024:4.71 user 0.05 system 1.29 elapsed 367% CPU
time.11.ptmalloc.2048:8.70 user 0.04 system 2.35 elapsed 371% CPU
time.11.tcmalloc.2048:4.97 user 0.07 system 1.43 elapsed 350% CPU
time.11.ptmalloc.4096:22.47 user 18.43 system 10.82 elapsed 377% CPU
time.11.tcmalloc.4096:4.22 user 0.03 system 1.91 elapsed 221% CPU
time.11.ptmalloc.8192:11.61 user 2.38 system 3.73 elapsed 374% CPU
time.11.tcmalloc.8192:3.74 user 0.09 system 2.46 elapsed 155% CPU
time.11.ptmalloc.16384:14.13 user 13.38 system 9.60 elapsed 286% CPU
time.11.tcmalloc.16384:3.61 user 0.03 system 3.63 elapsed 100% CPU
time.11.ptmalloc.32768:17.92 user 43.84 system 26.74 elapsed 230% CPU
time.11.tcmalloc.32768:6.31 user 0.03 system 6.45 elapsed 98% CPU
time.11.ptmalloc.65536:22.40 user 96.38 system 58.30 elapsed 203% CPU
time.11.tcmalloc.65536:6.92 user 0.12 system 6.98 elapsed 100% CPU
time.11.ptmalloc.131072:21.03 user 108.04 system 72.78 elapsed 177% CPU
time.11.tcmalloc.131072:9.79 user 0.08 system 9.94 elapsed 99% CPU
time.12.ptmalloc.64:12.23 user 7.16 system 8.38 elapsed 231% CPU
time.12.tcmalloc.64:5.21 user 0.05 system 1.41 elapsed 371% CPU
time.12.ptmalloc.128:16.97 user 10.19 system 10.47 elapsed 259% CPU
time.12.tcmalloc.128:5.10 user 0.02 system 1.31 elapsed 390% CPU
time.12.ptmalloc.256:19.99 user 12.10 system 11.57 elapsed 277% CPU
time.12.tcmalloc.256:5.01 user 0.03 system 1.29 elapsed 390% CPU
time.12.ptmalloc.512:21.85 user 12.66 system 11.46 elapsed 300% CPU
time.12.tcmalloc.512:5.05 user 0.00 system 1.32 elapsed 379% CPU
time.12.ptmalloc.1024:9.40 user 0.04 system 2.40 elapsed 393% CPU
time.12.tcmalloc.1024:5.14 user 0.02 system 1.39 elapsed 369% CPU
time.12.ptmalloc.2048:9.72 user 0.04 system 2.49 elapsed 391% CPU
time.12.tcmalloc.2048:5.74 user 0.05 system 1.62 elapsed 355% CPU
time.12.ptmalloc.4096:10.64 user 0.20 system 2.75 elapsed 393% CPU
time.12.tcmalloc.4096:4.45 user 0.03 system 2.04 elapsed 218% CPU
time.12.ptmalloc.8192:12.66 user 3.30 system 4.30 elapsed 371% CPU
time.12.tcmalloc.8192:4.21 user 0.13 system 2.65 elapsed 163% CPU
time.12.ptmalloc.16384:15.73 user 15.68 system 11.14 elapsed 281% CPU
time.12.tcmalloc.16384:4.17 user 0.06 system 4.10 elapsed 102% CPU
time.12.ptmalloc.32768:19.45 user 56.00 system 32.74 elapsed 230% CPU
time.12.tcmalloc.32768:6.96 user 0.08 system 7.14 elapsed 98% CPU
time.12.ptmalloc.65536:23.33 user 110.45 system 65.06 elapsed 205% CPU
time.12.tcmalloc.65536:7.77 user 0.15 system 7.72 elapsed 102% CPU
time.12.ptmalloc.131072:24.03 user 124.74 system 82.94 elapsed 179% CPU
time.12.tcmalloc.131072:10.81 user 0.06 system 10.94 elapsed 99% CPU
time.13.ptmalloc.64:14.08 user 7.60 system 8.85 elapsed 244% CPU
time.13.tcmalloc.64:5.51 user 0.01 system 1.47 elapsed 375% CPU
time.13.ptmalloc.128:18.20 user 10.98 system 10.99 elapsed 265% CPU
time.13.tcmalloc.128:5.34 user 0.01 system 1.39 elapsed 382% CPU
time.13.ptmalloc.256:21.48 user 13.94 system 12.25 elapsed 289% CPU
time.13.tcmalloc.256:5.33 user 0.01 system 1.39 elapsed 381% CPU
time.13.ptmalloc.512:24.22 user 14.84 system 12.97 elapsed 301% CPU
time.13.tcmalloc.512:5.49 user 0.02 system 1.41 elapsed 389% CPU
time.13.ptmalloc.1024:25.26 user 17.03 system 12.85 elapsed 328% CPU
time.13.tcmalloc.1024:5.65 user 0.04 system 1.50 elapsed 378% CPU
time.13.ptmalloc.2048:10.41 user 0.03 system 2.69 elapsed 387% CPU
time.13.tcmalloc.2048:5.93 user 0.10 system 1.77 elapsed 339% CPU
time.13.ptmalloc.4096:11.37 user 0.52 system 3.04 elapsed 391% CPU
time.13.tcmalloc.4096:5.08 user 0.11 system 2.22 elapsed 233% CPU
time.13.ptmalloc.8192:21.76 user 18.54 system 10.58 elapsed 380% CPU
time.13.tcmalloc.8192:5.04 user 0.16 system 2.93 elapsed 177% CPU
time.13.ptmalloc.16384:26.35 user 34.47 system 17.01 elapsed 357% CPU
time.13.tcmalloc.16384:4.66 user 0.04 system 4.66 elapsed 100% CPU
time.13.ptmalloc.32768:21.41 user 63.59 system 38.14 elapsed 222% CPU
time.13.tcmalloc.32768:7.71 user 0.03 system 7.83 elapsed 98% CPU
time.13.ptmalloc.65536:24.99 user 120.80 system 71.59 elapsed 203% CPU
time.13.tcmalloc.65536:8.87 user 0.64 system 8.37 elapsed 113% CPU
time.13.ptmalloc.131072:25.97 user 142.27 system 96.00 elapsed 175% CPU
time.13.tcmalloc.131072:11.48 user 0.06 system 11.67 elapsed 98% CPU
time.14.ptmalloc.64:15.01 user 9.11 system 9.41 elapsed 256% CPU
time.14.tcmalloc.64:5.98 user 0.02 system 1.58 elapsed 378% CPU
time.14.ptmalloc.128:20.34 user 12.72 system 11.62 elapsed 284% CPU
time.14.tcmalloc.128:5.88 user 0.04 system 1.51 elapsed 392% CPU
time.14.ptmalloc.256:24.26 user 14.95 system 12.92 elapsed 303% CPU
time.14.tcmalloc.256:5.72 user 0.02 system 1.50 elapsed 381% CPU
time.14.ptmalloc.512:27.28 user 16.45 system 13.89 elapsed 314% CPU
time.14.tcmalloc.512:5.99 user 0.02 system 1.54 elapsed 388% CPU
time.14.ptmalloc.1024:25.84 user 16.99 system 12.61 elapsed 339% CPU
time.14.tcmalloc.1024:5.94 user 0.06 system 1.59 elapsed 375% CPU
time.14.ptmalloc.2048:11.96 user 0.01 system 3.12 elapsed 382% CPU
time.14.tcmalloc.2048:6.39 user 0.07 system 1.79 elapsed 359% CPU
time.14.ptmalloc.4096:20.19 user 11.77 system 8.26 elapsed 386% CPU
time.14.tcmalloc.4096:5.65 user 0.05 system 2.32 elapsed 244% CPU
time.14.ptmalloc.8192:22.01 user 16.39 system 9.89 elapsed 387% CPU
time.14.tcmalloc.8192:5.44 user 0.11 system 3.07 elapsed 180% CPU
time.14.ptmalloc.16384:18.15 user 22.40 system 15.02 elapsed 269% CPU
time.14.tcmalloc.16384:5.29 user 0.08 system 5.34 elapsed 100% CPU
time.14.ptmalloc.32768:24.29 user 72.07 system 42.63 elapsed 225% CPU
time.14.tcmalloc.32768:8.47 user 0.02 system 8.62 elapsed 98% CPU
time.14.ptmalloc.65536:27.63 user 130.56 system 78.64 elapsed 201% CPU
time.14.tcmalloc.65536:9.85 user 1.61 system 9.04 elapsed 126% CPU
time.14.ptmalloc.131072:28.87 user 146.38 system 100.54 elapsed 174% CPU
time.14.tcmalloc.131072:12.46 user 0.11 system 12.71 elapsed 98% CPU
time.15.ptmalloc.64:16.25 user 10.05 system 9.82 elapsed 267% CPU
time.15.tcmalloc.64:6.30 user 0.02 system 1.64 elapsed 385% CPU
time.15.ptmalloc.128:22.33 user 13.23 system 12.24 elapsed 290% CPU
time.15.tcmalloc.128:6.08 user 0.03 system 1.59 elapsed 384% CPU
time.15.ptmalloc.256:26.56 user 16.57 system 13.70 elapsed 314% CPU
time.15.tcmalloc.256:6.14 user 0.03 system 1.61 elapsed 382% CPU
time.15.ptmalloc.512:29.68 user 18.08 system 14.56 elapsed 327% CPU
time.15.tcmalloc.512:6.12 user 0.04 system 1.68 elapsed 364% CPU
time.15.ptmalloc.1024:17.07 user 6.22 system 6.26 elapsed 371% CPU
time.15.tcmalloc.1024:6.38 user 0.02 system 1.75 elapsed 364% CPU
time.15.ptmalloc.2048:26.64 user 17.25 system 11.51 elapsed 381% CPU
time.15.tcmalloc.2048:6.77 user 0.18 system 1.92 elapsed 361% CPU
time.15.ptmalloc.4096:13.21 user 0.74 system 3.57 elapsed 390% CPU
time.15.tcmalloc.4096:6.03 user 0.09 system 2.36 elapsed 258% CPU
time.15.ptmalloc.8192:22.92 user 17.51 system 10.50 elapsed 385% CPU
time.15.tcmalloc.8192:5.96 user 0.12 system 3.36 elapsed 180% CPU
time.15.ptmalloc.16384:19.37 user 24.87 system 16.69 elapsed 264% CPU
time.15.tcmalloc.16384:5.88 user 0.07 system 5.84 elapsed 101% CPU
time.15.ptmalloc.32768:25.43 user 82.30 system 48.98 elapsed 219% CPU
time.15.tcmalloc.32768:9.11 user 0.05 system 9.30 elapsed 98% CPU
time.15.ptmalloc.65536:29.31 user 140.07 system 83.78 elapsed 202% CPU
time.15.tcmalloc.65536:8.51 user 1.59 system 9.75 elapsed 103% CPU
time.15.ptmalloc.131072:30.22 user 163.15 system 109.50 elapsed 176% CPU
time.15.tcmalloc.131072:13.35 user 0.10 system 13.54 elapsed 99% CPU
time.16.ptmalloc.64:17.69 user 10.11 system 10.11 elapsed 274% CPU
time.16.tcmalloc.64:6.63 user 0.04 system 1.72 elapsed 387% CPU
time.16.ptmalloc.128:23.05 user 14.37 system 12.75 elapsed 293% CPU
time.16.tcmalloc.128:6.61 user 0.02 system 1.71 elapsed 387% CPU
time.16.ptmalloc.256:29.11 user 19.35 system 14.57 elapsed 332% CPU
time.16.tcmalloc.256:6.62 user 0.03 system 1.73 elapsed 382% CPU
time.16.ptmalloc.512:31.65 user 18.71 system 14.71 elapsed 342% CPU
time.16.tcmalloc.512:6.63 user 0.04 system 1.73 elapsed 383% CPU
time.16.ptmalloc.1024:31.99 user 21.22 system 14.87 elapsed 357% CPU
time.16.tcmalloc.1024:6.81 user 0.04 system 1.79 elapsed 382% CPU
time.16.ptmalloc.2048:30.35 user 21.36 system 13.30 elapsed 388% CPU
time.16.tcmalloc.2048:6.91 user 0.50 system 2.01 elapsed 367% CPU
time.16.ptmalloc.4096:18.85 user 7.18 system 6.61 elapsed 393% CPU
time.16.tcmalloc.4096:6.70 user 0.10 system 2.62 elapsed 259% CPU
time.16.ptmalloc.8192:22.19 user 14.30 system 9.37 elapsed 389% CPU
time.16.tcmalloc.8192:6.18 user 0.19 system 3.58 elapsed 177% CPU
time.16.ptmalloc.16384:31.22 user 46.78 system 22.92 elapsed 340% CPU
time.16.tcmalloc.16384:6.79 user 0.07 system 6.86 elapsed 99% CPU
time.16.ptmalloc.32768:27.31 user 87.32 system 52.00 elapsed 220% CPU
time.16.tcmalloc.32768:9.85 user 0.06 system 10.07 elapsed 98% CPU
time.16.ptmalloc.65536:32.83 user 160.62 system 95.67 elapsed 202% CPU
time.16.tcmalloc.65536:10.18 user 0.09 system 10.41 elapsed 98% CPU
time.16.ptmalloc.131072:31.99 user 173.41 system 115.98 elapsed 177% CPU
time.16.tcmalloc.131072:14.52 user 0.05 system 14.67 elapsed 99% CPU
time.17.ptmalloc.64:19.38 user 11.61 system 10.61 elapsed 291% CPU
time.17.tcmalloc.64:7.11 user 0.02 system 1.84 elapsed 386% CPU
time.17.ptmalloc.128:26.25 user 16.15 system 13.53 elapsed 313% CPU
time.17.tcmalloc.128:6.97 user 0.02 system 1.78 elapsed 390% CPU
time.17.ptmalloc.256:30.66 user 18.36 system 14.97 elapsed 327% CPU
time.17.tcmalloc.256:6.94 user 0.04 system 1.80 elapsed 387% CPU
time.17.ptmalloc.512:33.71 user 22.79 system 15.95 elapsed 354% CPU
time.17.tcmalloc.512:7.00 user 0.02 system 1.83 elapsed 381% CPU
time.17.ptmalloc.1024:33.49 user 22.47 system 15.00 elapsed 373% CPU
time.17.tcmalloc.1024:7.20 user 0.03 system 1.90 elapsed 380% CPU
time.17.ptmalloc.2048:23.87 user 11.92 system 9.26 elapsed 386% CPU
time.17.tcmalloc.2048:6.01 user 1.83 system 2.15 elapsed 363% CPU
time.17.ptmalloc.4096:14.69 user 0.95 system 3.98 elapsed 392% CPU
time.17.tcmalloc.4096:7.25 user 0.10 system 2.62 elapsed 279% CPU
time.17.ptmalloc.8192:22.44 user 13.52 system 9.39 elapsed 382% CPU
time.17.tcmalloc.8192:7.21 user 0.24 system 3.95 elapsed 188% CPU
time.17.ptmalloc.16384:23.33 user 33.67 system 21.89 elapsed 260% CPU
time.17.tcmalloc.16384:7.28 user 0.06 system 7.10 elapsed 103% CPU
time.17.ptmalloc.32768:29.35 user 103.11 system 60.36 elapsed 219% CPU
time.17.tcmalloc.32768:10.53 user 0.07 system 10.71 elapsed 98% CPU
time.17.ptmalloc.65536:33.21 user 170.89 system 100.84 elapsed 202% CPU
time.17.tcmalloc.65536:10.85 user 0.05 system 11.04 elapsed 98% CPU
time.17.ptmalloc.131072:34.98 user 182.87 system 122.05 elapsed 178% CPU
time.17.tcmalloc.131072:15.27 user 0.09 system 15.49 elapsed 99% CPU
time.18.ptmalloc.64:21.08 user 12.15 system 11.43 elapsed 290% CPU
time.18.tcmalloc.64:7.45 user 0.03 system 1.95 elapsed 383% CPU
time.18.ptmalloc.128:27.65 user 17.26 system 14.03 elapsed 320% CPU
time.18.tcmalloc.128:7.46 user 0.03 system 1.92 elapsed 389% CPU
time.18.ptmalloc.256:32.78 user 20.55 system 15.70 elapsed 339% CPU
time.18.tcmalloc.256:7.31 user 0.02 system 1.88 elapsed 389% CPU
time.18.ptmalloc.512:33.31 user 20.06 system 15.05 elapsed 354% CPU
time.18.tcmalloc.512:7.33 user 0.02 system 1.91 elapsed 383% CPU
time.18.ptmalloc.1024:35.46 user 24.83 system 16.30 elapsed 369% CPU
time.18.tcmalloc.1024:7.60 user 0.06 system 2.05 elapsed 373% CPU
time.18.ptmalloc.2048:19.98 user 6.80 system 6.76 elapsed 395% CPU
time.18.tcmalloc.2048:6.89 user 1.29 system 2.28 elapsed 357% CPU
time.18.ptmalloc.4096:15.99 user 0.93 system 4.32 elapsed 391% CPU
time.18.tcmalloc.4096:7.70 user 0.10 system 2.77 elapsed 280% CPU
time.18.ptmalloc.8192:23.51 user 14.84 system 9.97 elapsed 384% CPU
time.18.tcmalloc.8192:8.16 user 0.27 system 4.25 elapsed 197% CPU
time.18.ptmalloc.16384:35.79 user 52.41 system 26.47 elapsed 333% CPU
time.18.tcmalloc.16384:7.81 user 0.07 system 7.61 elapsed 103% CPU
time.18.ptmalloc.32768:33.17 user 116.07 system 68.64 elapsed 217% CPU
time.18.tcmalloc.32768:11.34 user 0.13 system 11.57 elapsed 99% CPU
time.18.ptmalloc.65536:35.91 user 177.82 system 106.75 elapsed 200% CPU
time.18.tcmalloc.65536:11.54 user 0.06 system 11.74 elapsed 98% CPU
time.18.ptmalloc.131072:36.38 user 187.18 system 126.91 elapsed 176% CPU
time.18.tcmalloc.131072:16.34 user 0.05 system 16.43 elapsed 99% CPU
time.19.ptmalloc.64:22.90 user 13.23 system 11.82 elapsed 305% CPU
time.19.tcmalloc.64:7.81 user 0.02 system 2.01 elapsed 388% CPU
time.19.ptmalloc.128:30.13 user 18.58 system 14.77 elapsed 329% CPU
time.19.tcmalloc.128:7.74 user 0.02 system 2.01 elapsed 386% CPU
time.19.ptmalloc.256:35.33 user 21.41 system 16.35 elapsed 347% CPU
time.19.tcmalloc.256:7.79 user 0.04 system 2.04 elapsed 382% CPU
time.19.ptmalloc.512:39.30 user 26.22 system 17.84 elapsed 367% CPU
time.19.tcmalloc.512:7.80 user 0.06 system 2.05 elapsed 381% CPU
time.19.ptmalloc.1024:35.70 user 23.90 system 15.66 elapsed 380% CPU
time.19.tcmalloc.1024:8.08 user 0.06 system 2.16 elapsed 376% CPU
time.19.ptmalloc.2048:18.33 user 3.28 system 5.47 elapsed 394% CPU
time.19.tcmalloc.2048:8.71 user 0.05 system 2.40 elapsed 363% CPU
time.19.ptmalloc.4096:16.94 user 0.89 system 4.64 elapsed 383% CPU
time.19.tcmalloc.4096:8.21 user 0.07 system 2.85 elapsed 289% CPU
time.19.ptmalloc.8192:25.61 user 17.15 system 11.33 elapsed 377% CPU
time.19.tcmalloc.8192:8.79 user 0.30 system 4.58 elapsed 198% CPU
time.19.ptmalloc.16384:27.11 user 46.66 system 29.67 elapsed 248% CPU
time.19.tcmalloc.16384:8.64 user 0.05 system 8.58 elapsed 101% CPU
time.19.ptmalloc.32768:33.80 user 117.69 system 70.65 elapsed 214% CPU
time.19.tcmalloc.32768:11.88 user 0.07 system 12.04 elapsed 99% CPU
time.19.ptmalloc.65536:36.90 user 180.21 system 109.01 elapsed 199% CPU
time.19.tcmalloc.65536:12.17 user 0.07 system 12.40 elapsed 98% CPU
time.19.ptmalloc.131072:38.50 user 195.15 system 132.81 elapsed 175% CPU
time.19.tcmalloc.131072:17.44 user 0.10 system 17.65 elapsed 99% CPU
time.20.ptmalloc.64:23.37 user 13.74 system 11.86 elapsed 312% CPU
time.20.tcmalloc.64:8.18 user 0.02 system 2.10 elapsed 389% CPU
time.20.ptmalloc.128:31.29 user 19.97 system 15.53 elapsed 329% CPU
time.20.tcmalloc.128:8.03 user 0.02 system 2.12 elapsed 378% CPU
time.20.ptmalloc.256:38.40 user 25.65 system 18.25 elapsed 350% CPU
time.20.tcmalloc.256:8.05 user 0.05 system 2.12 elapsed 380% CPU
time.20.ptmalloc.512:40.60 user 27.70 system 18.46 elapsed 369% CPU
time.20.tcmalloc.512:8.22 user 0.08 system 2.20 elapsed 375% CPU
time.20.ptmalloc.1024:40.02 user 28.52 system 17.56 elapsed 390% CPU
time.20.tcmalloc.1024:8.50 user 0.07 system 2.19 elapsed 391% CPU
time.20.ptmalloc.2048:16.13 user 0.23 system 4.23 elapsed 386% CPU
time.20.tcmalloc.2048:8.98 user 0.03 system 2.45 elapsed 367% CPU
time.20.ptmalloc.4096:17.14 user 0.87 system 4.60 elapsed 391% CPU
time.20.tcmalloc.4096:8.93 user 0.20 system 2.97 elapsed 306% CPU
time.20.ptmalloc.8192:25.24 user 17.16 system 11.14 elapsed 380% CPU
time.20.tcmalloc.8192:9.78 user 0.30 system 5.14 elapsed 195% CPU
time.20.ptmalloc.16384:39.93 user 60.36 system 30.24 elapsed 331% CPU
time.20.tcmalloc.16384:9.57 user 0.09 system 9.43 elapsed 102% CPU
time.20.ptmalloc.32768:36.44 user 130.23 system 76.79 elapsed 217% CPU
time.20.tcmalloc.32768:12.71 user 0.09 system 12.97 elapsed 98% CPU
time.20.ptmalloc.65536:39.79 user 202.09 system 120.34 elapsed 200% CPU
time.20.tcmalloc.65536:12.93 user 0.06 system 13.15 elapsed 98% CPU
time.20.ptmalloc.131072:41.91 user 202.76 system 138.51 elapsed 176% CPU
time.20.tcmalloc.131072:18.23 user 0.07 system 18.42 elapsed 99% CPU

---

### Trunk 3rdparty Srs Docs Doc Arm (`trunk/3rdparty/srs-docs/doc/arm.md`)

---
title: ARM and CrossBuild
sidebar_label: ARM and CrossBuild
hide_title: false
hide_table_of_contents: false
---

# SRS for linux-arm

How to run SRS on ARM pcu?

* Run SRS on ARM: Client can play stream from ARM server.

## Why run SRS on ARM?

The use scenario:

* Run SRS on ARM server, see [#1282](https://github.com/ossrs/srs/issues/1282#issue-386077124).
* Crossbuild for ARM embeded device, see [#1547](https://github.com/ossrs/srs/issues/1547#issue-543780097).

## RaspberryPi

User is able to build and run SRS on RespberryPI. Please don't use crossbuild.

<a name="armv8-and-aarch64"></a>

## ARM Server: armv7, armv8(aarch64)

User is able to build and run SRS on ARM servers. Please don't use crossbuild.

```
./configure && make
```

Build SRS in ARM server docker, see [aarch64](https://github.com/ossrs/dev-docker/tree/aarch64#usage)

```
docker run -it --rm -v `pwd`:/srs -w /srs ossrs/srs:aarch64 \
    bash -c "./configure && make"
```

For armv8 or aarch64, user should specify the arch, if the CPU arch is not identified automatically, see [#1282](https://github.com/ossrs/srs/issues/1282#issuecomment-568891854):

```bash
./configure --extra-flags='-D__aarch64__' && make
```

Run SRS:

```
./objs/srs -c conf/console.conf
```

Publish stream:

```
ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://127.0.0.1:1935/live/livestream
```

Play stream：[http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)



<a name="ubuntu-cross-build-srs"></a>

## Ubuntu Cross Build SRS: ARMv8(aarch64)

Build SRS in docker(Ubuntu20(xenial))：

```
cd ~/git/srs/trunk
docker run --rm -it -v `pwd`:/srs -w /srs ossrs/srs:ubuntu20 bash
```

Install toolchain(optional):

```
apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
```

Cross build SRS:

```
./configure --cross-build --cross-prefix=aarch64-linux-gnu-
make
```

Run SRS on [aarch64 docker](https://hub.docker.com/r/arm64v8/ubuntu):

```
cd ~/git/srs/trunk && docker run --rm -it -v `pwd`:/srs -w /srs \
    -p 1935:1935 -p 1985:1985 -p 8080:8080 arm64v8/ubuntu \
    ./objs/srs -c conf/console.conf
```

Publish stream:

```
ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://127.0.0.1:1935/live/livestream
```

Play stream：[http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)

## Ubuntu Cross Build SRS: ARMv7

Cross build ST and OpenSSL on Ubuntu20.

Build SRS in docker(Ubuntu20(xenial))：

```
cd ~/git/srs/trunk
docker run --rm -it -v `pwd`:/srs -w /srs ossrs/srs:ubuntu20 bash
```

Install toolchain(optional), for example [Acqua or RoadRunner board](https://www.acmesystems.it/arm9_toolchain)

```
apt-get install -y gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
```

Cross build SRS:

```
./configure --cross-build --cross-prefix=arm-linux-gnueabihf-
make
```

Run SRS on [ARMv7 docker](https://hub.docker.com/r/armv7/armhf-ubuntu):

```
cd ~/git/srs/trunk && docker run --rm -it -v `pwd`:/srs -w /srs \
    -p 1935:1935 -p 1985:1985 -p 8080:8080 armv7/armhf-ubuntu \
    ./objs/srs -c conf/console.conf
```

Publish stream:

```
ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://127.0.0.1:1935/live/livestream
```

Play stream：[http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)

## Ubuntu Cross Build SRS: hisiv500(arm)

TBD.

## Use Other Cross build tools

SRS configure options for cross build:

```bash
./configure -h

Presets:
  --cross-build             Enable cross-build, please set bellow Toolchain also. Default: off
  
Cross Build options:        @see https://ossrs.io/lts/en-us/docs/v7/doc/arm#ubuntu-cross-build-srs
  --cpu=<CPU>               Toolchain: Select the minimum required CPU. For example: --cpu=24kc
  --arch=<ARCH>             Toolchain: Select architecture. For example: --arch=aarch64
  --host=<BUILD>            Toolchain: Build programs to run on HOST. For example: --host=aarch64-linux-gnu
  --cross-prefix=<PREFIX>   Toolchain: Use PREFIX for tools. For example: --cross-prefix=aarch64-linux-gnu-

Toolchain options:
  --static=on|off           Whether add '-static' to link options. Default: off
  --cc=<CC>                 Toolchain: Use c compiler CC. Default: gcc
  --cxx=<CXX>               Toolchain: Use c++ compiler CXX. Default: g++
  --ar=<AR>                 Toolchain: Use archive tool AR. Default: g++
  --ld=<LD>                 Toolchain: Use linker tool LD. Default: g++
  --randlib=<RANDLIB>       Toolchain: Use randlib tool RANDLIB. Default: g++
  --extra-flags=<EFLAGS>    Set EFLAGS as CFLAGS and CXXFLAGS. Also passed to ST as EXTRA_CFLAGS.
```

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Client Sdk (`trunk/3rdparty/srs-docs/doc/client-sdk.md`)

---
title: Client SDK
sidebar_label: Client SDK
hide_title: false
hide_table_of_contents: false
---

# Client SDK

The workflow of live streaming:

```
+---------+      +-----------------+       +---------+
| Encoder +-->---+ SRS/CDN Network +--->---+ Player  |
+---------+      +-----------------+       +---------+
```

## EXOPlayer

The [EXOPlayer](https://github.com/google/ExoPlayer) is a Android player which support HTTP-FLV and HLS.

## IJKPlayer

[ijkplayer](https://github.com/Bilibili/ijkplayer) is a player from [bilibili](http://www.bilibili.com/), for both Android and iOS.

## FFmpeg

[FFmpeg](https://ffmpeg.org) is a complete, cross-platform solution to record, convert and stream audio and video.

## LIBRTMP

The [LIBRTMP](https://github.com/ossrs/librtmp) or [SRS-LIBRTMP](https://github.com/ossrs/srs-librtmp) only provides transport over RTMP.

## WebRTC

[WebRTC](https://webrtc.org/) is Real-time communication for the web.

## PC

Although the number of PC users are smaller, there are still some use scenarios for [OBS](https://obsproject.com).

> Remark: For publishing by OBS, the **Stream Key** should be filled by stream name.





Winlin 2017.4

---

### Trunk 3rdparty Srs Docs Doc Cloud (`trunk/3rdparty/srs-docs/doc/cloud.md`)

---
title: Cloud
sidebar_label: Cloud
hide_title: false
hide_table_of_contents: false
---

# Cloud

Migrated to [Cloud](/cloud)

---

### Trunk 3rdparty Srs Docs Doc Delivery Hds (`trunk/3rdparty/srs-docs/doc/delivery-hds.md`)

---
title: HDS Delivery
sidebar_label: HDS Delivery
hide_title: false
hide_table_of_contents: false
---

# HDS Delivery

HDS is the Http Dynamic Stream of Adobe，similar to Apple [HLS](./hls.md).

For specification of HDS, read http://www.adobe.com/devnet/hds.html

## Build

We can disable or enable HDS when build SRS, read [Build](./install.md)

```
./configure --hds=on
```

## Player

The OSMF player can play HDS. For example, use VLC to play the following HDS:

```
http://ossrs.net:8081/live/livestream.f4m
```

## HDS Config

The vhost hds.srs.com of conf/full.conf describes the config for HDS:

```
vhost __defaultVhost__ {
    hds {
        # whether hds enabled
        # default: off
        enabled         on;
        # the hds fragment in seconds.
        # default: 10
        hds_fragment    10;
        # the hds window in seconds, erase the segment when exceed the window.
        # default: 60
        hds_window      60;
        # the path to store the hds files.
        # default: ./objs/nginx/html
        hds_path        ./objs/nginx/html;
    }
}
```

The config items are similar to HLS, read [HLS config](./hls.md#hls-config)

Winlin 2015.3

---

### Trunk 3rdparty Srs Docs Doc Delivery Hls (`trunk/3rdparty/srs-docs/doc/delivery-hls.md`)

---
title: HLS Delivery
sidebar_label: HLS Delivery
hide_title: false
hide_table_of_contents: false
---

# HLS Delivery

Migrated to [HLS](./hls.md).

---

### Trunk 3rdparty Srs Docs Doc Delivery Http Flv (`trunk/3rdparty/srs-docs/doc/delivery-http-flv.md`)

---
title: HTTP-FLV Delivery
sidebar_label: HTTP-FLV Delivery
hide_title: false
hide_table_of_contents: false
---

# HTTP-FLV Delivery

Migrated to [HTTP-FLV](./flv.md).

---

### Trunk 3rdparty Srs Docs Doc Delivery Rtmp (`trunk/3rdparty/srs-docs/doc/delivery-rtmp.md`)

---
title: RTMP Delivery
sidebar_label: RTMP Delivery 
hide_title: false
hide_table_of_contents: false
---

# RTMP Delivery

Migrated to [RTMP](./rtmp.md).

---

### Trunk 3rdparty Srs Docs Doc Drm (`trunk/3rdparty/srs-docs/doc/drm.md`)

---
title: DRM
sidebar_label: DRM
hide_title: false
hide_table_of_contents: false
---

# DRM

DRM use to protect the content, can use many strategys:
* Referer Anti-suck: Check the referer(PageUrl) of RTMP connect params, which is set by flash player.
* Token Authentication: Check the token of RTMP connect params, SRS can use http-callback to verify the token.
* FMS token tranverse: Edge server will verify each connection on origin server.
* Access Server: Adobe Access Server.
* Publish Authentication: The authentication protocol for publish.

<a name='refer-authentication'></a>
<a name='refer-autisuck'></a>

## Referer Anti-suck

SRS support config the referer to anti-suck.

When play RTMP url, adobe flash player will send the page url in the connect params PageUrl,
which is cannot changed by as code, server can check the web page url to ensure the user is ok.

While user use client application, the PageUrl can be any value, for example,
use srs-librtmp to play RTMP url, the Referer anti-suck is not work.

To config the referer anti-suck in srs:

```bash
# the vhost for anti-suck.
vhost refer.anti_suck.com {
    # refer hotlink-denial.
    refer {
        # whether enable the refer hotlink-denial.
        # default: off.
        enabled         on;
        # the common refer for play and publish.
        # if the page url of client not in the refer, access denied.
        # if not specified this field, allow all.
        # default: not specified.
        all           github.com github.io;
        # refer for publish clients specified.
        # the common refer is not overrided by this.
        # if not specified this field, allow all.
        # default: not specified.
        publish   github.com github.io;
        # refer for play clients specified.
        # the common refer is not overrided by this.
        # if not specified this field, allow all.
        # default: not specified.
        play      github.com github.io;
    }
}
```

> Remark: SRS3 use new style config for referer, which is compatible with SRS1/2.

The bellow protocols support referer:

* RTMP: Both publisher and player.

## Token Authentication

The token authentication similar to referer, but the token is put in the url, not in the args of connect:

```
rtmp://vhost/app/stream?token=xxxx
http://vhost/app/stream.flv?token=xxxx
http://vhost/app/stream.m3u8?token=xxxx
http://vhost/rtc/v1/whip/?app=live&stream=livestream&token=xxx
http://vhost/rtc/v1/whep/?app=live&stream=livestream&token=xxx
```

SRS will pass the token in the http-callback. read [HTTP callback](./http-callback.md)

Token is robust then referer, can specifies more params, for instance, the expire time. For example:

1. When user access the web page, web application server can generate a token in the URL, for example, `token = md5(time + id + salt + expire) = 88195f8943e5c944066725df2b1706f8`
1. The RTMP URL to publish is, for instance, `rtmp://192.168.1.10/live/livestream?time=1402307089&expire=3600&token=88195f8943e5c944066725df2b1706f8`
1. Config the http callback of SRS `on_publish http://127.0.0.1:8085/api/v1/streams;` , read [HTTP callback](./http-callback.md#config-srs)
1. When user publishing stream, SRS will callback the url with token to verify, if invalid, the http callback can return none zero which indicates error.

> Note: You're able to verify the play.

## TokenTraverse

The FMS token tranverse is when user connect to edge server, 
the edge server will send the client info which contains token
to origin server to verify. It seems that the token from client
tranverse from edge to origin server.

FMS edge and origin use private protocol, use a connection to fetch data, 
another to transport the control message, for example, the token tranverse
is a special command, @see https://github.com/ossrs/srs/issues/104

Recomment the token authentication to use http protocol;
the token tranverse must use RTMP protocol, so many RTMP servers do not 
support the token tranverse.

SRS supports token tranverse like FMS, but SRS always create a new connection
to verify the client info on origin server.

THe config for token tranverse, see `edge.token.traverse.conf`：

```bash
listen              1935;
vhost __defaultVhost__ {
    cluster {
        mode            remote;
        origin          127.0.0.1:19350;
        token_traverse  on;
    }
}
```

## Access Server

SRS does not support.

## Publish Authentication

SRS does not support.

Winlin 2015.8

---

### Trunk 3rdparty Srs Docs Doc Flv Vod Stream (`trunk/3rdparty/srs-docs/doc/flv-vod-stream.md`)

---
title: FLV Vod Streaming
sidebar_label: FLV Vod Streaming
hide_title: false
hide_table_of_contents: false
---

# FLV vod streaming

## HTTP VOD

I recomment:

* Vod stream should always use HTTP protocol, never use RTMP.
SRS can dvr RTMP live stream to flv file, and provides some tools for vod stream,
but user should use other HTTP server to delivery flv file as vod stream.
* In a word, SRS does not support vod, only support live.

The workflow of flv vod stream:

* SRS dvr live stream to flv file, or upload flv vod file, to the HTTP root dir: `objs/nginx/html`
* HTTP server must support flv?start=offset, for example, flv module of nginx, or use experiment SRS HTTP server.
* Use `research/librtmp/objs/srs_flv_injecter` inject the keyframe offset to metadata of flv.
* Flash player play http flv url, for instance, `http://192.168.1.170:8080/sample.flv`
* When user seek, for instance, seek to 300s.
* Player use the keyframe offset in metadata to calc the offset of 300s, for instance, 300s offset=`6638860`
* Start new request, url is `http://192.168.1.170:8080/sample.flv?start=6638860`

Note: SRS HTTP server is experiment, do not limit the bandwidth.
Note: SRS provides flv view tool `research/librtmp/objs/srs_flv_parser`, to list the seconds:offsets in metadata.

## SRS Embeded HTTP server

SRS supports http-api, so SRS can also parse HTTP protocol(partial HTTP right now), 
so SRS also implements a experiment HTTP server.

SRS HTTP server is rewrite, table and partial HTTP protocol support, 
ok for online service.

For some emebeded device, for instance, arm linux, user can use SRS HTTP server,
for arm is not easy to build some server.

## Config

Read [HTTP Server](./http-server.md#config)

Winlin 2015.1

---

### Trunk 3rdparty Srs Docs Doc Getting Started K8s (`trunk/3rdparty/srs-docs/doc/getting-started-k8s.md`)

---
title: K8s
sidebar_label: K8s
hide_title: false
hide_table_of_contents: false
---

# K8s

> **Note:** SRS K8s is deprecated. Please use [CDK](./getting-started-cdk.md) instead.

We recommend using the HELM method to deploy SRS, see [srs-helm](https://github.com/ossrs/srs-helm). Of course,
SRS also supports direct deployment with K8s, refer to [SRS K8s](./k8s.md).

Actually, HELM is based on K8s and deploys K8s pods, which can be managed with kubectl. However, HELM offers a
more convenient way to manage and install applications, so SRS will mainly support HELM in the future.

Compared to Docker, HELM and K8s are mainly for medium to large scale deployments. If your business is not that
big, we recommend using Docker or Oryx directly. Generally, if you have less than a thousand streams, please
do not use HELM or K8s.

---

### Trunk 3rdparty Srs Docs Doc Git (`trunk/3rdparty/srs-docs/doc/git.md`)

---
title: Git
sidebar_label: Git
hide_title: false
hide_table_of_contents: false
---

# Git Usage

How to use stable version of SRS? How to update code?

## Checkout Branch

Some features are introduced in SRS2.0, the SRS1.0 does not support.
The wiki url specifies the version of SRS supports it.

To checkout SRS1.0 branch:

```
git pull && git checkout 1.0release
```

To checkout SRS2.0 branch:

```
git pull && git checkout 2.0release
```

To checkout SRS3.0 branch:

```
git pull && git checkout 3.0release
```

To checkout SRS4.0 branch:

```
git pull && git checkout 4.0release
```

To checkout SRS5.0 branch(if no 5.0release branch, it's develop):

```
git pull && git checkout develop
```

## SRS Branches

The release branch is more stable than develop.

* 3.0release, stable release branch.
* 4.0release, stable release branch.
* develop(5.0), not stable.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Gperf (`trunk/3rdparty/srs-docs/doc/gperf.md`)

---
title: GPERF
sidebar_label: GPERF
hide_title: false
hide_table_of_contents: false
---

# GPerf

No English version, please read [v4_CN_GPERF](./gperf.md) or [SRS性能(CPU)、内存优化工具用法](https://www.jianshu.com/p/6d4a89359352)

---

### Trunk 3rdparty Srs Docs Doc Gprof (`trunk/3rdparty/srs-docs/doc/gprof.md`)

---
title: GPROF
sidebar_label: GPROF
hide_title: false
hide_table_of_contents: false
---

# Gprof

Please read [SRS性能(CPU)、内存优化工具用法](https://www.jianshu.com/p/6d4a89359352)

---

### Trunk 3rdparty Srs Docs Doc Ide (`trunk/3rdparty/srs-docs/doc/ide.md`)

---
title: IDE
sidebar_label: IDE
hide_title: false
hide_table_of_contents: false
---

# IDE

SRS supports JetBrains [CLion](http://www.jetbrains.com/clion/)

## VSCode

See [VSCode: Usage](https://github.com/ossrs/srs/blob/develop/.vscode/README.md) for example.

## JetBrains

The clion of JetBrains, please open `trunk/ide/srs_clion/CMakeLists.txt`

Read [http://www.jetbrains.com/clion/](http://www.jetbrains.com/clion/)

Winlin 2015.10

---

### Trunk 3rdparty Srs Docs Doc Install (`trunk/3rdparty/srs-docs/doc/install.md`)

---
title: Build and Install
sidebar_label: Build and Install
hide_title: false
hide_table_of_contents: false
---

# Install

You can directly use the release binaries, or build SRS step by step. See: [Github: release](http://ossrs.net/srs.release/releases/) or [Mirror of China: release](http://www.ossrs.net/srs.release/releases/)

## OS

* <strong>Ubuntu20</strong> is recommended.
* Use [srs-docker](https://github.com/ossrs/dev-docker/tree/dev) to build SRS.
* Use [srs-docker](https://github.com/ossrs/dev-docker) to run SRS.

## Iptables and Selinux

Sometimes the stream play failed, but without any error message, or server cann't connect to. Please check the iptables and selinux.

Turn off <code>iptables</code>:

```bash
# disable the firewall
sudo /etc/init.d/iptables stop
sudo /sbin/chkconfig iptables off
```

Disable the <code>selinux</code>, to run `getenforce` to ensure the result is `Disabled`:

1. Edit the config of selinux: `sudo vi /etc/sysconfig/selinux`
1. Change the SELINUX to disabled: `SELINUX=disabled`
1. Rebot: `sudo init 6`

## Build and Run SRS

It's very easy to build SRS:

```
./configure && make
```

Also easy to start SRS:

```bash
./objs/srs -c conf/srs.conf
```

Publish RTMP, please read: [Usage: RTMP](./rtmp.md)

For service management, please read [Service](./service.md)

Run SRS in docker, please read [srs-docker](https://github.com/ossrs/dev-docker#usage)

## ARM

It's also ok to directly build on ARM server.

For ARM/MIPS or crossbuild, please read [here](./arm.md)

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc K8s (`trunk/3rdparty/srs-docs/doc/k8s.md`)

---
title: K8s Guide
sidebar_label: K8s Guide
hide_title: false
hide_table_of_contents: false
---

# K8S

> **Note:** SRS K8s is deprecated. Please use [CDK](./getting-started-cdk.md) instead.

> Cloud+Docker+K8S enable everyone to build live video streaming cluster and service.

Why should you use [k8s](https://docs.kubernetes.io/docs/concepts/overview/what-is-kubernetes) to build your SRS cluster?

* Simple: It's really simple and convenient, let's figure it out by [QuickStart](./k8s.md#quick-start).
* Declarative deployment: We declare a desired SRS cluster and it'll always be there, without starting and migrating service, watchdog and SLB configuration.
* Expand easily: K8S allows you to expand infrastructure automatically, and you can expand your business cluster easily by change the number of Pods.
* Rolling Update: K8S allows deployment update, rollback and gray release with zero downtime.
* XXX: Coming soon...

This tutorial highlights how to build SRS cluster for a variety of scenarios in [ACK(AlibabaCloud Container Service for Kubernetes)](https://www.alibabacloud.com/product/kubernetes).

1. [Deploy to Cloud Platforms](./k8s.md#deploy-to-cloud-platforms): Clone template project and use actions to deploy.
2. [Quick Start](./k8s.md#quick-start): Deployment an SRS origin server in ACK.
3. [SRS Shares Volume with Nginx](./k8s.md#srs-shares-volume-with-nginx): SRS is able to deliver simple HTTP content, or work with Nginx, SRS delivers RTMP/HTTP-FLV and write HLS to a share volume, then Nginx reads and delivers HLS.
4. [SRS Edge Cluster for High Concurrency Streaming](./k8s.md#srs-edge-cluster-with-slb): SRS edge cluster, which is configured and updated automatically, to provide services for huge players.
5. [SRS Origin Cluster for a Large Number of Streams](./k8s.md#srs-origin-cluster-for-a-large-number-of-streams): SRS origin cluster is designed to serve a large number of streams.
6. [SRS Cluster Update, Rollback, Gray Release with Zero Downtime](./k8s.md#srs-cluster-update-rollback-gray-release-with-zero-downtime): K8S allows deployment update, rollback and gray release with zero downtime.
7. [Useful Tips](./k8s.md#useful-tips)
    1. [Create K8S Cluster in ACK](./k8s.md#create-k8s-cluster-in-ack): Create your own k8s cluster in ACK.
    2. [Publish Demo Streams to SRS](./k8s.md#publish-demo-streams-to-srs): Publish the demo streams to SRS.
    3. [Cleanup For DVR/HLS Temporary Files](./k8s.md#cleanup-for-dvrhls-temporary-files): Remove the temporary files for DVR/HLS.
    4. [Use One SLB and EIP for All Streaming Service](./k8s.md#use-one-slb-and-eip-for-all-streaming-service): Use one SLB for RTMP/HTTP-FLV/HLS streaming service.
    5. [Build SRS Origin Cluster as Deployment](./k8s.md#build-srs-origin-cluster-as-deployment): Rather than StatefulSet, we can also use deployment to build Origin Cluster.
    6. [Managing Compute Resources for Containers](./k8s.md#managing-compute-resources-for-containers): Resource requests and limits, and how pods requests are scheduled and limits are run.
    7. [Auto Reload by Inotify](./k8s.md#auto-reload-by-inotify): SRS supports auto reload by inotify watching ConfigMap changes.

## Deploy to Cloud Platforms

SRS provides a set of template repository for fast deploy:

* [General K8s](https://github.com/ossrs/srs-k8s-template)
* [TKE(Tencent Kubernetes Engine)](https://github.com/ossrs/srs-tke-template)
* [ACK(Alibaba Cloud Container Service for Kubernetes)](https://github.com/ossrs/srs-ack-template)
* [EKS(Amazon Elastic Kubernetes Service)](https://github.com/ossrs/srs-eks-template)
* [AKS(Azure Kubernetes Service)](https://github.com/ossrs/srs-aks-template)

## Quick Start

Assumes you have access to a k8s cluster:

```bash
kubectl cluster-info
```

Let's take a look at a single SRS origin server in k8s.



**Step 1:** Create a [k8s deployment](https://v1-14.docs.kubernetes.io/docs/concepts/workloads/controllers/deployment) for SRS origin server:

```bash
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: srs-deployment
  labels:
    app: srs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: srs
  template:
    metadata:
      labels:
        app: srs
    spec:
      containers:
      - name: srs
        image: ossrs/srs:3
        ports:
        - containerPort: 1935
        - containerPort: 1985
        - containerPort: 8080
EOF
```

**Step 2:** Create a [k8s service](https://v1-14.docs.kubernetes.io/docs/concepts/services-networking/service) which exposing live video streaming service by [SLB](https://www.alibabacloud.com/product/server-load-balancer) with [EIP](https://www.alibabacloud.com/product/eip):

```bash
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: srs-service
spec:
  type: LoadBalancer
  selector:
    app: srs
  ports:
  - name: srs-service-1935-1935
    port: 1935
    protocol: TCP
    targetPort: 1935
  - name: srs-service-1985-1985
    port: 1985
    protocol: TCP
    targetPort: 1985
  - name: srs-service-8080-8080
    port: 8080
    protocol: TCP
    targetPort: 8080
EOF
```

**Step 3:** Done, you could get the EIP and play with SRS now.

Please use `kubectl get svc/srs-service` to get the EIP:

```
NAME          TYPE           CLUSTER-IP      EXTERNAL-IP
srs-service   LoadBalancer   172.21.12.131   28.170.32.118
```

Then you can publish and play with `28.170.32.118`:

* Publish RTMP to `rtmp://28.170.32.118/live/livestream`
* Play RTMP from `rtmp://28.170.32.118/live/livestream`
* Play HTTP-FLV from [http://28.170.32.118:8080/live/livestream.flv](http://ossrs.net/players/srs_player.html?app=live&stream=livestream.flv&server=28.170.32.118&port=8080&autostart=true&vhost=28.170.32.118&schema=http)
* Play HLS from [http://28.170.32.118:8080/live/livestream.m3u8](http://ossrs.net/players/srs_player.html?app=live&stream=livestream.m3u8&server=28.170.32.118&port=8080&autostart=true&vhost=28.170.32.118&schema=http)



## SRS Shares Volume with Nginx

This chapter will show you how SRS is going to provide HTTP Service with Nginx based on K8S.

SRS can distribute RTMP and HTTP-FLV, and write HLS segments to shared Volume, the Nginx Container can read Volume and distribute HLS. Of course SRS can distribute HLS too, but the next scenarios are better to use Nginx :

* 80 port is already used by nginx, SRS can share Volume with Nginx
* Nginx support HTTPS, after configure certificate, it can serve the HLS files generated by SRS through HTTPS protocol.
* Nginx or other Web server, can provide authenticate to serve HLS segments in a secure way.
* SRS now only support a part of HTTP/1.1。 Nginx Open Source version 1.9.5 or higher has built-in support for HTTP/2

the difference of traditional package deployment vs K8S:

|  |ECS|K8S|comment|
|:--|:--|:--|:--|
|resources|Manually|Automatically|From the traditional deployment, the resources SLB、EIP and ECS, you need to buy and configure one by one yourself,  use k8s the mentioned resources can be acquired and configured automatically.|
|deployment|Package|Image|From the K8s deployment, the pod’s docker image can easily rollback, and can keep the dev environment in touch with the prod, and the image can be cached on the node. So with docker image, you will get the required high efficiency、high density、high portability、resource isolation.|
|migration|Manually|Automatically|From the traditional deployment way, when change ECS, you need to apply the new machine resource, modify SLB,  and install application by yourself. Based on K8S, it can auto complete the service migration, update SLB, configure liveness, readiness and startup probes.|

The following architecture of the K8s deployment:


Step 1: Create a k8s deployment for SRS and Nginx, the srs container will write the HLS segment to the shared Volume

```
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: srs-deploy
  labels:
    app: srs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: srs
  template:
    metadata:
      labels:
        app: srs
    spec:
      volumes:
      - name: cache-volume
        emptyDir: {}
      containers:
      - name: srs
        image: ossrs/srs:3
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 1935
        - containerPort: 1985
        - containerPort: 8080
        volumeMounts:
        - name: cache-volume
          mountPath: /usr/local/srs/objs/nginx/html
          readOnly: false
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - name: cache-volume
          mountPath: /usr/share/nginx/html
          readOnly: true
      - name: srs-cp-files
        image: ossrs/srs:3
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: cache-volume
          mountPath: /tmp/html
          readOnly: false
        command: ["/bin/sh"]
        args:
        - "-c"
        - >
          if [[ ! -f /tmp/html/index.html ]]; then
            cp -R ./objs/nginx/html/* /tmp/html
          fi &&
          sleep infinity
EOF
```

> Note: Nginx’s default directory is /usr/share/nginx/html, please be awared, and change it to your own directory

> Note: To share HLS segments, both SRS and Nginx are mounted to the emptyDir Volume at different paths, the emptyDir volume is initially empty and will be emptied as the pod is destoryed.

> Note: Since the shared emptyDir Volume is initially empty, we start a srs-cp-files container, and copied the SRS default files, please refer to [#1603](https://github.com/ossrs/srs/issues/1603).

Step 2: create a [k8s Service](https://kubernetes.io/docs/concepts/services-networking/service/), using SLB to provide external streaming service.

```
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: srs-origin-service
spec:
  type: LoadBalancer
  selector:
    app: srs
  ports:
  - name: srs-origin-service-80-80
    port: 80
    protocol: TCP
    targetPort: 80
  - name: srs-origin-service-1935-1935
    port: 1935
    protocol: TCP
    targetPort: 1935
  - name: srs-origin-service-1985-1985
    port: 1985
    protocol: TCP
    targetPort: 1985
  - name: srs-origin-service-8080-8080
    port: 8080
    protocol: TCP
    targetPort: 8080
EOF
```

> Note: We expose ports for external services through k8s LoadBalancer Service, where RTMP(1935)/FLV(8080)/API(1985) is served by SRS and HLS(80) is served by Nginx.

> Note: Here we choose ACK to create SLB and EIP automatically, or you can specify SLB manually, refer to [Use One SLB and EIP for All Streaming Service](./k8s.md#ack-srs-buy-slb-eip).

Step 3: Great job. You can publish and play streams now. the HLS stream can by played from SRS(8080) or Nginx(80).
* Publish RTMP to rtmp://28.170.32.118/live/livestream or Publish Demo Streams to SRS.
* Play RTMP from rtmp://28.170.32.118/live/livestream
* Play HTTP-FLV from http://28.170.32.118:8080/live/livestream.flv
* Play HLS from http://28.170.32.118:8080/live/livestream.m3u8
* Play HLS from http://28.170.32.118/live/livestream.m3u8

> Note: Please replace the above EIP with your own, and use 'kubectl get svc/srs-origin-service’ to check your EIP

## SRS Edge Cluster for High Concurrency Streaming

This chapter will show you how to build Edge Cluster for high concurrency streaming based on k8s.

Edge Cluster realizes merging the request of origin source. When there are many players, but request for a same stream, the Edge server still only request one stream from origin. So you can scale up the Edge Cluster to facilitate more clients requests. This is CDN’s  important capability:high concurreny.

> Note: Edge Cluster can be classified as RTMP Edge Cluster or HTTP-FLV Edge Cluster depending on the player’s stream protocol, for more details, can refer to the related Wiki.

For self-host origin, without so many play requests, why is it not recommended to use SRS Single Origin mode, and instead use Edge Cluster mode? look at the related scenarios:

* Avoid overloading of origin. Even if it’s a bit push and play scene, in the case of many CDN requests for one origin stream, may be result in one stream has many request connections. Use Edge cluster can protect origin from too many requests, and transfer the danger to edge.

* Can easily scale up multi Edge Clusters with different SLB exported, and to avoid interference of multiple CDNs,  can execute traffic limit on sperate SLB. Use many Edge Clusters can ensure some CDN is available when Origin is down.

* Can let Edge Cluster to handle stream distribution, and let Origin focus on Slice segments、 DVR、 Authentication functions.

the difference of  traditional package deployment vs K8S:

|          |    ECS   |   K8S   |  comment  |
|  :----:  | :----   | :----  |  :----   |
|   Resources      |       Manually    |Automatically|     From the traditional deployment, the resources SLB、EIP and ECS, you need to buy and configure one by one yourself,  use k8s the mentioned resources can be acquired and configured automatically.     |
|   Deployment      |       Package    |Image|     From the K8s deployment, the pod’s docker image can easily rollback, and can keep the dev environment in touch with the prod, and the image can be cached on the node. <br/>So with docker image, you will get the required high efficiency、high density、high portability、resource isolation.     |
|   Watchdog      |       Manually    |Automatically|     When srs exited abnormally, the event should be monitored and auto restarted, you need do it by yourself from the traditional way.<br/>K8s provides liveness probes and ensuring automatically recovered when anormaly appears.     |
|   Migration      |       Manually    |Automatically|     From the traditional deployment way, when change ECS, you need to apply the new machine resource, modify SLB,  and install application by yourself.<br/>Based on K8S, it can auto complete the service migration, update SLB, configure liveness, readiness and startup probes.     |
|   Configure      |       File    |Volume|     From the traditional deployment way, you need to configure ECS manually.<br/>K8s stores configuration data in ConfigMap, the data can be added to a specific path in the Volume, and consumed by the Pods. Allow you to decouple ECS scale up.     |
|   Scale Up      |       Manually    |Automatically|     From the traditional deployment way, you need to deploy and configure for the new applied ECS. <br/>Based on K8s, just modify the Replicas is ok, you can also enable auto scale.     |
|   Service Discovery      |       Manually    |Automatically|    From the traditional deployment way, when the Origin’s ip changed, you need to configure the new ip in Edge's config file.<br/>Use K8s, it will discover and notify the change to the Edge.      |
|   SLB      |       Manually    |Automatically|    From the traditional deployment way, when add a new Edge server, you need to update SLB config manually.<br/>Based on K8s, it will get updated automatically.      |

The following architecture of The K8s deployment:



Step 1: Create Deployment and Service for SRS origin and Nginx origin.

* srs-origin-deploy: create a [k8s deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) of stateless application, which contains SRS Server(with origin config)、Nginx containers and a shared volume for containers to mount. The srs container will write the HLS segment to the shared [volume](https://kubernetes.io/docs/concepts/storage/volumes/).

* srs-origin-service: create a k8s ClusterIP [Service](https://kubernetes.io/docs/concepts/services-networking/service/) to provide Origin service, which can only be accessed inside the cluster.

* srs-http-service: create a k8s LoadBalancer [Service](https://kubernetes.io/docs/concepts/services-networking/service/) to provide the SLB based HTTP distribution service of HLS segments powered by Nginx.

```
/* Detailed source-code truncated for AI context efficiency. */
```

> Note: The Origin server only can be accessed inside the cluster, for it’s service type is ClsterIP, the Edge Server can connect to the remote Origin Server through the internal domain srs-origin-service.

> Note: For share HLS segments, both SRS and Nginx are mounted to the [emptyDir Volume](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) at different paths, the emptyDIr volume is initially empty and the data in the emptyDir is deleted when the pod is removed.

> Note: As the emptyDir is initially empty, so we start a srs-cp-files container, which will copy srs’s cached files to the shared volume. please refer[1603](https://github.com/ossrs/srs/issues/1603)

> Note: The srs-http-service provide HLS distribution service with Nginx’s 80 port exported, and provide API service with SRS’s 1985 port exported.

> Note: Here we choose ACK to create SLB and EIP automatically, or you can specify SLB manually, refer to [Use One SLB and EIP for All Streaming Service](./k8s.md#ack-srs-buy-slb-eip)

Step 2: Create Deployment and Service for SRS edge.

* srs-edge-config: create a k8s [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/), which stores configuration of SRS Edge Server.

* sts-edge-deploy: create a [k8s deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/), which will deploy a stateless application,  and running multi replicas of SRS Edge Server.

* srs-edge-service: create a [k8s Service](https://kubernetes.io/docs/concepts/services-networking/service/), using SLB to provide external streaming service

```
/* Detailed source-code truncated for AI context efficiency. */
```

Note: The Edge Server’s configuration is stored in [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) of srs-edge-config, and [mount](https://kubernetes.io/docs/concepts/storage/volumes/#configmap) it to the /usr/local/srs/conf path, the srs.conf will appear in the directory.

Note: The Edge Server has been configured to work in cluster mode:remote, it will connect to the Origin Server through domain:srs-origin-service.

Note: The srs-edge-service provide RTMP service with SRS’s 1935 port exported, and provide HTTP-FLV service with SRS’s 80 port.

Note: we choose ACK to create SLB and EIP automatically, or you can specify SLB manually, refer to [Use One SLB and EIP for All Streaming Service](./k8s.md#ack-srs-buy-slb-eip).

Step 3: Now, you made it. you can push retmp stream to the edge, and pull hls stream from Nginx, pull RTMP, HTTP-FLV from SRS.

* Publish RTMP to rtmp://28.170.32.118/live/livestream or [Publish Demo Streams to SRS](./k8s.md#ack-srs-publish-demo-stream-to-edge).

* Play RTMP from `rtmp://28.170.32.118/live/livestream`

* Play HTTP-FLV from [http://28.170.32.118:8080/live/livestream.flv](http://ossrs.net/players/srs_player.html?app=live&stream=livestream.flv&server=28.170.32.118&port=8080&autostart=true&vhost=28.170.32.118&schema=http)

* Play HLS from [http://28.170.32.118/live/livestream.m3u8](http://ossrs.net/players/srs_player.html?app=live&stream=livestream.m3u8&server=28.170.32.118&port=80&autostart=true&vhost=28.170.32.118&schema=http)

> Note: Please change the EIP in the stream address to yourself. you can exec 'kubectl get svc/srs-http-service' or 'kubectl get svc/srs-edge-service’ command to check your EIP address.

> Note: If the SLB and EIP are created automatically, the HLS and RTMP/HTTP-FLV’s EIP are different. you can choose to specify the SLB manually, and both services can use the same SLB, for details please refer to [Use One SLB and EIP for All Streaming Service](./k8s.md#ack-srs-buy-slb-eip).

## SRS Origin Cluster for a Large Number of Streams

Coming soon...

## SRS Cluster Update, Rollback, Gray Release with Zero Downtime

Coming soon...

## Useful Tips

There are some useful tips for you.

1. [Create K8S Cluster in ACK](./k8s.md#create-k8s-cluster-in-ack): Create your own k8s cluster in ACK.
1. [Publish Demo Streams to SRS](./k8s.md#publish-demo-streams-to-srs): Publish the demo streams to SRS.
1. [Use One SLB and EIP for All Streaming Service](./k8s.md#use-one-slb-and-eip-for-all-streaming-service): Use one SLB for RTMP/HTTP-FLV/HLS streaming service.
1. [Build SRS Origin Cluster as Deployment](./k8s.md#build-srs-origin-cluster-as-deployment): Rather than StatefulSet, we can also use deployment to build Origin Cluster.
1. [Managing Compute Resources for Containers](./k8s.md#managing-compute-resources-for-containers): Resource requests and limits, and how pods requests are scheduled and limits are run.
1. [Auto Reload by Inotify](./k8s.md#auto-reload-by-inotify): SRS supports auto reload by inotify watching ConfigMap changes.

### Create K8S Cluster in ACK

Coming soon...

### Publish Demo Streams to SRS

Coming soon...

### Use One SLB for All Streaming Service

Coming soon...

### Build SRS Origin Cluster as Deployment

Coming soon...

### Managing Compute Resources for Containers

Coming soon...

### Auto Reload by Inotify

Coming soon...

Winlin 2020.02

---

### Trunk 3rdparty Srs Docs Doc Learning Path (`trunk/3rdparty/srs-docs/doc/learning-path.md`)

---
title: Learning Path
sidebar_label: Learning Path
hide_title: false
hide_table_of_contents: false
---

# Learning Path

A learning path for newcomers, please be sure to follow the documentation.

## Quick Preview

First, It takes about 5 to 15 minutes to see what live streaming and WebRTC look like, as the following picture shown:。



> Note: This may seem easy, even if you can open two pages directly from the SRS website, but you must build it yourself with SRS, not just open the online demo page.

How do you do it？Please refer to [Getting Started](./getting-started.md)。

The first step in approaching something new is to have an intuitive experience and feel for it. Although it seems simple, it involves almost the whole chain of things in the audio/video field：
- FFmpeg, a powerful audio/video client that supports publish and pull streaming, codecs encoding and decoding , as well as various processing capabilities.
- Chrome (or browser), H5 is the most convenient client, very convenient for demo and learning, SRS’s features basically have H5 demo.
- Audio and video protocols: RTMP, HTTP-FLV, HLS and WebRTC.
- SRS server, deploying audio and video cloud by itself, or providing cloud services for audio and video, SRS is essentially a kind of server for video cloud.

> Note: The above diagram is still missing the mobile end, in fact, the mobile end is just a kind of end, and there is no new protocol, you can also download the SRS live streaming client, experience the above push stream and play, you can also enter your server's stream address to play.

## Deeper

Second, understand each typical scenario of audio and video applications, about five core scenarios, which takes about 3~7 days in total:

Typical audio and video business scenarios, including but not limited to:
- All-platform live streaming. The Encoders (FFmpeg/OBS) above can publish RTMP to SRS; an SRS Origin (no need Cluster), which is muxed into HTTP-FLV streams and HLS; Players can choose HTTP-FLV or HLS streams to play according to the platform's player.
- WebRTC call services, one-to-one calls, multi-person calls, conference rooms, etc. WebRTC is the key and core capability introduced in SRS4. From 1 to 3 seconds latency at the beginning, to 100 to 300 milliseconds latency now, it is definitely not a change of numbers, but an essential change.
- Monitoring and broadcasting business to the cloud. In addition to using FFmpeg to actively pull streams to SRS, you can also use the SRT protocol of the broadcasting industry to publish streams, or the GB28181 protocol of the surveillance industry to publish streams, SRS can converts it to the Internet protocols for playing.
- Low latency live streaming and interactive live streaming. Convert RTMP to WebRTC for playing to reduce the latency of palying, and can also use the WebRTC to publish stream. In the future will support WebTransport live streaming.
- Large-Scale Business, if business grows rapidly, you can use SRS Edge Cluster to support massice Players, or use SRS Origin Cluster to support massive Encoders, of course, you can migrate your business to the video cloud smoothly too. In the future, SRS will also support WebRTC cluster.

Each scenario can build a typical application.

## For Details

Third, Understand the technical points, application scenarios, code and problem solving, about 3 to 6 months.

- [Video Columns](./introduction.md#effective-srs), includes environment building, code analysis, and explanations from professional teachers at Voice Academy.
- [Solution Guides](./introduction.md#solution-guides)，share and explore the application of SRS in different scenarios.
- [Deployment Guides](./introduction.md#deployment-guides), how to deploy to implement different specific functions.
- [Cluster Guides](./introduction.md#cluster-guides), when business grows rapidly, how to scale single server to cluster, and how to serve users in different regions.
- [Integration Guides](./introduction.md#integration-guides), How to integrate with existing systems, how to authenticate users, security and anti-stealing chain mechanisms, etc.
- [Develop Guides](./introduction.md#develop-guide), Concurrent principles, code analysis, high performance server framework, performance optimization, etc.

If you can thoroughly understand SRS, it's really not difficult.

Author：winlinvip

Origin Link：https://www.jianshu.com/p/2662df9fe078

From：jianshu.com

The copyright belongs to the author. For commercial reproduction, please contact the author for authorization, and for non-commercial reproduction, please cite the source.

---

### Trunk 3rdparty Srs Docs Doc Log Rotate (`trunk/3rdparty/srs-docs/doc/log-rotate.md`)

---
title: Log Rotate
sidebar_label: Log Rotate
hide_title: false
hide_table_of_contents: false
---

# LogRotate

SRS always writes log to a single log file `srs.log`, so it will become very larger. We can use rotate the log to zip or remove it.

1. First, move the log file to another tmp log file:```mv objs/srs.log /tmp/srs.`date +%s`.log```
1. Then, send signal to SRS. SRS will close the previous file fd and reopen the log file:```killall -s SIGUSR1```
1. Finally, zip or remove the tmp log file.

## Use logrotate

Recommend to use [logrotate](https://www.jianshu.com/p/ec7f1626a3d3) to manage log files.

1. Install logrotate:

```
sudo yum install -y logrotate
```

1. Config logrotate to manage SRS log file:

```
cat << END > /etc/logrotate.d/srs
/usr/local/srs/objs/srs.log {
    daily
    dateext
    compress
    rotate 7
    size 1024M
    sharedscripts
    postrotate
        kill -USR1 \`cat /usr/local/srs/objs/srs.pid\`
    endscript
}
END
```

> Note: Run logrotate manually by `logrotate -f /etc/logrotate.d/srs`

## CopyTruncate

For SRS2, we could use [copytruncate](https://unix.stackexchange.com/questions/475524/how-copytruncate-actually-works),
**but it's strongly not recommended** because the logs maybe dropped, so it's only a workaround for server not supported
SIGUSR1 such as SRS2.

> Yes, SRS3 surely supports copytruncate and it's not recommended.

The config is bellow, from [PR#1561](https://github.com/ossrs/srs/pull/1561#issuecomment-571408173) by [wnpllrzodiac](https://github.com/wnpllrzodiac):

```
cat << END > /etc/logrotate.d/srs
/usr/local/srs/objs/srs.log {
    daily
    dateext
    compress
    rotate 7
    size 1024M
    copytruncate
}
END
```

Winlin 2016.12

---

### Trunk 3rdparty Srs Docs Doc Log (`trunk/3rdparty/srs-docs/doc/log.md`)

---
title: Log
sidebar_label: Log
hide_title: false
hide_table_of_contents: false
---

# SRS Log System

SRS can log to console or file, with level, session oriented log and tracable log.

## LogTank

The tank is the container for log, to where write log:

There are two tank of SRS log, config the `srs_log_tank` to:
* console: Write log to console. Before config parsed, write log to console too.
* file: Default. Write log to file, and the `srs_log_file` specified the path of log file, which default to  `./objs/srs.log`

The log specified config:

```bash
# the log tank, console or file.
# if console, print log to console.
# if file, write log to file. requires srs_log_file if log to file.
# default: file.
srs_log_tank        file;
```

## LogLevel

The level is specified by `srs_log_level_v2` and control which level of log to print:

* trace: Lots of log, which hurts performance. SRS default to disable it when compile.
* debug：Detail log, which huts performance. SRS default to disable it when compile.
* info: Important log, less and SRS enable it as default level.
* warn: Warning log, without debug log.
* error: Error level.

The level in config file:

```bash
# The log level for logging to console or file. It can be:
#       verbose, info, trace, warn, error
# If configure --log-level_v2=off, use SRS 4.0 level specs which is v1, the level text is:
#       Verb, Info, Trace, Warn, Error
# If configure --log-level_v2=on, use SRS 5.0 level specs which is v2, the level text is:
#       TRACE, DEBUG, INFO, WARN, ERROR
# Note: Do not support reloading, for SRS5+
# Overwrite by env SRS_LOG_LEVEL or SRS_SRS_LOG_LEVEL
# default: trace
srs_log_level trace;

# The log level v2, rewrite the config srs_log_level if not empty, it can be:
#       trace, debug, info, warn, error
# If configure --log-level_v2=off, use SRS 4.0 level specs which is v1, the level text is:
#       Verb, Info, Trace, Warn, Error
# If configure --log-level_v2=on, use SRS 5.0 level specs which is v2, the level text is:
#       TRACE, DEBUG, INFO, WARN, ERROR
# Overwrite by env SRS_LOG_LEVEL_V2 or SRS_SRS_LOG_LEVEL_V2
srs_log_level_v2 info;
```

> Note: For SRS 5.0+, the `--log-level_v2` is default to `on`, which means we use the new log level by default.

Notes:

* Enable all high level, for example, enable trace/warn/error when set level to trace.
* The trace and debug level is disabled when compile. Modify the `srs_kernel_log.hpp` when need to enable this.
* Recomment to use `info` level.

## Log of tools

The feature Transcode/Ingest use external tools, for instance, FFMPEG. SRS use isolate log file for the external tools.

Set the tools log to `/dev/null` to disable the log:

```bash
# the logs dir.
# if enabled ffmpeg, each stracoding stream will create a log file.
# "/dev/null" to disable the log.
# default: ./objs
ff_log_dir          ./objs;
```

## Log Format

SRS provides session oriented log, to enalbe us to grep specified connection log:

```bash
[2014-04-04 11:21:29.183][trace][2837][104][11] rtmp get peer ip success. ip=192.168.1.179
```

The log format is:
* <strong>[2014-04-04 11:21:29.183]</strong> Date of log. The ms is set by the time cache of SRS_TIME_RESOLUTION_MS to avoid performance issue.
* <strong>[trace]</strong> Level of log. Trace is ok, warn and error maybe something is wrong.
* <strong>[2837]</strong> The pid of process(SrsPid). The session id maybe duplicated for multiple process.
* <strong>[104]</strong> The session id(SrsId), unique for the same process. So the pid+session-id is used to identify a connection.
* <strong>[11]</strong> The errno of system, optional for warn and error.
* <strong>rtmp get peer ip success.</strong> The description of log.

The following descript how to analysis the log of SRS.

### Tracable Log

SRS can get the whole log when we got something, for example, the ip of client, or the stream for client and time to play, the page url.

Event for the cluster, SRS can find the session oriented directly. We can get the session of server, and the source id for the session, and the upnode session log util the origin server and the publish id.

The client also can get the pid and session-id of the connection on server. For example:

A client play stream: rtmp://dev:1935/live/livestream

We can get the server ip `192.168.1.107`, the pid `9131` and session id `117`. We can grep on this server directly by keyword "\[9131\]\[117\]":
```
/* Detailed source-code truncated for AI context efficiency. */
```

While the source id is 115(`source_id=115`), then find this session:
```
[winlin@dev6 srs]$ grep -ina "\[12665\]\[115\]" objs/edge.log
1320:[2014-05-27 19:21:27.518][trace][12665][115] edge connected, can_publish=1, url=rtmp://dev:1935/live/livestream, server=127.0.0.1:19350
1321:[2014-05-27 19:21:27.518][trace][12665][115] connect to server success. server=127.0.0.1, ip=127.0.0.1, port=19350
1323:[2014-05-27 19:21:27.519][trace][12665][115] complex handshake with server success.
1324:[2014-05-27 19:21:27.561][trace][12665][115] set ack window size to 2500000
1325:[2014-05-27 19:21:27.602][trace][12665][115] drop unknown message, type=6
1326:[2014-05-27 19:21:27.602][trace][12665][115] connected, version=0.9.119, ip=127.0.0.1, pid=12633, id=141
1327:[2014-05-27 19:21:27.602][trace][12665][115] set output chunk size to 60000
1328:[2014-05-27 19:21:27.602][trace][12665][115] edge change from 100 to state 101 (ingest connected).
1329:[2014-05-27 19:21:27.603][trace][12665][115] set input chunk size to 60000
1330:[2014-05-27 19:21:27.603][trace][12665][115] dispatch metadata success.
1331:[2014-05-27 19:21:27.603][trace][12665][115] update video sequence header success. size=46
1332:[2014-05-27 19:21:27.603][trace][12665][115] update audio sequence header success. size=4
1335:[2014-05-27 19:21:37.653][trace][12665][115] <- EIG time=10163, okbps=0,0,0, ikbps=234,254,231
```

We can finger out the upnode server session info `connected, version=0.9.119, ip=127.0.0.1, pid=12633, id=141`, then to grep on the upnode server:
```
/* Detailed source-code truncated for AI context efficiency. */
```

And the source id 149(`source_id=149`), that is the session id of encoder:
```
[winlin@dev6 srs]$ grep -ina "\[12633\]\[149\]" objs/srs.log
857:[2014-05-27 19:22:56.919][trace][12633][149] serve client, peer ip=127.0.0.1
858:[2014-05-27 19:22:56.921][trace][12633][149] complex handshake with client success
859:[2014-05-27 19:22:56.960][trace][12633][149] rtmp connect app success. tcUrl=rtmp://127.0.0.1:19350/live?vhost=__defaultVhost__, pageUrl=, swfUrl=, schema=rtmp, vhost=__defaultVhost__, port=19350, app=live
860:[2014-05-27 19:22:57.040][trace][12633][149] identify client success. type=publish(FMLEPublish), stream_name=livestream, duration=-1.00
861:[2014-05-27 19:22:57.040][trace][12633][149] set output chunk size to 60000
862:[2014-05-27 19:22:57.040][trace][12633][149] source url=__defaultVhost__/live/livestream, ip=127.0.0.1, cache=1, is_edge=0, id=-1
863:[2014-05-27 19:22:57.123][trace][12633][149] set input chunk size to 60000
864:[2014-05-27 19:22:57.210][trace][12633][149] dispatch metadata success.
865:[2014-05-27 19:22:57.210][trace][12633][149] update video sequence header success. size=46
866:[2014-05-27 19:22:57.210][trace][12633][149] update audio sequence header success. size=4
870:[2014-05-27 19:23:04.970][trace][12633][149] <- CPB time=8117, okbps=4,0,0, ikbps=320,0,0
```

Encoder => Origin => Edge => Player, the whole link log we got directly!

### Reverse Tracable Log

The tracable is finger log from the player to the origin. The reverse tracable log is from the origin to the edge and player.

For example, there is a origin and a edge, to grep the log on origin by keyword `edge-srs`:

```
[winlin@dev6 srs]$ grep -ina "edge-srs" objs/srs.origin.log 
30:[2014-08-06 09:41:31.649][trace][21433][107] edge-srs ip=192.168.1.159, version=0.9.189, pid=21435, id=108
```

We get all edge srs which connectted to this origin, this edge ip is 192.168.1.159, pid is 21435, session id is 108. Then grep the log on the edge:

```
[winlin@dev6 srs]$ grep --color -ina "\[108\]" objs/srs.log 
29:[2014-08-06 10:09:34.579][trace][22314][108] edge pull connected, can_publish=1, url=rtmp://dev:1935/live/livestream, server=127.0.0.1:1936
30:[2014-08-06 10:09:34.591][trace][22314][108] complex handshake success.
31:[2014-08-06 10:09:34.671][trace][22314][108] connected, version=0.9.190, ip=127.0.0.1, pid=22288, id=107
32:[2014-08-06 10:09:34.672][trace][22314][108] out chunk size to 60000
33:[2014-08-06 10:09:34.672][trace][22314][108] ignore the disabled transcode: 
34:[2014-08-06 10:09:34.672][trace][22314][108] edge change from 100 to state 101 (pull).
35:[2014-08-06 10:09:34.672][trace][22314][108] input chunk size to 60000
36:[2014-08-06 10:09:34.672][trace][22314][108] got metadata, width=768, height=320, vcodec=7, acodec=10
37:[2014-08-06 10:09:34.672][trace][22314][108] 46B video sh, codec(7, profile=100, level=32, 0x0, 0kbps, 0fps, 0s)
38:[2014-08-06 10:09:34.672][trace][22314][108] 4B audio sh, codec(10, profile=1, 2channels, 0kbps, 44100HZ), flv(16bits, 2channels, 44100HZ)
39:[2014-08-06 10:09:34.779][trace][22314][107] update source_id=108[108]
46:[2014-08-06 10:09:36.853][trace][22314][110] source url=__defaultVhost__/live/livestream, ip=192.168.1.179, cache=1, is_edge=1, source_id=108[108]
50:[2014-08-06 10:09:44.949][trace][22314][108] <- EIG time=10293, okbps=3,0,0, ikbps=441,0,0
53:[2014-08-06 10:09:47.805][warn][22314][108][4] origin disconnected, retry. ret=1007
```

On this edge, we finger out there is 2 connections which connected on the source, by keyword `source_id=108`:

```
39:[2014-08-06 10:09:34.779][trace][22314][107] update source_id=108[108]
46:[2014-08-06 10:09:36.853][trace][22314][110] source url=__defaultVhost__/live/livestream, ip=192.168.1.179, cache=1, is_edge=1, source_id=108[108]
```

There are 2 connections connected on this source, 107 and 110.

### Any Tracable Log

For SRS support tracalbe and reverse tracable log, so we can got the whold stream delivery log at any point.

For example, a cluster has a origin and an edge, origin ingest stream.

When I know the stream name, or any information, for example, we can grep the keyword `type=Play` for all client to play stream on origin server:

```
[winlin@dev6 srs]$ grep -ina "type=Play" objs/srs.origin.log 
31:[2014-08-06 10:09:34.671][trace][22288][107] client identified, type=Play, stream_name=livestream, duration=-1.00
```

We got session id 107 which play the stream on origin:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The soruce id is 105, specified by `source_id=105`:

```
[winlin@dev6 srs]$ grep --color -ina "\[105\]" objs/srs.origin.log 
16:[2014-08-06 10:09:30.331][trace][22288][105] RTMP client ip=127.0.0.1
17:[2014-08-06 10:09:30.331][trace][22288][105] srand initialized the random.
18:[2014-08-06 10:09:30.332][trace][22288][105] simple handshake success.
19:[2014-08-06 10:09:30.373][trace][22288][105] connect app, tcUrl=rtmp://127.0.0.1:1936/live?vhost=__defaultVhost__, pageUrl=, swfUrl=, schema=rtmp, vhost=__defaultVhost__, port=1936, app=live, args=null
21:[2014-08-06 10:09:30.417][trace][22288][105] client identified, type=publish(FMLEPublish), stream_name=livestream, duration=-1.00
22:[2014-08-06 10:09:30.417][trace][22288][105] out chunk size to 60000
23:[2014-08-06 10:09:30.418][trace][22288][105] source url=__defaultVhost__/live/livestream, ip=127.0.0.1, cache=1, is_edge=0, source_id=-1[-1]
24:[2014-08-06 10:09:30.466][trace][22288][105] got metadata, width=768, height=320, vcodec=7, acodec=10
25:[2014-08-06 10:09:30.466][trace][22288][105] 46B video sh, codec(7, profile=100, level=32, 0x0, 0kbps, 0fps, 0s)
26:[2014-08-06 10:09:30.466][trace][22288][105] 4B audio sh, codec(10, profile=1, 2channels, 0kbps, 44100HZ), flv(16bits, 2channels, 44100HZ)
33:[2014-08-06 10:09:34.671][trace][22288][107] source url=__defaultVhost__/live/livestream, ip=127.0.0.1, cache=1, is_edge=0, source_id=105[105]
38:[2014-08-06 10:09:40.732][trace][22288][105] <- CPB time=10100, okbps=3,0,0, ikbps=332,0,0
```

This source is the ingest stream source, we got the root source.

And we got 107 which is srs edge connection, by keyword `edge-srs`:

```
30:[2014-08-06 10:09:34.631][trace][22288][107] edge-srs ip=192.168.1.159, version=0.9.190, pid=22314, id=108
```

Find the log on edge, the session id is 108:

```
[winlin@dev6 srs]$ grep --color -ina "\[108\]" objs/srs.log 
29:[2014-08-06 10:09:34.579][trace][22314][108] edge pull connected, can_publish=1, url=rtmp://dev:1935/live/livestream, server=127.0.0.1:1936
30:[2014-08-06 10:09:34.591][trace][22314][108] complex handshake success.
31:[2014-08-06 10:09:34.671][trace][22314][108] connected, version=0.9.190, ip=127.0.0.1, pid=22288, id=107
32:[2014-08-06 10:09:34.672][trace][22314][108] out chunk size to 60000
33:[2014-08-06 10:09:34.672][trace][22314][108] ignore the disabled transcode: 
34:[2014-08-06 10:09:34.672][trace][22314][108] edge change from 100 to state 101 (pull).
35:[2014-08-06 10:09:34.672][trace][22314][108] input chunk size to 60000
36:[2014-08-06 10:09:34.672][trace][22314][108] got metadata, width=768, height=320, vcodec=7, acodec=10
37:[2014-08-06 10:09:34.672][trace][22314][108] 46B video sh, codec(7, profile=100, level=32, 0x0, 0kbps, 0fps, 0s)
38:[2014-08-06 10:09:34.672][trace][22314][108] 4B audio sh, codec(10, profile=1, 2channels, 0kbps, 44100HZ), flv(16bits, 2channels, 44100HZ)
39:[2014-08-06 10:09:34.779][trace][22314][107] update source_id=108[108]
46:[2014-08-06 10:09:36.853][trace][22314][110] source url=__defaultVhost__/live/livestream, ip=192.168.1.179, cache=1, is_edge=1, source_id=108[108]
50:[2014-08-06 10:09:44.949][trace][22314][108] <- EIG time=10293, okbps=3,0,0, ikbps=441,0,0
53:[2014-08-06 10:09:47.805][warn][22314][108][4] origin disconnected, retry. ret=1007
```

We got the edge source 108, and there are 2 clients connected on this source 107 and 110, specified by keyword `source_id=108`:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The 107 is a client which trigger the edge to fetch stream from origin. Find 110:

```
[winlin@dev6 srs]$ grep --color -ina "\[110\]" objs/srs.log
40:[2014-08-06 10:09:36.609][trace][22314][110] RTMP client ip=192.168.1.179
41:[2014-08-06 10:09:36.613][trace][22314][110] complex handshake success
42:[2014-08-06 10:09:36.613][trace][22314][110] connect app, tcUrl=rtmp://dev:1935/live, pageUrl=http://www.ossrs.net/players/srs_player.html?vhost=dev&stream=livestream&server=dev&port=1935, swfUrl=http://www.ossrs.net/players/srs_player/release/srs_player.swf?_version=1.23, schema=rtmp, vhost=__defaultVhost__, port=1935, app=live, args=null
43:[2014-08-06 10:09:36.835][trace][22314][110] ignored. set buffer length to 800
44:[2014-08-06 10:09:36.853][trace][22314][110] client identified, type=Play, stream_name=livestream, duration=-1.00
45:[2014-08-06 10:09:36.853][trace][22314][110] out chunk size to 60000
46:[2014-08-06 10:09:36.853][trace][22314][110] source url=__defaultVhost__/live/livestream, ip=192.168.1.179, cache=1, is_edge=1, source_id=108[108]
47:[2014-08-06 10:09:36.853][trace][22314][110] dispatch cached gop success. count=95, duration=1573
48:[2014-08-06 10:09:36.853][trace][22314][110] create consumer, queue_size=30.00, tba=44100, tbv=25
49:[2014-08-06 10:09:36.853][trace][22314][110] ignored. set buffer length to 800
51:[2014-08-06 10:09:45.919][trace][22314][110] -> PLA time=8759, msgs=21, okbps=461,0,0, ikbps=3,0,0
52:[2014-08-06 10:09:46.247][warn][22314][110][104] client disconnect peer. ret=1004
```

The 110 is a flash player client.

### System info

The system info and port listen at:

```
/* Detailed source-code truncated for AI context efficiency. */
```

It means:
* <strong>The log file path</strong>：[2014-04-04 11:39:24.176][trace][0][0] log file is ./objs/srs.log
* <strong>SRS version</strong>：[2014-04-04 11:39:24.177][trace][0][0] srs 0.9.46
* <strong>Compile info</strong>：[2014-04-04 11:39:24.177][trace][0][0] uname: Linux dev6 2.6.32-71.el6.x86_64 
#1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux
* <strong>Compile date</strong>：[2014-04-04 11:39:24.177][trace][0][0] build: 2014-04-03 18:38:23, little-endian
* <strong>Build options</strong>：[2014-04-04 11:39:24.177][trace][0][0] configure:  --dev --with-hls --with-nginx 
--with-ssl --with-ffmpeg --with-http-callback --with-http-server --with-http-api --with-librtmp 
--with-bwtc --with-research --with-utest --without-gperf --without-gmc --without-gmp 
--without-gcp --without-gprof --without-arm-ubuntu12 --jobs=1 --prefix=/usr/local/srs
* <strong>PID file</strong>：[2014-04-04 11:39:24.177][trace][0][0] write pid=4021 to ./objs/srs.pid success!
* <strong>Listen at port 1935（RTMP）</strong>：[2014-04-04 11:39:24.177][trace][100][16] server started, listen at port=1935, type=0, fd=6
* <strong>Listen at port 1985（HTTP接口）</strong>：[2014-04-04 11:39:24.177][trace][100][16] server started, listen at port=1985, type=1, fd=7
* <strong>Listen at port 8080（HTTP服务）</strong>：[2014-04-04 11:39:24.177][trace][100][16] server started, listen at port=8080, type=2, fd=8
* <strong>Ready for connections</strong>：[2014-04-04 11:39:24.177][trace][101][16] listen cycle start, port=1935, type=0, fd=6

### Session oriented log

SRS provides session oriented log.

For example, SRS running for 365 days, served 10000000 clients, how to find a specified client log?

We need something to grep, for instance, we know the stream url: `rtmp://192.168.1.107:1935/live/livestream`, then we can find the keyword to grep by research the publish log:

```bash
[2014-04-04 11:56:06.074][trace][104][11] rtmp get peer ip success. ip=192.168.1.179, 
send_to=30000000us, recv_to=30000000us
[2014-04-04 11:56:06.080][trace][104][11] srand initialized the random.
[2014-04-04 11:56:06.082][trace][104][11] simple handshake with client success.
[2014-04-04 11:56:06.083][trace][104][11] rtmp connect app success. 
tcUrl=rtmp://192.168.1.107:1935/live, pageUrl=, swfUrl=rtmp://192.168.1.107:1935/live, 
schema=rtmp, vhost=__defaultVhost__, port=1935, app=live
[2014-04-04 11:56:06.288][trace][104][11] set ack window size to 2500000
[2014-04-04 11:56:06.288][trace][104][11] identify ignore messages except AMF0/AMF3 
command message. type=0x5
[2014-04-04 11:56:06.288][trace][104][11] identify client success. 
type=publish(FMLEPublish), stream_name=livestream
```

The keyword to grep:
* Use keyword `identify client success`, then `type=publish`, then `livestream`.
* Or, use keyword `identify client success. type=publish`, then `livestream`.
* We can grep all `identify client success. type=publish`, and research the result.

For example:

```bash
[winlin@dev6 srs]$ cat objs/srs.log|grep -ina "identify client success. type=publish"
20:[2014-04-04 11:56:06.288][trace][104][11] identify client success. type=publish, stream_name=livestream
43:[2014-04-04 11:56:18.138][trace][105][11] identify client success. type=publish, stream_name=winlin
65:[2014-04-04 11:56:29.531][trace][106][11] identify client success. type=publish, stream_name=livestream
86:[2014-04-04 11:56:35.966][trace][107][11] identify client success. type=publish, stream_name=livestream
```

There are some publish stream, and we can grep specified streamname.

```bash
[winlin@dev6 srs]$ cat objs/srs.log|grep -ina "identify client success. type=publish"|grep -a "livestream"
20:[2014-04-04 11:56:06.288][trace][104][11] identify client success. type=publish, stream_name=livestream
65:[2014-04-04 11:56:29.531][trace][106][11] identify client success. type=publish, stream_name=livestream
86:[2014-04-04 11:56:35.966][trace][107][11] identify client success. type=publish, stream_name=livestream
```

We can filter the result by time, for example, we use session id 104 to grep by keyword `\[104\]\[`:
```
/* Detailed source-code truncated for AI context efficiency. */
```

Then we got the log for this session, and client closed connection by log: `36:[2014-04-04 11:56:12.620][error][104][104] identify client failed. ret=207(Connection reset by peer)`.

## Daemon

When default SRS only print less log? Because SRS default use `conf/srs.conf` in daemon mode and print to log file.

When enable daemon, then no need to start by nohup:

```bash
# whether start as deamon
# default: on
daemon              on;
```

Use `conf/console.conf` to not start in daemon and log to conosle.

```bash
# no-daemon and write log to console config for srs.
# @see full.conf for detail config.

listen              1935;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {
}
```

Startup command:

```bash
./objs/srs -c conf/console.conf 
```

To startup with default config `conf/srs.conf`:

```bash
[winlin@dev6 srs]$ ./objs/srs -c conf/srs.conf 
[2014-04-14 12:12:57.775][trace][0][0] config parse complete
[2014-04-14 12:12:57.775][trace][0][0] write log to file ./objs/srs.log
[2014-04-14 12:12:57.775][trace][0][0] you can: tailf ./objs/srs.log
[2014-04-14 12:12:57.775][trace][0][0] @see https://ossrs.io/lts/en-us/docs/v4/doc/log
```

Winlin 2014.10

---

### Trunk 3rdparty Srs Docs Doc Nginx Exec (`trunk/3rdparty/srs-docs/doc/nginx-exec.md`)

---
title: Nginx RTMP EXEC
sidebar_label: Nginx RTMP EXEC
hide_title: false
hide_table_of_contents: false
---

# Exec

## NGINX RTMP EXEC

SRS only support some exec introduced by NGINX RTMP:

1. exec/exec_publish: Support.
1. exec_pull: Not support.
1. exec_play: Not support.
1. exec_record_done: Not support.

> Note: You could use [HTTP Callback](./http-callback.md) to start FFmpeg on your backend server. It's much better solution.

## Config

The config for SRS EXEC list bellow, you can refer to `conf/exec.conf`.

```
vhost __defaultVhost__ {
    # the exec used to fork process when got some event.
    exec {
        # whether enable the exec.
        # default: off.
        enabled     off;
        # when publish stream, exec the process with variables:
        #       [vhost] the input stream vhost.
        #       [port] the intput stream port.
        #       [app] the input stream app.
        #       [stream] the input stream name.
        #       [engine] the tanscode engine name.
        # other variables for exec only:
        #       [url] the rtmp url which trigger the publish.
        #       [tcUrl] the client request tcUrl.
        #       [swfUrl] the client request swfUrl.
        #       [pageUrl] the client request pageUrl.
        # @remark empty to ignore this exec.
        publish     ./objs/ffmpeg/bin/ffmpeg -f flv -i [url] -c copy -y ./[stream].flv;
    }
}
```

Winlin 2015.8

[ne]: https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec

---

### Trunk 3rdparty Srs Docs Doc Perf (`trunk/3rdparty/srs-docs/doc/perf.md`)

---
title: Perf Analysis
sidebar_label: Perf Analysis 
hide_title: false
hide_table_of_contents: false
---

# Perf

Please read [SRS性能(CPU)、内存优化工具用法](https://www.jianshu.com/p/6d4a89359352)

---

### Trunk 3rdparty Srs Docs Doc Raspberrypi (`trunk/3rdparty/srs-docs/doc/raspberrypi.md`)

---
title: RaspBerryPi
sidebar_label: RaspBerryPi
hide_title: false
hide_table_of_contents: false
---

# Performance benchmark for SRS on RaspberryPi

SRS can running on armv6(RaspberryPi) or armv7(Android). 
The bellow data show the performance benchmark.

## Install SRS

Download the binary for armv6 from [Github](http://ossrs.net/srs.release/releases/) 
or [SRS Server](http://ossrs.net/srs/releases/)

## RaspberryPi

The hardware of raspberrypi:
* [RaspberryPi](http://item.jd.com/1014155.html)：Type B
* <strong>SoC</strong> BroadcomBCM2835(CPU,GPU,DSP,SDRAM,USB)
* <strong>CPU</strong> ARM1176JZF-S(ARM11) 700MHz
* <strong>GPU</strong> Broadcom VideoCore IV, OpenGL ES 2.0, 1080p 30 h.264/MPEG-4 AVC decoder
* <strong>RAM</strong> 512MByte
* <strong>USB</strong> 2 x USB2.0
* <strong>VideoOutput</strong> Composite RCA(PAL&NTSC), HDMI(rev 1.3&1.4), raw LCD Panels via DSI 14 HDMI resolution from 40x350 to 1920x1200 plus various PAL and NTSC standards
* <strong>AudioOutput</strong> 3.5mm, HDMI
* <strong>Storage</strong> SD/MMC/SDIO socket
* <strong>Network</strong> 10/100 ethernet
* <strong>Device</strong> 8xGPIO, UART, I2C, SPI bus, +3.3V, +5V, ground(nagetive)
* <strong>Power</strong> 700mA(3.5W) 5V
* <strong>Size</strong> 85.60 x 53.98 mm(3.370 x 2.125 in)
* <strong>OS</strong> Debian GNU/linux, Fedora, Arch Linux ARM, RISC OS, XBMC

Software:
* RaspberryPi img：2014-01-07-wheezy-raspbian.img
* <strong>uname</strong>: Linux raspberrypi 3.10.25+ #622 PREEMPT Fri Jan 3 18:41:00 GMT 2014 armv6l GNU/Linux
* <strong>cpu</strong>: arm61
* <strong>Server</strong>: srs 0.9.38
* <strong>ServerType</strong>: raspberry pi
* <strong>Client</strong>：[srs-bench](https://github.com/ossrs/srs-bench)
* <strong>ClientType</strong>: Virtual Machine Centos6
* <strong>Play</strong>: PC win7, flash
* <strong>Network</strong>: 100Mbps

Stream information:
* Video Bitrate: 200kbps
* Resolution: 768x320
* Audio Bitrate: 30kbps

For arm [SRS: arm](./arm.md#raspberrypi)

## OS settings

Login as root, set the fd limits:

* Set limit: `ulimit -HSn 10240`
* View the limit:

```bash
[root@dev6 ~]# ulimit -n
10240
```

* Restart SRS：`sudo /etc/init.d/srs restart`

## Publish and Play

Use centos to publish to SRS:

* Start FFMPEG:

```bash
for((;;)); do \
    ./objs/ffmpeg/bin/ffmpeg \
        -re -i doc/source.flv \
        -acodec copy -vcodec copy \
        -f flv rtmp://192.168.1.105:1935/live/livestream; \
    sleep 1; 
done
```

* Play RTMP: `rtmp://192.168.1.105:1935/live/livestream`
* Online Play: [Online Player](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)

## Client

The RTMP load test tool, read [srs-bench](https://github.com/ossrs/srs-bench)

The sb_rtmp_load used to test RTMP load, support 800-3k concurrency for each process.

* Build: `./configure && make`
* Start: `./objs/sb_rtmp_load -c 800 -r <rtmp_url>`

## Record Data

Record data before test:

* The cpu for SRS:

```bash
pid=`ps aux|grep srs|grep objs|awk '{print $2}'` && top -p $pid
```

* The cpu for srs-bench:

```bash
pid=`ps aux|grep load|grep rtmp|awk '{print $2}'` && top -p $pid
```

* The connections:

```bash
for((;;)); do \
    srs_connections=`sudo netstat -anp|grep 1935|grep ESTABLISHED|wc -l`;  \
    echo "srs_connections: $srs_connections";  \
    sleep 5;  \
done
```

* The bandwidth in NBps:

```bash
[winlin@dev6 ~]$ dstat 30
----total-cpu-usage---- -dsk/total- -net/lo- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
  0   0  96   0   0   3|   0     0 |1860B   58k|   0     0 |2996   465 
  0   1  96   0   0   3|   0     0 |1800B   56k|   0     0 |2989   463 
  0   0  97   0   0   2|   0     0 |1500B   46k|   0     0 |2979   461 
```

* The table

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------ | ------- | ---------- | ---------- | ------- | ------- |
| SRS | 1.0% | 3MB | 3 | - | - | - | 0.8s |

Memory(Mem): The memory usage for server.

Clients(Conn): The cocurrency connections to server.

ExpectNbps(ENbps): The expect network bandwidth in Xbps.

ActualNbps(ANbps): The actual network bandwidth in Xbps.

## Benchmark SRS 0.9.38

Let's start performance benchmark.

* The data for 10 clients:

```bash
./objs/sb_rtmp_load -c 10 -r rtmp://192.168.1.105:1935/live/livestream >/dev/null &
```

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------ | ------- | ---------- | ---------- | ------- | ------- |
| SRS | 17% | 1.4MB | 11 | 2.53Mbps | 2.6Mbps | 1.3% | 1.7s |

* The data for 20 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------ | ------- | ---------- | ---------- | ------- | ------- |
| SRS | 23% | 2MB | 21 | 4.83Mbps | 5.5Mbps | 2.3% | 1.5s |

* The data for 30 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------ | ------- | ---------- | ---------- | ------- | ------- |
| SRS | 50% | 4MB | 31 | 7.1Mbps | 8Mbps | 4% | 2s |

The summary for RaspberryPi Type B, 230kbps performance:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------ | ------- | ---------- | ---------- | ------- | ------- |
| SRS | 17% | 1.4MB | 11 | 2.53Mbps | 2.6Mbps | 1.3% | 1.7s |
| SRS | 23% | 2MB | 21 | 4.83Mbps | 5.5Mbps | 2.3% | 1.5s |
| SRS | 50% | 4MB | 31 | 7.1Mbps | 8Mbps | 4% | 2s |

## Benchmark SRS 0.9.72

The benchmark for RTMP SRS 0.9.72.

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------ | ------- | ---------- | ---------- | ------- | ------- |
| SRS | 5% | 2MB | 2 | 1Mbps | 1.2Mbps | 0% | 1.5s |
| SRS | 20% | 2MB | 12 | 6.9Mbps | 6.6Mbps | 2.8% | 2s |
| SRS | 36% | 2.4MB | 22 | 12.7Mbps | 12.9Mbps | 2.3% | 2.5s |
| SRS | 47% | 3.1MB | 32 | 18.5Mbps | 18.5Mbps | 5% | 2.0s |
| SRS | 62% | 3.4MB | 42 | 24.3Mbps | 25.7Mbps | 9.3% | 3.4s |
| SRS | 85% | 3.7MB | 52 | 30.2Mbps | 30.7Mbps | 13.6% | 3.5s |

## cubieboard benchmark

No data.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Reload (`trunk/3rdparty/srs-docs/doc/reload.md`)

---
title: Reload
sidebar_label: Reload
hide_title: false
hide_table_of_contents: false
---

# Reload

Almost all features of SRS support reload, donot disconnect 
all connection and apply the new config.

## NotSupportedFeatures

The bellow features can not reload:
* deamon: whether start as deamon mode.
* mode: the mode of vhost.

The daemon never support reload.

The mode of vhost, to make the vhost origin or edge, should never directly 
change the mode, because of:

* The origin and edge switch is too complex.
* The origin always put in a device group, never change to edge actually.
* The upnode or origin restart have no effect to user, edge will retry.

A workaround to modify the mode of vhost:
* Delete the vhost and reload.
* Ensure the vhost is deleted, for the reload is async.
* Add vhost with new mode, then reload.

## Use Scenario

The use scenario of reload:
* Donot restart server to apply new config, only `killall -1 srs`.
* Donot disconnect user connections.

## Usage

The usage of reload: `killall -1 srs`

Or send signal to process: `kill -1 7635`

Or use SRS scripts: `/etc/init.d/srs reload`

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Reuse Port (`trunk/3rdparty/srs-docs/doc/reuse-port.md`)

---
title: Reuse Port
sidebar_label: Reuse Port
hide_title: false
hide_table_of_contents: false
---

# Reuse Port

You can use REUSE_PORT for different use scenarios.

## For Edge Server

The [performance of SRS2](https://github.com/ossrs/srs/tree/2.0release#performance) is improved huge, but is it enough?
Absolutely NOT! In SRS3, we provide [OriginCluster](./sample-origin-cluster.md) for multiple origin servers to work together,
and [go-oryx](https://github.com/ossrs/go-oryx) as a tcp proxy for edge server, and these are not good enough, so we support
SO_REUSEPORT feature for multiple processes edge server.



> Remark: The SO_REUSEPORT requires Linux Kernel 3.9+, so you should upgrade your kernel for CentOS6, or you could choose Ubuntu20.

First, we start a edge server which listen at 1935:

```
./objs/srs -c conf/edge.conf
```

Then, at the same server, start another edge server which also listen at 1935:

```
./objs/srs -c conf/edge2.conf
```

> Note: They should use different pid file, or it will fail to start the second edge server.

There are two SRS edge servers:

```
[root@bf2e88b31f9b trunk]# ps aux|grep srs
root       381  0.1  0.0  19888  5752 pts/2    S+   08:03   0:01 ./objs/srs -c conf/edge.conf
root       383  0.0  0.0  19204  5468 pts/1    S+   08:04   0:00 ./objs/srs -c conf/edge2.conf

[root@bf2e88b31f9b trunk]# lsof -p 381
srs     381 root    7u     IPv6  18835      0t0        TCP *:macromedia-fcs (LISTEN)
[root@bf2e88b31f9b trunk]# lsof -p 383
srs     383 root    7u     IPv6  17831      0t0        TCP *:macromedia-fcs (LISTEN)
```

After that, we start the origin server, from which these edge server to pull streams:

```
./objs/srs -c conf/origin.conf 
```

Finally, we could publish to origin/edge, and play stream from each edge server:

```
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Use VLC to play the RTMP stream: `rtmp://192.168.1.170:1935/live/livestream`

## For Origin Server

You can use REUSE_PORT in Origin Server. Each Origin Server is isolated, only works for HLS:

```
              +-----------------+
Client --->-- + Origin Servers  +------> Player
              +-----------------+
```

> Note: If need to deliver RTMP or HTTP-FLV, pelease use [OriginCluster](./sample-origin-cluster.md).

Start the first Origin Server, listen at `1935` and `8080`, covert RTMP to HLS:

```bash
./objs/srs -c conf/origin.hls.only1.conf
```

Start the second Origin Server, listen at `1935` and `8080`, covert RTMP to HLS:

```bash
./objs/srs -c conf/origin.hls.only2.conf
```

Publish stream to origin, system will select a random Origin Server:

```bash
./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream1
```

Publish another stream to origin, system will select a random Origin Server:

```bash
./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream2
```

> Note: It works only for HLS, please use [OriginCluster](./sample-origin-cluster.md) for RTMP or HTTP-FLV.

---

### Trunk 3rdparty Srs Docs Doc Rtmp Atc (`trunk/3rdparty/srs-docs/doc/rtmp-atc.md`)

---
title: RTMP ATC
sidebar_label: RTMP ATC
hide_title: false
hide_table_of_contents: false
---

# ATC Deploy

How to deploy RTMP fault backup? When origin for edge restart, edge will 
switch to another origin, so it is easy to config fault tolerance for edge,
only need to specifies multiple origin servers.

How to deploy HLS fault backup? When edge can not got a piece of ts, it
will fetch from another origin server, so the ts in these two server must
be absolutely equals. We must use atc for HLS/HDS which over http file stream.

For the deploy of HDS/HLS, read [Adobe: HDS/HLS fault backup](http://www.adobe.com/cn/devnet/adobe-media-server/articles/varnish-sample-for-failover.html):

```bash
                        +----------+        +----------+
               +--ATC->-+  server  +--ATC->-+ packager +-+   +---------+
+----------+   | RTMP   +----------+ RTMP   +----------+ |   | Reverse |    +-------+
| encoder  +->-+                                         +->-+  Proxy  +-->-+  CDN  +
+----------+   |        +----------+        +----------+ |   | (nginx) |    +-------+
               +--ATC->-+  server  +--ATC->-+ packager +-+   +---------+
                 RTMP   +----------+ RTMP   +----------+
```

The RTMP is in ATC, the absolute time, so server or other tools can output
HLS in multiple tools.

## Config ATC on SRS

ATC of SRS is default off, the RTMP timestamp to client always start at 0.

```bash
vhost __defaultVhost__ {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # vhost for atc for hls/hds/rtmp backup.
        # generally, atc default to off, server delivery rtmp stream to client(flash) timestamp from 0.
        # when atc is on, server delivery rtmp stream by absolute time.
        # atc is used, for instance, encoder will copy stream to master and slave server,
        # server use atc to delivery stream to edge/client, where stream time from master/slave server
        # is always the same, client/tools can slice RTMP stream to HLS according to the same time,
        # if the time not the same, the HLS stream cannot slice to support system backup.
        #
        # @see http://www.adobe.com/cn/devnet/adobe-media-server/articles/varnish-sample-for-failover.html
        # @see http://www.baidu.com/#wd=hds%20hls%20atc
        #
        # default: off
        atc             off;
    }
}
```

## ATC for Adobe Flash Player

When ATC is on, flash will start play ok when:
* sequence header: The timstamp of sequence header must equals to the first packet.
* metadata: The timstamp of metadata must equals to the first packet.

We test the flash player, it ok to play the RTMP stream with or without ATC.

## ATC for encoder

The encoder can control the atc of SRS, when encoder write a field 
"bravo_atc":"true".

We can disable this feature:

```bash
vhost atc.srs.com {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # whether enable the auto atc,
        # if enabled, detect the bravo_atc="true" in onMetaData packet,
        # set atc to on if matched.
        # always ignore the onMetaData if atc_auto is off.
        # default: off
        atc_auto        off;
    }
}
```

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Rtmp Handshake (`trunk/3rdparty/srs-docs/doc/rtmp-handshake.md`)

---
title: RTMP Handshake
sidebar_label: RTMP Handshake
hide_title: false
hide_table_of_contents: false
---

# RTMP Handshake

The rtmp specification 1.0 defines the RTMP handshake:
* c0/s0: 1 bytes, specifies the protocol is RTMP or RTMPE/RTMPS.
* c1/s1: 1536 bytes, first 4 bytes is time, next 4 bytes is 0x00, 1528 random bytes.
* c2/s2: 1536 bytes, first 4 bytes is time echo, next 4 bytes is time, 1528 bytes c2==s1 and s2==c1.
This is the simple handshake, the standard handshake, and the FMLE use this handshake.

While the server connected by flash player only support simple handshake, the flash player can only play the vp6 codec, and do not support h.264+aac. Adobe changed the simple handshake to encrypted complex handshake, see: [Changed Handshake of RTMP](http://blog.csdn.net/win_lin/article/details/13006803)

The handshake summary: | 

| Handshake | Depends | Player | Client | SRS | Use Scenario |
| ---- | ----- | --------------------- | -------- | --- | ---- |
| Simple<br/>Standard | No | vp6+mp3/speex | All | Supprted | Encoder, for examle, FMLE, FFMPEG |
| Complex | openssl | vp6+mp3/speex<br/>h264+aac | Flash | Supported | Flash player requires complex handshake to play h.264+aac codec. |

Player(Flash palyer): The supported codec for flash player.

Notes: When compile SRS with SSL, SRS will try complex, then simple.

Winlin 2014.10

---

### Trunk 3rdparty Srs Docs Doc Rtmp Pk Http (`trunk/3rdparty/srs-docs/doc/rtmp-pk-http.md`)

---
title: RTMP vs HTTP
sidebar_label: RTMP vs HTTP
hide_title: false
hide_table_of_contents: false
---

# RTMP PK HTTP

There are two major methods to deliver video over internet, Live and WebRTC.

* Live streaming: [HLS](./hls.md), [RTMP](./rtmp.md) and [HTTP-FLV](./flv.md) for entertainment.
* WebRTC: [RTC](./webrtc.md), for communication.

Ignore other delivery protocol, which is not used on internet:
* UDP: Private protocols, realtime protocol, latence in ms.
* P2P: FlashP2P of Adobe, others are private protocol. Large latence, in minutes.
* RTSP: Private protocol not for internet.

And the protocol base on HTTP:
* HTTP progressive: Ancient protocol, not used now.
* HTTP stream: Support seek in query string, for instance, http://x/x.mp4?start=x.
* HLS: The HLS is developed by Apple. Both Apple and Android support it.
* HDS: The HLS like developed by Adobe, shit.
* DASH: The HLS like developed by some companies, not used in China.

Compare the delivery methods on internet:

* HLS: Apple HLS, for both live and vod.
* HTTP: HTTP stream, private http stream, for vod.
* RTMP: Adobe RTMP, for live stream.

## RTMP

The RTMP is stream protocol, good for:
* Realtime: RTMP latency can be 0.8-3s.
* DRM: RTMPE/RTMPS encrypt protocol.
* Stable for PC flash.
* Server input: The actual industrial standard for encoder to output to server is RTMP.
* Fault Tolerance: The RTMP edge-origin can support fault tolerance for stream protocol.
* Monitor: The stream protocol can be monitored.

RTMP is bad for:
* Complex: RTMP is more complex than HTTP, especially the edge.
* Hard to cache: Must use edge to cache.

## HTTP

The HTTP stream is the vod stream used for some video website:

HTTP is delivery files, good for:
* High performance: There are lots of good HTTP server, such as nginx, squid, traffic server.
* No small piece of file: The large file is good than pieces of file for HTTP cache.
* Firewall traverse: Almost all firewall never block the HTTP protocol.

HTTP is bad for:
* Large lantency: The http stream atleast N10s latency.
* Player does not support: Only PC flash can play http stream. Mobile platform does not support http stream.

## HLS

HLS is the open standard of Apple. HLS is supported by Android3+.

HLS is good for:
* High performance: Same to HTTP stream.
* Firewall traverse: Same to HTTP stream.
* Mobile Platform standard: Apple IOS/OSX, Android and PC/flash support HLS.

HLS is bad for:
* Large lantency: The http stream atleast N10s latency.
* Pieces of file: CDN does not like small file.

## Use Scenario

See [HTTP](./hls.md)
and [RTMP](./rtmp.md)

I recomment to use these delivery protocols in:
* Encoder always output RTMP for internet server.
* Server always accept RTMP from encoder.
* The cluster use RTMP as internal delivery protocol.
* The low latency application on PC: Use flash to play RTMP.
* Application without low latency required: RTMP or HLS.
* The vod stream on PC: Use HLS or HTTP stream.
* Apple IOS/OSX: Always use HLS. Or use library to play RTMP, like [https://www.vitamio.org](https://www.vitamio.org)
* Android: Always use HLS. Or use library to play RTMP.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Rtmp Url Vhost (`trunk/3rdparty/srs-docs/doc/rtmp-url-vhost.md`)

---
title: RTMP URL
sidebar_label: RTMP URL
hide_title: false
hide_table_of_contents: false
---

# RTMP URL/Vhost

The url of RTMP is simple, and the vhost is not a new concept, although it's easy to confuse for the fresh.
What is vhost? What is app? Why FMLE should input the app and stream?

Vhost(Virtual Host) is used to seperate customers or businesses.
Let's take a look at the typical use scenaio of vhost.



The benifit of RTMP and HLS, see: [HLS](./hls.md)

## Use Scenario

The use scenario of vhost:
* Multiple customers cloud: For example, CDN(content delivery network) serves multiple customers. How does CDN to seperate customer and stat the data? Maybe stream path is duplicated, for example, live/livestream is the most frequently used app and stream. The vhost, similar to the virtual server, provides abstract for multiple customers.
* Different config: For example, FMLE publish h264+mp3, which should be transcoded to h264+aac. We can use vhost to use different config, h264+mp3 disabled hls while the h264+aac vhost enalbe hls.

In a word, vhost is the element of config, to seperate customer and apply different config.

## Standard RTMP URL

Standard RTMP URL is the most compatible URL, for all servers and players can identify. The RTMP URL is similar to the HTTP URL:

| HTTP | Schema | Host | Port | App | Stream |
| ----- | ----- | ----- | ----| ---- | ---- |
| http://192.168.1.10:80/players/srs_player.html | http | 192.168.1.10 | 80 | players | srs_player.html|
| rtmp://192.168.1.10:1935/live/livestream | rtmp | 192.168.1.10 | 1935 | live | livestream |

It is:
* Schema：The protocol prefix, HTTP/HTTPS for HTTP protocol, and RTMP/RTMPS/RTMPE/RTMPT for RTMP protocol, while the RTMFP is adobe flash p2p protocol.
* Host：The server ip or dns name to connect to. It is dns name for CDN, and the dns name is used as the vhost for the specified customer.
* Port：The tcp port, default 80 for HTTP and 1935 for RTMP.
* Path：The http file path for HTTP.
* App：The application for RTMP, similar to the directory of resource(stream).
* Stream：The stream for RTMP, similar to the resource(file) in specified app.

## NO Vhost

However, most user donot need the vhost, and it's a little complex, so donot use it when you donot need it. Most user actually only need app and stream.

When to use vhost? When you serve 100+ customers and use the same delivery network, they use theire own vhost and can use the sample app and stream.

The common use scenario, for example, if you use SRS to build a video website. So you are the only customer, donot need vhost. Suppose you provides video chat, there are some categories which includes some chat rooms. For example, categories are military, reader, history. The military category has rooms rock, radar; the reader category has red_masion. The config of SRS is very simple:

```bash
listen              1935;
vhost __defaultVhost__ {
}
```

When generate web pages, for instance, military category, all app is `military`. The url of chat room is `rtmp://yourdomain.com/military/rock`, while the encoder publish this stream, and all player play this stream.

The other pages of the military category use the same app name `military`, but use the different stream name, fr example, radar chat room use the stream url `rtmp://yourdomain.com/military/radar`.

When generate the pages, add new stream, the config of SRS no need to change. For example, when add a new chat room cannon, no need to change config of SRS. It is simple enough!

The reader category can use app `reader`, and the `red_mansion` chat room can use the url `rtmp://yourdomain.com/reader/red_mansion`.

## Vhost Use Scenarios

The vhost of RTMP is same to HTTP virtual server. For example, the demo.srs.com is resolve to 192.168.1.10 by dns or hosts:

| HTTP | Host | Port | Vhost |
| --- | --- | --- | ----- |
| http://demo.srs.com:80/players/srs_player.html | 192.168.1.10 | 80 | demo.srs.com |
| rtmp://demo.srs.com:1935/live/livestream | 192.168.1.10 | 1935 | demo.srs.com |

The use scenario of vhost:
* Multiple Customers: When need to serve multiple customers use the same network, for example, cctv and wasu delivery stream on the same CDN, how to seperate them, when they use the same app and stream?
* DNS scheduler: When CDN delivery content, the fast edge for the specified user is resolved for the dns name. We can use vhost as the dns name to scheduler user to different edge.
* Multiple Config sections: Sometimes we need different config, for example, to delivery RTMP for PC and transcode RTMP to HLS for android and IOS, we can use one vhost to delivery RTMP and another for HLS.

### Multiple Customers

For example, we got two customers cctv and wasu, use the same edge server 192.168.1.10, when user access the stream of these two customers:

| RTMP | Host | Port | Vhost | App | Stream |
| --- | --- | -------| ----- | ---| --------|
|  rtmp://show.cctv.cn/live/livestream | 192.168.1.10 | 1935 | show.cctv.cn | live | livestream |
|  rtmp://show.wasu.cn/live/livestream | 192.168.1.10 | 1935 | show.wasu.cn | live | livestream |

The config on the edge 192.168.1.10, need to config the vhost:

```bash
listen              1935;
vhost show.cctv.cn {
}
vhost show.wasu.cn {
}
```

### DNS GSLB

Please refer to the tech for DNS and CDN.

### Config Unit

For example, two customers cctv and wasu, and cctv needs mininum latency, while wasu needs fast startup. 

Then we config the cctv without gop cache, and wasu config with gop cache:

```bash
listen              1935;
vhost show.cctv.cn {
    chunk_size 128;
}
vhost show.wasu.cn {
    chunk_size 4096;
}
```

These two vhosts is completely isolated.

## Default Vhost

The default vhost is \_\_defaultVhost\_\ introduced by FMS. When mismatch and vhost not found, use the default vhost if configed.

For example, the config of SRS on 192.168.1.10:

```bash
listen              1935;
vhost demo.srs.com {
}
```

Then, when user access the vhost:
* rtmp://demo.srs.com/live/livestream：OK, matched vhost is demo.srs.com.
* rtmp://192.168.1.10/live/livestream：Failed, no matched vhost, and no default vhost.

The rule of default vhost is same to other vhost, the default is used for the vhost not matched and not find.

## Locate Vhost

There are two ways to access the vhost on server:
* DNS name: When access the dns name equals to the vhost, by dns resolve or hosts file, we can access the vhost on server.
* Stream parameters: While publishing or playing stream, the parameter can take the vhost. This needs the server supports this way, for example, SRS can use parameter `?vhost=VHOST` and `?domain=VHOST` to access specified vhost.

For example:

```bash
RTMP URL: rtmp://demo.srs.com/live/livestream
Edge servers: 50 servers
Edge server ip: 192.168.1.100 to 192.168.1.150
Edge SRS config:
    listen              1935;
    vhost demo.srs.com {
        mode remote;
        origin: xxxxxxx;
    }
```

The ways to access the url on edge servers:

| User   | RTMP URL | hosts                      | Target                   |
|--------| -------- |----------------------------|--------------------------|
| User   | rtmp://demo.srs.com/live/livestream | -                          | Resolved by DNS          |
| DevOps | rtmp://demo.srs.com/live/livestream | 192.168.1.100 demo.srs.com | Connect to 192.168.1.100 |
| DevOps     | rtmp://192.168.1.100/live?<br/>vhost=demo.srs.com/livestream | -                          | Connect to 192.168.1.100       |
| DevOps     | rtmp://192.168.1.100/live<br/>...vhost...demo.srs.com/livestream | -                          | Connect to 192.168.1.100       |

It is sample way to access other servers.

## Parameters in URL

There is no parameters for RTMP URL, similar to query string of HTTP, we can pass parameters in RTMP URL for SRS:
* Vhost：Specifies the vhost in the RTMP URL for SRS.
* Token authentication: Not implements for SRS, while user can specifies the token in the RTMP URL, SRS can fetch the token and verify it on remote authentication server. The token authentication is better and complex than refer authentication.

The parameters in SRS URL:

* `rtmp://192.168.1.100/live/livestream?vhost=demo.srs.com`
* `rtmp://192.168.1.100/live/livestream?domain=demo.srs.com`
* `rtmp://192.168.1.100/live/livestream?token=xxx`
* `rtmp://192.168.1.100/live/livestream?vhost=demo.srs.com&token=xxx`

> Note: FMLE passes the parameters in app, which should not be used now, because it confuses people.

It's also applied to other protocols, for example:

* `http://192.168.1.100/live/livestream.flv?vhost=demo.srs.com&token=xxx`
* `http://192.168.1.100/live/livestream.m3u8?vhost=demo.srs.com&token=xxx`
* `webrtc://192.168.1.100/live/livestream?vhost=demo.srs.com&token=xxx`

> Note: SRT is another story, please read [SRT Parameters](./srt.md) for details.

## URL of SRS

SRS always simplify the problem, never make it more complex.

The RTMP URL of SRS use standard RTMP URL. Generally do not need to modify the url or add parameters in it, except:
* Change vhost: Manually change vhost in RTMP URL for debuging.
* Token authentication: To support token authentication.

Furthermore, recomment user to use one level app and stream, never use multiple level app and stream. For example:

```bash
// Not recomment multiple level app and stream, which confuse people.
rtmp://demo.srs.com/show/live/livestream
rtmp://demo.srs.com/show/live/livestream/2013
```

The srs_player and srs_publisher donot support multiple level app and stream. Both srs_player and srs_publisher make the word behind the last / to stream, the left is tcUrl(vhost/app). For example:

```bash
// For both srs_player and srs_publisher:
// play or publish the following rtmp URL:
rtmp://demo.srs.com/show/live/livestream/2013
schema: rtmp
host/vhost: demo.srs.com
app: show/live/livestream
stream: 2013
```

It simplify the url, the palyer and publisher only need user to input a url, not tcUrl and stream.

The RTMP URL of SRS:

| URL | Description |
| ---- | ------ |
| rtmp://demo.srs.com/live/livestream | Standard RTMP URL |
| rtmp://192.168.1.10/live/livestream?vhost=demo.srs.com | URL specifies vhost |
| rtmp://demo.srs.com/live/livestream?key=ER892ID839KD9D0A1D87D | URL specifies token authentication |

## Example Vhosts in SRS

The full.conf of conf of SRS contains many vhost, which used to show each feature. All features is put into the vhost demo.srs.com:

| Category | Vhost | Description |
| -------- | ----- | ---- |
| RTMP | __defaultVhost__ | Default Vhost, only RTMP.| 
| RTMP | chunksize.vhost.com | Sample to set the chunk_size.| 
| Forward | same.vhost.forward.vhost.com | Sample for Foward stream to the same vhost.| 
| HLS | with-hls.vhost.com | Sample for HLS.| 
| HLS | no-hls.vhost.com | Sample to disable the HLS.| 
| RTMP | min.delay.com | Sample to config the minimum latency for RTMP.| 
| RTMP | refer.anti_suck.com | Sample for Refer anti-suck DRM.| 
| RTMP | removed.vhost.com | Sample to disable vhost.| 
| Callback | hooks.callback.vhost.com | Sample for http callback.| 
| Transcode | mirror.transcode.vhost.com | Sample for transcode, to use the sample filter of FFMPEG.| 
| Transcode | crop.transcode.vhost.com | Sample for transcode, to use the crop filter of FFMPEG.| 
| Transcode | logo.transcode.vhost.com | Sample for transcode, to use the logo filter of FFMPEG.| 
| Transcode | audio.transcode.vhost.com | Sample for transcode, to transcode audio only.| 
| Transcode | copy.transcode.vhost.com | Sample for transcode, demux and mux.| 
| Transcode | all.transcode.vhost.com | Sample for transcode, all transcode features.| 
| Transcode | ffempty.transcode.vhost.com | Sample for empty transcode, display the parameters.| 
| Transcode | app.transcode.vhost.com | Sample for transcode, transcode specified app streams.| 
| Transcode | stream.transcode.vhost.com | Sample for transcode, transcode specified streams. |

The demo.conf of conf of SRS, used for demo of SRS。

| Category | Vhost | Description |
| -------- | ----- | ---- |
| DEMO | players | The vhost for default stream of srs_player, ingest this stream.| 
| DEMO | players_pub | The vhost for the srs_publisher to publish stream to.| 
| DEMO | players_pub_rtmp | The low latency vhost for demo.| 
| DEMO | demo.srs.com | The full features for demo.| 
| Others | dev | The vhost for dev, ignore.|

Winlin 2014.10

---

### Trunk 3rdparty Srs Docs Doc Sample Arm (`trunk/3rdparty/srs-docs/doc/sample-arm.md`)

---
title: ARM Deploy
sidebar_label: ARM Deploy
hide_title: false
hide_table_of_contents: false
---

# SRS ARM deploy example

SRS can deploy on ARM linux. SRS provides srs-librtmp as client library for ARM.

Compile and build ARM, read [SrsLinuxArm](./arm.md),
this artical describes how to deploy.

**Suppose the IP of ubuntu12: 192.168.1.170**

**Suppose the ARM device running in VirtualBox 1935 mapped to Ubuntu12 19350, 22 mapped to 2200.
That is, we can access Ubuntu12 19350 to access the ARM 1935, while the Ubuntu 2200 for ARM 22.**

For more information, read [SrsLinuxArm](./arm.md)

> Note: We need to patch ST, read [ST#1](https://github.com/ossrs/state-threads/issues/1) and [SrsLinuxArm](./arm.md#st-arm-bug-fix)

## Ubuntu12 cross build SRS

### Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

### Step 2, build SRS

For detail, read [SrsLinuxArm](./arm.md)

```bash
./configure --cross-build && make
```

> Note: To directly build on ARM device, for example RaspberryPi, use `./configure` instead. For others, please read [SrsLinuxArm](./arm.md)

### Step 3, send SRS to ARM virtual machine

For detail, read [SrsLinuxArm](./arm.md)

```bash
# Password is：root
scp -P 2200 objs/srs  root@localhost:~
scp -P 2200 conf/rtmp.conf root@localhost:~
```

## Start SRS on ARM

Login to Ubuntu 2200, we are on ARM:

### Step 4, start SRS

For detail, read [SrsLinuxArm](./arm.md)

```bash
./objs/srs -c conf/rtmp.conf
```

### Step 5, start Encoder

For detail, read [SrsLinuxArm](./arm.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170:19350/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE to publish stream:

```bash
FMS URL: rtmp://192.168.1.170:19350/live
Stream: livestream
```

## User Machine

Play RTMP stream on user machine.

### Step 6, play RTMP stream

RTMP url is: `rtmp://192.168.1.170:19350/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Dash (`trunk/3rdparty/srs-docs/doc/sample-dash.md`)

---
title: DASH Deploy
sidebar_label: DASH Deploy
hide_title: false
hide_table_of_contents: false
---

# DASH deploy example

Delivery DASH by SRS:

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure && make
```

## Step 3, config SRS

Please read [DASH](https://github.com/ossrs/srs/issues/299#issuecomment-306022840)

Save bellow as config, or use `conf/dash.conf`:

```bash
# conf/dash.conf
listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {
    dash {
        enabled         on;
        dash_fragment       30;
        dash_update_period  150;
        dash_timeshift      300;
        dash_path           ./objs/nginx/html;
        dash_mpd_file       [app]/[stream].mpd;
    }
}
```

## Step 4, start SRS

```bash
./objs/srs -c conf/dash.conf
```

> Note: You can also use other web server, such as NGINX, to delivery files of DASH.

## Step 5, start Encoder

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

The stream in SRS:
* RTMP url：`rtmp://192.168.1.170/live/livestream`
* DASH url： `http://192.168.1.170:8080/live/livestream.mpd`

## Step 6, play RTMP stream

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

## Step 7, play DASH stream

DASH url： `http://192.168.1.170:8080/live/livestream.mpd`

Please use VLC to play.

Winlin 2020.01

---

### Trunk 3rdparty Srs Docs Doc Sample Ffmpeg (`trunk/3rdparty/srs-docs/doc/sample-ffmpeg.md`)

---
title: Transcode Deploy
sidebar_label: Transcode Deploy
hide_title: false
hide_table_of_contents: false
---

# Transcode deploy example

FFMPEG can used to transcode the live stream, output the other RTMP server.
For detail, read [FFMPEG](./ffmpeg.md).

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure --ffmpeg-tool=on && make
```

## Step 3, config file

For detail, read [FFMPEG](./ffmpeg.md)

Save the bellow as config file, or use `conf/ffmpeg.transcode.conf` instead:

```bash
# conf/ffmpeg.transcode.conf
listen              1935;
max_connections     1000;
vhost __defaultVhost__ {
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine ff {
            enabled         on;
            vfilter {
            }
            vcodec          libx264;
            vbitrate        500;
            vfps            25;
            vwidth          768;
            vheight         320;
            vthreads        12;
            vprofile        main;
            vpreset         medium;
            vparams {
            }
            acodec          libfdk_aac;
            abitrate        70;
            asample_rate    44100;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}
```

## Step 4, start SRS

For detail, read [FFMPEG](./ffmpeg.md)

```bash
./objs/srs -c conf/ffmpeg.conf
```

## Step 5, start encoder

For detail, read [FFMPEG](./ffmpeg.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE to publish:

```bash
FMS URL: rtmp://192.168.1.170/live
Stream: livestream
```

The stream in SRS:
* Stream publish by encoder: rtmp://192.168.1.170:1935/live/livestream
* Play the original stream: rtmp://192.168.1.170:1935/live/livestream
* Play the transcoded stream: rtmp://192.168.1.170:1935/live/livestream_ff

## Step 6, play the stream

For detail, read [FFMPEG](./ffmpeg.md)

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

## Step 7, play the transcoded stream

For detail, read [FFMPEG](./ffmpeg.md)

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream_ff`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Forward (`trunk/3rdparty/srs-docs/doc/sample-forward.md`)

---
title: Forward Deploy
sidebar_label: Forward Deploy
hide_title: false
hide_table_of_contents: false
---

# Forward deploy example

SRS can forward stream to other RTMP server.

**Suppose the server ip is 192.168.1.170**

Forward will copy streams to other RTMP server:
* Master: Encoder publish stream to master, which will forward to slave.
* Slave: Slave forward stream to slave.

We use master to listen at 1935, and slave listen at 19350.

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure && make
```

## Step 3, config master SRS

For detail, read [Forward](./forward.md)

Save bellow as config, or use `conf/forward.master.conf`:

```bash
# conf/forward.master.conf
listen              1935;
max_connections     1000;
pid                 ./objs/srs.master.pid;
srs_log_tank        file;
srs_log_file        ./objs/srs.master.log;
vhost __defaultVhost__ {
    forward {
        enabled on;
        destination 127.0.0.1:19350;
    }
}
```

## Step 4, start master SRS

For detail, read [Forward](./forward.md)

```bash
./objs/srs -c conf/forward.master.conf
```

## Step 5, config slave SRS

For detail, read [Forward](./forward.md)

Save bellow as config, or use `conf/forward.slave.conf`:

```bash
# conf/forward.slave.conf
listen              19350;
pid                 ./objs/srs.slave.pid;
srs_log_tank        file;
srs_log_file        ./objs/srs.slave.log;
vhost __defaultVhost__ {
}
```

## Step 6, start slave SRS

For detail, read [Forward](./forward.md)

```bash
./objs/srs -c conf/forward.slave.conf
```

Note: Ensure the master and slave is ok, no error in log.

```bash
[winlin@dev6 srs]$ sudo netstat -anp|grep srs
tcp        0      0 0.0.0.0:1935                0.0.0.0:*                   LISTEN      7826/srs            
tcp        0      0 0.0.0.0:19350               0.0.0.0:*                   LISTEN      7834/srs
```

## Step 7, start Encoder

For detail, read [Forward](./forward.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE to publish:

```bash
FMS URL: rtmp://192.168.1.170/live
Stream: livestream
```

The stream in SRS:
* Stream publish by encoder: rtmp://192.168.1.170:1935/live/livestream
* The stream forward by master SRS: rtmp://192.168.1.170:19350/live/livestream
* Play stream on master: rtmp://192.168.1.170/live/livestream
* Play strema on slave: rtmp://192.168.1.170:19350/live/livestream

## Step 8, play the stream on master

For detail, read [Forward](./forward.md)

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

## Step 9, play the stream on slave

For detail, read [Forward](./forward.md)

RTMP url is: `rtmp://192.168.1.170:19350/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Hls Cluster (`trunk/3rdparty/srs-docs/doc/sample-hls-cluster.md`)

---
title: HLS Cluster Deploy
sidebar_label: HLS Cluster Deploy
hide_title: false
hide_table_of_contents: false
---

# HLS Edge Cluster Example

Example for HLS Edge Cluster, like to create a CDN to deliver HLS files.

**Suppose the server ip is 192.168.1.170**

## Step 1, Get SRS code

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, Configure and build SRS

For detail, read [Build](./install.md)

```bash
./configure && make
```

## Step 3, Config origin srs, to generate HLS files

See [HLS](./hls.md).

Please use config `conf/hls.origin.conf`, or create a config file by:

```bash
# conf/hls.origin.conf
listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
http_server {
    enabled         on;
    listen          8080;
}
vhost __defaultVhost__ {
    hls {
        enabled         on;
        hls_ctx off;
        hls_ts_ctx off;
    }
}
```

## Step 4, Config edge NGINX to deliver HLS files.

See [Nginx for HLS](./nginx-for-hls.md).

Save bellow as config, or use `conf/hls.edge.conf`:

```bash
# conf/hls.edge.conf
worker_processes  3;
events {
    worker_connections  10240;
}

http {
    # For Proxy Cache.
    proxy_cache_path  /tmp/nginx-cache levels=1:2 keys_zone=srs_cache:8m max_size=1000m inactive=600m;
    proxy_temp_path /tmp/nginx-cache/tmp; 

    server {
        listen       8081;
        # For Proxy Cache.
        proxy_cache_valid  404      10s;
        proxy_cache_lock on;
        proxy_cache_lock_age 300s;
        proxy_cache_lock_timeout 300s;
        proxy_cache_min_uses 1;

        location ~ /.+/.*\.(m3u8)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri$args;
            proxy_cache_valid  200 302  10s;
        }
        location ~ /.+/.*\.(ts)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri;
            proxy_cache_valid  200 302  60m;
        }
    }
}
```

## Step 5, Start SRS Origin and NGINX Edge Server

```bash
nginx -c $(pwd)/conf/hls.edge.conf
./objs/srs -c conf/hls.origin.conf
```

> Note: Please follow instructions of [NGINX](https://nginx.org/) to download and install.

## Step 6, Publish RTMP stream to SRS Origin, to generate HLS files.

Use FFMPEG to publish stream:

```bash
for((;;)); do \
    ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
    -c copy -f flv rtmp://192.168.1.170/live/livestream; \
    sleep 1; \
done
```

Or use OBS to publish:

```bash
Server: rtmp://192.168.1.170/live
StreamKey: livestream
```

## Step 7, Play HLS stream

HLS by SRS Origin: `http://192.168.1.170:8080/live/livestream.m3u8`

HLS by NGINX Edge: `http://192.168.1.170:8081/live/livestream.m3u8`

Note: Please replace all ip 192.168.1.170 to your server ip.

## Step 8: Benchmark and More NGINX Edge Servers

Please use [srs-bench](https://github.com/ossrs/srs-bench#usage) to simulate a set of visitors:

```bash
docker run --rm -it --network=host --name sb ossrs/srs:sb \
  ./objs/sb_hls_load -c 100 -r http://192.168.1.170:8081/live/livestream.m3u8
```

You could run more NGINX from another server, use the same config.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Hls (`trunk/3rdparty/srs-docs/doc/sample-hls.md`)

---
title: HLS Deploy
sidebar_label: HLS Deploy
hide_title: false
hide_table_of_contents: false
---

# HLS deploy example

Migrated to [HLS](./hls.md).

---

### Trunk 3rdparty Srs Docs Doc Sample Http Flv Cluster (`trunk/3rdparty/srs-docs/doc/sample-http-flv-cluster.md`)

---
title: HTTP-FLV Cluster Deploy
sidebar_label: HTTP-FLV Cluster Deploy
hide_title: false
hide_table_of_contents: false
---

# HTTP FLV Cluster Example

About the HTTP FLV cluster of SRS, read [HTTP FLV](./flv.md#about-http-flv)

How to use multiple process for HTTP FLV? Please read [Reuse Port](./reuse-port.md) for detail.

This example show how to deploy three SRS instance, listen at different port at a machine(user can deploy each to different machine, use same port), while one is origin server, another two are edge servers. We can publish RTMP to origin or edge, and play the RTMP/FLV at any edge. The latency is same to RTMP, 0.8-1s.

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure && make
```

## Step 3, config origin SRS

For detail, read [HTTP FLV](./flv.md)

Save bellow as config, or use `conf/http.flv.live.conf`:

```bash
# conf/http.flv.live.conf
listen              1935;
max_connections     1000;
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {
    http_remux {
        enabled     on;
        mount       [vhost]/[app]/[stream].flv;
        hstrs       on;
    }
}
```

## Step 4, config edge SRS

For detail, read [HTTP FLV](./flv.md)

Save bellow as config, or use `conf/http.flv.live.edge1.conf` or `conf/http.flv.live.edge2.conf`:

```bash
# conf/http.flv.live.edge1.conf
listen              19351;
max_connections     1000;
pid                 objs/srs.flv.19351.pid;
srs_log_file        objs/srs.flv.19351.log;
http_server {
    enabled         on;
    listen          8081;
    dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {
    mode remote;
    origin 127.0.0.1;
    http_remux {
        enabled     on;
        mount       [vhost]/[app]/[stream].flv;
        hstrs       on;
    }
}
```

## Step 5, start SRS

For detail, read [HTTP FLV](./flv.md)

```bash
./objs/srs -c conf/http.flv.live.conf &
./objs/srs -c conf/http.flv.live.edge1.conf &
./objs/srs -c conf/http.flv.live.edge2.conf &
```

## Step 6, start Encoder

For detail, read read [HTTP FLV](./flv.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE to publish：

```bash
FMS URL: rtmp://192.168.1.170/live
Stream: livestream
```

The streams on SRS origin:
* RTMP: `rtmp://192.168.1.170/live/livestream`
* HTTP FLV: `http://192.168.1.170:8080/live/livestream.flv`

The streams on SRS edge1:
* RTMP: `rtmp://192.168.1.170:19351/live/livestream`
* HTTP FLV: `http://192.168.1.170:8081/live/livestream.flv`

The streams on SRS edge2:
* RTMP: `rtmp://192.168.1.170:19352/live/livestream`
* HTTP FLV: `http://192.168.1.170:8082/live/livestream.flv`

## Step 7, play RTMP

For detail, read [HTTP FLV](./flv.md)

Origin RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`, User can use vlc to play the RTMP stream.

Edge1 RTMP url is: `rtmp://192.168.1.170:19351/live/livestream`, User can use vlc to play the RTMP stream.

Edge2 RTMP url is: `rtmp://192.168.1.170:19352/live/livestream`, User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

## Step 8, play HTTP FLV

For detail, read [HTTP FLV](./flv.md)

Origin HTTP FLV url: `http://192.168.1.170:8080/live/livestream.flv`, User can use vlc to play the HLS stream. Or, use online SRS player(you must input the flv url): [srs-player](https://ossrs.net/players/srs_player.html)

Edge1 HTTP FLV url: `http://192.168.1.170:8081/live/livestream.flv`, User can use vlc to play the HLS stream. Or, use online SRS player(you must input the flv url): [srs-player](https://ossrs.net/players/srs_player.html)

Edge2 HTTP FLV url: `http://192.168.1.170:8082/live/livestream.flv`, User can use vlc to play the HLS stream. Or, use online SRS player(you must input the flv url): [srs-player](https://ossrs.net/players/srs_player.html)

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Http Flv (`trunk/3rdparty/srs-docs/doc/sample-http-flv.md`)

---
title: HTTP-FLV Deploy
sidebar_label: HTTP-FLV Deploy
hide_title: false
hide_table_of_contents: false
---

# HTTP FLV deploy example

Migrated to [HTTP-FLV](./flv.md).

---

### Trunk 3rdparty Srs Docs Doc Sample Http (`trunk/3rdparty/srs-docs/doc/sample-http.md`)

---
title: HTTP Server Deploy
sidebar_label: HTTP Server Deploy
hide_title: false
hide_table_of_contents: false
---

# SRS HTTP server deploy example

SRS embeded HTTP server, to delivery HLS and files.

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure && make
```

## Step 3, config SRS

For detail, read [HLS](./hls.md) and [HTTP Server](./http-server.md)

Save bellow as config, or use `conf/http.hls.conf`:

```bash
# conf/http.hls.conf
listen              1935;
max_connections     1000;
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {
    hls {
        enabled         on;
        hls_path        ./objs/nginx/html;
        hls_fragment    10;
        hls_window      60;
    }
}
```

Note: The hls_path must exists, srs never create it. For detail, read [HLS](./hls.md)

## Step 4, start SRS

For detail, read [HLS](./hls.md) and [SRS HTTP Server](./http-server.md)

```bash
./objs/srs -c conf/http.hls.conf
```

## Step 5, start Encoder

For detail, read [HLS](./hls.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE(which support h.264+aac) to publish, read [Transcode2HLS](./sample-transcode-to-hls.md)：

```bash
FMS URL: rtmp://192.168.1.170/live
Stream: livestream
```

The streams on SRS:
* RTMP: `rtmp://192.168.1.170/live/livestream`
* HLS: `http://192.168.1.170:8080/live/livestream.m3u8`

## Step 6, play RTMP

For detail, read [HLS](./hls.md)

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

## Step 7, play HLS

For detail, read [HLS](./hls.md)

HLS url: `http://192.168.1.170:8080/live/livestream.m3u8`

User can use vlc to play the HLS stream.

Or, use online SRS player: [srs-player](https://ossrs.net/players/srs_player.html)

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Ingest (`trunk/3rdparty/srs-docs/doc/sample-ingest.md`)

---
title: Ingest Deploy
sidebar_label: Ingest Deploy
hide_title: false
hide_table_of_contents: false
---

# Ingest deploy example

SRS can start process to ingest file/stream/device, transcode or not,
then publish to SRS. For detail, read [Ingest](./ingest.md).

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure --ffmpeg-tool=on && make
```

## Step 3, config SRS

For detail, read [Ingest](./ingest.md)

Save bellow as config, or use `conf/ingest.conf`:

```bash
# conf/ingest.conf
listen              1935;
max_connections     1000;
vhost __defaultVhost__ {
    ingest livestream {
        enabled      on;
        input {
            type    file;
            url     ./doc/source.flv;
        }
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine {
            enabled          off;
            output          rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
        }
    }
}
```

## Step 4, start SRS

For detail, read [Ingest](./ingest.md)

```bash
./objs/srs -c conf/ingest.conf
```

The streams on SRS:
* Stream ingest: rtmp://192.168.1.170:1935/live/livestream

## Step 5, play RTMP

For detail, read [Ingest](./ingest.md)

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Origin Cluster (`trunk/3rdparty/srs-docs/doc/sample-origin-cluster.md`)

---
title: RTMP Origin Cluster
sidebar_label: RTMP Origin Cluster
hide_title: false
hide_table_of_contents: false
---

# RTMP Origin Cluster

RTMP Origin Cluster is a powerful feature for huge pushing streams,
we could use RTMP Origin Cluster and RTMP Edge Cluster together,
to support huge pushing and pulling streams.

**Suppose your server is: 192.168.1.170**

## Step 1: Get SRS

For more information please read [here](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update your repository:

```bash
git pull
```

## Step 2: Build SRS

For more information please read [here](./install.md)

```bash
./configure && make
```

## Step 3: Config the first origin, Origin ServerA

For more information please read [here](./origin-cluster.md)

You can use the file `conf/origin.cluster.serverA.conf`, or write your own:

```bash
# conf/origin.cluster.serverA.conf
listen              19350;
max_connections     1000;
daemon              off;
srs_log_tank        console;
pid                 ./objs/origin.cluster.serverA.pid;
http_api {
    enabled         on;
    listen          9090;
}
vhost __defaultVhost__ {
    cluster {
        mode            local;
        origin_cluster  on;
        coworkers       127.0.0.1:9091;
    }
}
```

## Step 4: Config the second origin, Origin ServerB

For more information please read [here](./origin-cluster.md)

You can use the file `conf/origin.cluster.serverB.conf`, or write your own:

```bash
# conf/origin.cluster.serverB.conf
listen              19351;
max_connections     1000;
daemon              off;
srs_log_tank        console;
pid                 ./objs/origin.cluster.serverB.pid;
http_api {
    enabled         on;
    listen          9091;
}
vhost __defaultVhost__ {
    cluster {
        mode            local;
        origin_cluster  on;
        coworkers       127.0.0.1:9090;
    }
}
```

## Step 5: Config edge server, which pulls streams from Origin Servers

For more information please read [here](./origin-cluster.md)

You can use the file `conf/origin.cluster.edge.conf`, or write your own:

```bash
# conf/origin.cluster.edge.conf
listen              1935;
max_connections     1000;
pid                 objs/edge.pid;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {
    cluster {
        mode            remote;
        origin          127.0.0.1:19351 127.0.0.1:19350;
    }
}
```

## Step 6: Start SRS servers

For more information please read [here](./origin-cluster.md)

```bash
./objs/srs -c conf/origin.cluster.serverA.conf &
./objs/srs -c conf/origin.cluster.serverB.conf &
./objs/srs -c conf/origin.cluster.edge.conf &
```

## Step 7: Push stream to any Origin Server

For more information please read [here](./origin-cluster.md)

By FFmpeg: 

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170:19350/live/livestream; \
        sleep 1; \
    done
```

Or FMLE:

```bash
FMS URL: rtmp://192.168.1.170:19350/live
Stream: livestream
```

## Step 8: Play RTMP stream from Edge server

For more information please read [here](./origin-cluster.md)

RTMP URL is: `rtmp://192.168.1.170/live/livestream`, you can choose VLC.

> Remark: Replace the IP `192.168.1.170` to your server IP.

Winlin 2018.2

---

### Trunk 3rdparty Srs Docs Doc Sample Realtime (`trunk/3rdparty/srs-docs/doc/sample-realtime.md`)

---
title: RTMP Realtime Deploy
sidebar_label: RTMP Realtime Deploy
hide_title: false
hide_table_of_contents: false
---

# RTMP low latency deploy example

The SRS realtime(low latency) mode can decrease the latency to 0.8-3s.
For detail about latency, read [LowLatency](./low-latency.md).

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure && make
```

## Step 3, config SRS

For detail, read [LowLatency](./low-latency.md)

Save bellow as config, or use `conf/realtime.conf`:

```bash
# conf/realtime.conf
listen              1935;
max_connections     1000;
vhost __defaultVhost__ {
    tcp_nodelay     on;
    min_latency     on;

    play {
        gop_cache       off;
        queue_length    10;
        mw_latency      100;
    }

    publish {
        mr off;
    }
}
```

## Step 4, start SRS

For detail, read [LowLatency](./low-latency.md)

```bash
./objs/srs -c conf/realtime.conf
```

## Step 5, start Encoder

For detail, read [LowLatency](./low-latency.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE to publish:

```bash
FMS URL: rtmp://192.168.1.170/live
Stream: livestream
```

Note: To measure the latency, can use the clock of mobile phone.


## Step 6, play RTMP

For detail, read [LowLatency](./low-latency.md)

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.12

---

### Trunk 3rdparty Srs Docs Doc Sample Rtmp Cluster (`trunk/3rdparty/srs-docs/doc/sample-rtmp-cluster.md`)

---
title: RTMP Cluster Deploy
sidebar_label: RTMP Cluster Deploy 
hide_title: false
hide_table_of_contents: false
---

# RTMP Edge Cluster Example

RTMP Edge cluster deploy example

RTMP Edge cluster is the kernel feature of SRS.

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure && make
```

## Step 3, config origin SRS

For detail, read [RTMP](./rtmp.md) and [Edge](./edge.md)

Save bellow as config, or use `conf/origin.conf`:

```bash
# conf/origin.conf
listen              19350;
max_connections     1000;
pid                 objs/origin.pid;
srs_log_file        ./objs/origin.log;
vhost __defaultVhost__ {
}
```

## Step 4, config edge SRS

For detail, read [RTMP](./rtmp.md) and [Edge](./edge.md)

Save bellow as config, or use `conf/edge.conf`:

```bash
# conf/edge.conf
listen              1935;
max_connections     1000;
pid                 objs/edge.pid;
srs_log_file        ./objs/edge.log;
vhost __defaultVhost__ {
    cluster {
        mode            remote;
        origin          127.0.0.1:19350;
    }
}
```

## Step 5, start SRS

For detail, read [RTMP](./rtmp.md) and [Edge](./edge.md)

```bash
./objs/srs -c conf/origin.conf &
./objs/srs -c conf/edge.conf &
```

## Step 6, start Enocder

For detail, read [RTMP](./rtmp.md) and [Edge](./edge.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE to publish:

```bash
FMS URL: rtmp://192.168.1.170/live
Stream: livestream
```

## Step 7, play RTMP

For detail, read [RTMP](./rtmp.md) and [Edge](./edge.md)

Origin RTMP url is: `rtmp://192.168.1.170:19350/live/livestream`, User can use vlc to play the RTMP stream.

Edge RTMP url is: `rtmp://192.168.1.170:1935/live/livestream`, User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample Rtmp (`trunk/3rdparty/srs-docs/doc/sample-rtmp.md`)

---
title: RTMP Deploy
sidebar_label: RTMP Deploy 
hide_title: false
hide_table_of_contents: false
---

# RTMP Delivery

Migrated to [RTMP](./rtmp.md).

---

### Trunk 3rdparty Srs Docs Doc Sample Srt (`trunk/3rdparty/srs-docs/doc/sample-srt.md`)

---
title: SRT Deploy
sidebar_label: SRT Deploy
hide_title: false
hide_table_of_contents: false
---

# SRT deploy example

Migrated to [SRT](./srt.md).

---

### Trunk 3rdparty Srs Docs Doc Sample Transcode To Hls (`trunk/3rdparty/srs-docs/doc/sample-transcode-to-hls.md`)

---
title: Transcode HLS Deploy
sidebar_label: Transcode HLS Deploy
hide_title: false
hide_table_of_contents: false
---

# Transcode for HLS deploy example

HLS required h.264+aac, user can transcode for other codecs.

Pure audio HLS, read [HLS audio only][http://ossrs.net/srs.release/wiki/HLS-Audio-Only]

**Suppose the server ip is 192.168.1.170**

## Step 1, get SRS

For detail, read [GIT](./git.md)

```bash
git clone https://github.com/ossrs/srs
cd srs/trunk
```

Or update the exists code:

```bash
git pull
```

## Step 2, build SRS

For detail, read [Build](./install.md)

```bash
./configure --ffmpeg-tool=on && make
```

## Step 3, config SRS

For detail, read [HLS](./hls.md)

Save bellow as config, or use `conf/transcode2hls.audio.only.conf`:

```bash
# conf/transcode2hls.audio.only.conf
listen              1935;
max_connections     1000;
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {
    hls {
        enabled         on;
        hls_path        ./objs/nginx/html;
        hls_fragment    10;
        hls_window      60;
    }
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine ff {
            enabled         on;
            vcodec          copy;
            acodec          libfdk_aac;
            abitrate        45;
            asample_rate    44100;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}
```

## Step 4, strat SRS

For detail, read [HLS](./hls.md)

```bash
./objs/srs -c conf/transcode2hls.audio.only.conf
```

## Step 5, start Encoder

For detail, read [HLS](./hls.md)

Use FFMPEG to publish stream:

```bash
    for((;;)); do \
        ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
        -c copy \
        -f flv rtmp://192.168.1.170/live/livestream; \
        sleep 1; \
    done
```

Or use FMLE to publish:

```bash
FMS URL: rtmp://192.168.1.170/live
Stream: livestream
```

The stream in SRS:
* RTMP URL: `rtmp://192.168.1.170/live/livestream`
* Transcode RTMP: `rtmp://192.168.1.170/live/livestream_ff`
* Transcode HLS: `http://192.168.1.170:8080/live/livestream_ff.m3u8`

Note: we can use another vhost to output HLS, other codecs transcode then output to this vhost.

## Step 6, play RTMP

For detail, read [HLS](./hls.md)

RTMP url is: `rtmp://192.168.1.170:1935/live/livestream_ff`

User can use vlc to play the RTMP stream.

Note: Please replace all ip 192.168.1.170 to your server ip.

## Step 7, play HLS

For detail, read [HLS](./hls.md)

HLS url: `http://192.168.1.170:8080/live/livestream_ff.m3u8`

User can use vlc to play the HLS stream.

Or, use online SRS player: [srs-player](https://ossrs.net/players/srs_player.html)

Note: Please replace all ip 192.168.1.170 to your server ip.

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Sample (`trunk/3rdparty/srs-docs/doc/sample.md`)

---
title: Use Scenarios
sidebar_label: Use Scenarios
hide_title: false
hide_table_of_contents: false
---

# Use Scenarios

一般来讲，SRS的应用方式有以下几类：

1. 搭建大规模CDN集群，可以在CDN内部的源站和边缘部署SRS。
2. 小型业务快速搭建几台流媒体集群，譬如学校、企业等，需要分发的流不多，同时CDN覆盖不如自己部署几个节点，可以用SRS搭建自己的小集群。
3. SRS作为源站，CDN作为加速边缘集群。比如推流到CDN后CDN转推到源站，播放时CDN会从源站取流。这样可以同时使用多个CDN。同时还可以在源站做DRM和DVR，输出HLS，更重要的是如果直接推CDN一般CDN之间不是互通的，当一个CDN出现故障无法快速切换到其他CDN。
4. 编码器可以集成SRS支持拉流。一般编码器支持推RTMP/UDP流，如果集成SRS后，可以支持拉多种流。
5. 协议转换网关，比如可以推送FLV到SRS转成RTMP协议，或者拉RTSP转RTMP，还有拉HLS转RTMP。SRS只要能接入流，就能输出能输出的协议。
6. 学习流媒体可以用SRS。SRS提供了大量的协议的文档，wiki，和文档对应的代码，详细的issues，流媒体常见的功能实现，还有新流媒体技术的尝试。
7. 还可以装逼用，在SRS微信群里涉及到很多流媒体和传输的问题，是个装逼的好平台。 

## Quzhibo

趣直播，一个知识直播平台，目前直播技术为主。

主要流程：

* obs 直播
* 有三台hls 服务器，主 srs 自动 forward 到 srs，然后那三台切割
* 有两台 flv 服务器，remote 拉群，发现有时会挂掉，用了个监控srs的脚本，一发现挂掉立马重启
* srs 推流到七牛，利用七牛接口，来生成 m3u8 回放 这样可以结束后，立马看到回放

## Europe: Forward+EXEC

BEGINHO STREAMING PROJECT

I needed solution for pushing streams from origin server 
to edge server. On origin server all streams are avaliable 
in multicast (prepared with ffmpeg, h264 in mpegts container). 
But routing multicast through GRE tunnel to the edge 
server was very buggy. Any networks hickups in origin-edge 
route were affecting streams in bad way (freezeing, pixelation and such)...
So, I found SRS project and after some reading of docs, I 
decided to give it a try. Most intereseting feature of SRS 
to me was a "forward" option. It allows to push all streams 
you have avaliable on local server (SRS origin) to remote 
server (SRS edge) with a single line in config file.
https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-forward

SRS2 config on origin server:
```
    vhost __defaultVhost__ {
           forward         xxx:19350;
    }
```

I "told" to ffmpegs on transcoder to publish stream to rtmp, 
instead of multicast (and yes, I used multicast group as rtmp stream name):
```
    ffmpeg -i udp://xxx:1234 -vcodec libx264 -acodec libfdk_aac \
      -metadata service_name="Channel 1" -metadata service_provider="PBS" \
      -f flv rtmp://xxx:1935/live/xxx:1234
```

Tested stream with ffprobe:
```
    [root@encoder1 ~]# ffprobe rtmp://xxx:1935/live/xxx:1234
    Input #0, flv, from 'rtmp://xxx:1935/live/xxx:1234':
      Metadata:
        service_name    : Channel 1
        service_provider: PBS
        encoder         : Lavf57.24.100
        server          : SRS/2.0.209(ZhouGuowen)
        srs_primary     : SRS/1.0release
        srs_authors     : winlin,wenjie.zhao
        server_version  : 2.0.209
      Duration: N/A, start: 0.010000, bitrate: N/A
        Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp, 128 kb/s
        Stream #0:1: Video: h264 (High), yuvj420p(pc, bt709), 720x576 [SAR 16:11 DAR 20:11], 24 fps, 24 tbr, 1k tbn
```

On edge server (example IP xxx), there is a streaming software 
wich accepts only mpegts as source. So, after receiving rtmp streams 
from origin server, I needed all streams back to mpegts.
SRS have support for several types for output (hls, hds, rtmp, http-flv...) 
but not mpegts, and i need udp mpegts. Then I asked Winlin for help 
and he suggested to use SRS3 on edge server, as SRS3 have an feature 
that SRS2 dont, and thats "exec" option. In SRS3 config, you can use 
exec option, to call ffmpeg for every incoming stream and convert it to
whatever you like. I compiled SRS3 with "--with-ffmpeg" switch 
(yes, source tree comes with ffmpeg in it) on edge server and...

SRS3 config on edge:
```
    listen              19350;
    max_connections     1024;
    srs_log_tank        file;
    srs_log_file        ./objs/srs.slave.log;
    srs_log_level       error;
    vhost __defaultVhost__ {
        exec {
            enabled     on;
            publish     ./objs/ffmpeg/bin/ffmpeg -v quiet -re -i rtmp://127.0.0.1:1935/[app]?vhost=[vhost]/[stream] -c copy -vbsf h264_mp4toannexb -f mpegts "udp://[stream]?localaddr=127.0.0.1&pkt_size=1316";
        }
    }
```

FFmpeg will convert all incoming streams to udp mpegts, binding them 
to lo (127.0.0.1) interface (you dont want multicast to leak all around).
SRS3 will use [stream] for udp address, thats why rtmp stream have name 
by its multicast group on origin server ;)
When converting from rtmp to mpegts, "-vbsf h264_mp4toannexb" option is needed!
After starting SRS3 with this config, i checked is stream forwarded from 
master server properly. So, ffprobe again, now on edge server:
```
    [root@edge ~]# ffprobe  udp://xxx:1234?localaddr=127.0.0.1
    Input #0, mpegts, from 'udp://xxx:5002?localaddr=127.0.0.1':
      Duration: N/A, start: 29981.146500, bitrate: 130 kb/s
      Program 1
        Metadata:
          service_name    : Channel 1
          service_provider: PBS
        Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuvj420p(pc, bt709), 720x576 [SAR 16:11 DAR 20:11], 24 fps, 24 tbr, 90k tbn, 180k tbc
        Stream #0:1[0x101]: Audio: aac ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 130 kb/s
```

I keep adding new streams with ffmpeg at origin server and they are avaliable 
on slave server after second or two. Its almost a year when I started this origin 
and edge SRS instances and they are still working without single restart ;)

Many thanks to Winlin!

## LijiangTV

[丽江热线](https://www.lijiangtv.com/live/)，丽江广播电视台。

## UPYUN

2015，[又拍云直播部分](https://www.upyun.com/solutions/video.html)，在SRS3基础上深度定制的版本。

## bravovcloud

2015，[观止云直播服务器](http://www.bravovcloud.com/product/yff/)，在SRS3基础上深度定制的版本。

## gosun

2014.11，[高升CDN直播部分](http://www.gosun.com/service/streaming_acceleration.html)，在SRS1的基础上深度定制的版本。

## 北京云博视

2014.10.10 by 谁变  63110982<br/>
[http://www.y-bos.com/](http://www.y-bos.com/)

## verycdn

[verycdn](http://www.verycdn.cn/) 开始用SRS。

2014.9.13 by 1163202026 11:19:35<br/>
目前SRS在测试中，没用过别的，直接上的srs，目前测试下来比较OK，没什么大问题。

## SRS产品使用者

2014.7.23 by 阿才(1426953942) 11:04:01 <br/>
我接触srs才几个月，不敢发表什么意见，只是通过这段时间的学习，觉得这个项目做得相当棒，作者及项目团队工作相当出色，精神非常值得赞赏，目前还在学习中。

2014.7.23 by 随想曲(156530446) 11:04:48 <br/>
我作为使用者来说，就是这玩意完全当成正规高大上的产品用啦！

2014.7.23 by 湖中鱼(283946467) 11:06:23 <br/>
me没怎么去具体分析srs只是觉得作者文档写得比较流畅不乏幽默感。但是目前我用到的功能只有rtmp推送直播，及hls这些nginx-rtmp都有，所以还是选择了用老外的东西

2014.7.23 by 我是蝈蝈(383854294)  11:11:59 <br/>
为什么用SRS？轻便，省资源，有中文说明。SRS那些一站式的脚本与演示demo就能看出来作者是很用心的

## web秀场

2014.7 by 刘重驰

我们目前正在调研 准备用到web秀场 和 移动端流媒体服务上

## 视频直播

2014.7 by 大腰怪

## 远程视频直播

2014.7 by 韧

我们的分发服务器用的就是srs，简单易用，稳定性好

我们以前也用过几个分发软件，都没有srs好用，真心的

## chnvideo

2014.7 [chnvideo](http://chnvideo.com/)编码器内置SRS提供RTMP和HLS拉服务。

## 某工厂监控系统

2014.4 by 斗破苍穷(154554381)

某工厂的监控系统主要组成：
* 采集端：采集端采用IPC摄像头安装在工厂重要监控位置，通过网线或者wifi连接到监控中心交换机。
* 监控中心：中心控制服务器，负责管理采集端和流媒体服务器，提供PC/Android/IOS观看平台。
* 流媒体服务器：负责接收采集端的流，提供观看端RTMP/HLS的流。
* 观看端：PC/Android/IOS。要求PC端的延迟在3秒内。Android/IOS延迟在20秒之内。

主要流程包括：
* 采集端启动：IPC摄像头像监控中心注册，获得发布地址，并告知监控中心采集端的信息，譬如摄像头设备名，ip地址，位置信息之类。
* 采集端开始推流：IPC摄像头使用librtmp发布到地址，即将音频视频数据推送到RTMP流媒体服务器。
* 流媒体服务器接收流：流媒体服务器使用SRS，接收采集端的RTMP流。FMS-3/3.5/4.5都有问题，估计是和librtmp对接问题。
* 观看端观看：用户使用PC/Android/IOS登录监控中心后，监控中心返回所有的摄像头信息和流地址。PC端使用flash，延迟在3秒之内；Android/IOS使用HLS，延迟在20秒之内。
* 时移：监控中心会开启录制计划，将RTMP流录制为FLV文件。用户可以在监控中心观看录制的历史视频。

## 网络摄像机

2014.4 by camer(2504296471)

网络摄像机使用hi3518芯片，如何用网页无插件直接观看网络摄像机的流呢？

目前有应用方式如下：
* hi3518上跑采集和推流程序（用srslibrtmp）
* 同时hi3518上还跑了srs/nginx-rtmp作为服务器
* 推流程序推到hi3518本机的nginx服务器
* PC上网页直接观看hi3518上的流

## IOS可以看的监控

2014.3 by 独孤不孤独(378668966)

一般监控摄像头只支持输出RTMP/RTSP，或者支持RTSP方式读取流。如果想在IOS譬如IPad上看监控的流，怎么办？先部署一套rtmp服务器譬如nginx-rtmp/crtmpd/wowza/red5之类，然后用ffmpeg把rtsp流转成rtmp（或者摄像头直接推流到rtmp服务器），然后让服务器切片成hls输出，在IOS上观看。想想都觉得比较麻烦额，如果摄像头比较多怎么办？一个服务器还扛不住，部署集群？

最简单的方式是什么？摄像头自己支持输出HLS流不就好了？也就是摄像头有个内网ip作为服务器，摄像头给出一个hls的播放地址，IOS客户端譬如IPad可以播放这个HLS地址。

SRS最适合做这个事情，依赖很少，提供[arm编译脚本](./sample-arm.md)，只需要[改下configure的交叉编译工具](./arm.md#%E4%BD%BF%E7%94%A8%E5%85%B6%E4%BB%96%E4%BA%A4%E5%8F%89%E7%BC%96%E8%AF%91%E5%B7%A5%E5%85%B7)就可以编译了。

主要流程：
* 编译arm下的srs，部署到树莓派，在摄像头中启动srs。
* 使用ffmpeg将摄像头的rtsp以RTMP方式推到srs。或者用自己程序采集设备数据推送RTMP流到srs。
* srs分发RTMP流和HLS流。其实PC上也可以看了。
* IOS譬如IPad上播放HLS地址。

## 清华活动直播

2014.2 by youngcow(5706022)

清华大学每周都会有活动，譬如名家演讲等，使用SRS支持，少量的机器即可满足高并发。

主要流程：
* 在教室使用播控系统（摄像机+采集卡或者摄像机+导播台）推送RTMP流到主SRS
* 主SRS自动Forward给从SRS（参考[Forward](./forward.md)）
* PC客户端（Flash）使用FlowerPlayer，支持多个服务器的负载均衡
* FlowerPlayer支持在两个主从SRS，自动选择一个服务器，实现负载均衡

主要的活动包括：
* 2014-02-23，丘成桐清华演讲

## 某农场监控

2014.1 by 孙悟空

农场中摄像头支持RTSP访问，FFMPEG将RTSP转换成RTMP推送到SRS，flash客户端播放RTMP流。同时flash客户端可以和控制服务器通信，控制农场的浇水和施肥。



截图：农场的植物开花了，据说种的是萝卜。。。

Winlin 2014.2

---

### Trunk 3rdparty Srs Docs Doc Service (`trunk/3rdparty/srs-docs/doc/service.md`)

---
title: Linux Service
sidebar_label: Linux Service
hide_title: false
hide_table_of_contents: false
---

# SRS Linux Service

There are many ways to startup SRS:
* Directly run srs at the trunk/objs, and need start again when system restart.
* Linux service, the init.d scirpt at `srs/trunk/etc/init.d/srs`, and user can add to linux service when linked to the /etc/init.d/srs then add as service `/sbin/chkconfig --add srs`.

The SRS release binary can be downloaded from release site, we can install as system service, see: [Github: release](http://ossrs.net/srs.release) or [Mirror for China: release](http://www.ossrs.net)

## Manual

We donot need to add to linux service to directly start SRS:

```bash
cd srs/trunk &&
./etc/init.d/srs start
```

or

```bash
cd srs/trunk &&
./objs/srs -c conf/srs.conf
```

## init.d

Install and startup SRS as linux system service:
* Build SRS: the install script will modify the INSTALL ROOT of init.d script.
* Link to init.d: link the `trunk/etc/init.d/srs` to `/etc/init.d/srs`
* Add to linux service: use /sbin/chkconfig for Centos.

<strong>Step1:</strong> Build and Install SRS

Intall SRS when build ok:

```bash
make && sudo make install
```

the install of make will install srs to the prefix dir, default to `/usr/local/srs`, which is specified by configure, for instance, ```./configure --prefix=`pwd`/_release``` set the install dir to _release of current dir to use `make install` without sudo.

<strong>Step2:</strong> Link script to init.d:

```bash
sudo ln -sf \
    /usr/local/srs/etc/init.d/srs \
    /etc/init.d/srs
```

<strong>Step3:</strong>Add as linux service:

```bash
#centos 6
sudo /sbin/chkconfig --add srs
```

or

```bash
#ubuntu12
sudo update-rc.d srs defaults
```

Use init.d script

Get the status of SRS:

```bash
/etc/init.d/srs status
```

Start SRS：

```bash
/etc/init.d/srs start
```

Stop SRS：

```bash
/etc/init.d/srs stop
```

Restart SRS：

```bash
/etc/init.d/srs restart
```

Reload SRS：

```bash
/etc/init.d/srs reload
```

For logrotate(`SIGUSR1`):

```bash
/etc/init.d/srs rotate
```

For Gracefully Quit(`SIGQUIT`):

```bash
/etc/init.d/srs grace
```

## systemctl

Ubuntu20 use systemctl to manage services, we also need to install init.d service, then add to systemctl:

```
./configure && make && sudo make install &&
sudo ln -sf /usr/local/srs/etc/init.d/srs /etc/init.d/srs &&
sudo cp -f /usr/local/srs/usr/lib/systemd/system/srs.service /usr/lib/systemd/system/srs.service &&
sudo systemctl daemon-reload && sudo systemctl enable srs
```

> Remark: We MUST copy the srs.service, or we couldn't enable the service by systemctl.

Use systemctl to start SRS:

```
sudo systemctl start srs
```

## Gracefully Upgrade

Gracefully Upgrade allows upgrade with zero downtime, it can be done by:

* New SRS and old SRS should be able to listen at the same ports. They provide services in the same ports simultaneously.
* The old SRS then closes listeners, and quit util all connections closed, this is Gracefully Quit.

> Note: About more informations, please see [#1579](https://github.com/ossrs/srs/issues/1579#issuecomment-587233844).

SRS3 supports Gracefully Quit:

* Use signal `SIGQUIT`, or command `/etc/init.d/srs grace`
* A new config `grace_start_wait` to wait for a while then start gracefully quit, default 2.3s
* A new config `grace_final_wait` allows wait for a few minutes finally, default 3.2s
* A new config `force_grace_quit` to force gracefully quit, see [#1579](https://github.com/ossrs/srs/issues/1579#issuecomment-587475077).

```bash
# For gracefully quit, wait for a while then close listeners,
# because K8S notify SRS with SIGQUIT and update Service simultaneously,
# maybe there is some new connections incoming before Service updated.
# @see https://github.com/ossrs/srs/issues/1595#issuecomment-587516567
# default: 2300
grace_start_wait 2300;
# For gracefully quit, final wait for cleanup in milliseconds.
# @see https://github.com/ossrs/srs/issues/1579#issuecomment-587414898
# default: 3200
grace_final_wait 3200;
# Whether force gracefully quit, never fast quit.
# By default, SIGTERM which means fast quit, is sent by K8S, so we need to
# force SRS to treat SIGTERM as gracefully quit for gray release or canary.
# @see https://github.com/ossrs/srs/issues/1579#issuecomment-587475077
# default: off
force_grace_quit off;
```

> Note: There is a example for Gracefully Quit, see [#1579](https://github.com/ossrs/srs/issues/1579#issuecomment-587414898)

Winlin 2019.10

---

### Trunk 3rdparty Srs Docs Doc Special Control (`trunk/3rdparty/srs-docs/doc/special-control.md`)

---
title: Special Control
sidebar_label: Special Control
hide_title: false
hide_table_of_contents: false
---

# SpecialControl

SRS provides a set of config to ingerate with other systems.

## Send Minimal Interval

```
vhost __defaultVhost__ {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # the minimal packets send interval in ms,
        # used to control the ndiff of stream by srs_rtmp_dump,
        # for example, some device can only accept some stream which
        # delivery packets in constant interval(not cbr).
        # @remark 0 to disable the minimal interval.
        # @remark >0 to make the srs to send message one by one.
        # @remark user can get the right packets interval in ms by srs_rtmp_dump.
        # default: 0
        send_min_interval       10.0;
    }
}
```

## Reduce Sequence Header

```
vhost __defaultVhost__ {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # whether reduce the sequence header,
        # for some client which cannot got duplicated sequence header,
        # while the sequence header is not changed yet.
        # default: off
        reduce_sequence_header  on;
    }
}
```

## Publish 1st Packet Timeout

```
vhost __defaultVhost__ {
    # the config for FMLE/Flash publisher, which push RTMP to SRS.
    publish {
        # the 1st packet timeout in ms for encoder.
        # default: 20000
        firstpkt_timeout    20000;
    }
}
```

## Publish Normal Timeout

```
vhost __defaultVhost__ {
    # the config for FMLE/Flash publisher, which push RTMP to SRS.
    publish {
        # the normal packet timeout in ms for encoder.
        # default: 5000
        normal_timeout      7000;
    }
}
```

## Debug SRS Upnode

```
vhost __defaultVhost__ {
    # when upnode(forward to, edge push to, edge pull from) is srs,
    # it's strongly recommend to open the debug_srs_upnode,
    # when connect to upnode, it will take the debug info, 
    # for example, the id, source id, pid.
    # please see https://ossrs.io/lts/en-us/docs/v4/doc/log
    # default: on
    debug_srs_upnode    on;
}
```

## UTC Time

```
# whether use utc_time to generate the time struct,
# if off, use localtime() to generate it,
# if on, use gmtime() instead, which use UTC time.
# default: off
utc_time            off;
```

## HLS TS Floor

```
vhost __defaultVhost__ {
    hls {
        # whether use floor for the hls_ts_file path generation.
        # if on, use floor(timestamp/hls_fragment) as the variable [timestamp],
        #       and use enahanced algorithm to calc deviation for segment.
        # @remark when floor on, recommend the hls_segment>=2*gop.
        # default: off
        hls_ts_floor    off;
    }
}
```

## HLS Wait Keyframe

```
vhost __defaultVhost__ {
    hls {
        # whether wait keyframe to reap segment,
        # if off, reap segment when duration exceed the fragment,
        # if on, reap segment when duration exceed and got keyframe.
        # default: on
        hls_wait_keyframe       on;
    }
}
```

## HttpHooks On HLS Notify

```
vhost __defaultVhost__ {
    http_hooks {
        # when srs reap a ts file of hls, call this hook,
        # used to push file to cdn network, by get the ts file from cdn network.
        # so we use HTTP GET and use the variable following:
        #       [app], replace with the app.
        #       [stream], replace with the stream.
        #       [ts_url], replace with the ts url.
        # ignore any return data of server.
        # @remark random select a url to report, not report all.
        on_hls_notify   http://127.0.0.1:8085/api/v1/hls/[app]/[stream][ts_url];
    }
}
```

## TCP NoDelay

```
vhost __defaultVhost__ {
    # whether enable the TCP_NODELAY
    # if on, set the nodelay of fd by setsockopt
    # default: off
    tcp_nodelay     on;
}
```

## ATC Auto

```
vhost __defaultVhost__ {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # whether enable the auto atc,
        # if enabled, detect the bravo_atc="true" in onMetaData packet,
        # set atc to on if matched.
        # always ignore the onMetaData if atc_auto is off.
        # default: off
        atc_auto        off;
    }
}

Winlin 2015.8

---

### Trunk 3rdparty Srs Docs Doc Srs Lib Rtmp (`trunk/3rdparty/srs-docs/doc/srs-lib-rtmp.md`)

---
title: Librtmp
sidebar_label: Librtmp
hide_title: false
hide_table_of_contents: false
---

# SRS librtmp

[SRS](https://github.com/ossrs/srs) is a dedicated server project,
please use [librtmp](https://github.com/ossrs/librtmp) instead,
please read [#32](https://github.com/ossrs/srs-librtmp/issues/32).

Winlin 2014.11

---

### Trunk 3rdparty Srs Docs Doc Srt Codec (`trunk/3rdparty/srs-docs/doc/srt-codec.md`)

---
title: SRT Codec
sidebar_label: SRT Codec
hide_title: false
hide_table_of_contents: false
---

# SRT codec support

Migrated to [SRT](./srt.md).

---

### Trunk 3rdparty Srs Docs Doc Srt Params (`trunk/3rdparty/srs-docs/doc/srt-params.md`)

---
title: SRT Params
sidebar_label: SRT Params
hide_title: false
hide_table_of_contents: false
---

# SRT Config

Migrated to [SRT](./srt.md).

---

### Trunk 3rdparty Srs Docs Doc Srt Url (`trunk/3rdparty/srs-docs/doc/srt-url.md`)

---
title: SRT URL
sidebar_label: SRT URL
hide_title: false
hide_table_of_contents: false
---

# SRT URL Specification

Migrated to [SRT](./srt.md).

---

### Trunk 3rdparty Srs Docs Doc Streamer (`trunk/3rdparty/srs-docs/doc/streamer.md`)

---
title: Stream Converter
sidebar_label: Caster
hide_title: false
hide_table_of_contents: false
---

# Stream Caster

Stream Converters listen at special TCP/UDP ports, accept new connections and receive packets, then convert to and push 
RTMP stream to SRS server like a RTMP client.

In short, it converts other protocols to RTMP, works like this:

```text
Client ---PUSH--> Stream Converter --RTMP--> SRS --RTMP/FLV/HLS/WebRTC--> Clients
```

> Note: Some stream protocol contains more than one single stream or even transport connections.

## Use Scenario

There are some use scenarios for stream caster, for example:

* Push MPEG-TS over UDP, by some encoder device.
* Push FLV by HTTP POST, by some mobile device.

> Note: FFmpeg supports PUSH MPEGTS over UDP and FLV by HTTP POST to SRS.

## Build

Stream Converter is always enabled in SRS, while some protocols might need special configure parameters, please read 
instructions of each protocol.

## Protocols

The protocols supported by Stream Converter:

* MPEG-TS over UDP: MPEG-TS stream over UDP protocol.
* FLV by HTTP POST: FLV stream over HTTP protocol.

## Config

The configuration for stream converter:

```
# Push MPEGTS over UDP to SRS.
stream_caster {
    # Whether stream converter is enabled.
    # Default: off
    enabled on;
    # The type of stream converter, could be:
    #       mpegts_over_udp, push MPEG-TS over UDP and convert to RTMP.
    caster mpegts_over_udp;
    # The output rtmp url.
    # For mpegts_over_udp converter, the typically output url:
    #           rtmp://127.0.0.1/live/livestream
    output rtmp://127.0.0.1/live/livestream;
    # The listen port for stream converter.
    # For mpegts_over_udp converter, listen at udp port. for example, 8935.
    listen 8935;
}

# Push FLV by HTTP POST to SRS.
stream_caster {
    # Whether stream converter is enabled.
    # Default: off
    enabled on;
    # The type of stream converter, could be:
    #       flv, push FLV by HTTP POST and convert to RTMP.
    caster flv;
    # The output rtmp url.
    # For flv converter, the typically output url:
    #           rtmp://127.0.0.1/[app]/[stream]
    # For example, POST to url:
    #           http://127.0.0.1:8936/live/livestream.flv
    # Where the [app] is "live" and [stream] is "livestream", output is:
    #           rtmp://127.0.0.1/live/livestream
    output rtmp://127.0.0.1/[app]/[stream];
    # The listen port for stream converter.
    # For flv converter, listen at tcp port. for example, 8936.
    listen 8936;
}
```

Please follow instructions of specified protocols bellow.

## Push MPEG-TS over UDP

You're able to push MPEGTS over UDP to SRS, then covert to RTMP and other protocols.

First, start SRS with configuration for MPEGTS:

```bash
./objs/srs -c conf/push.mpegts.over.udp.conf
```

> Note: About the detail configuration, please read about the `mpegts_over_udp` section of [config](#config).

Then, start to push stream, for example, by FFmpeg:

```bash
ffmpeg -re -f flv -i doc/source.flv -c copy -f mpegts udp://127.0.0.1:8935
```

Finally, play the stream:

* [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?stream=livestream.flv)
* [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?stream=livestream.m3u8)
* [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html?autostart=true)

Please note that each UDP port is bind to a RTMP stream.

> Note: About the development notes, please see [#250](https://github.com/ossrs/srs/issues/250).

## Push HTTP FLV to SRS

You're also able to push HTTP FLV by HTTP POST, which is very simple for mobile device to send HTTP stream.

First, start SRS with configuration for FLV:

```bash
./objs/srs -c conf/push.flv.conf
```

> Note: About the detail configuration, please read about the `flv` section of [config](#config).

Then, start to push stream, for example, by FFmpeg:

```bash
ffmpeg -re -f flv -i doc/source.flv -c copy \
    -f flv http://127.0.0.1:8936/live/livestream.flv
```

Finally, play the stream:

* [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?stream=livestream.flv)
* [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?stream=livestream.m3u8)
* [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html?autostart=true)

> Note: About the development notes, please see [#2611](https://github.com/ossrs/srs/issues/2611).

## Push RTSP to SRS

It's been eliminated, see [#2304](https://github.com/ossrs/srs/issues/2304#issuecomment-826009290).

2015.1

---

### Trunk 3rdparty Srs Docs Doc Time Jitter (`trunk/3rdparty/srs-docs/doc/time-jitter.md`)

---
title: Time Jitter
sidebar_label: Time Jitter
hide_title: false
hide_table_of_contents: false
---

# TimeJitter

This article describes the timestamp correct of SRS.

## RTMP Monotonically Increase Timestamp

RTMP requires the timestamp is mono-inc(monotonically increase). The mono-inc is the 
timestamp of packet is always larger.

RTMP requires the stream is mono-inc. The audio is mono-inc, 
video is mono-inc, and stream mixed audio with video is mono-inc. 

What happens when not mono-inc? Some server will disconnect connection, flash maybe
failed to play stream.

## Timestamp Jitter

SRS will ensure the stream timestamp is mono-inc. When delta of packets too large, set to 40ms(fps 25).

Some components use the timestamp jitter:
* RTMP delivery: The timestamp jitter algorithm can set by vhost `time_jitter`.
* DVR: The timestamp jitter algorithm can set by dvr `time_jitter`.
* HLS: Always ensure the timestamp is mono-inc, use `full` timestamp jitter algorithm.
* Forward: Always ensure the timestamp is mono-inc, use `full` timestamp jitter algorithm.
* HTTP Audio Stream Fast Cache: Equals to RTMP time jitter, the vhost config. @see `fast_cache`.

You can disable the timestamp jitter algorithm when your encoder can not ensure the 
video+autio mono-inc, some encoder can ensure video mono-inc and audio mono-inc.

## Config

Config the timestamp jitter in vhost for RTMP delivery:

```bash
vhost jitter.srs.com {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # about the stream monotonically increasing:
        #   1. video timestamp is monotonically increasing, 
        #   2. audio timestamp is monotonically increasing,
        #   3. video and audio timestamp is interleaved/mixed monotonically increasing.
        # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format
        # however, some encoder cannot provides this feature, please set this to off to ignore time jitter.
        # the time jitter algorithm:
        #   1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
        #   2. zero, only ensure sttream start at zero, ignore timestamp jitter.
        #   3. off, disable the time jitter algorithm, like atc.
        # default: full
        time_jitter             full;
        # whether use the interleaved/mixed algorithm to correct the timestamp.
        # if on, always ensure the timestamp of audio+video is interleaved/mixed monotonically increase.
        # if off, use time_jitter to correct the timestamp if required.
        # default: off
        mix_correct             off;
    }
}
```

While the `mix_correct` of vhost can correct the audio+video stream to mixed monotonically increase.

Config timestamp jitter for dvr:

```
vhost dvr.srs.com {
    # dvr RTMP stream to file,
    # start to record to file when encoder publish,
    # reap flv according by specified dvr_plan.
    # http callbacks:
    # @see http callback on_dvr_hss_reap_flv on http_hooks section.
    dvr {
        # about the stream monotonically increasing:
        #   1. video timestamp is monotonically increasing, 
        #   2. audio timestamp is monotonically increasing,
        #   3. video and audio timestamp is interleaved monotonically increasing.
        # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format
        # however, some encoder cannot provides this feature, please set this to off to ignore time jitter.
        # the time jitter algorithm:
        #   1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
        #   2. zero, only ensure sttream start at zero, ignore timestamp jitter.
        #   3. off, disable the time jitter algorithm, like atc.
        # default: full
        time_jitter             full;
    }
}
```

## ATC

When [RTMP ATC](./rtmp-atc.md) is on,
RTMP always disable the time_jitter.

Winlin 2015.4

---

### Trunk 3rdparty Srs Docs Doc Windows (`trunk/3rdparty/srs-docs/doc/windows.md`)

---
title: Windows
sidebar_label: Windows
hide_title: false
hide_table_of_contents: false
---

# SRS for Windows

SRS 5.0.89+ supports Windows(Cygwin64).

SRS 7.0.60+ remove the supports for Windows, because it's too complex to maintain.

Please use WSL(Windows Subsystem for Linux) which starts a Ubuntu in Windows, 
so you can simply build and run SRS by:

```bash
wsl --install -d Ubuntu-22.04
```

Winlin 2022.11

---

### Trunk 3rdparty St Srs Docs Timeout Heap (`trunk/3rdparty/st-srs/docs/timeout_heap.txt`)

How the timeout heap works

As of version 1.5, the State Threads Library represents the queue of
sleeping threads using a heap data structure rather than a sorted
linked list.  This improves performance when there is a large number
of sleeping threads, since insertion into a heap takes O(log N) time
while insertion into a sorted list takes O(N) time.  For example, in
one test 1000 threads were created, each thread called st_usleep()
with a random time interval, and then all the threads where
immediately interrupted and joined before the sleeps had a chance to
finish.  The whole process was repeated 1000 times, for a total of a
million sleep queue insertions and removals.  With the old list-based
sleep queue, this test took 100 seconds; now it takes only 12 seconds.

Heap data structures are typically based on dynamically resized
arrays.  However, since the existing ST code base was very nicely
structured around linking the thread objects into pointer-based lists
without the need for any auxiliary data structures, implementing the
heap using a similar nodes-and-pointers based approach seemed more
appropriate for ST than introducing a separate array.

Thus, the new ST timeout heap works by organizing the existing
_st_thread_t objects in a balanced binary tree, just as they were
previously organized into a doubly-linked, sorted list.  The global
_ST_SLEEPQ variable, formerly a linked list head, is now simply a
pointer to the root of this tree, and the root node of the tree is the
thread with the earliest timeout.  Each thread object has two child
pointers, "left" and "right", pointing to threads with later timeouts.

Each node in the tree is numbered with an integer index, corresponding
to the array index in an array-based heap, and the tree is kept fully
balanced and left-adjusted at all times.  In other words, the tree
consists of any number of fully populated top levels, followed by a
single bottom level which may be partially populated, such that any
existing nodes form a contiguous block to the left and the spaces for
missing nodes form a contiguous block to the right.  For example, if
there are nine threads waiting for a timeout, they are numbered and
arranged in a tree exactly as follows:

              1
           /     \
          2       3
         / \     / \
        4   5   6   7
       / \
      8   9

Each node has either no children, only a left child, or both a left
and a right child.  Children always time out later than their parents
(this is called the "heap invariant"), but when a node has two
children, their mutual order is unspecified - the left child may time
out before or after the right child.  If a node is numbered N, its
left child is numbered 2N, and its right child is numbered 2N+1.

There is no pointer from a child to its parent; all pointers point
downward.  Additions and deletions both work by starting at the root
and traversing the tree towards the leaves, going left or right
according to the binary digits forming the index of the destination
node.  As nodes are added or deleted, existing nodes are rearranged to
maintain the heap invariant.

---

### Trunk 3rdparty St Srs Docs Win64 Coroutine (`trunk/3rdparty/st-srs/docs/win64_coroutine.md`)

# How coroutines work on native Windows x64

This note explains how State Threads switches and starts threads (coroutines) on native Windows x64 with
MSVC (`WIN64`), and why a new thread starts in an assembly entry, `_st_md_thread_start`, instead of the way
it starts on Linux and macOS. The code is in `md_win64.asm`, the `WIN64` branch of `md.h`, and
`st_thread_create` in `sched.c`.

## A thread is a saved set of registers

Running code is described by the CPU registers and the stack that `rsp` points into. To pause a thread, ST
saves the registers into its jmpbuf (`thread->context`); to resume it, ST loads them back. Two assembly
functions in `md_win64.asm` do this:

- `_st_md_cxt_save(env)`, like `setjmp`, stores the registers into `env` and returns 0.
- `_st_md_cxt_restore(env, val)`, like `longjmp`, loads the registers from `env`, sets `rsp`, and jumps to
  the saved PC. The CPU continues right after the `_st_md_cxt_save` call that filled `env`, as if that call
  returned a second time, with `val` (1 if `val` is 0).

The jmpbuf holds every register the Windows x64 ABI calls callee-saved, which a function must give back
unchanged, so the compiler may keep values in them across a call. A context switch is such a call.

| Slot | Content | Why |
| --- | --- | --- |
| 0-7 | `rbx`, `rbp`, `rdi`, `rsi`, `r12`-`r15` | Callee-saved integer registers. On Linux, `rdi` and `rsi` are not. |
| 8 | `rsp` | The stack the thread runs on (`MD_GET_SP`). |
| 9 | PC | Where the thread continues: the return address of the save. |
| 10-12 | TIB `StackBase`, `StackLimit`, `DeallocationStack` | The bounds Windows keeps for the current stack (see below). |
| after 12 | MXCSR, x87 control word, `xmm6`-`xmm15` | Also callee-saved on Windows. On Linux, no `xmm` register is. |

## Switching between two threads

A thread that blocks saves itself and restores the next one:

```c
if (_st_md_cxt_save(me->context) == 0) {   /* save me, returns 0 */
    _st_md_cxt_restore(next->context, 1);  /* jump into next */
}
/* Later, when another thread restores me, the save returns 1 here and I go on. */
```

The next thread was paused the same way, so its jmpbuf holds its own stack, PC, and registers, and it
continues inside a function that really runs on that stack.

## Starting a new thread

A new thread has never run, so it has never called `_st_md_cxt_save`; its first jmpbuf must be made up: a
stack pointer into its new, empty stack, and a PC to start at.

### Linux and macOS: save, then patch the SP

```c
if (_st_md_cxt_save(thread->context)) {  /* 1. save the creator's registers */
    _st_thread_main();                   /* 3. the new thread starts here */
}
MD_GET_SP(thread) = stack->sp;           /* 2. point only the SP at the new stack */
```

The first restore of this jmpbuf jumps back into `st_thread_create`, the save returns 1, and the code calls
`_st_thread_main`. But that code now runs on the new stack, where `st_thread_create` was never called:

```
creator's stack                       new thread's stack
+---------------------------+         +---------------------------+
| st_thread_create locals,  |         | empty                     | <- rsp after the restore
| saved registers, return   |         |                           |
+---------------------------+         +---------------------------+
```

After the second return, a read of a local from the stack frame gets garbage, and a value the compiler kept
in a register from before the save is right only if it is one of the callee-saved registers the restore
loads back. The trick works only while the compiler emits nothing there but "if 1, call `_st_thread_main`".
The C language does not promise that, and the compiler does not know that `_st_md_cxt_save` returns twice.

On Linux it holds in practice: an access to a `__thread` variable such as `_st_this_thread` is one
instruction (`mov %fs:offset` on x86-64, `tpidr_el0` on arm64), so there is nothing worth computing before
the save, and GCC and Clang have generated safe code there for decades.

On Windows it held only by luck. With `/O2` and with `/GL` (LTCG), MSVC inlines `_st_thread_main` into
`st_thread_create`. A Windows TLS access takes several steps (`gs:[58h]`, the TLS array, `_tls_index`, the
offset), so MSVC computes the TLS base and `&_st_this_vp` before the save, keeps them in `r13` and `r14`
(`rbp` and `r15` with LTCG), and uses them after the second return. That is right only because those
registers are callee-saved; a spill to the stack would crash the new thread.

### Windows: start in an assembly entry

On `WIN64`, `MD_INIT_THREAD_ENTRY` runs in `st_thread_create` after the SP is patched, and points the
jmpbuf at a small function written in assembly, so no compiler decides what runs first on the new stack:

```c
sp = align_down(stack->sp, 16) - 8;  /* 8 mod 16, as at the entry of a function */
*(void **)sp = NULL;                 /* a return address of 0 */
jmpbuf[8] = sp;                      /* SP */
jmpbuf[9] = _st_md_thread_start;     /* PC */
```

The new stack is then:

```
higher addresses: the thread object and its keys
+----------------------+
| pad, 128 bytes       |
+----------------------+ <- 16-byte aligned
| 0, return address    | <- the SP in the jmpbuf, 8 mod 16
+----------------------+
| free stack, grows down
v
```

The first restore loads the registers, sets `rsp` to that slot, and jumps to `_st_md_thread_start`. To the
CPU this is a normal function call from address 0: a call pushes the return address and jumps, and the
"pushed" return address is the 0 written there.

```asm
_st_md_thread_start PROC FRAME
    sub rsp, 40          ; the callee's 32-byte home space, and 8 bytes to align rsp to 16
    .allocstack 40       ; unwind info: this frame is 40 bytes
    .endprolog
    call _st_thread_main ; run start(arg), then st_thread_exit
    int 3                ; never reached; st_thread_exit never returns
_st_md_thread_start ENDP
```

- The Windows x64 ABI wants `rsp` 16-byte aligned at every `call`, so it is 8 mod 16 at the entry of a
  function. The entry starts in exactly that state, and `sub rsp, 40` aligns it again for the call. A wrong
  alignment breaks aligned SSE instructions such as `movaps`.
- `_st_thread_main` is ordinary C with a normal frame. It runs the thread function and then
  `st_thread_exit`, which switches to another thread and never comes back.
- The new thread never runs a line of `st_thread_create`. The only code between the restore and
  `_st_thread_main` is the four instructions above, and the registers the creator saved are left over and
  never read. So the start no longer depends on how the compiler uses that frame or its registers after the
  save returns twice, at `/Od`, `/O2`, or `/GL`.

The restore itself is the same for every switch; only the first jmpbuf of a new thread differs.

## Exceptions and stack walks (SEH)

Structured Exception Handling (SEH) is how Windows handles errors raised while code runs: a hardware fault
such as an access violation is an SEH exception, and MSVC implements a C++ `throw` as an SEH exception too
(code `0xE06D7363`). To find a handler (a `catch` or an `__except`), Windows walks the stack frame by frame,
from the current function to its callers. Debuggers, crash dumps, and `RtlCaptureStackBackTrace` walk the
stack the same way.

On x64, Windows does not follow `rbp` chains. Every function has an entry in the unwind tables (`.pdata`
and `.xdata`) that the compiler or assembler generates. For a PC, the entry tells how far the function moved
`rsp` and which registers it saved, so Windows finds the return address and steps to the caller.

Windows also checks every step against the stack bounds in the thread information block (TIB). If `rsp`
leaves `StackLimit`..`StackBase`, it takes the stack as corrupt and ends the process. That is why the
context switch saves and loads the TIB bounds (slots 10-12), and `st_thread_create` sets them for a new
thread (`MD_INIT_STACK_BOUNDS`). Without them, any exception on a thread stack would look like a corrupt
stack.

With the save-then-patch-SP trick, the outermost frame of a new thread would be code of `st_thread_create`
on a stack it was never called on. Its unwind entry points to a return address above the SP, in the pad or
the thread object, which is not a return address, so a walk would step into a random caller. With the assembly entry, the walk ends
cleanly:

```
thread function      -> unwind info: returns to _st_thread_main
_st_thread_main      -> unwind info: returns to _st_md_thread_start
_st_md_thread_start  -> PROC FRAME, .allocstack 40: the return address is at rsp+40, it is 0
0                    -> no caller: the end of the stack
```

`PROC FRAME`, `.allocstack`, and `.endprolog` make `ml64` generate the unwind entry of the assembly
function; without them, Windows could not step over it. A return address of 0 is the usual mark of the
outermost frame. So a backtrace in a thread function has exactly three frames: the thread function,
`_st_thread_main`, and `_st_md_thread_start`. A C++ `throw` is caught across any depth of frames, and an
unhandled exception ends the process with its exception code instead of hanging.

Linux has the same idea with DWARF `.eh_frame` instead of `.pdata`, but with no TIB check, and C++ code on
a thread stack normally catches its exceptions inside the thread function.

## Summary

| | Linux and macOS | Windows x64 |
| --- | --- | --- |
| PC of a new thread | In `st_thread_create`, after the save | `_st_md_thread_start`, in assembly |
| SP of a new thread | The new stack top | The new stack top, aligned, with a return address of 0 |
| First code on the new stack | The tail of `st_thread_create`, from the compiler | Four instructions written by hand |
| Depends on the optimizer | Yes, in theory | No |
| Stack walk at the top | Not defined | Ends at the return address of 0 |
| Registers saved | `rbx`, `rbp`, `r12`-`r15`, `rsp`, PC | Also `rdi`, `rsi`, `xmm6`-`xmm15`, MXCSR, x87 control word, TIB bounds |

Only `WIN64` defines `MD_INIT_THREAD_ENTRY` now; the other platforms keep the save-then-patch-SP trick. A
later change may give every platform and CPU an assembly entry, so all start new threads the same way.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Dvr (`skills/internal-docs-for-srs/references/cpp-docs/doc/dvr.md`)

---
title: DVR
sidebar_label: DVR 
hide_title: false
hide_table_of_contents: false
---

# DVR

SRS supports DVR RTMP stream to FLV/MP4 file. Although the bellow using FLV as example, but MP4 is also available.

When FFmpeg/OBS publish RTMP stream to SRS, SRS will write the stream to FLV/MP4 file. The workflow is:

```text
+------------+            +-------+           +---------------+
+ FFmpeg/OBS +---RTMP-->--+  SRS  +---DVR-->--+ FLV/MP4 File  +
+------------+            +-------+           +---------------+
```

Many users want more features about DVR, please consider use [Oryx](./getting-started-oryx.md#dvr) instead, 
for example:

* Oryx supports S3 cloud storage, move the final MP4 file to S3 cloud storage.
* Oryx supports glob filters, to only record specified streams, not all streams.
* Oryx supports merge multiple publishing sessions to one MP4 file.

In facts, DVR feature can be very complicated, SRS only support basic DVR feature, while Oryx will continue 
to improve the DVR features.

## Build

DVR is always enabled for SRS3+.

For information about the dvr option, read [Build](./install.md)

## Config

The difficult of DVR is about the flv name, while SRS use app/stream+random name.
User can use http-callback to rename, for example, when DVR reap flv file.

Config for DVR:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The plan of DVR used to reap flv file:

* session: When start publish, open flv file, close file when unpublish.
* segment: Reap flv file by the dvr_duration and dvr_wait_keyframe.
* time_jitter: The time jitter algorithm to use.
* dvr_path: The path of dvr, the rules is specified at below.

The config file can also use `conf/dvr.segment.conf` or `conf/dvr.session.conf`.

## Apply

The dvr apply is a filter which enable or disable the dvr of specified stream.
This feature is similar to nginx control module, but stronger than nginx.
User can use [http raw api](./http-api.md) to control when to dvr specified stream.
Please read [351](https://github.com/ossrs/srs/issues/459#issuecomment-134983742).

The following exmaple dvr `live/stream1`和`live/stream2`, the config:
```
vhost xxx {
    dvr {
        dvr_apply live/stream1 live/stream2;
    }
}
```

About the RAW API to control DVR, read [319](https://github.com/ossrs/srs/issues/319) and [wiki](./http-api.md#raw-dvr).

## Custom Path

We can custom the dvr path(dir and filename) by rules:

* Use date and time and stream info as dir name, to avoid too many files in a dir.
* Use date and time and stream info as filename, for better search.
* Provides the data/time and stream info variables, use brackets to identify them.
* Keep SRS1.0 rule, supports write to a specified dir and uses timestamp as filename. If no filename specified(dir specified only), use `[stream].[timestamp].flv` as filename to compatible with SRS1.0 rule.

About the data and time variable, refer to go time format string, for example, use an actual year 2006 instead YYYY, it's a good design:

```
2006-01-02 15:04:05.999
```

The variables of dvr:

1. Year, [2006], replace this const to current year.
1. Month, [01], replace this const to current month.
1. Date, [02], replace this const to current date.
1. Hour, [15], replace this const to current hour.
1. Minute, [04], repleace this const to current minute.
1. Second, [05], repleace this const to current second.
1. Millisecond, [999], repleace this const to current millisecond.
1. Timestamp, [timestamp],replace this const to current UNIX timestamp in ms.
1. Stream info, refer to transcode output, variables are [vhost], [app], [stream]

For example, for url `rtmp://ossrs.net/live/livestream` and time `2015-01-03 10:57:30.776`:

1. No variables, the rule of SRS1.0(auto add `[stream].[timestamp].flv` as filename):
    * dvr_path ./objs/nginx/html;
    * =>
    * dvr_path ./objs/nginx/html/live/livestream.1420254068776.flv;

1. Use stream and date as dir name, time as filename:
    * dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv;
    * =>
    * dvr_path /data/ossrs.net/live/livestream/2015/01/03/10.57.30.776.flv;

1. Use stream and year/month as dir name, date and time as filename:
    * dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]-[15].[04].[05].[999].flv;
    * =>
    * dvr_path /data/ossrs.net/live/livestream/2015/01/03-10.57.30.776.flv;

1. Use vhost/app and year/month as dir name, stream/date/time as filename:
    * dvr_path /data/[vhost]/[app]/[2006]/[01]/[stream]-[02]-[15].[04].[05].[999].flv;
    * =>
    * dvr_path /data/ossrs.net/live/2015/01/livestream-03-10.57.30.776.flv;

1. Use app as dirname, stream and timestamp as filename(the SRS1.0 rule):
    * dvr_path /data/[app]/[stream].[timestamp].flv;
    * =>
    * dvr_path /data/live/livestream.1420254068776.flv;

## Http Callback

Enable the `on_dvr` of `http_hooks`:

```
vhost your_vhost {
    dvr {
        enabled             on;
        dvr_path            ./objs/nginx/html/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv;
        dvr_plan            segment;
        dvr_duration        30;
        dvr_wait_keyframe   on;
    }
    http_hooks {
        enabled         on;
        on_dvr          http://127.0.0.1:8085/api/v1/dvrs;
    }
}
```

The log of api-server for api dvrs：

```
[2015-01-03 15:25:48][trace] post to dvrs, req={"action":"on_dvr","client_id":108,"ip":"127.0.0.1","vhost":"__defaultVhost__","app":"live","stream":"livestream","cwd":"/home/winlin/git/srs/trunk","file":"./objs/nginx/html/live/livestream/2015/1/3/15.25.18.442.flv"}
[2015-01-03 15:25:48][trace] srs on_dvr: client id=108, ip=127.0.0.1, vhost=__defaultVhost__, app=live, stream=livestream, cwd=/home/winlin/git/srs/trunk, file=./objs/nginx/html/live/livestream/2015/1/3/15.25.18.442.flv
127.0.0.1 - - [03/Jan/2015:15:25:48] "POST /api/v1/dvrs HTTP/1.1" 200 1 "" "SRS(Simple RTMP Server)2.0.88"
```

For more information, read about [HttpCallback](./http-callback.md)

## Bug

The bugs of dvr:

* The dir and filename rules: [#179](https://github.com/ossrs/srs/issues/179)
* The http callback for dvr: [#274](https://github.com/ossrs/srs/issues/274)
* The MP4 format support: [#738](https://github.com/ossrs/srs/issues/738)
* How to DVR multiple segments to a file?  Read [#776](https://github.com/ossrs/srs/pull/776).

## Reload

The changing of dvr and reload will restart the dvr, that is, to close current dvr file then apply new config.

Winlin 2015.1

---

### Skills Internal Docs For Srs References Cpp Docs Doc Edge (`skills/internal-docs-for-srs/references/cpp-docs/doc/edge.md`)

---
title: Edge Cluster
sidebar_label: Edge Cluster
hide_title: false
hide_table_of_contents: false
---

# Edge Server

SRS edge dedicates to support huge players for a small set of streams.



Note: The edge server need to serve many clients, the SRS performance is ok.

Use Scenarios for Edge:
* CDN/VDN RTMP cluster, for many clients to upload(publish) or download(play).
* Small cluster, but many clients to publish. Forward is not ok for all stream is forwarded,
while edge is ok for it only fetch when user play the specified stream.
* The BGP server is costly, while the edge is cheap. Use multiple levels edge
to ensure the BGP server low bandwidth.

Note: Edge can fetch  stream from or push stream to origin. When user play
a stream on edge, edge will fetch from origin. When user publish stream to
edge, edge will push to origin.

Note: Always use Edge, except you actually know the forward. The forward will
always forward stream to multiple servers; while the edge only fetch or push
stream to a server and switch to next when error.

## Concepts

When a vhost set mode to remote, the vhost in server is edge.
When a vhost set mode to local, the vhost in server is origin.
Edge is used to cache the stream of origin.

When user publish stream to the edge server, edge will forward the stream 
to origin. For example, the origin server is in beijing, a user at shanghai needs
to pubish stream to origin server, we can add a edge server at shanghai, when 
user publish stream to shanghai edge server, the edge server will forward stream to 
beijing.

When user play the stream on edge, edge will fetch from origin when it has not 
cache it yet. When edge already cached the stream, edge will directly delivery
stream to client. That is, when many clients connect to edge, there is only one
connection to origin for each stream. This is the CDN(content delivery network).
For example, the origin server is at beijing, there are 320 edge servers on other 
provience, each edge server serves 2000 clients. There are 640,000 users play this 
stream, and the bandwidth of CDN consumed 640Gbps; the origin server only serves 320 
connections from all edge servers.

The edge server is design for huge cluster. Futhermore, the SRS edge can config with
multiple origin servers, SRS will switch to next when current origin server crash, and
the end user never disconnect when edge switch origin server.

## Config

Config the edge in vhost:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The origin can specifies multiple servers.

## Example

The example below specifies how to config a origin and edge.

The config of origin, see `origin.conf`：

```bash
listen              19350;
pid                 objs/origin.pid;
srs_log_file        ./objs/origin.log;
vhost __defaultVhost__ {
}
```

The config of edge, see `edge.conf`：

```bash
listen              1935;
pid                 objs/edge.pid;
srs_log_file        ./objs/edge.log;
vhost __defaultVhost__ {
    cluster {
        mode            remote;
        origin          127.0.0.1:19350;
    }
}
```

## HLS Edge

The edge is for RTMP, that is, when publish stream to origin, only origin server output
the HLS, all edge server never output HLS util client access the RTMP stream on edge.

That is, never config HLS on edge server, it's no use. The HLS delivery must use squid or 
traffic server to cache the HTTP origin server.

## WebRTC Edge

Currently edge cluster only support RTMP and HTTP-FLV, doesn't support WebRTC. A new version 
of Edge Cluster is planning, see [#4402](https://github.com/ossrs/srs/discussions/4402) for details.

Note that you can use new version of [Origin Cluster](./origin-cluster.md) for WebRTC, as it 
can also used to expand the capacity of streams. However, if you need to expand the capacity 
of viewers for one stream, you still need the new version of Edge Cluster.

## Transform Vhost

The design of CDN stream system, always use `up.xxxx` and `down.xxxx` to operate them, for example, user publish to cdn by host `up.srs.com` and play by `down.srs.com`.

SRS can config the edge mode to transform the host to origin, use the config `vhost down.srs.com` for up edge server.

For more information, read the config of edge server.

Winlin 2015.4

---

### Skills Internal Docs For Srs References Cpp Docs Doc Exporter (`skills/internal-docs-for-srs/references/cpp-docs/doc/exporter.md`)

---
title: Prometheus Exporter
sidebar_label: Exporter
hide_title: false
hide_table_of_contents: false
---

# Prometheus Exporter

The observability of SRS is about metrics(Prometheus Exporter), tracing(APM) and logging(Cloud Logging). 

## Introduction

For detail specs, please read [OpenTelemetry](https://opentelemetry.io/docs/concepts/observability-primer).



> Note: Please see [Metrics, tracing, and logging](https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html)

The architecture for Prometheus exporter:

```
+-----+               +-----------+     +---------+
| SRS +--Exporter-->--| Promethus +-->--+ Grafana +
+-----+   (HTTP)      +-----------+     +---------+
```

There is special config for exporter.

## Config

The config for exporter is bellow. Highly recommend using environment variables to enable it:

```bash
# Prometheus exporter config.
# See https://prometheus.io/docs/instrumenting/exporters
exporter {
    # Whether exporter is enabled.
    # Overwrite by env SRS_EXPORTER_ENABLED
    # Default: off
    enabled off;
    # The http api listen port for exporter metrics.
    # Overwrite by env SRS_EXPORTER_LISTEN
    # Default: 9972
    # See https://github.com/prometheus/prometheus/wiki/Default-port-allocations
    listen 9972;
    # The logging label to category the cluster servers.
    # Overwrite by env SRS_EXPORTER_LABEL
    label cn-beijing;
    # The logging tag to category the cluster servers.
    # Overwrite by env SRS_EXPORTER_TAG
    tag cn-edge;
}
```

Let's start SRS exporter to export metrics to Prometheus.

## Usage for SRS Exporter

Build and start `SRS 5.0.86+`：

```bash
./configure && make
env SRS_ENV_ONLY=on SRS_EXPORTER_ENABLED=on SRS_RTMP_LISTEN=1935 \
  ./objs/srs -e
```

> Note: We use envrionment variables to config SRS, without config file. However, you're able to use config file `conf/prometheus.conf` to start the demo.

> Note: Please open [http://localhost:9972/metrics](http://localhost:9972/metrics) to verify SRS.

Then, use FFmpeg to push a live stream to SRS:

```bash
docker run --rm -it ossrs/srs:encoder ffmpeg -re -i doc/source.flv -c copy \
  -f flv rtmp://host.docker.internal/live/livestream
```

Next, run [node_exporter](https://github.com/prometheus/node_exporter) to collect the node data:

```bash
docker run --rm -p 9100:9100 prom/node-exporter
```

> Note: Highly recommend downloading from [here](https://github.com/prometheus/node_exporter/releases) and startting by binary file.

> Note: Please open [http://localhost:9100/metrics](http://localhost:9100/metrics) to verify it.

Finally, create a `prometheus.yml` for prometheus:

```yml
scrape_configs:
  - job_name: "node"
    metrics_path: "/metrics"
    scrape_interval: 5s
    static_configs:
      - targets: ["host.docker.internal:9100"]
  - job_name: "srs"
    metrics_path: "/metrics"
    scrape_interval: 5s
    static_configs:
      - targets: ["host.docker.internal:9972"]
```

> Note: We set the `scrape_interval` to `5s`, which is default to `1m` or one minute.

Start Prometheus by：

```bash
docker run --rm -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
  -p 9090:9090 prom/prometheus
```

Please ope [Prometheus: Targets](http://localhost:9090/targets), or [Prometheus: Graph](http://localhost:9090/graph) to query the input bitrate:

```sql
rate(srs_receive_bytes_total[10s])*8
```

This query is used to query the input bitrate, which is the bitrate of stream:



Normally we use Grafana to render the graph.

## Usage for Grafana

First, start Grafana in docker:

```bash
docker run --rm -it -p 3000:3000 \
  -e GF_SECURITY_ADMIN_USER=admin \
  -e GF_SECURITY_ADMIN_PASSWORD=12345678 \
  -e GF_USERS_DEFAULT_THEME=light \
  grafana/grafana
```

Please access Grafana console by [http://localhost:3000/](http://localhost:3000/)

> Note: Please input username `admin` and password `12345678` then click login.

Run command to [add](https://grafana.com/docs/grafana/latest/developers/http_api/data_source/#create-a-data-source) a Prometheus DataSource:

```bash
curl -s -H "Content-Type: application/json" \
    -XPOST http://admin:12345678@localhost:3000/api/datasources \
    -d '{
    "name": "prometheus",
    "type": "prometheus",
    "access": "proxy", "isDefault": true,
    "url": "http://host.docker.internal:9090"
}'
```

Run command to [import](https://grafana.com/docs/grafana/latest/developers/http_api/dashboard/#create--update-dashboard) the HelloWorld dashboard:

```bash
data=$(curl https://raw.githubusercontent.com/ossrs/srs-grafana/main/dashboards/helloworld-import.json 2>/dev/null)
curl -s -H "Content-Type: application/json" \
    -XPOST http://admin:12345678@localhost:3000/api/dashboards/db \
    --data-binary "{\"dashboard\":${data},\"overwrite\":true,\"inputs\":[],\"folderId\":0}"
```

> Note: For other dashboards, please see [srs-grafana](https://github.com/ossrs/srs-grafana/tree/main/dashboards).

Then open [Dashboards](http://localhost:3000/dashboards) in browser, you will see the imported dashboard:



There are more other dashboards, please get them in [srs-grafana](https://github.com/ossrs/srs-grafana/tree/main/dashboards). 



Any patch is welcome.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Ffmpeg (`skills/internal-docs-for-srs/references/cpp-docs/doc/ffmpeg.md`)

---
title: FFMPEG
sidebar_label: FFMPEG 
hide_title: false
hide_table_of_contents: false
---

# Live Streaming Transcode

SRS can transcode RTMP streams and output to any RTMP server, typically itself.

## Use Scenario

The important use scenario of FFMPEG:
* One in N out: Publish a high resolution video with big bitrate, for intance, h.264 5Mbps 1080p. Then use FFMPEG to transcode to multiple bitrates, for example, 1080p/720p/576p, the 576p is for mobile devices.
* Support multiple screen: The stream published by flash is in h264/vp6/mp3/speex codec. Use FFMPEG to transcode to HLS(h264+aac) for IOS/Android.
* Stream filters: For example, add logo to stream. SRS supports all filters from FFMPEG.
* Snapshot: Please read [snapshot by transcoder](./snapshot.md#transcoder)

## Workflow

The workflow of SRS transcoding:

1. Encoder publishes RTMP to SRS.
1. SRS forks a process for FFMPEG when transcoding is configured.
1. The forked FFMPEG transcodes the stream and publishes it to SRS or other servers.

## Transcode Config

The SRS transcoding feature can apply on vhost, app or a specified stream.

```
/* Detailed source-code truncated for AI context efficiency. */
```

The configuration applies to all streams of this vhost, for example:
* Publish stream to: rtmp://dev:1935/live/livestream
* Play the origin stream: rtmp://dev:1935/live/livestream
* Play the transcoded stream: rtmp://dev:1935/live/livestream_ff

The output URL contains some variables:
* [vhost] The input stream vhost, for instance, dev.ossrs.net
* [port] The input stream port, for instance, 1935
* [app] The input stream app, for instance, live
* [stream] The input stream name, for instance, livestream
* [engine] The transcode engine name, which follows the keyword engine, for instance, ff

Add the app or app/stream when you need to apply transcoding to it:

```bash
listen              1935;
vhost __defaultVhost__ {
    # Transcode all streams of app "live"
    transcode live {
    }
}
```

Or for streams:

```bash
listen              1935;
vhost __defaultVhost__ {
    # Transcode stream name is "livestream" and app is "live"
    transcode live/livestream{
    }
}
```

## Transcode Rulers

All params of SRS transcode are for FFMPEG, and SRS renames some parameters:

| SRS | FFMPEG | Exammple | Description |
| ------ | --------- | ---- | ----- |
| vcodec | vcodec | ffmpeg ... -vcodec libx264 ... | The codec to use. |
| vbitrate | b:v | ffmpeg ... -b:v 500000 ... | The bitrate in kbps (for SRS) or bps (for FFMPEG) at which to output the transcoded stream. |
| vfps | r | ffmpeg ... -r 25 ... | The output framerate. |
| vwidth/vheight | s | ffmpeg ... -s 400x300 -aspect 400:300 ... | The output video size, the width x height and the aspect set to width:height. |
| vthreads | threads | ffmpeg ... -threads 8 ... | The number of encoding threads for x264. |
| vprofile | profile:v | ffmpeg ... -profile:v high ... | The profile for x264. |
| vpreset | preset | ffmpeg ... -preset medium ... | The preset for x264. |
| acodec | acodec | ffmpeg ... -acodec libfdk_aac ... | The codec for audio. |
| abitrate | b:a | ffmpeg ... -b:a 70000 ... | The bitrate in kbps (for SRS) and bps (for FFMPEG) for output audio. For libaacplus：16-72k. No limit for libfdk_aac. |
| asample_rate | ar | ffmpeg ... -ar 44100 ... | The audio sample rate. |
| achannels | ac | ffmpeg ... -ac 2 ... | The audio channel. |

There are more parameters for SRS:
* vfilter：Parameters added before the vcodec, for the FFMPEG filters.
* vparams：Parameters added after the vcodec, for the video transcode parameters.
* aparams：Parameters added after the acodec and before the -y, for the audio transcode parameters.

These parameters will generated by the sequence:

```bash
ffmpeg -f flv -i <input_rtmp> {vfilter} -vcodec ... {vparams} -acodec ... {aparams} -f flv -y {output}
```

The actual parameters used to fork FFMPEG can be found in the log by the keywords `start transcoder`:

```bash
[2014-02-28 21:38:09.603][4][trace][start] start transcoder, 
log: ./objs/logs/encoder-__defaultVhost__-live-livestream.log, 
params: ./objs/ffmpeg/bin/ffmpeg -f flv -i 
rtmp://127.0.0.1:1935/live?vhost=__defaultVhost__/livestream 
-vcodec libx264 -b:v 500000 -r 25.00 -s 768x320 -aspect 768:320 
-threads 12 -profile:v main -preset medium -acodec libfdk_aac 
-b:a 70000 -ar 44100 -ac 2 -f flv 
-y rtmp://127.0.0.1:1935/live?vhost=__defaultVhost__/livestream_ff 
```

## FFMPEG Log Path

When an FFMPEG process is forked, SRS will redirect the stdout and stderr to the log file, for instance, `./objs/logs/encoder-__defaultVhost__-live-livestream.log`. Sometimes the log file is very large, so users can add parameters to vfilter to tell FFMPEG to generate less verbose logs:

```bash
listen              1935;
vhost __defaultVhost__ {
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine ff {
            enabled         on;
            vfilter {
                # -v quiet
                v           quiet;
            }
            vcodec          libx264;
            vbitrate        500;
            vfps            25;
            vwidth          768;
            vheight         320;
            vthreads        12;
            vprofile        main;
            vpreset         medium;
            vparams {
            }
            acodec          libfdk_aac;
            abitrate        70;
            asample_rate    44100;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}
```

That is, add the parameter `-v quiet` to FFMPEG.

## Copy Without Transcode

Set the vcodec/acodec to copy, FFMPEG will demux and mux without transcoding, like the forward of SRS. Users can copy video and transcode audio, for example, when flash is publishing the stream with h264+speex.

```bash
listen              1935;
vhost __defaultVhost__ {
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine ff {
            enabled         on;
            vcodec          copy;
            acodec          libfdk_aac;
            abitrate        70;
            asample_rate    44100;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}
```

Or, copy video and audio:
```bash
listen              1935;
vhost __defaultVhost__ {
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine ff {
            enabled         on;
            vcodec          copy;
            acodec          copy;
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}
```

## Drop Video or Audio

FFMPEG can drop video or audio streams by configuring vcodec to vn and acodec to an. For example:

```bash
listen              1935;
vhost __defaultVhost__ {
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine vn {
            enabled         on;
            vcodec          vn;
            acodec          libfdk_aac;
            abitrate        45;
            asample_rate    44100;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}
```

The configuration above will output pure audio in the aac codec.

## Other Transcoding Configuration

There are lots of vhost in conf/full.conf for transcoding, or refer to FFMPEG:
* mirror.transcode.srs.com
* drawtext.transcode.srs.com 
* crop.transcode.srs.com
* logo.transcode.srs.com 
* audio.transcode.srs.com
* copy.transcode.srs.com
* all.transcode.srs.com
* ffempty.transcode.srs.com 
* app.transcode.srs.com 
* stream.transcode.srs.com 
* vn.transcode.srs.com

## FFMPEG Transcoding Streams by Flash Encoder

Flash web pages can encode and publish RTMP streams to the server, and the audio codec must be speex, nellymoser or pcma/pcmu.

Flash will disable audio when no audio is published, so FFMPEG may cannot discover the audio in the stream and will disable the audio.

## FFMPEG

FFMPEG links:
* [ffmpeg.org](http://ffmpeg.org)
* [ffmpeg CLI](http://ffmpeg.org/ffmpeg.html)
* [ffmpeg filters](http://ffmpeg.org/ffmpeg-filters.html)
* [ffmpeg codecs](http://ffmpeg.org/ffmpeg-codecs.html)

Winlin 2015.6

---

### Skills Internal Docs For Srs References Cpp Docs Doc Flv (`skills/internal-docs-for-srs/references/cpp-docs/doc/flv.md`)

---
title: HTTP-FLV
sidebar_label: HTTP-FLV
hide_title: false
hide_table_of_contents: false
---

# HTTP-FLV

HTTP-FLV is a live streaming protocol, sometimes simply called FLV, which is used to transmit live streams in FLV 
format over an HTTP connection.

Unlike file downloads, live streams have an indefinite or uncertain length, so they are usually implemented using 
the HTTP Chunked protocol. Similar to HTTP-FLV, there are also HTTP-TS and HTTP-MP3. TS is mainly used in broadcasting 
and television, while MP3 is mainly used in the audio field.

Different from HLS, which is essentially an HTTP file download, HTTP-FLV is a streaming protocol. CDN support for 
HTTP file downloads is well-developed, making HLS more compatible than HTTP-FLV. However, HTTP-FLV has lower latency 
than HLS, typically achieving a delay of around 3 to 5 seconds, while HLS latency is generally 8 to 10 seconds or more.

In terms of protocol implementation, RTMP and HTTP-FLV are very similar. RTMP is based on the TCP protocol, and 
HTTP-FLV is based on HTTP, which is also a TCP protocol. Therefore, their characteristics are very similar. RTMP 
is generally used for streaming and live production because most live production devices support RTMP. For playback 
and consumption, HTTP-FLV or HLS is used because playback devices have better support for HTTP.

HTTP-FLV is highly compatible, supported by almost all platforms and browsers except for the native iOS browser. 
You can refer to [MSE](https://caniuse.com/?search=mse) for more information. To support the iOS browser, you can 
consider using HLS or WASM. Note that for native iOS apps, the ijkplayer can be used as a playback option.

## Usage

SRS supports HTTP-FLV distribution, you can use [docker](./getting-started.md) or [build from source](./getting-started-build.md):

```bash
docker run --rm -it -p 1935:1935 -p 8080:8080 \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_SERVER_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  ossrs/srs:8 ./objs/srs -e
```

Use [FFmpeg(click to download)](https://ffmpeg.org/download.html) or [OBS(click to download)](https://obsproject.com/download) to push the stream:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

Open the following page to play the stream (if SRS is not on your local machine, please replace localhost with the server IP):

* HLS by SRS player: [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html)

## Config

The configuration for HTTP-FLV is as follows:

```
/* Detailed source-code truncated for AI context efficiency. */
```

> Note: These settings are only for playing HLS. For streaming settings, please follow your protocol, like referring to [RTMP](./rtmp.md#config), [SRT](./srt.md#config), or [WebRTC](./webrtc.md#config) streaming configurations.

The important settings are explained below:

* `has_audio`: If there is an audio stream or not. If your stream doesn't have audio, set this to `off`. Otherwise, the player might wait for audio.
* `has_video`: If there is a video stream or not. If your stream doesn't have video, set this to `off`. Otherwise, the player might wait for video.

## Cluster

SRS supports HTTP-FLV cluster distribution, which can handle a large number of viewing clients. Please refer to [HTTP-FLV Cluster](./sample-http-flv-cluster.md) and [Edge](./edge.md).

## Crossdomain

SRS supports HTTP CORS by default. Please refer to [HTTP CORS](./http-server.md#crossdomain).

## Websocket FLV

You can convert HTTP-FLV to WebSocket-FLV stream. Please refer to [videojs-flow](https://github.com/winlinvip/videojs-flow).

For HTTP to WebSocket conversion, please refer to [mse.go](https://github.com/winlinvip/videojs-flow/blob/master/demo/mse.go).

## HTTP FLV VOD Stream

For HTTP FLV on-demand streaming, please refer to: [v4_CN_FlvVodStream](./flv-vod-stream.md).

## HTTP and HTTPS Proxy

SRS works well with HTTP/HTTPS proxies such as [Nginx](https://github.com/ossrs/srs/issues/2881#nginx-proxy), [HTTPX](https://github.com/ossrs/srs/issues/2881#httpx-proxy), [CaddyServer](https://github.com/ossrs/srs/issues/2881#caddy-proxy), etc. For detailed configuration, please refer to [#2881](https://github.com/ossrs/srs/issues/2881).

## HTTPS FLV Live Stream

SRS supports converting RTMP streams to HTTPS FLV streams. When publishing RTMP streams, a corresponding HTTP address is mounted in the SRS HTTP module (according to the configuration). Users can access this HTTPS FLV file, and the RTMP stream is converted to FLV for distribution.

Please refer to [HTTPS Server](./http-server.md#https-server) or the `conf/https.flv.live.conf` configuration file.

## HTTP TS Live Stream

SRS supports converting RTMP streams to HTTP TS streams. When publishing RTMP streams, a corresponding HTTP address is mounted in the SRS HTTP module (according to the configuration). Users can access this HTTP TS file, and the RTMP stream is converted to TS for distribution.

Please refer to the `conf/http.ts.live.conf` configuration file.

## HTTP Mp3 Live Stream

SRS supports discarding video from RTMP streams and converting audio streams to MP3 format. A corresponding HTTP address is mounted in the SRS HTTP module (according to the configuration). Users can access this HTTP MP3 file, and the RTMP stream is converted to MP3 for distribution.

Please refer to the `conf/http.mp3.live.conf` configuration file.

## HTTP Aac Live Stream

SRS supports discarding video from RTMP streams and converting audio streams to AAC format. A corresponding HTTP address is mounted in the SRS HTTP module (according to the configuration). Users can access this HTTP AAC file, and the RTMP stream is converted to AAC for distribution.

Please refer to the `conf/http.aac.live.conf` configuration file.

## Why HTTP FLV

Why use HTTP FLV? HTTP FLV streaming is becoming more popular. The main advantages are:

1. In the field of real-time Internet streaming media, RTMP is still dominant. HTTP-FLV has the same latency as RTMP, so it can meet latency requirements.
2. Firewall penetration: Many firewalls block RTMP but not HTTP, so HTTP FLV is less likely to have strange issues.
3. Scheduling: RTMP has a 302 feature, but it's only supported in the player's ActionScript. HTTP FLV supports 302, making it easier for CDNs to correct DNS errors.
4. Fault tolerance: SRS's HTTP FLV can have multiple sources, just like RTMP, supporting multi-level hot backup.
5. Universality: Flash can play both RTMP and HTTP FLV. Custom apps and mainstream players also support HTTP FLV playback.
6. Simplicity: FLV is the simplest streaming media encapsulation, and HTTP is the most widely used protocol. Combining these two makes maintenance much easier than RTMP.

## IPv6

SRS (v7.0.67+) supports IPv6 for HTTP-FLV streaming, enabling dual-stack (IPv4/IPv6) operation for low-latency live streaming. This allows HTTP-FLV clients to access streams using IPv6 addresses while maintaining full compatibility with existing IPv4 infrastructure.

IPv6 support is enabled automatically when SRS detects IPv6 addresses in the HTTP server configuration. Configure the HTTP server to listen on IPv6 addresses:

```bash
http_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 8080 [::]:8080;
    dir ./objs/nginx/html;
}
```

Access HTTP-FLV streams via IPv6:

```bash
# HTTP-FLV stream via IPv6
http://[::1]:8080/live/livestream.flv
```

Play HTTP-FLV stream via IPv6 using FFplay:

```bash
ffplay 'http://[::1]:8080/live/livestream.flv'
```

SRS supports dual-stack HTTP-FLV operation, allowing both IPv4 and IPv6 clients to access streams simultaneously:

```bash
http_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 8080 [::]:8080;
    dir ./objs/nginx/html;
}
vhost __defaultVhost__ {
    http_remux {
        enabled on;
        mount [vhost]/[app]/[stream].flv;
    }
}
```

This configuration allows:
- IPv4 clients: `http://192.168.1.100:8080/live/livestream.flv`
- IPv6 clients: `http://[2001:db8::1]:8080/live/livestream.flv`

---

### Skills Internal Docs For Srs References Cpp Docs Doc Forward (`skills/internal-docs-for-srs/references/cpp-docs/doc/forward.md`)

---
title: Forward
sidebar_label: Forward 
hide_title: false
hide_table_of_contents: false
---

# Forward For Small Cluster

SRS is design for live server, the forward is a important feature, used to 
forward stream on server to other live servers.

Note: The information about edge, read [Edge](./edge.md),
the best solution for large cluster and huge concurrency.

Note: The edge is for both play and publish.

Note: Use edge first, except need to copy a stream to multiple servers in a time.

The forward is used for fault backup, the origin can forward a stream to multiple origin servers, 
the edge can use multiple origin server for backup.

For the usage of forward, read [Usage: Forward](./sample-forward.md)

## Keywords

The forward defined some roles:

* master: The master server which forward stream to slave server.
* slave: The slave server which accept stream from master.

Although the origin/edge can be master/slave, but it is too complex, it is strongly recomments that
the forward(master/slave) only for origin, never use edge to forward stream.

## Config

Please refer to the vhost `same.vhost.forward.srs.com` of `full.conf`:

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Dynamic Forward

SRS support dynamic forwarding, to query the forwarding config from your backend API.

So you must write a backend server, which is an HTTP server, or web server. It accepts HTTP requests from SRS, and then 
responses the content with configs for SRS to do forward. It works like this:

```text
                        +------+
Client ---Push-RTMP-->--+ SRS  +---HTTP-Request---> Your Backend Server
                        |      |                        +
                        +      +--<---Forward-Config----+
                        |      |
                        +      +----Push-RTMP----> RTMP Server
                        +------+
```

First, config the `backend` of forward:

```
vhost __defaultVhost__ {
    forward {
        enabled on;
        backend http://127.0.0.1:8085/api/v1/forward;
    }
}
```

While client publishing to SRS, SRS will request your HTTP backend server, with request body:

```json
{
    "action": "on_forward",
    "server_id": "vid-k21d7y2",
    "client_id": "9o7g1330",
    "ip": "127.0.0.1",
    "vhost": "__defaultVhost__",
    "app": "live",
    "tcUrl": "rtmp://127.0.0.1:1935/live",
    "stream": "livestream",
    "param": ""
}
```

If your backend server responses with RTMP urls, SRS will start forwarding to the RTMP server:

```json
{
   "code": 0,
   "data": {
       "urls":[
          "rtmp://127.0.0.1:19350/test/teststream"
       ]
   }
}
```

> Note: If urls is empty array, SRS won't forward it.

For more details about dynamic forwarding, please read [#1342](https://github.com/ossrs/srs/issues/1342).

> Note: If both `backend` and `destination` are configured, SRS uses only the `backend`, even if it returns no urls.

## Keyframe Restart

Each forwarder is an RTMP client that publishes to its destination. When the destination is down, the forwarder
retries every 3 seconds, while the stream keeps coming from the encoder.

After each successful publish to the destination, the first one and every reconnect, the forwarder starts fresh from live:

* It drops the media queued before the publish succeeded, so the destination never gets a burst of stale media.
* It sends the metadata, then the video and audio sequence headers, once each.
* It drops video until the next keyframe, so the destination never starts in the middle of a GOP. Audio is never dropped.

The forwarder queue is bounded by `play.queue_length` of the vhost. When the destination is too slow and the queue
overflows, the forwarder drops the queued media and waits for the next keyframe the same way.

This is always on, with no config.

## Forward Status

SRS lists each forwarder of each publishing stream by the HTTP API `/api/v1/forwards/`, for both `destination`
and `backend` forwarders. It is read-only:

```bash
curl http://127.0.0.1:1985/api/v1/forwards/
```

```json
{
  "code": 0,
  "server": "vid-0w2w3z5",
  "service": "x0e5c1u5",
  "pid": "50234",
  "total": 1,
  "forwards": [
    {
      "id": "fwd-3k9x1zq",
      "stream": "vid-a4r1n2m",
      "vhost": "vid-7m2c0d1",
      "app": "live",
      "name": "livestream",
      "url": "rtmp://192.168.1.6:1935/live/livestream",
      "state": "forwarding",
      "state_at": 1760086530123
    }
  ]
}
```

The `total` is the number of forwards, after the `?stream=` filter if any. The list has at most `count` forwards
from `start` (default 0 and 10), so use `total` to page through them.

The fields of each forward:

* `id`: The id of the forward, for `/api/v1/forwards/{id}`. It stays the same across retries; each publish creates new forwarders with new ids.
* `stream`: The id of the publishing stream, the same as `/api/v1/streams/`. The `vhost`, `app` and `name` are those of the publishing stream.
* `url`: The RTMP url the forwarder publishes to, with the stream key and query. For `destination`, it is the destination with the app, stream and query of the publisher; for `backend`, it is the url the backend returned. SRS may append a `vhost` param, for example, `?vhost=localhost` when the publisher used `rtmp://localhost/live/livestream`, or the IP of a backend url without a `vhost` param.
* `state`: `connecting` until the publish to the destination succeeds, `forwarding` while sending, or `retrying` during the 3 seconds wait after an error.
* `state_at`: When the forward entered this state, in Unix milliseconds.

A forwarder exists only while its stream is publishing; it is removed when the stream unpublishes. To query the forwards
of one stream, use `?stream=<stream id>`; to query one forward, use its id:

```bash
curl http://127.0.0.1:1985/api/v1/forwards/?stream=vid-a4r1n2m
curl http://127.0.0.1:1985/api/v1/forwards/fwd-3k9x1zq
```

See [HTTP API: Forwards](./http-api.md#forwards) for details.

> Note: The url contains the stream key, so please protect the HTTP API by `http_api.auth`.

## Add or Remove a Forward

SRS creates the forwarders of a stream only when the stream is published, and deletes them when it unpublishes.
There is no API to add or remove a forward of a live stream, and `/api/v1/forwards/` is read-only: `DELETE`
returns HTTP 405. Removing a forwarder is the same as kicking its publisher, so SRS keeps only these primitives:

* For dynamic forward, your backend decides which forwards to create, on each publish.
* Kicking the publisher deletes every forwarder of the stream.

To stop a forward that is not created yet, your backend returns no url for it in the next `on_forward`.

To stop an active forward, your backend stops returning its url, then kicks the publisher. When the encoder
republishes, SRS asks your backend again, and creates only the forwards it returns. Adding a forward to a live
stream works the same way: return the new url, then kick the publisher.

To kick the publisher of a forward, find the stream id of the forward, then the client id of the publisher:

```bash
# 1. The stream id of the forward, the field `stream`.
curl http://127.0.0.1:1985/api/v1/forwards/
# 2. The client id of the publisher, the field `stream.publish.cid`.
curl http://127.0.0.1:1985/api/v1/streams/vid-a4r1n2m
# 3. Kick the publisher.
curl -X DELETE http://127.0.0.1:1985/api/v1/clients/4o3v9172
```

After the kick, the forwards of the stream are removed from `/api/v1/forwards/`. The encoder must republish by itself,
for example, by a loop in a script; the new forwarders get new ids.

> Note: For `destination`, kicking the publisher and republishing creates the same forwards again. To change the
> destinations, change the config and restart SRS.

## For Small Cluster

Forward can also used to build a small cluster:

```bash
                                   +-------------+    +---------------+
                               +-->+ Slave(1935) +->--+  Player(3000) +
                               |   +-------------+    +---------------+
                               |   +-------------+    +---------------+
                               |-->+ Slave(1936) +->--+  Player(3000) +
         publish       forward |   +-------------+    +---------------+
+-----------+    +--------+    |     192.168.1.6                       
|  Encoder  +-->-+ Master +-->-|                                       
+-----------+    +--------+    |   +-------------+    +---------------+
 192.168.1.3    192.168.1.5    +-->+ Slave(1935) +->--+  Player(3000) +
                               |   +-------------+    +---------------+
                               |   +-------------+    +---------------+
                               +-->+ Slave(1936) +->--+  Player(3000) +
                                   +-------------+    +---------------+
                                     192.168.1.7                          
```

The below sections is the example for this small cluster.

### Encoder

Use FFMPEG as encoder to publish stream to master:

```bash
for((;;)); do\
    ./objs/ffmpeg/bin/ffmpeg -re -i doc/source.flv \
        -c copy -f flv rtmp://192.168.1.5:1935/live/livestream; \
done
```

### SRS-Master Server

The SRS master server(192.168.1.5) config:

```bash
listen              1935;
pid                 ./objs/srs.pid;
max_connections     10240;
vhost __defaultVhost__ {
    forward {
        enabled on;
        destination 192.168.1.6:1935 192.168.1.6:1936 192.168.1.7:1935 192.168.1.7:1936;
    }
}
```

The RTMP play url on master is: `rtmp://192.168.1.5/live/livestream`

The master will forward stream to four slaves on two servers.

### SRS-Slave Server

The slave server can use different port to run on multiple cpu server.
The slave on the same server must use different port and pid file.

For example, the slave server 192.168.1.6, start two SRS servers, listen at 1935 and 1936.

The config file for port 1935 `srs.1935.conf`:

```bash
listen              1935;
pid                 ./objs/srs.1935.pid;
max_connections     10240;
vhost __defaultVhost__ {
}
```

The config file for port 1936 `srs.1936.conf`:

```bash
listen              1936;
pid                 ./objs/srs.1936.pid;
max_connections     10240;
vhost __defaultVhost__ {
}
```

Start these two SRS processes:

```bash
nohup ./objs/srs -c srs.1935.conf >/dev/null 2>&1 &
nohup ./objs/srs -c srs.1936.conf >/dev/null 2>&1 &
```

The player random access these streams:
* `rtmp://192.168.1.6:1935/live/livestream`
* `rtmp://192.168.1.6:1936/live/livestream`

The other slave server 192.168.1.7 is similar to 192.168.1.6

### Stream in Service

The stream in service:

| Url | Server | Port | Clients |
| ---- | ----- | ----- | ------- |
| rtmp://192.168.1.6:1935/live/livestream | 192.168.1.6 | 1935 | 3000 |
| rtmp://192.168.1.6:1936/live/livestream | 192.168.1.6 | 1936 | 3000 |
| rtmp://192.168.1.7:1935/live/livestream | 192.168.1.7 | 1935 | 3000 |
| rtmp://192.168.1.7:1936/live/livestream | 192.168.1.7 | 1936 | 3000 |

This architecture can support 12k clients. 
User can add more slave or start new ports.

## Forward VS Edge

The forward is not used in cdn, because CDN has thousands of servers, thousands of streams. 
The forward will always forward all stream to slave servers.

CDN or large cluster must use edge, never use forward.

## Other Use Scenarios

Forward used for transcoder, we can transcode a h.264+speex stream to a vhost, while this vhost forward
stream to slave. Then all stream on slave is h.264+aac, to delivery HLS.

Winlin 2014.11

---

### Skills Internal Docs For Srs References Cpp Docs Doc Gb28181 (`skills/internal-docs-for-srs/references/cpp-docs/doc/gb28181.md`)

---
title: GB28181
sidebar_label: GB28181
hide_title: false
hide_table_of_contents: false
---

# GB28181

SRS uses an external SIP server, such as
[srs-sip](https://github.com/ossrs/srs-sip), for GB28181 signaling and receives
the media stream as RTP/PS over TCP. The external SIP server creates the SRS
media session through the HTTP API, then instructs the device to publish to the
TCP port returned by SRS.

Build SRS with GB28181 enabled:

```bash
./configure --gb28181=on && make
```

Configure the GB28181 stream caster:

```conf
stream_caster {
    enabled on;
    caster gb28181;
    output rtmp://127.0.0.1/live/[stream];
    listen 9000;

    # Maximum time, in seconds, that an API-created session waits for its
    # media TCP connection. Fractional values such as 0.5 are supported.
    # Default: 10
    media_connect_timeout 10;
}

http_api {
    enabled on;
    listen 1985;
}
```

## External SIP API

After completing the SIP negotiation, create the media session with the stream
ID and decimal RTP SSRC selected by the external SIP server:

```bash
curl -X POST http://127.0.0.1:1985/gb/v1/publish/ \
  -H 'Content-Type: application/json' \
  -d '{"id":"34020000001320000001","ssrc":"47190001"}'
```

SRS returns the media endpoint:

```json
{"code":0,"port":9000,"is_tcp":true}
```

The device or external SIP service should then connect to the returned port and
publish RFC4571-framed RTP/PS over TCP using the same SSRC.

## Session Lifecycle

The stream ID and SSRC uniquely reserve a GB28181 session. Creating another
session with either value while it remains reserved returns `StreamBusy`.

`media_connect_timeout` controls how long SRS keeps a session that was created
through `/gb/v1/publish/` but never receives its media TCP connection. It is
measured in seconds, supports fractional values, and defaults to 10 seconds.
When the timeout expires, SRS releases both the stream ID and SSRC so the
external SIP server can publish them again.

Once the media TCP connection binds, the connection owns the media-session
lifecycle and `media_connect_timeout` no longer applies. Closing the current TCP
connection destroys the session and releases its stream ID and SSRC. A later
publish request may therefore reuse both values.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Getting Started Ai (`skills/internal-docs-for-srs/references/cpp-docs/doc/getting-started-ai.md`)

---
title: AI Agent
sidebar_label: AI Agent
hide_title: false
hide_table_of_contents: false
---

# AI Agent

SRS provides several ways to use AI: you can chat with the SRS Robot in Telegram or Discord for quick answers, or run AI locally with Claude Code, Codex, OpenClaw, or Kiro using the pre-configured SRS knowledge base.

## Claude Code

You can use Claude Code locally with the SRS codebase. SRS ships with its skills in the `.claude/skills` directory, so Claude Code works out of the box with full context of the project.

Clone the SRS code, related projects, and start Claude Code:

```bash
git clone https://github.com/ossrs/oryx.git
git clone https://github.com/ossrs/dev-docker.git
git clone https://github.com/ossrs/srs.git
cd srs
claude
```

Claude Code will automatically load the SRS skills from `srs/.claude/skills`, giving it deep knowledge of the SRS codebase so you can ask questions, debug issues, write code, and more.

## Codex

You can also use Codex locally with the SRS codebase. SRS ships with its skills in the `.agents/skills` directory, so Codex works out of the box.

Clone the SRS code, related projects, and start Codex:

```bash
git clone https://github.com/ossrs/oryx.git
git clone https://github.com/ossrs/dev-docker.git
git clone https://github.com/ossrs/srs.git
cd srs
codex
```

Codex will automatically load the SRS skills from `srs/.agents/skills`.

## Kiro

You can also use Kiro locally with the SRS codebase. SRS ships with its skills in the `.kiro/skills` directory, so Kiro works out of the box.

Clone the SRS code, related projects, and start Kiro:

```bash
git clone https://github.com/ossrs/oryx.git
git clone https://github.com/ossrs/dev-docker.git
git clone https://github.com/ossrs/srs.git
cd srs
kiro-cli
```

Kiro will automatically load the SRS skills from `srs/.kiro/skills`.

## OpenClaw

You can create an OpenClaw agent with the SRS knowledge base for local use. First 
clone the SRS code, and related projects:

```bash
git clone https://github.com/ossrs/oryx.git
git clone https://github.com/ossrs/dev-docker.git
git clone https://github.com/ossrs/srs.git
```

There are two ways to point the agent at the SRS knowledge base:

- **Set the workspace directly** — when creating the agent, set the workspace path to `srs/.openclaw`.
- **Soft link** — create the agent with its default workspace, then remove the default workspace directory and replace it with a soft link to `srs/.openclaw`:

```bash
ln -sf ~/git/srs/.openclaw ~/.openclaw/workspace
```

Once the agent is running, list the available skills and trigger them to load the knowledge base. The skills tell the AI which files to load and how to work more effectively with the SRS codebase.

## SRS Robot

SRS provides an AI-powered support robot built on OpenClaw, available in both the Telegram group and Discord channel. The robot has a deep knowledge base covering SRS code, documentation, and common usage scenarios, and is powered by the latest AI model.

You can ask the SRS Robot anything about SRS — how to use it, how to match your use case, how to configure it, how to debug issues, or any other questions. The robot will give you accurate, up-to-date answers based on the latest SRS knowledge base.

Join the SRS Telegram group: [https://t.me/+RiynvKOxpQ42MGJl](https://t.me/+RiynvKOxpQ42MGJl)

Join the SRS Discord channel: [https://discord.gg/yZ4BnPmHAd](https://discord.gg/yZ4BnPmHAd)

Once you're in the group, @ the SRS Robot and ask your question directly.

## Skills

After starting Claude Code, Codex, OpenClaw, or Kiro with the SRS codebase, you should use skills to get the best results. Skills load the right knowledge base for your task and guide the AI through the correct workflow.

The `srs-support` skill is provided for answering questions about the SRS project. It automatically loads the relevant knowledge base based on your question, so the AI can give you accurate and context-aware answers.

More skills will be added over time. To see what skills are currently available, simply ask the AI:

```
What skills can I use for SRS?
```

## Knowledge Base

Code and documentation alone are not enough for AI to truly understand and maintain a project. There is background knowledge, design thinking, accumulated experience, use cases, community communication, and debugging workflows that live only in people's heads — not in any file. The SRS knowledge base is an effort to make all of that explicit.

The knowledge base is the AI agent memory — files that encode the background, experience, and context behind SRS. It is built by having AI read the code and documents, then talking with AI to surface the implicit knowledge and write it down. Over time, the knowledge base will cover everything: not just what the code does, but why it was designed that way, how to think about problems, and how to operate and maintain the project.

The knowledge base and the code together are the single source of truth for SRS. The knowledge base captures what the code cannot — background, design decisions, use cases, debugging experience, and community knowledge. In the future, traditional documentation will be generated from the knowledge base and maintained entirely by AI.

On top of the knowledge base, there are skills. Skills are workflows that tell AI how to handle specific tasks, such as:

- **Support** — answering user questions and matching use cases
- **Issue triage and fix** — understanding, reproducing, and resolving issues
- **Feature development** — designing and implementing new features
- **Maintenance** — reviewing pull requests, managing releases, keeping the project healthy
- **Debugging** — diagnosing and tracing problems in the codebase

Each skill loads the relevant parts of the knowledge base and guides the AI through the right workflow for that task. This is what makes AI effective at maintaining SRS — not just raw intelligence, but structured knowledge and workflows built up over time.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Getting Started Build (`skills/internal-docs-for-srs/references/cpp-docs/doc/getting-started-build.md`)

---
title: Build
sidebar_label: Build
hide_title: false
hide_table_of_contents: false
---

# Build

You can build SRS from source code, but [docker](./getting-started.md) is highly recommend.

## Live Streaming

SRS supports live streaming.

Get SRS source, recommend [Ubuntu20](./install.md):

```
git clone -b develop https://github.com/ossrs/srs.git
```

Build SRS in `srs/trunk`:

```
cd srs/trunk
./configure
make
```

Run SRS server:

```
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_SERVER_ENABLED=on \
    SRS_VHOST_HTTP_REMUX_ENABLED=on SRS_VHOST_HLS_ENABLED=on \
    ./objs/srs -e
```

Check SRS by [http://localhost:8080/](http://localhost:8080/) or by the HTTP API, and the logs are in the console:

```
curl http://localhost:1985/api/v1/versions
```

Publish stream by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) :

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

> Note: The file `./doc/source.flv` is under the source repository of SRS.

Play stream by:

* RTMP (by [VLC](https://www.videolan.org/)): `rtmp://localhost/live/livestream`
* H5(HTTP-FLV): [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)
* H5(HLS): [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.m3u8&port=8080&schema=http)

## WebRTC

SRS supports WebRTC for video chat.

Get SRS source, recommend [Ubuntu20](./install.md):

```
git clone -b develop https://github.com/ossrs/srs.git
```

Build SRS in `srs/trunk`:

```
cd srs/trunk
./configure
make
```

Run SRS server:

```
CANDIDATE="192.168.1.10"
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_SERVER_ENABLED=on \
    SRS_RTC_SERVER_ENABLED=on SRS_RTC_SERVER_CANDIDATE=$CANDIDATE SRS_VHOST_RTC_ENABLED=on \
    SRS_VHOST_HTTP_REMUX_ENABLED=on SRS_VHOST_HLS_ENABLED=on \
    ./objs/srs -e
```

> Note: Please replace the IP with your server IP.

> Note: About CANDIDATE, please read [CANDIDATE](./webrtc.md#config-candidate)

Check SRS by [http://localhost:8080/](http://localhost:8080/) or by the HTTP API, and the logs are in the console:

```
curl http://localhost:1985/api/v1/versions
```

If SRS runs on localhost, push stream to SRS by [WebRTC: Publish](http://localhost:8080/players/rtc_publisher.html?autostart=true&stream=livestream&port=8080&schema=http)

> Note: If not localhost, browser(WebRTC) requires HTTPS, please see [WebRTC using HTTPS](./getting-started.md#webrtc-using-https) for detail.

Play stream of SRS by [WebRTC: Play](http://localhost:8080/players/rtc_player.html?autostart=true&stream=livestream&schema=http)

> Note: If use different streams, you're able to do video chat application.

## WebRTC for Live Streaming

SRS supports converting live streaming to WebRTC.

Get SRS source, recommend [Ubuntu20](./install.md):

```
git clone -b develop https://github.com/ossrs/srs.git
```

Build SRS in `srs/trunk`:

```
cd srs/trunk
./configure
make
```

Run SRS server:

```
CANDIDATE="192.168.1.10"
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_SERVER_ENABLED=on \
    SRS_RTC_SERVER_ENABLED=on SRS_RTC_SERVER_CANDIDATE=$CANDIDATE SRS_VHOST_RTC_ENABLED=on \
    SRS_VHOST_RTC_RTMP_TO_RTC=on SRS_VHOST_RTC_RTC_TO_RTMP=on \
    SRS_VHOST_HTTP_REMUX_ENABLED=on SRS_VHOST_HLS_ENABLED=on \
    ./objs/srs -e
```

> Note: Please replace the IP with your server IP.

> Note: About CANDIDATE, please read [CANDIDATE](./webrtc.md#config-candidate)

> Note: If convert RTMP to WebRTC, you can also use the config file [`rtmp2rtc.conf`](https://github.com/ossrs/srs/issues/2728#rtmp2rtc-cn-guide)

Publish stream by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) :

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

> Note: The file `./doc/source.flv` is under the source repository of SRS.

Play stream by:

* WebRTC: [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html?autostart=true)
* H5(HTTP-FLV): [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)
* H5(HLS): [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.m3u8&port=8080&schema=http)

## WebRTC using HTTPS

If not localhost, for example, to view WebRTC on pad or mobile phone, when SRS is running on remote server.

Get SRS source, recommend [Ubuntu20](./install.md):

```
git clone -b develop https://github.com/ossrs/srs.git
```

Build SRS in `srs/trunk`:

```
cd srs/trunk
./configure
make
```

Run SRS server:

```
CANDIDATE="192.168.1.10"
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_HTTPS_ENABLED=on \
    SRS_HTTP_SERVER_ENABLED=on SRS_HTTP_SERVER_HTTPS_ENABLED=on \
    SRS_RTC_SERVER_ENABLED=on SRS_RTC_SERVER_CANDIDATE=$CANDIDATE SRS_VHOST_RTC_ENABLED=on \
    SRS_VHOST_HTTP_REMUX_ENABLED=on \
    ./objs/srs -e
``` 

> Note: Please replace the IP with your server IP.

> Note: About CANDIDATE, please read [CANDIDATE](./webrtc.md#config-candidate)

> Remark: Please use your HTTPS key and cert file, please read
> **[HTTPS API](./http-api.md#https-api)**
> and **[HTTPS Callback](./http-callback.md#https-callback)**
> and **[HTTPS Live Streaming](./flv.md#https-flv-live-stream)**,
> however HTTPS proxy also works perfect with SRS such as Nginx.

Push stream to SRS by [WebRTC: Publish](https://192.168.3.82:8088/players/rtc_publisher.html?autostart=true&stream=livestream&api=1990&schema=https)

Play stream of SRS by [WebRTC: Play](https://192.168.3.82:8088/players/rtc_player.html?autostart=true&stream=livestream&api=1990&schema=https)

> Note: For self-sign certificate, please type `thisisunsafe` to accept it.

> Note: If use different streams, you're able to do video chat application.

## Cross Build

Normally you're able to build SRS on both ARM or MIPS servers.

If need to cross-build SRS for embed devices, pelase read [ARM and CrossBuild](./arm.md).

---

### Skills Internal Docs For Srs References Cpp Docs Doc Getting Started Cdk (`skills/internal-docs-for-srs/references/cpp-docs/doc/getting-started-cdk.md`)

---
title: CDK
sidebar_label: CDK
hide_title: false
hide_table_of_contents: false
---

# CDK

Please use [srs-cdk](https://github.com/ossrs/srs-cdk) to deploy SRS on AWS.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Hevc (`skills/internal-docs-for-srs/references/cpp-docs/doc/hevc.md`)

---
title: HEVC
sidebar_label: HEVC
hide_title: false
hide_table_of_contents: false
---

# HEVC

HEVC, also known as H.265, is the next-generation encoding after H.264 and belongs to the same generation of codecs
as AV1. H.265 can save about half the bandwidth compared to H.264, or provide double the clarity and image quality at
the same bandwidth.

However, the problem with H.265 is that it's not yet widely supported by clients. Almost all devices support H.264,
including low-performance phones or boxes, which have dedicated chips for H.264 support. Although H.265 has been
developed for almost ten years, there are still not enough devices that support it. In specific scenarios, like when
the device clearly supports H.265, you can choose H.265; otherwise, stick with H.264.

Additionally, the support for H.265 in transport protocols is gradually improving, but not all protocols support it
yet. MPEG-TS was the first to support H.265, and since SRT and HLS are based on TS, they also support it. RTMP and
HTTP-FLV only started supporting HEVC and AV1 in March 2023 with the [Enhanced RTMP](https://github.com/veovera/enhanced-rtmp)
project. As for WebRTC, only Safari supports it currently, and Chrome is said to be in development.

SRS 6.0 officially supports the H.265 feature. If you want to use the H.265 function, please switch to the SRS 
6.0 version. Please refer to [#465](https://github.com/ossrs/srs/issues/465) for the detailed research and development process.

## Overview

The architecutre for SRS to support H.265(or HEVC):

```text
FFmpeg --RTMP(h.265)---> SRS ----RTMP/FLV/TS/HLS/WebRTC(h.265)--> Chrome/Safari
```

For live streaming:

* [Chrome 105+](https://caniuse.com/?search=HEVC) supports HEVC by default, see [this post](https://zhuanlan.zhihu.com/p/541082191).
    * You're able to play mp4 directly by H5 video, or by MSE if HTTP-FLV/HTTP-TS/HLS etc.
    * Please use [mpegts.js](https://github.com/xqq/mpegts.js) to play HTTP-TS with HEVC.
    * There is a plan for mpegts.js to support HTTP-FLV with HEVC, see [mpegts.js#64](https://github.com/xqq/mpegts.js/issues/64)
* [OBS 29+](https://github.com/obsproject/obs-studio/releases/tag/29.1.3) supports HEVC over RTMP.
* FFmpeg or ffplay supports libx265
    * FFmpeg 6 supports HEVC over RTMP, see [637c761b](https://github.com/FFmpeg/FFmpeg/commit/637c761be1bf9c3e1f0f347c5c3a390d7c32b282) for detail.
    * FFmpeg 4 or 5, need some patch for HEVC over RTMP/FLV, see **[FFmpeg Tools](#ffmpeg-tools)** bellow.
* SRS also supports HEVC.
    * We have merged HEVC support into SRS 6.0
    * The original supports for HEVC is [srs-gb28181/feature/h265](https://github.com/ossrs/srs-gb28181/commits/feature/h265) by [runner365](https://github.com/runner365)

> Note: To check if your Chrome support HEVC, please open `chrome://gpu` and search `hevc`.

For WebRTC:

* Chrome does not support HEVC right now(2022.11), but supports AV1, please see [#2324](https://github.com/ossrs/srs/pull/2324)
* Safari supports HEVC if user enable it, please see this [section](#safari-webrtc)
* SRS also only supports AV1, because Chrome does not support HEVC yet.

## Usage

Please make sure your SRS is `6.0.4+`, build with h265:

```bash
docker run --rm -it -p 1935:1935 -p 8080:8080 \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_SERVER_ENABLED=on \
  --env SRS_VHOST_HTTP_REMUX_ENABLED=on --env SRS_VHOST_HLS_ENABLED=on \
  ossrs/srs:8 ./objs/srs -e
```

> Note: Besides environment variables, you can also use `conf/hevc.flv.conf` or `conf/hevc.ts.conf` config files.
> Note: Recommend `conf/hevc.ts.conf` because TS is better for HEVC.

Build and patch FFmpeg, see [FFmpeg Tools](#ffmpeg-tools):

```bash
# For macOS
docker run --rm -it ossrs/srs:encoder ffmpeg -stream_loop -1 -re -i doc/source.flv \
  -acodec copy -vcodec libx265 -f flv rtmp://host.docker.internal/live/livestream

# For linux
docker run --net=host --rm -it ossrs/srs:encoder ffmpeg -stream_loop -1 -re -i doc/source.flv \
  -acodec copy -vcodec libx265 -f flv rtmp://127.0.0.1/live/livestream
```

> Note: Please change the ip `host.docker.internal` to your SRS's IP.

Play the HEVC live streams by:

* HTTP-FLV(by H5):  [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true)
* HLS(by VLC or fflay): `http://localhost:8080/live/livestream.m3u8`

> Note: Please enable MPEG-DASH by `SRS_VHOST_DASH_ENABLED=on` then use VLC/ffplay to play stream `http://localhost:8080/live/livestream.mpd`

> Note: Please enable HTTP-TS by `SRS_VHOST_HTTP_REMUX_MOUNT=[vhost]/[app]/[stream].ts` then use H5/VLC/ffplay to play stream `http://localhost:8080/live/livestream.ts`

> Note: Please enable DVR MP4 by `SRS_VHOST_DVR_ENABLED=on SRS_VHOST_DVR_DVR_PATH=./objs/nginx/html/[app]/[stream].[timestamp].mp4` if want to covert live stream to MP4 file.

> Note: The detail about available protocols and tools for HEVC, please see [Status of HEVC in SRS](#status-of-hevc-in-srs).

> Note: The H5 player uses [mpegts.js](https://github.com/xqq/mpegts.js).

## Status of HEVC in SRS

The status of protocols and HEVC:

* [x] PUSH HEVC over RTMP by FFmpeg. [v6.0.2](https://github.com/ossrs/srs/commit/178e40a5fc3cf0856ace914ae61696a73007f5bf)
* [x] PUSH HEVC over SRT by FFmpeg. [v6.0.20](https://github.com/ossrs/srs/pull/3366)
* [x] PUSH HEVC over RTMP by OBS. [#3464](https://github.com/ossrs/srs/issues/3464) https://github.com/obsproject/obs-studio/pull/8522
* [x] PUSH HEVC over SRT by OBS. [v6.0.20](https://github.com/ossrs/srs/pull/3366)
* [x] PUSH HEVC over GB28181. [v6.0.25](https://github.com/ossrs/srs/pull/3408)
* [x] PULL HEVC over RTMP by FFmpeg, with [patch](#ffmpeg-tools) for FFmpeg. [v6.0.2](https://github.com/ossrs/srs/commit/178e40a5fc3cf0856ace914ae61696a73007f5bf)
* [x] PULL HEVC over HTTP-FLV by FFmpeg, with [patch](#ffmpeg-tools) for FFmpeg. [v6.0.2](https://github.com/ossrs/srs/commit/178e40a5fc3cf0856ace914ae61696a73007f5bf)
* [x] PULL HEVC over HTTP-TS by FFmpeg [v6.0.4](https://github.com/ossrs/srs/commit/70d5618979e5c8dc41b7cd87c78db7ca2b8a10e8)
* [x] PULL HEVC over HLS by FFmpeg [v6.0.11](https://github.com/ossrs/srs/commit/fff8d9863c3fba769b01782428257edf40f80a12)
* [x] PULL HEVC over MPEG-DASH  by FFmpeg [v6.0.14](https://github.com/ossrs/srs/commit/edba2c25f13c0fa915bd8e8093a4005df6077858)
* [x] PULL HEVC over SRT by FFmpeg. [v6.0.20](https://github.com/ossrs/srs/pull/3366)
* [x] PUSH HEVC over WebRTC by Safari. [v6.0.34](https://github.com/ossrs/srs/pull/3441)
* [x] PULL HEVC over WebRTC by Safari. [v6.0.34](https://github.com/ossrs/srs/pull/3441)
* [ ] PUSH HEVC over WebRTC by Chrome/Firefox
* [ ] PULL HEVC over WebRTC by Chrome/Firefox
* [x] Play HEVC over HTTP-TS by [mpegts.js](https://github.com/xqq/mpegts.js), by Chrome 105+ MSE, **NO WASM**. [v6.0.1](https://github.com/ossrs/srs/commit/7e02d972ea74faad9f4f96ae881d5ece0b89f33b)
* [x] Play pure video(no audio) HEVC over HTTP-TS by [mpegts.js](https://github.com/xqq/mpegts.js). [v6.0.9](https://github.com/ossrs/srs/commit/d5bf0ba2da30698e18700b210d2b12eed5b21d29)
* [x] Play HEVC over HTTP-FLV by [mpegts.js](https://github.com/xqq/mpegts.js), by Chrome 105+ MSE, **NO WASM**. [v6.0.1](https://github.com/ossrs/srs/commit/7e02d972ea74faad9f4f96ae881d5ece0b89f33b)
* [ ] Play HEVC over HLS by [hls.js](https://github.com/video-dev/hls.js)
* [ ] Play HEVC over MPEG-DASH by [dash.js](https://github.com/Dash-Industry-Forum/dash.js)
* [x] Play HEVC over HTTP-TS by ffplay, by offical release. [v6.0.4](https://github.com/ossrs/srs/commit/70d5618979e5c8dc41b7cd87c78db7ca2b8a10e8)
* [x] PULL HEVC over RTMP by ffplay, with [patch](#ffmpeg-tools) for FFmpeg. [v6.0.2](https://github.com/ossrs/srs/commit/178e40a5fc3cf0856ace914ae61696a73007f5bf)
* [x] Play HEVC over HTTP-FLV by ffplay, with [patch](#ffmpeg-tools) for FFmpeg. [v6.0.2](https://github.com/ossrs/srs/commit/178e40a5fc3cf0856ace914ae61696a73007f5bf)
* [x] Play pure video(no audio) HEVC by ffplay.
* [x] Play HEVC over HLS by ffplay. [v6.0.11](https://github.com/ossrs/srs/commit/fff8d9863c3fba769b01782428257edf40f80a12)
* [x] Play HEVC over MPEG-DASH by ffplay. [v6.0.14](https://github.com/ossrs/srs/commit/edba2c25f13c0fa915bd8e8093a4005df6077858)
* [x] Play HEVC over SRT by ffplay. [v6.0.20](https://github.com/ossrs/srs/pull/3366)
* [x] Play HEVC over HTTP-TS by VLC, by official release. [v6.0.4](https://github.com/ossrs/srs/commit/70d5618979e5c8dc41b7cd87c78db7ca2b8a10e8)
* [x] Play HEVC over SRT by VLC, by official. [v6.0.20](https://github.com/ossrs/srs/pull/3366)
* [x] Play pure video(no audio) HEVC by VLC.
* [ ] Play HEVC over RTMP by VLC.
* [ ] Play HEVC over HTTP-FLV by VLC.
* [x] Play HEVC over HLS by VLC. [v6.0.11](https://github.com/ossrs/srs/commit/fff8d9863c3fba769b01782428257edf40f80a12)
* [x] Play HEVC over MPEG-DASH by VLC. [v6.0.14](https://github.com/ossrs/srs/commit/edba2c25f13c0fa915bd8e8093a4005df6077858)
* [x] DVR HEVC to MP4/FLV file. [v6.0.14](https://github.com/ossrs/srs/commit/edba2c25f13c0fa915bd8e8093a4005df6077858)
* [x] HTTP API contains HEVC metadata.
* [ ] HTTP Callback takes HEVC metadata.
* [ ] Prometheus Exporter supports HEVC metadata.
* [ ] Improve coverage for HEVC.
* [x] Add regression/blackbox tests for HEVC.
* [ ] Supports benchmark for HEVC by [srs-bench](https://github.com/ossrs/srs-bench).
* [x] Support patched FFmpeg for SRS dockers: [CentOS7](https://github.com/ossrs/dev-docker/commit/0691d016adfe521f77350728d15cead8086d527d), [Ubuntu20](https://github.com/ossrs/dev-docker/commit/0e36323d15544ffe2901d10cfd255d9ef08fb250) and [Encoder](https://github.com/ossrs/dev-docker/commit/782bb31039653f562e0765a0c057d9f9babd1d1f).
* [x] Update [WordPress plugin SrsPlayer](https://github.com/ossrs/WordPress-Plugin-SrsPlayer) for HEVC.
* [ ] Update [srs-cloud](https://github.com/ossrs/srs-cloud) for HEVC.
* [ ] Edge server supports publish HEVC stream to origin.
* [ ] Edge server supprots play HEVC stream from origin.
* [ ] [HEVC: Error empty SPS/PPS when coverting RTMP to HEVC.](https://github.com/ossrs/srs/issues/3407)

> Note: We're merging HEVC support to SRS 6.0, the original supports for HEVC is [srs-gb28181/feature/h265](https://github.com/ossrs/srs-gb28181/commits/feature/h265) by [runner365](https://github.com/runner365)

## FFmpeg Tools

The FFmpeg in `ossrs/srs:encoder` or `ossrs/srs:6` is built with libx265 and patched with HEVC over RTMP support. So you're able to directly use:

```bash
docker run --rm -it --net host ossrs/srs:encoder \
  ffmpeg -re -i doc/source.flv -acodec copy -vcodec libx265 \
    -f flv rtmp://localhost/live/livestream
```

If you want to build from code, please read the bellow instructions. Before build FFmpeg, we must build 
[libx264](https://www.videolan.org/developers/x264.html):

```bash
git clone https://code.videolan.org/videolan/x264.git ~/git/x264
cd ~/git/x264
./configure --prefix=$(pwd)/build --disable-asm --disable-cli --disable-shared --enable-static
make -j10
make install
```

And then [libx265](https://www.videolan.org/developers/x265.html):

```bash
git clone https://bitbucket.org/multicoreware/x265_git.git ~/git/x265_git
cd ~/git/x265_git/build/linux
cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/build -DENABLE_SHARED=OFF ../../source
make -j10
make install
```

Keep in mind that FFmpeg 6.0 does not support HEVC over RTMP until the following commit 
[637c761b](https://github.com/FFmpeg/FFmpeg/commit/637c761be1bf9c3e1f0f347c5c3a390d7c32b282):

```
commit 637c761be1bf9c3e1f0f347c5c3a390d7c32b282
Author: Steven Liu <liuqi05@kuaishou.com>
Date:   Mon Aug 28 09:59:24 2023 +0800

    avformat/rtmpproto: support enhanced rtmp
    
    add option named rtmp_enhanced_codec,
    it would support hvc1,av01,vp09 now,
    the fourcc is using Array of strings.
    
    Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
```

So, if you are using FFmpeg 6, you can build FFmpeg without any patch, directly by the following commands:

```bash
git clone -b master https://github.com/FFmpeg/FFmpeg.git ~/git/FFmpeg
cd ~/git/FFmpeg
env PKG_CONFIG_PATH=~/git/x264/build/lib/pkgconfig:~/git/x265_git/build/linux/build/lib/pkgconfig \
./configure \
  --prefix=$(pwd)/build \
  --enable-gpl --enable-nonfree --enable-pthreads --extra-libs=-lpthread \
  --disable-asm --disable-x86asm --disable-inline-asm \
  --enable-decoder=aac --enable-decoder=aac_fixed --enable-decoder=aac_latm --enable-encoder=aac \
  --enable-libx264 --enable-libx265 \
  --pkg-config-flags='--static'
make -j10
```

Push HEVC over RTMP to SRS:

```bash
./ffmpeg -stream_loop -1 -re -i ~/srs/doc/source.flv -acodec copy -vcodec libx265 \
  -f flv rtmp://localhost/live/livestream
```

Play HEVC over RTMP by ffplay:

```bash
./ffplay rtmp://localhost/live/livestream
```

It works like magic!

If you want to use HEVC over RTMP in FFmpeg 4.1 or 5.1, please read the following instructions. Please clone FFmepg
and checkout to 5.1:

> Note: The [specfication](https://github.com/ksvc/FFmpeg/wiki) and [usage](https://github.com/ksvc/FFmpeg/wiki/hevcpush)
to support HEVC over RTMP or FLV. There is a [patch for FFmpeg 4.1/5.1/6.0](https://github.com/runner365/ffmpeg_rtmp_h265)
from [runner365](https://github.com/runner365) for FFmpeg to support HEVC over RTMP or FLV. There is also a
[patch](https://github.com/VCDP/CDN/blob/master/FFmpeg_patches/0001-Add-SVT-HEVC-FLV-support-on-FFmpeg.patch)
from Intel for this feature.

```bash
git clone -b n5.1.2 https://github.com/FFmpeg/FFmpeg.git ~/git/FFmpeg
```

Then, patch for [HEVC over RTMP/FLV](https://github.com/runner365/ffmpeg_rtmp_h265):

```bash
git clone -b 5.1 https://github.com/runner365/ffmpeg_rtmp_h265.git ~/git/ffmpeg_rtmp_h265
cp ~/git/ffmpeg_rtmp_h265/flv.h ~/git/FFmpeg/libavformat/
cp ~/git/ffmpeg_rtmp_h265/flv*.c ~/git/FFmpeg/libavformat/
```

Finally, follow the previous instructions to build FFmpeg.

## MSE for HEVC

[MSE](https://caniuse.com/?search=mse) is a base technology for [mpegts.js](https://github.com/xqq/mpegts.js), [hls.js](https://github.com/video-dev/hls.js/) and [dash.js](https://github.com/Dash-Industry-Forum/dash.js).

Now [Chrome 105+](https://caniuse.com/?search=HEVC) supports HEVC by default, see [this post](https://zhuanlan.zhihu.com/p/541082191), which means, MSE(Chrome 105+) is available for HEVC.

You can verify this feature, by generating a HEVC mp4 file:

```bash
ffmpeg -i ~/git/srs/trunk/doc/source.flv -acodec copy \
  -vcodec libx265 -y source.hevc.mp4
```

> Note: Please make sure your FFmpeg is 5.0 and libx265 is enabled.

Open `source.hevc.mp4` in Chrome 105+ directly, it should works.

You can also move the file to SRS webserver:

```bash
mkdir -p ~/git/srs/trunk/objs/nginx/html/vod/
mv source.hevc.mp4 ~/git/srs/trunk/objs/nginx/html/vod
```

Then open by [srs-player](http://localhost:8080/players/srs_player.html?app=vod&stream=source.hevc.mp4&autostart=true)

## Safari WebRTC

Safari supports WebRTC, if you enable it by:

* English version: `Develop > Experimental Features > WebRTC H265 codec`
* Chinese version: `Development > Experimental Features > WebRTC H265 codec`

Then open the url in safari, to publish or play WebRTC stream:

* Play [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream&codec=hevc](http://localhost:8080/players/whep.html?autostart=true&codec=hevc)
* Publish [http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&codec=hevc](http://localhost:8080/players/whip.html?autostart=true&codec=hevc)

Please follow other section to publish HEVC stream.

## Thanks for Contributors

There is a list of commits and contributors about HEVC in SRS:

* [H265: For #1747, Support HEVC/H.265 in SRT/RTMP/HLS.](https://github.com/ossrs/srs-gb28181/commit/3ca11071b45495e82d2d6958e5d0f7eab05e71e5)
* [H265: For #1747, Fix build fail bug for H.265](https://github.com/ossrs/srs-gb28181/commit/e355f3c37228f3602c88fed68e8fe5e6ba1153ea)
* [H265: For #1747, GB28181 support h.265 (#2037)](https://github.com/ossrs/srs-gb28181/commit/b846217bc7f94034b33bdf918dc3a49fb17947e0)
* [H265: fix some important bugs (#2156)](https://github.com/ossrs/srs-gb28181/commit/26218965dd083d13173af6eb31fcdf9868b753c6)
* [H265: Deliver the right hevc nalu and dump the wrong nalu. (#2447)](https://github.com/ossrs/srs-gb28181/commit/a13b9b54938a14796abb9011e7a8ee779439a452)
* [H265: Fix multi nal hevc frame demux fail. #2494](https://github.com/ossrs/srs-gb28181/commit/6c5e6090d7c82eb37530e109c230cabaedf948e1)
* [H265: Fix build error #2657 #2664](https://github.com/ossrs/srs-gb28181/commit/eac99e19fba6063279b9e47272523014f5e3334a)
* [H265: Update mpegts demux in srt. #2678](https://github.com/ossrs/srs-gb28181/commit/391c1426fc484c990e4324a4ae2f0de900074578)
* [H265: Fix the stat issue for h265. (#1949)](https://github.com/ossrs/srs-gb28181/commit/b4486e3b51281b4c227b2cc4f58d2b06db599ce0)
* [H265: Add h265 codec written support for MP4 format. (#2697)](https://github.com/ossrs/srs-gb28181/commit/3175d7e26730a04b27724e55dc95ef86c1f2886e)
* [H265: Add h265 for SRT.](https://github.com/runner365/srs/commit/0fa86e4f23847e8a46e3d0e91e0acd2c27047e11)

We will merge some of these commits to SRS 6.0, but not all commits.

* [PULL HEVC over WebRTC by Safari. v6.0.34](https://github.com/ossrs/srs/pull/3441)
* [GB: Support H.265 for GB28181. v6.0.25 (#3408)](https://github.com/ossrs/srs/pull/3408)
* [H265: Support HEVC over SRT. v6.0.20 (#465) (#3366)](https://github.com/ossrs/srs/pull/3366)
* [H265: Support DVR HEVC stream to MP4. v6.0.14](https://github.com/ossrs/srs/pull/3360)
* HLS: Support HEVC over HLS. v6.0.11
* [HEVC: The codec information is incorrect. v6.0.5](https://github.com/ossrs/srs/issues/3271)
* FFmpeg support libx265 and HEVC over RTMP/FLV: [CentOS7](https://github.com/ossrs/dev-docker/commit/0691d016adfe521f77350728d15cead8086d527d), [Ubuntu20](https://github.com/ossrs/dev-docker/commit/0e36323d15544ffe2901d10cfd255d9ef08fb250) and [Encoder](https://github.com/ossrs/dev-docker/commit/782bb31039653f562e0765a0c057d9f9babd1d1f).
* [H265: Support HEVC over HTTP-TS. v6.0.4](https://github.com/ossrs/srs/commit/70d5618979e5c8dc41b7cd87c78db7ca2b8a10e8)
* [H265: Support parse multiple NALUs in a frame. v6.0.3](https://github.com/ossrs/srs/commit/f316e9a0de3a892d25f2d8e7efd28ee9334f5bd6)
* [H265: Support HEVC over RTMP or HTTP-FLV. v6.0.2](https://github.com/ossrs/srs/commit/178e40a5fc3cf0856ace914ae61696a73007f5bf)
* [H265: Update mpegts.js to play HEVC over HTTP-TS/FLV. v6.0.1](https://github.com/ossrs/srs/commit/7e02d972ea74faad9f4f96ae881d5ece0b89f33b)

## Known Issues

1. HEVC over Safari WebRTC, only support WebRTC to WebRTC, doesn't support converting to RTMP.
2. Chrome/Firefox does not support HEVC, no any plan as I know.
3. Almost all browsers supports MSE, except iOS. HEVC over MSE requires hardware decoder.
4. Apart from mpegts.js, other H5 players such as hls.js/dash.js doesn't support HEVC.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Hls (`skills/internal-docs-for-srs/references/cpp-docs/doc/hls.md`)

---
title: HLS
sidebar_label: HLS
hide_title: false
hide_table_of_contents: false
---

# HLS

HLS is the best streaming protocol for adaptability and compatibility. Almost all devices in the world support HLS, 
including PCs, Android, iOS, OTT, SmartTV, and more. Various browsers also support HLS well, including Chrome, Safari, 
Firefox, Edge, and mobile browsers.

If your users are diverse, especially if their devices have lower performance, HLS is the best choice. If you want 
to be compatible with more devices, HLS is the best choice. If you want to distribute your live stream on any CDN 
and globally, HLS is the best choice.

Of course, HLS is not perfect; its main issue is high latency, usually around 30 seconds. Although it can be optimized 
to about 8 seconds, different players' behavior may vary. Compared to other streaming protocols, the optimized latency 
is still high. So if you care about live streaming latency, please use RTMP or HTTP-FLV protocols.

The main application scenarios of HLS include:
* Cross-platform: The main live streaming solution for PCs is HLS, which can be played using the hls.js library. So if you choose one protocol for PC/Android/iOS, it's HLS.
* Strict stability requirements on iOS: HLS is the most stable on iOS, with stability comparable to RTMP and HTTP-FLV.
* Friendly CDN distribution: HLS is based on HTTP, so CDN integration and distribution are more complete than RTMP. HLS can switch between various CDNs.
* Fewer simple issues: HLS is a very simple streaming protocol, well supported by Apple. Android's support for HLS will also improve.

HLS is the core protocol of SRS and will be continuously maintained and updated, constantly improving support for HLS. 
SRS converts RTMP, SRT, or WebRTC streams into HLS streams, especially WebRTC, where SRS implements audio transcoding 
capabilities.

## Usage

SRS has built-in HLS support, which you can use with [docker](./getting-started.md) or [compile from source](./getting-started-build.md):

```bash
docker run --rm -it -p 1935:1935 -p 8080:8080 \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_SERVER_ENABLED=on --env SRS_VHOST_HLS_ENABLED=on \
  ossrs/srs:8 ./objs/srs -e
```

Use [FFmpeg(click to download)](https://ffmpeg.org/download.html) or [OBS(click to download)](https://obsproject.com/download) to stream:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

Open the following page to play the stream (if SRS is not on your local machine, replace localhost with the server IP):

* HLS by SRS player: [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?stream=livestream.m3u8)

> Note: Please wait about 10 seconds before playing the stream, otherwise it will fail, as it takes some time to generate the first segment.

## Config

The config for HLS:

```
/* Detailed source-code truncated for AI context efficiency. */
```

> Note: These settings are only for playing HLS. For streaming settings, please follow your protocol, like referring to [RTMP](./rtmp.md#config), [SRT](./srt.md#config), or [WebRTC](./webrtc.md#config) streaming configurations.

Here are the main settings:
* enabled: Turn HLS on/off, default is off.
* hls_fragment: Seconds, specify the minimum length of ts slices. For the actual length of ts files, please refer to the detailed description of [HLS TS Duration](#hls-ts-duration).
* hls_td_ratio: Normal slice duration multiple. For the actual length of ts files, please refer to the detailed description of [HLS TS Duration](#hls-ts-duration).
* hls_wait_keyframe: Whether to slice by top, i.e., wait for the keyframe before slicing. For the actual length of ts files, please refer to the detailed description of [HLS TS Duration](#hls-ts-duration).
* hls_aof_ratio: Pure audio slice duration multiple. For pure audio, when the ts duration exceeds the configured ls_fragment multiplied by this factor, the file is cut. For the actual length of ts files, please refer to the detailed description of [HLS TS Duration](#hls-ts-duration).
* hls_window: Seconds, specify the HLS window size, i.e., the sum of ts file durations in the m3u8, which determines the number of ts files in the m3u8. For more details, refer to [HLS TS Files](#hls-ts-files).
* hls_path: The path where the HLS m3u8 and ts files are saved. Both m3u8 and ts files are saved in this directory.
* hls_m3u8_file: The file name of the HLS m3u8, including replaceable `[vhost]`, `[app]`, and `[stream]` variables.
* hls_ts_file: The file name of the HLS ts, including a series of replaceable variables. Refer to [dvr variables](./dvr.md#custom-path). Also, `[seq]` is the ts sequence number.
* hls_entry_prefix: The base url of TS. Optional, default is an empty string; when not empty, it is added in front of ts as the base url.
* hls_acodec: Default audio codec. When the stream codec changes, the PMT/PAT information will be updated; the default is aac, so the default PMT/PAT information is aac; if the stream is mp3, this parameter can be set to mp3 to avoid PMT/PAT changes.
* hls_vcodec: Default video codec. When the stream codec changes, the PMT/PAT information will be updated; the default is h264. If it is a pure audio HLS, it can be set to vn, which can reduce the time for SRS to detect pure audio and directly enter pure audio mode.
* hls_cleanup: Whether to delete expired ts slices that are not in the hls_window. You can turn off ts slice cleanup to implement time-shifting and storage, using your own slice management system.
* hls_dispose: When there is no stream, the HLS cleanup expiration time (seconds). When the system restarts or exceeds this time, all HLS files, including m3u8 and ts, will be cleaned up. If set to 0, no cleanup will be done.
* hls_nb_notify: The length of data read from the notify server.
* on_hls: When a slice is generated, callback this url using POST. Used to integrate with your own system, such as implementing slice movement.
* on_hls_notify: When a slice is generated, callback this url using GET. Used to integrate with the system, you can use the `[ts_url]` variable to implement pre-distribution (i.e., download a ts slice once).

## HLS TS Duration

How is the duration of HLS TS segments determined? It depends on the configuration and the characteristics of the stream.

If there is video, the segment duration is `max(hls_fragment*hls_td_ratio, gop_size*N)`, which is the maximum value of `hls_fragment` and `gop_size`. The `gop_size` is determined by the encoder, for example, OBS can set the GOP size in seconds, while FFmpeg uses the number of frames combined with the frame rate to calculate seconds.

For example, if the stream's frame rate is 25 and the GOP is 50 frames, then the `gop_size` is 2 seconds:

* If `hls_fragment` is 10 seconds, the final TS segment duration is 10 seconds.
* If `hls_fragment` is 5 seconds, the final TS segment duration is 6 seconds, with 3 GOPs.
* If `hls_fragment` is 5 seconds and `hls_td_ratio` is 2, the final TS segment duration is 10 seconds.

If `hls_wait_keyframe off` is configured, the GOP size is no longer considered, and the TS segment duration is determined by `hls_fragment` regardless of the GOP size. For example, if the GOP is 10 seconds:

* If `hls_fragment` is 10 seconds, the final TS segment duration is 10 seconds.
* If `hls_fragment` is 5 seconds, the final TS segment duration is 5 seconds.
* If `hls_fragment` is 3 seconds and `hls_td_ratio` is 2, the final TS segment duration is 6 seconds.

> Note: Turning off `hls_wait_keyframe` can reduce segment size and latency, but some players may experience screen artifacts when starting playback with a non-keyframe.

For audio-only HLS, the segment duration is determined by `hls_fragment*hls_aof_ratio`:

* If `hls_fragment` is 10 seconds and `hls_aof_ratio` is 1.2, the final TS segment duration is 12 seconds.
* If `hls_fragment` is 5 seconds and `hls_aof_ratio` is 1, the final TS segment duration is 5 seconds.

Note that if the segment duration is unusually long, exceeding a certain size (usually 3 times the maximum segment length), it will be discarded.

## HLS TS Files

The number of TS files in the m3u8 is determined by the TS duration and `hls_window`. When the total duration of TS files exceeds `hls_window`, the first segment in the m3u8 is discarded until the total TS duration is within the configured range.

SRS ensures the following formula:

```bash
hls_window >= sum(duration of each ts in m3u8)
```

For example, if `hls_window` is 60 seconds and `hls_fragment` is 10 seconds, and the actual TS segment duration is 10 seconds, there will be 6 TS files in the m3u8. The actual TS segment duration may be larger than `hls_fragment`, see [HLS TS Duration](#hls-ts-duration) for details.

## HTTP Callback

You can set up an `on_hls` callback in the `http_hooks` section, not in the HLS section.

Note: HLS hot backup can be implemented based on this callback, see [#351](https://github.com/ossrs/srs/issues/351).

Note: HLS hot backup must ensure that the slices on both servers are exactly the same, because the load balancer or edge may fetch slices from both servers. Ensuring that the slices on both servers are exactly the same is a very complex streaming media issue. However, through the callback and business system, you can achieve a simple and reliable HLS hot backup system by choosing slices from both servers.

## HLS Authentication

SRS supports HLS client playback and online user statistics. By default, it will enable `hls_ctx` and `hls_ts_ctx`. This way, HLS and other protocols can implement authentication playback and data statistics through callbacks. For example, when playing HLS, you can use the `on_play` callback to return an error and reject client playback.

```bash
vhost __defaultVhost__ {
    hls {
        enabled  on;
        hls_ctx on;
        hls_ts_ctx on;
    }
}
```

However, this feature will cause HLS cache to fail on CDN because each playback will have a different ctx_id, similar to a session ID function. Therefore, in [HLS Cluster](./nginx-for-hls.md), you must disable these two options.

## HLS Dispose

If the stream is stopped, the HLS client can still play the previous content because the slice files still exist.

Sometimes during a live broadcast, you may need to temporarily stop the stream, change encoding parameters or streaming devices, and then restart the stream. Therefore, SRS should not delete HLS files when stopping the stream.

By default, SRS will clean up the HLS slice files after the `hls_dispose` configured time. This time is set to 120 seconds (2 minutes) by default.

```bash
vhost __defaultVhost__ {
    hls {
        enabled  on;
        hls_dispose 120;
    }
}
```

If you need to clean up faster, you can shorten this cleanup time. However, this configuration should not be too short. It is recommended not to be less than `hls_window`, otherwise, it may cause early cleanup when restarting the stream, making the HLS stream inaccessible to the player.

## HLS in RAM

If you need to increase the number of concurrent HLS streams, you can try distributing HLS directly from memory without writing to disk.

You can mount memory as a disk directory and then write HLS slices to the memory disk:

```bash
mkdir -p /ramdisk &&
mount -o size=7G -t tmpfs none /ramdisk
```

> Note: To unmount the memory disk, use the command `unmount /randisk`.

> Note: If you don't have many streams and don't need much disk space, you can write HLS slices to the `/tmp` directory, which is a memory disk by default.

Then configure `hls_path` or create a soft link to the directory.

## HLS Delivery Cluster

To deploy an HLS distribution cluster and edge distribution cluster for your own CDN to handle a large number of viewers, please refer to [Nginx for HLS](./nginx-for-hls.md).

## HLS with Reverse Proxy

When deploying SRS behind a reverse proxy with path rewriting, you may encounter issues where HLS master playlists use absolute paths (e.g., `/live/livestream.m3u8?hls_ctx=xxx`), which can break playback when the proxy rewrites request paths. For example, if the external URL is `http://proxy/srs/live/stream.m3u8` but gets rewritten to `http://origin/live/stream.m3u8`, the absolute path in the master playlist will drop the `/srs` prefix, causing a 404 error.

SRS (v7.0.104+) provides the `hls_master_m3u8_path_relative` option to use relative paths in master playlists for reverse proxy compatibility:

```bash
vhost __defaultVhost__ {
    hls {
        enabled on;
        hls_master_m3u8_path_relative on;  # Use relative path for reverse proxy
    }
}
```

When enabled, the master playlist uses relative paths (e.g., `livestream.m3u8?hls_ctx=xxx`) instead of absolute paths, allowing the player to correctly resolve URLs through the reverse proxy. This is useful for deployments with Nginx, Apache, HAProxy, API gateways, or multi-tenant systems with path-based routing. The default is `off` for backward compatibility.

## HLS Low Latency

How to reduce HLS latency? The key is to reduce the number of slices and the number of TS files in the m3u8. SRS's default configuration is 10 seconds per slice and 60 seconds per m3u8, resulting in a latency of about 30 seconds. Some players start requesting slices from the middle position, so there will be a delay of 3 slices.

You can adjust the following three settings to reduce latency to about 6-8 seconds:

* Reduce the GOP size, e.g., set OBS's GOP to 1 second or FFmpeg's GOP to the number of FPS frames.
* Reduce the encoder's delay, for example, set OBS to `Profile` as `baseline` and choose `Tune` as `zerolatency`.
* Reduce `hls_fragment`, e.g., set it to 2 seconds or 1 second.
* Reduce `hls_window`, e.g., set it to 10 seconds or 5 seconds.
* Use low-latency players like hls.js, ijkplayer, or ffplay, and avoid high-latency players like VLC.

Refer to the configuration file `conf/hls.realtime.conf`:

```bash
vhost __defaultVhost__ {
    hls {
        enabled  on;
        hls_fragment 2;
        hls_window 10;
    }
}
```

> Note: If you can't adjust the encoder's OGP size, consider setting `hls_wait_keyframe off` to ignore GOP, but this may cause screen artifacts. Test your device's compatibility.

Of course, you can't reduce it too much, as it may cause insufficient buffering for the player or skipping when the player's network is poor, possibly resulting in playback failure. The lower the latency, the higher the chance of buffering. HLS latency cannot be less than 5 seconds, especially considering CDN and player compatibility.

Even after adjusting, the HLS delay won't be less than 5 seconds, and the LLHLS protocol can't reduce it further. This is because LLHLS only tries to solve the impact of the initial GOP during playback. In the above settings, we also reduced the GOP's impact through the encoder's configuration. However, network jitter and player strategy are reasons for the higher HLS delay, and they can't be solved.
If you need latency within 5 seconds, consider using protocols like [HTTP-FLV](./flv.md), [SRT](./srt.md), or [WebRTC](./webrtc.md).

## ON HLS Notify

You can configure `on_hls_notify` for CDN pre-distribution. This should be set in `http_hooks` rather than in the HLS configuration.

## HLS Audio Corrupt

HLS might have loud noise issues, which is caused by the sampling rate of AAC causing a small error when switching between FLV (tbn=1000) and TS (tbn=90000). SRS3 uses the number of samples to calculate the exact timestamp, for more details, refer to [HLS Loud Noise](https://github.com/ossrs/srs/issues/547#issuecomment-294350544).

> Note: To solve the HLS loud noise problem, you need to manually disable `hls_dts_directly` (set to off).

After SRS3 is corrected, it is found that some audio streams have problems with their timestamps, causing the timestamps calculated from the AAC sample count to be incorrect. Therefore, the configuration item `hls_dts_directly` is provided to force the use of the original timestamp, refer to [HLS Force Original Timestamp](https://github.com/ossrs/srs/issues/547#issuecomment-563942711).

## HLS Audio Only

SRS supports distributing HLS pure audio streams. When the RTMP stream has no video and the audio is AAC (you can use transcoding to convert to AAC, refer to [Usage: Transcode2HLS](./sample-transcode-to-hls.md)), SRS only slices the audio.

If the RTMP stream already has video and audio, and you need to support pure audio HLS streams, you can use transcoding to remove the video, refer to: [Transcoding: Disable Stream](./ffmpeg.md#%E7%A6%81%E7%94%A8). Then distribute the audio stream.

Distributing pure audio streams does not require special configuration, just like HLS distribution.

## HLS and Forward

Forward streams are not distinguished from ordinary streams. If the forward stream's VHOST is configured with HLS, the HLS configuration will be applied for slicing.

Therefore, you can transcode the original stream to ensure that the stream meets the h.264/aac standard, and then forward it to multiple VHOSTs configured with HLS for slicing. This supports hot backup for multiple source stations.

## HLS and Transcode

HLS requires the RTMP stream encoding to be h.264+aac/mp3, otherwise, HLS will be automatically disabled, and you may see RTMP streams but not HLS streams (or the HLS streams you see are from previous streams).

Transcoding the RTMP stream allows SRS to access any encoded RTMP stream and then convert it to the h.264/aac/mp3 encoding required by HLS.

When configuring Transcode, if you need to control the ts length, you need to [configure the ffmpeg encoding gop](http://ffmpeg.org/ffmpeg-codecs.html#Options-7), for example:
```bash
vhost hls.transcode.vhost.com {
    transcode {
        enabled     on;
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        engine hls {
            enabled         on;
            vfilter {
            }
            vcodec          libx264;
            vbitrate        500;
            vfps            20;
            vwidth          768;
            vheight         320;
            vthreads        2;
            vprofile        baseline;
            vpreset         superfast;
            vparams {
                g           100;
            }
            acodec          libaacplus;
            abitrate        45;
            asample_rate    44100;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
        }
    }
}
```
This FFMPEG transcoding parameter specifies the gop duration as 100/20=5 seconds, fps frame rate (vfps=20), and gop frame count (g=100).

## HLS Multiple Bitrate

SRS currently does not support HLS adaptive bitrate, as it generally requires transcoding a single stream into multiple streams and requires GOP alignment. You can use FFmpeg to achieve this, refer to [How to generate multiple resolutions HLS using FFmpeg for live streaming](https://stackoverflow.com/a/71985380/17679565).

## Apple Examples

Apple's HLS example files:

https://developer.apple.com/library/ios/technotes/tn2288/_index.html

## HLS Encryption

SRS3 supports slice encryption, for specific usage, refer to [#1093](https://github.com/ossrs/srs/issues/1093#issuecomment-415971022).

## HLS fMP4

SRS (7.0.51+) supports HLS with fMP4 (fragmented MP4) segments instead of traditional MPEG-TS segments. fMP4 is the modern container format for HLS that offers several advantages:

* **Better codec support**: Required for HEVC/H.265 and essential for Low-Latency HLS (LL-HLS)
* **Lower overhead**: fMP4 has smaller file overhead compared to MPEG-TS segments
* **DVR compatibility**: fMP4 segments can be used for DVR and time-shifting applications
* **Future-proof**: fMP4 is the recommended format for modern HLS implementations

To enable HLS with fMP4 segments, set `hls_use_fmp4 on` in your configuration:

```bash
vhost __defaultVhost__ {
    hls {
        enabled on;
        hls_use_fmp4 on;
        hls_fragment 10;
        hls_window 60;
        hls_m3u8_file   [app]/[stream].m3u8;
        hls_init_file   [app]/[stream]-init.mp4;
        hls_fmp4_file   [app]/[stream]-[seq].m4s;
    }
}
```

When fMP4 is enabled, SRS generates:
* **Initialization segment**: `init.mp4` file containing codec information
* **Media segments**: `.m4s` files containing the actual media data

You can customize the file naming using these configuration options:
* `hls_fmp4_file`: Media segment filename pattern (default: `[app]/[stream]-[seq].m4s`)
* `hls_init_file`: Initialization segment filename pattern (default: `[app]/[stream]/init.mp4`)

For example, start SRS with fMP4 enabled:

```bash
docker run --rm -it -p 1935:1935 -p 8080:8080 \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_SERVER_ENABLED=on --env SRS_VHOST_HLS_ENABLED=on \
  --env SRS_VHOST_HLS_HLS_USE_FMP4=on --env 'SRS_VHOST_HLS_HLS_INIT_FILE=[app]/[stream]-init.mp4' \
  ossrs/srs:8 ./objs/srs -e
```

Publish a stream:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

The generated m3u8 playlist will reference fMP4 segments instead of TS segments, making it compatible with modern HLS players and Low-Latency HLS requirements.

Play the stream by SRS player: [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?stream=livestream.m3u8)

## IPv6

SRS (v7.0.67+) supports IPv6 for HLS streaming, enabling dual-stack (IPv4/IPv6) operation for HTTP-based live streaming. This allows HLS clients to access streams using IPv6 addresses while maintaining full compatibility with existing IPv4 infrastructure.

IPv6 support is enabled automatically when SRS detects IPv6 addresses in the HTTP server configuration. Configure the HTTP server to listen on IPv6 addresses:

```bash
http_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 8080 [::]:8080;
    dir ./objs/nginx/html;
}
```

Access HLS streams via IPv6:

```bash
# HLS stream via IPv6
http://[::1]:8080/live/livestream.m3u8

# HLS segments are also accessible via IPv6
http://[::1]:8080/live/livestream-1.ts
http://[::1]:8080/live/livestream-2.ts
```

Play HLS stream via IPv6 using FFplay:

```bash
ffplay 'http://[::1]:8080/live/livestream.m3u8'
```

SRS supports dual-stack HLS operation, allowing both IPv4 and IPv6 clients to access streams simultaneously:

```bash
http_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 8080 [::]:8080;
    dir ./objs/nginx/html;
}
```

This configuration allows:
- IPv4 clients: `http://192.168.1.100:8080/live/livestream.m3u8`
- IPv6 clients: `http://[2001:db8::1]:8080/live/livestream.m3u8`

---

### Skills Internal Docs For Srs References Cpp Docs Doc Http Api (`skills/internal-docs-for-srs/references/cpp-docs/doc/http-api.md`)

---
title: HTTP API
sidebar_label: HTTP API
hide_title: false
hide_table_of_contents: false
---

# HTTP API

SRS provides HTTP api, to external application to manage SRS, and support crossdomain for js.

Once HTTP API enabled, you can use [srs-console](http://ossrs.net/console/) to connect to your SRS server.

The workflow is:

```text
+-------------------------+               +-------+
+ Chrome/Your Application +--HTTP-API-->--+  SRS  +
+-------------------------+               +-------+
```

You can use Chrome or your application, to request the HTTP API of SRS to get the state of SRS.

## Goals

The HTTP API of SRS follows the simple priciple:

* Only provides API in json format, both request and response are json.
* Please use [srs-console](https://github.com/ossrs/srs-console) to access API.
* When error, response in HTTP status or code in json.

## Build

SRS always enable the http api, read [configure](./install.md)

```bash
./configure && make
```

## Config

The config also need to enable it:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The `http_api` enable the HTTP API, and `stats` used for SRS to stat the system info, including:

* network: Used for heartbeat to report the network info, where heartbeat used to report system info.
* disk: Used to stat the specified disk iops. You can use command `cat /proc/diskstats` to get the right disk names, for instance, xvda.

## Start

Start SRS: `./objs/srs -c http-api.conf`

Access api, open the url in web browser: 

* [http://127.0.0.1:1985/api/v1](http://127.0.0.1:1985/api/v1)
* [https://127.0.0.1:1986/api/v1](https://127.0.0.1:1986/api/v1)

> Remark: Please use your server ip instead.

## Performance

The HTTP api supports 370 request per seconds, please test by AB(Apache Benchmark).

## Access Api

Use web brower, or curl, or other http library.

SRS provides api urls list, no need to remember:
* code, an int error code. 0 is success.
* urls, the url lists, can be access.
* data, the last level api serve data.

Root directory:

```bash
# curl http://192.168.1.102:1985/
    "urls": {
        "api": "the api root"
    }
```

Go on:

```bash
# curl http://192.168.1.102:1985/api/v1/versions
        "major": 0,
        "minor": 9,
        "revision": 43,
        "version": "0.9.43"
```

Or:

```bash
# curl http://192.168.1.102:1985/api/v1/authors
        "primary_authors": "xxx",
        "contributors_link": "https://github.com/ossrs/srs/blob/master/AUTHORS.txt",
        "contributors": "xxx"
```

The Api of SRS is self-describes api.

## Error Code

SRS response error in both HTTP status or HTTP body.

For example, SRS response HTTP error, where HTTP status not 200:

```
winlin:~ winlin$ curl -v http://127.0.0.1:1985 && echo ""
< HTTP/1.1 404 Not Found
< Connection: Keep-Alive
< Content-Length: 9
< Content-Type: text/plain; charset=utf-8
< Server: SRS/2.0.184
< 
Not Found
```

For example, SRS response code not 0 when HTTTP Status 200:

```
winlin:~ winlin$ curl -v http://127.0.0.1:1985/api/v1/tests/errors && echo ""
< HTTP/1.1 200 OK
< Connection: Keep-Alive
< Content-Length: 12
< Content-Type: application/json
< Server: SRS/2.0.184
< 
{"code":100}
```

User should handle these two error style.

## Crossdomain

SRS HTTP API supports js crossdomain, so the html/js can invoke http api of srs。

SRS support two main CROS styles:

* OPTIONS: JQuery can directly access the CROS, where the brower will send an OPTIONS first, then the API request.
* JSONP: JQuery/Angularjs can send JSONP CROS request to SRS API, where specifes the function name by QueryString `callback`.
* JSONP-DELETE: JSONP only support GET, so we use the `method` in QueryString to override the HTTP method for JSONP.

For example, the JSONP crossdomain request:

```
GET http://localhost:1985/api/v1/vhosts/?callback=JSON_CALLBACK
JSON_CALLBACK({"code":0,"server":13449})
GET http://localhost:1985/api/v1/vhosts/100?callback=JSON_CALLBACK&method=DELETE
JSON_CALLBACK({"code":0})
```

## HTTPS API

SRS supports HTTPS API by turn the `https` on:

```
http_api {
    enabled         on;
    listen          1985;
    https {
        # Whether enable HTTPS API.
        # default: off
        enabled on;
        # The listen endpoint for HTTPS API.
        # default: 1990
        listen 1990;
        # The SSL private key file, generated by:
        #       openssl genrsa -out server.key 2048
        # default: ./conf/server.key
        key ./conf/server.key;
        # The SSL public cert file, generated by:
        #       openssl req -new -x509 -key server.key -out server.crt -days 3650 -subj "/C=CA/ST=Toronto/L=Toronto/O=Me/OU=Me/CN=ossrs.io"
        # default: ./conf/server.crt
        cert ./conf/server.crt;
    }
}
```

> Remark: Please use your HTTPS key and cert file.

> Note: To enable the HTTPS live streaming, please read [HTTPS FLV Live Stream](./flv.md#https-flv-live-stream)

## HTTP and HTTPS Proxy

SRS works well with HTTP/HTTPS proxies such as [Nginx](./http-server.md#nginx-proxy), [HTTPX](./http-server.md#httpx-proxy),
[CaddyServer](./http-server.md#caddy-proxy), and so on.

## Server ID

Each response of api contains a `server` field, which identify the server. When ServerID changed, SRS already restarted, all information before is invalid.

## API Navigation

SRS provides the Navigation of APIs.

User can access the `http://192.168.1.102:1985/api/v1`, where:

| API | Example  | Description |
| --- | -------- | ---------   |
| server | 4481  | The identity of SRS   |
| versions | /api/v1/versions  | the version of SRS |
| summaries | /api/v1/summaries | the summary(pid, argv, pwd, cpu, mem) of SRS |
| rusages  | /api/v1/rusages | the rusage of SRS |
| self_proc_stats | /api/v1/self_proc_stats | the self process stats |
| system_proc_stats | /api/v1/system_proc_stats | the system process stats |
| meminfos | /api/v1/meminfos | the meminfo of system |
| authors | /api/v1/authors | the license, copyright, authors and contributors |
| features | /api/v1/features | the supported features of SRS |
| requests | /api/v1/requests | the request itself, for http debug |
| vhosts | /api/v1/vhosts | manage all vhosts or specified vhost |
| streams | /api/v1/streams | manage all streams or specified stream |
| clients | /api/v1/clients | manage all clients or specified client, default query top 10 clients |
| forwards | /api/v1/forwards | query all forwards or specified forward, read-only, default query top 10 forwards |
| configs | /api/v1/configs | RAW API for CUID the configs |
| publish | /rtc/v1/publish/ | The push stream API for WebRTC |
| play | /rtc/v1/play/ | The play stream API for WebRTC |

## WebRTC Publish

In order to push stream over WebRTC to SRS, SRS supports [WHIP](https://datatracker.ietf.org/doc/draft-ietf-wish-whip/).
The request is defined as:

```text
POST /rtc/v1/whip/?app=live&stream=livestream

Body in SDP, the Content-type is application/sdp:

v=0
......
a=ssrc:2064016335 label:c8243ce9-ace5-4d17-9184-41a2543101b5
```

SRS responses the SDP answer as the HTTP response:

```text
v=0
......
a=candidate:1 1 udp 2130706431 172.18.0.4 8000 typ host generation 0
```

> Note: The HTTP Status is 201, not 200, according to WHIP specification.

Please also see examples at [srs.sdk.js](https://github.com/ossrs/srs/blob/develop/trunk/research/players/js/srs.sdk.js) and [srs-unity: Publisher](https://github.com/ossrs/srs-unity#usage-publisher).

## WebRTC Play

In order to pull stream over WebRTC from SRS, SRS also supports [WHEP](https://datatracker.ietf.org/doc/draft-murillo-whep/). 
The request is defined as:

```text
POST /rtc/v1/whep/?app=live&stream=livestream

Body in SDP, the Content-type is application/sdp:

v=0
......
a=ssrc:2064016335 label:c8243ce9-ace5-4d17-9184-41a2543101b5
```

> Note: Although WHIP is defined to push stream to SRS, but you're able to use it for pulling stream from SRS. There is another [WHEP](https://datatracker.ietf.org/doc/draft-murillo-whep/) for players, but not a RFC draft.

SRS responses the SDP answer as the HTTP response:

```
v=0
......
a=candidate:1 1 udp 2130706431 172.18.0.4 8000 typ host generation 0
```

> Note: The HTTP Status is 201, not 200, according to WHIP specification.

Please also see examples at [srs.sdk.js](https://github.com/ossrs/srs/blob/develop/trunk/research/players/js/srs.sdk.js) and [srs-unity: Player](https://github.com/ossrs/srs-unity#usage-player).

## Summaries

User can get the system summaries, for instance, the memory, cpu, network, load usage.

Please access the url `http://192.168.1.170:1985/api/v1/summaries`

## Vhosts

SRS provides http api to query all vhosts.

The http api vhost url: `http://192.168.1.102:1985/api/v1/vhosts`

To process specified vhost by id, for instance `http://192.168.1.102:1985/api/v1/vhosts/3756`

## Streams

SRS provides http api to query all streams.

The http api stream url: `http://192.168.1.102:1985/api/v1/streams`

Parameters in query string:

* `?start=N`: The start index, default is 0.
* `?count=N`: The max number of result, default is 10.

To process specified stream by id, for instance `http://192.168.1.102:1985/api/v1/streams/3756`

## Clients

SRS provides http api to query clients.

The http api client url: `http://192.168.1.102:1985/api/v1/clients`

Parameters in query string:

* `?start=N`: The start index, default is 0.
* `?count=N`: The max number of result, default is 10.

To process specified client by id, for instance `http://192.168.1.102:1985/api/v1/clients/3756`

## Forwards

SRS provides a read-only http api to query the forwarders of the publishing streams, see [Forward](./forward.md#forward-status).

The http api forward url: `http://192.168.1.102:1985/api/v1/forwards`

Parameters in query string:

* `?stream=ID`: Only the forwards of this stream, the id from the streams api.
* `?start=N`: The start index, default is 0.
* `?count=N`: The max number of result, default is 10.

The response has the array `forwards`, and `total`, the number of forwards after the `stream` filter, regardless of
`start` and `count`. To query specified forward by id, for instance
`http://192.168.1.102:1985/api/v1/forwards/fwd-3k9x1zq`, the response has the object `forward`:

```json
{
  "code": 0,
  "server": "vid-0w2w3z5",
  "service": "x0e5c1u5",
  "pid": "50234",
  "forward": {
    "id": "fwd-3k9x1zq",
    "stream": "vid-a4r1n2m",
    "vhost": "vid-7m2c0d1",
    "app": "live",
    "name": "livestream",
    "url": "rtmp://192.168.1.6:1935/live/livestream",
    "state": "forwarding",
    "state_at": 1760086530123
  }
}
```

The fields of a forward:

| Field | Description |
| --- | --- |
| id | The id of the forward. |
| stream | The id of the publishing stream, the same as the streams api. |
| vhost | The id of the vhost, the same as the vhosts api. |
| app | The app of the publishing stream. |
| name | The name of the publishing stream. |
| url | The RTMP url the forwarder publishes to, with the stream key and query. |
| state | `connecting`, `forwarding` or `retrying`. |
| state_at | When the forward entered this state, in Unix milliseconds. |

The states of a forward:

* `connecting`: Connecting and publishing to the destination, from the start or a retry.
* `forwarding`: Published to the destination, and sending the stream.
* `retrying`: Failed, and waiting 3 seconds to retry.

An unknown forward id returns the error code 2057 (`ForwardNotFound`). Other methods than `GET` return HTTP 405. A
forward is removed when its stream unpublishes; to remove a forward, kick the publisher, see [Forward](./forward.md#add-or-remove-a-forward).

## Kickoff Client

SRS provides HTTP RESTful api to kickoff user:

```
DELETE /api/v1/clients/{id}
```

User can get the id of client to kickoff:

```
GET /api/v1/clients
```

User can get the id of publish client from streams api:

```
GET /api/v1/streams
or GET /api/v1/streams/6745
```

The client cid is the info from stream api `stream.publish.cid`:

```
1. GET http://192.168.1.170:1985/api/v1/streams/6745
2. Response stream.publish.cid:
stream: {
    publish: {
        active: true,
        cid: 107
    }
}
3. DELETE http://192.168.1.170:1985/api/v1/clients/107
```

Remark: User can use [HTTP REST Tool](http://ossrs.net/srs.release/http-rest/index.html) to send a request.

Remark: User can use linux tool `curl` to start HTTP request. For example:

```
curl -v -X GET http://192.168.1.170:1985/api/v1/clients/426 && echo ""
curl -v -X DELETE http://192.168.1.170:1985/api/v1/clients/426 && echo ""
```

## Persistence Config

This feature is disabled by SRS 4.0.

## HTTP RAW API

SRS supports powerful HTTP RAW API, while other server only support `Read API`, for instance, to get the stat of server. SRS supports `Write API`, which can `Reload` or change server state.

<b>Remark:</b> User must enable the HTTP RAW API, in config section `http_api` to enable the `http_api.raw_api.enabled`, or SRS will response error code 1061.

```
http_api {
    enabled         on;
    listen          1985;
    raw_api {
        enabled             on;
        allow_reload        on;
    }
}
```

The supported HTTP RAW APi of SRS is:

* `Raw`: To query the HTTP RAW API config.
* `Reload`: To reload the SRS.

### Raw

| Key | DESC | 
| ---- | ---- |
| feature | Query the HTTP RAW API info. |
| url  | `/api/v1/raw?rpc=raw` |
| curl | `curl http://127.0.0.1:1985/api/v1/raw?rpc=raw` |
| config | No config |
| params | No params|

### RAW Reload

| Key | DESC | 
| ---- | ---- |
| feature | Reload is the same to `killall -1 srs` to reload the config |
| url  | `/api/v1/raw?rpc=reload` |
| curl | `curl http://127.0.0.1:1985/api/v1/raw?rpc=reload` |
| params | No params |

### Other RAW APIs

Other RAW APIs are disabled by SRS 4.0.

## Authentication

Starting from version `5.0.152+` or `6.0.40+`, SRS supports HTTP API authentication, which can be enabled by configuring `http_api.auth`.

### Basic Authentication

```bash
# conf/http.api.auth.basic.conf
http_api {
    enabled on;
    listen 1985;
    auth {
        enabled on;
        type basic;
        username admin;
        password admin;
    }
}
```

Otherwise, you can use environment variables to enable it:

```bash
env SRS_HTTP_API_ENABLED=on SRS_HTTP_SERVER_ENABLED=on \
    SRS_HTTP_API_AUTH_ENABLED=on SRS_HTTP_API_AUTH_TYPE=basic \
    SRS_HTTP_API_AUTH_USERNAME=admin SRS_HTTP_API_AUTH_PASSWORD=admin \
    ./objs/srs -e
```

Then, you can access the following urls to verify it:
- Prompt for username and password: http://localhost:1985/api/v1/versions
- URL with authentication: http://admin:admin@localhost:1985/api/v1/versions

To clean up the username and password, you can access the HTTP API with the username only:
- http://admin@localhost:1985/api/v1/versions

### Bearer Token Authentication

Bearer authentication protects the SRS HTTP API with a token sent in the
`Authorization` request header. By default, WebRTC signaling APIs remain
unprotected by Bearer authentication. Set the type to `bearer` and configure a
non-empty token:

```bash
# conf/http.api.auth.bearer.conf
http_api {
    enabled on;
    listen 1985;
    auth {
        enabled on;
        type bearer;
        token srs-api-token;
        rtc_bearer_enabled off;
    }
}
```

The equivalent environment variables are:

```bash
env SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 \
    SRS_HTTP_API_AUTH_ENABLED=on \
    SRS_HTTP_API_AUTH_TYPE=bearer \
    SRS_HTTP_API_AUTH_TOKEN=srs-api-token \
    ./objs/srs -e
```

Include the token in each API request:

```bash
curl -H 'Authorization: Bearer srs-api-token' \
    http://127.0.0.1:1985/api/v1/versions
```

To protect WHIP, WHEP, and other WebRTC signaling requests under `/rtc/`, also
enable RTC Bearer authentication:

```bash
SRS_HTTP_API_AUTH_RTC_BEARER_ENABLED=on
```

Or set `rtc_bearer_enabled on;` in `http_api.auth`. The WHIP and WHEP clients
must then send the same header:

```bash
curl -H 'Authorization: Bearer srs-api-token' \
    -H 'Content-Type: application/sdp' --data-binary @offer.sdp \
    'http://127.0.0.1:1985/rtc/v1/whip/?app=live&stream=livestream'
```

Requests with a missing or incorrect token receive HTTP `401 Unauthorized` and
the response header `WWW-Authenticate: Bearer`.

`SRS_HTTP_API_AUTH_TOKEN` protects the SRS server's own HTTP API and, when
`SRS_HTTP_API_AUTH_RTC_BEARER_ENABLED=on`, its WebRTC signaling APIs. It is
separate from proxy registration authentication and heartbeat credentials.

> Note: Basic and Bearer authentication protect APIs under `/api/`. Basic does
> not apply to WebRTC signaling APIs. Bearer protects `/rtc/` only when
> `rtc_bearer_enabled` is on. Neither type protects files served by the HTTP
> server.

Bearer authentication can be combined with [HTTP callbacks](./http-callback.md).
When RTC Bearer authentication is enabled, a WHIP or WHEP request must first
pass Bearer authentication, and SRS then invokes `on_publish` or `on_play` for
stream-specific authorization. When RTC Bearer authentication is disabled, the
HTTP callback can authorize WHIP and WHEP by itself.

Winlin 2015.8

---

### Skills Internal Docs For Srs References Cpp Docs Doc Http Callback (`skills/internal-docs-for-srs/references/cpp-docs/doc/http-callback.md`)

---
title: HTTP Callback
sidebar_label: HTTP Callback
hide_title: false
hide_table_of_contents: false
---

# HTTPCallback

SRS supports HTTP callback to extends SRS. The workflow is:

```text
+--------+     +--------+                    +-----------------------+
| FFmpeg |-->--+  SRS   |--HTTP-Callback-->--+  Your Business Server |
+--------+     +--------+                    +-----------------------+
```

When FFmpeg/OBS publish or play a stream to SRS, SRS will call your business server to notify the event.

## Usage

First, run SRS with HTTP callback enabled:

```bash
env SRS_RTMP_LISTEN=1935 SRS_VHOST_HTTP_HOOKS_ENABLED=on \
    SRS_VHOST_HTTP_HOOKS_ON_PUBLISH=http://127.0.0.1:8085/api/v1/streams \
    SRS_VHOST_HTTP_HOOKS_ON_UNPUBLISH=http://127.0.0.1:8085/api/v1/streams \
    SRS_VHOST_HTTP_HOOKS_ON_PLAY=http://127.0.0.1:8085/api/v1/sessions \
    SRS_VHOST_HTTP_HOOKS_ON_STOP=http://127.0.0.1:8085/api/v1/sessions \
    ./objs/srs -e
```

Start the demo HTTP callback server, which is your business server:

```bash
go run research/api-server/server.go
```

Publish a stream to SRS, with the params:

```bash
ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://localhost/live/livestream?k=v
```

Your business server will got the HTTP event:

```text
Got action=on_publish, client_id=3y1tcaw2, ip=127.0.0.1, vhost=__defaultVhost__, stream=livestream, param=?k=v
```

Note that the `k=v` can be used for authentication, for token authentication based on HTTP callbacks,
read [Token Authentication](./drm.md#token-authentication)

## Compile

SRS always enable http callbacks.

For more information, read [Build](./install.md)

## Configuring SRS

An example [conf/http.hooks.callback.conf](https://github.com/ossrs/srs/blob/develop/trunk/conf/http.hooks.callback.conf) 
is available, demonstrating the configuration of common callback events for direct use.

The config for HTTP hooks is:

```
/* Detailed source-code truncated for AI context efficiency. */
```

Description about some fields:

* `stream_url`: The stream identify without extension, such as `/live/livestream`.
* `stream_id`: The id of stream, by which you can query the stream information.

> Note: The callbacks for streaming are `on_publish` and `on_unpublish`, while the callbacks for playback are `on_play` and `on_stop`.

> Note: These callbacks also apply to WebRTC. WHIP publishing invokes
> `on_publish`, and WHEP playback invokes `on_play`. The callbacks can authorize
> WHIP and WHEP by themselves because RTC Bearer authentication is disabled by
> default. When combined with [Bearer authentication](./http-api.md#bearer-token-authentication),
> enable `rtc_bearer_enabled`; the WHIP or WHEP request must then pass Bearer
> authentication before SRS invokes the callback.

> Note: Before SRS 4, there were `on_connect` and `on_close`, which are events defined by RTMP and only applicable to RTMP streams. These events overlap with streaming and playback events, so their use is not recommended.

> Note: You can refer to the hooks.callback.vhost.com example in the conf/full.conf configuration file.

## Protocol

The detail protocol, for example, `on_publish`:

```text
POST /api/v1/streams HTTP/1.1
Content-Type: application-json

Body:
{
  "server_id": "vid-0xk989d",
  "action": "on_publish",
  "client_id": "341w361a",
  "ip": "127.0.0.1",
  "vhost": "__defaultVhost__",
  "app": "live",
  "tcUrl": "rtmp://127.0.0.1:1935/live?vhost=__defaultVhost__",
  "stream": "livestream",
  "param": "",
  "stream_url": "video.test.com/live/livestream",
  "stream_id": "vid-124q9y3"
}
```

> Note: You can use wireshark or tcpdump to verify it.

## Heartbeat

SRS will send heartbeat to the HTTP callback server. This allows you to monitor the health of SRS server.
Enable this feature by:

```
/* Detailed source-code truncated for AI context efficiency. */
```

By enable the `summaries`, you can get the SRS server states, such as `self.pid` and `self.srs_uptime`, so you
can use this to determine whether SRS restarted.

> Note: About fileds of `summaries`, see [HTTP API: summaries](./http-api.md#summaries) for details.

## Go Example

Write Go code to handle SRS callback, for example, handling `on_publish`:

```go
http.HandleFunc("/api/v1/streams", func(w http.ResponseWriter, r *http.Request) {
    b, err := ioutil.ReadAll(r.Body)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }

    fmt.Println(string(b))

    res, err := json.Marshal(struct {
        Code int `json:"code"`
        Message string `json:"msg"`
    }{
        0, "OK",
    })
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
    w.Write(res)
})

_ = http.ListenAndServe(":8085", nil)
```

## Nodejs Koa Example

Write Nodejs/Koa code to handle SRS callback, for example, handling `on_publish`:

```js
const Router = require('koa-router');
const router = new Router();

router.all('/api/v1/streams', async (ctx) => {
  console.log(ctx.request.body);

  ctx.body = {code: 0, msg: 'OK'};
});
```

## PHP Example

Write PHP code to handle SRS callback, for example, handling `on_publish`:

```php
$body = json_decode(file_get_contents('php://input'));
printf($body);

echo json_encode(array("code"=>0, "msg"=>"OK"));
```

## HTTP Callback Events

SRS can call HTTP callbacks for events:

* `on_publish`: When a client publishes a stream, for example, using flash or FMLE to publish a stream to the server. 
* `on_unpublish`: When a client stops publishing a stream. 
* `on_play`: When a client starts playing a stream. 
* `on_stop`: When a client stops playback. 
* `on_dvr`: When reap a DVR file.
* `on_hls`: When reap a HLS file.

For events `on_publish`和`on_play`:
* Return Code: SRS requires that the response is an int indicating the error, 0 is success.

Notes:
* Event: When this event occurs, call back to the specified HTTP URL.
* HTTP URL: Can be multiple URLs, split by spaces, SRS will notify all one by one.
* Data: SRS will POST the data to specified HTTP API.

SRS will disconnect the connection when the response is not 0, or HTTP status is not 200.

## SRS HTTP Callback Server

SRS provides a default HTTP callback server, using golang native http framework.

To start it: 

```bash
cd research/api-server && go run server.go 8085
```

```bash
#2023/01/18 22:57:40.835254 server.go:572: api server listen at port:8085, static_dir:/Users/panda/srs/trunk/static-dir
#2023/01/18 22:57:40.835600 server.go:836: start listen on::8085
```

> Remark: For SRS4, the HTTP/HTTPS url is supported, see [#1657](https://github.com/ossrs/srs/issues/1657#issuecomment-720889906).

## HTTPS Callback

HTTPS Callback is supported by SRS4, only change the callback URL from `http://` to `https://`, for example:

```
vhost your_vhost {
    http_hooks {
        enabled         on;
        on_publish      https://127.0.0.1:8085/api/v1/streams;
        on_unpublish    https://127.0.0.1:8085/api/v1/streams;
        on_play         https://127.0.0.1:8085/api/v1/sessions;
        on_stop         https://127.0.0.1:8085/api/v1/sessions;
        on_dvr          https://127.0.0.1:8085/api/v1/dvrs;
        on_hls          https://127.0.0.1:8085/api/v1/hls;
        on_hls_notify   https://127.0.0.1:8085/api/v1/hls/[app]/[stream]/[ts_url][param];
    }
}
```

## Response

If success, you must response `something` to identify the success, or SRS will reject the client, which enable you to reject the illegal client, please read [Callback Error Code](./http-api.md#error-code). 

> Note: The `on_publish` callback also could be used as advanced security, to `allow` or `deny` a client by its IP, or token in request url, or any other information of client.

Where `something` means:

* HTTP/200, which is HTTP success.
* `AND` response and int value 0, or JSON object with field code 0.

Like this:

```
HTTP/1.1 200 OK
Content-Length: 1
0
```

OR:

```
HTTP/1.1 200 OK
Content-Length: 11
{"code": 0}
```

You could run the example HTTP callback server by:

```
cd srs/trunk/research/api-server && go run server.go 8085
```

And you will finger out what's the `right` response.

## Snapshot

The HttpCallback can used to snapshot, please read [snapshot](./snapshot.md#httpcallback)

Winlin 2015.1

---

### Skills Internal Docs For Srs References Cpp Docs Doc Http Server (`skills/internal-docs-for-srs/references/cpp-docs/doc/http-server.md`)

---
title: HTTP Server
sidebar_label: HTTP Server 
hide_title: false
hide_table_of_contents: false
---

# HTTP Server

SRS Embeded a HTTP web server, supports api and simple HTTP file for HLS.

To deploy SRS HTTP server, read [Usage: HTTP](./sample-http.md)

The SRS Embeded HTTP server is rewrite refer to go http module, so it's ok to use srs as http server. Read [#277](https://github.com/ossrs/srs/issues/277)

> Remark: The SRS HTTP server is just a origin HTTP server, for HTTP edge server, please use NGINX, SQUID and ATS.

SRS also works well with HTTP reverse proxy servers, like [NGINX](#nginx-proxy) and [Caddy](#caddy-proxy).

## Use Scenario

The SRS Embeded HTTP server is design to provides basic HTTP service, 
like the camera of mobile phone.

SRS should provides HTTP api, which is actually a embeded HTTP server.

Actually, RTMP is more complex than HTTP, so HTTP server on st is absolutely ok.
The HTTP Server in SRS1.0 is an experiment, and I will enhance it in the future.

## Config

Config the HTTP port and root.

```bash
# embeded http server in srs.
# the http streaming config, for HLS/HDS/DASH/HTTPProgressive
# global config for http streaming, user must config the http section for each vhost.
# the embed http server used to substitute nginx in ./objs/nginx,
# for example, srs runing in arm, can provides RTMP and HTTP service, only with srs installed.
# user can access the http server pages, generally:
#       curl http://192.168.1.170:80/srs.html
# which will show srs version and welcome to srs.
# @remeark, the http embeded stream need to config the vhost, for instance, the __defaultVhost__
# need to open the feature http of vhost.
http_server {
    # whether http streaming service is enabled.
    # default: off
    enabled         on;
    # the http streaming port
    # @remark, if use lower port, for instance 80, user must start srs by root.
    # default: 8080
    listen          8080;
    # the default dir for http root.
    # default: ./objs/nginx/html
    dir             ./objs/nginx/html;
}
```

And, each vhost can specifies the dir.

```bash
vhost your_vhost {
    # http static vhost specified config
    http_static {
        # whether enabled the http static service for vhost.
        # default: off
        enabled     on;
        # the url to mount to, 
        # typical mount to [vhost]/
        # the variables:
        #       [vhost] current vhost for http server.
        # @remark the [vhost] is optional, used to mount at specified vhost.
        # @remark the http of __defaultVhost__ will override the http_stream section.
        # for example:
        #       mount to [vhost]/
        #           access by http://ossrs.net:8080/xxx.html
        #       mount to [vhost]/hls
        #           access by http://ossrs.net:8080/hls/xxx.html
        #       mount to /
        #           access by http://ossrs.net:8080/xxx.html
        #           or by http://192.168.1.173:8080/xxx.html
        #       mount to /hls
        #           access by http://ossrs.net:8080/hls/xxx.html
        #           or by http://192.168.1.173:8080/hls/xxx.html
        # default: [vhost]/
        mount       [vhost]/hls;
        # main dir of vhost,
        # to delivery HTTP stream of this vhost.
        # default: ./objs/nginx/html
        dir         ./objs/nginx/html/hls;
    }
}
```

Remark: The `http_stream` of SRS1 renamed to `http_server` in SRS2, which specifies the global HTTP server config, used to delivery http static files, for dvr files(HLS/FLV/HDS/MPEG-DASH).

Remark: The `http` of vhost of SRS1 renamed to `http_static`, similar to global `http_server` for HTTP static files delivery. While the `http_remux` introduced in SRS2 is dynamic remux RTMP to HTTP Live FLV/Mp3/Aac/HLS/Hds/MPEG-DASH stream.

## HTTPS Server

SRS supports HTTPS, just enable it in the configuration. By default, it uses a sub-signed certificate. If you need 
to use a CA-issued certificate, please replace the relevant files. The related configuration is as follows:

```bash
http_server {
    https {
        # Whether enable HTTPS Streaming.
        # Overwrite by env SRS_HTTP_SERVER_HTTPS_ENABLED
        # default: off
        enabled on;
        # The listen endpoint for HTTPS Streaming.
        # Overwrite by env SRS_HTTP_SERVER_HTTPS_LISTEN
        # default: 8088
        listen 8088;
        # The SSL private key file, generated by:
        #       openssl genrsa -out server.key 2048
        # Overwrite by env SRS_HTTP_SERVER_HTTPS_KEY
        # default: ./conf/server.key
        key ./conf/server.key;
        # The SSL public cert file, generated by:
        #       openssl req -new -x509 -key server.key -out server.crt -days 3650 -subj "/C=CA/ST=Toronto/L=Toronto/O=Me/OU=Me/CN=ossrs.io"
        # Overwrite by env SRS_HTTP_SERVER_HTTPS_CERT
        # default: ./conf/server.crt
        cert ./conf/server.crt;
    }
}
```

## Crossdomain

SRS has CORS (Cross-Origin Resource Sharing) support enabled by default. The related configuration is as follows:

```bash
http_server {
    # whether enable crossdomain request.
    # for both http static and stream server and apply on all vhosts.
    # Overwrite by env SRS_HTTP_SERVER_CROSSDOMAIN
    # default: on
    crossdomain on;
}
```

## MIME

Only some MIME is supported:

| File ext name | Content-Type |
| ------------- | -----------  |
| .ts | Content-Type: video/MP2T;charset=utf-8 |
| .m3u8 | Content-Type: application/x-mpegURL;charset=utf-8 |
| .json | Content-Type: application/json;charset=utf-8 |
| .css | Content-Type: text/css;charset=utf-8 |
| .swf | Content-Type: application/x-shockwave-flash;charset=utf-8 |
| .js | Content-Type: text/javascript;charset=utf-8 |
| .xml | Content-Type: text/xml;charset=utf-8 |
| Others | Content-Type: text/html;charset=utf-8 |

## Method

Supported HTTP method:
* GET: Query API, or download file.

## Paths

HTTP/HTTPS API:

* `/api/` SRS HTTP API
* `/rtc/` SRS WebRTC API

HTTP/HTTPS Stream:

* `/{app}/{stream}` HTTP Stream mounted by publisher.

The bellow is some reverse proxy to work with SRS.

> Note: Generally, a proxy can be used to route API and Stream together based on the path.

## Nginx Proxy

The config for NGINX as file [nginx.conf](https://github.com/ossrs/srs/blob/develop/trunk/conf/nginx.proxy.conf):

```
worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include             /etc/nginx/mime.types;

    server {
        listen       80;
        listen       443 ssl http2;
        server_name  _;
        ssl_certificate      /usr/local/srs/conf/server.crt;
        ssl_certificate_key  /usr/local/srs/conf/server.key;

        # For SRS homepage, console and players
        #   http://r.ossrs.net/console/
        #   http://r.ossrs.net/players/
        location ~ ^/(console|players)/ {
           proxy_pass http://127.0.0.1:8080/$request_uri;
        }
        # For SRS streaming, for example:
        #   http://r.ossrs.net/live/livestream.flv
        #   http://r.ossrs.net/live/livestream.m3u8
        location ~ ^/.+/.*\.(flv|m3u8|ts|aac|mp3)$ {
           proxy_pass http://127.0.0.1:8080$request_uri;
        }
        # For SRS backend API for console.
        # For SRS WebRTC publish/play API.
        location ~ ^/(api|rtc)/ {
           proxy_pass http://127.0.0.1:1985$request_uri;
        }
    }
}
```

## Caddy Proxy

The config for [CaddyServer](https://caddyserver.com/docs/getting-started) with automatic HTTPS, use the config file `Caddyfile`.

For HTTP server, note that to set the default port:

```
:80
reverse_proxy /* 127.0.0.1:8080
reverse_proxy /api/* 127.0.0.1:1985
reverse_proxy /rtc/* 127.0.0.1:1985
```

For HTTPS server, please enable a domain name:

```
example.com {
  reverse_proxy /* 127.0.0.1:8080
  reverse_proxy /api/* 127.0.0.1:1985
  reverse_proxy /rtc/* 127.0.0.1:1985
}
```

Start the CaddyServer:

```
caddy start -config Caddyfile
```

## Nodejs KOA Proxy

The nodejs koa proxy also works well for SRS, please use [koa-proxies](https://www.npmjs.com/package/koa-proxies) based by [node-http-proxy](https://github.com/nodejitsu/node-http-proxy), here is an example:

```js
const Koa = require('koa');
const proxy = require('koa-proxies');
const BodyParser = require('koa-bodyparser');
const Router = require('koa-router');

const app = new Koa();
app.use(proxy('/api/', {target: 'http://127.0.0.1:1985/'}));
app.use(proxy('/rtc/', {target: 'http://127.0.0.1:1985/'}));
app.use(proxy('/*/*.(flv|m3u8|ts|aac|mp3)', {target: 'http://127.0.0.1:8080/'}));
app.use(proxy('/console/', {target: 'http://127.0.0.1:8080/'}));
app.use(proxy('/players/', {target: 'http://127.0.0.1:8080/'}));

// Start body-parser after proxies, see https://github.com/vagusX/koa-proxies/issues/55
app.use(BodyParser());

// APIs that depends on body-parser
const router = new Router();
router.all('/', async (ctx) => {
  ctx.body = 'Hello World';
});
app.use(router.routes());

app.listen(3000, () => {
  console.log(`Server start on http://localhost:3000`);
});
```

Save it as `index.js`, then run:

```
npm init -y 
npm install koa koa-proxies koa-proxies koa-bodyparser koa-router
node .
```

## HTTPX Proxy

Well [httpx-static](https://github.com/ossrs/go-oryx/tree/develop/httpx-static#usage) is a simple HTTP/HTTPS proxy written by Go:

```
go get github.com/ossrs/go-oryx/httpx-static
cd $GOPATH/bin
./httpx-static -http=80 -https=443 \
  -skey /usr/local/srs/etc/server.key -scert /usr/local/srs/etc/server.crt \
  -proxy=http://127.0.0.1:1985/api/v1/ \
  -proxy=http://127.0.0.1:1985/rtc/v1/ \
  -proxy=http://127.0.0.1:8080/
```

> Please make sure the path `/` is the last one.

Winlin 2015.1

---

### Skills Internal Docs For Srs References Cpp Docs Doc Ingest (`skills/internal-docs-for-srs/references/cpp-docs/doc/ingest.md`)

---
title: Ingest
sidebar_label: Ingest 
hide_title: false
hide_table_of_contents: false
---

# Ingest

Ingest is used to ingest file(flv, mp4, mkv, avi, rmvb...), 
stream(RTMP, RTMPT, RTMPS, RTSP, HTTP, HLS...) and device,
encode or passthrough then publish as RTMP to SRS.

Ingest actually use FFmpeg, or your tool, to encode or remux
to suck known data to RTMP to SRS.

How to deploy ingest, read [Ingest](./sample-ingest.md)

## Use Scenario

The main use scenarios:
* Virtual Live Stream: Convert vod file to live stream.
* Input RTSP IP Camera: Many IP Camera supports to pull in RTSP, user can ingest the RTSP to RTMP to SRS.
* Directly ingest device, use the FFmpeg as encoder actually.
* Ingest HTTp stream to RTMP for some old stream server.

In a word, the Ingest is used to ingest any stream supported by FFMPEG to SRS.

SRS server is support encoder to publish stream, while ingest can enable SRS to act like a client to pull 
stream from other place.

## Build

Config SRS with option `--with-ingest`, read [Build](./install.md)

The ingest tool of SRS can use FFMPEG, or use your own tool.

## Config

The config to use ingest:

```bash
vhost your_vhost {
    # ingest file/stream/device then push to SRS over RTMP.
    # the name/id used to identify the ingest, must be unique in global.
    # ingest id is used in reload or http api management.
    ingest livestream {
        # whether enabled ingest features
        # default: off
        enabled      on;
        # input file/stream/device
        # @remark only support one input.
        input {
            # the type of input.
            # can be file/stream/device, that is,
            #   file: ingest file specifies by url.
            #   stream: ingest stream specifeis by url.
            #   device: not support yet.
            # default: file
            type    file;
            # the url of file/stream.
            url     ./doc/source.flv;
        }
        # the ffmpeg 
        ffmpeg      ./objs/ffmpeg/bin/ffmpeg;
        # the transcode engine, @see all.transcode.srs.com
        # @remark, the output is specified following.
        engine {
            # @see enabled of transcode engine.
            # if disabled or vcodec/acodec not specified, use copy.
            # default: off.
            enabled          off;
            # output stream. variables:
            # [vhost] current vhost which start the ingest.
            # [port] system RTMP stream port.
            output          rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
        }
    }
}
```

The word after ingest keyword is the id of ingest, the id must be unique.

The `type` specifies the ingest type:
* file: To ingest file to RTMP, SRS will add `-re` for FFMPEG.
* stream: To ingest stream to RTMP.
* device: Not support yet.

The `engine` specifies the transcode engine and output:
* enabled: Whether transcode, remux when off.
* output：The output RTMP url. The vhost and port is variable.
* others is same to [FFMPEG](./ffmpeg.md)

Note: Engine is copy, when:
* The enabled is off.
* The vcodec and acodec is not specified.

## Ingest File list

SRS does not ingest a file list, a wordaround:
* Use script as the ingest tool, which use ffmpeg to copy file to RTMP stream one by one.

Read https://github.com/ossrs/srs/issues/55

Winlin 2014.11

---

### Skills Internal Docs For Srs References Cpp Docs Doc Introduction (`skills/internal-docs-for-srs/references/cpp-docs/doc/introduction.md`)

---
title: Introduction
sidebar_label: Introduction
hide_title: false
hide_table_of_contents: false
---

# Introduction

> Remark: SRS6 is developing and not stable.

SRS is a open-source ([MIT Licensed](../../../license)), simple, high-efficiency, real-time video server supporting RTMP, 
WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH, and GB28181. SRS media server works with clients like [FFmpeg](https://ffmpeg.org),
[OBS](https://obsproject.com), [VLC](https://www.videolan.org), and [WebRTC](https://webrtc.org) to provide 
the ability to [receive and distribute streams](./getting-started.md) in a typical publish (push) and 
subscribe (play) server model. SRS supports widely used internet audio and video protocol conversions, 
such as converting [RTMP](./rtmp.md) or [SRT](./srt.md) to [HLS](./hls.md), [HTTP-FLV](./flv.md), or 
[WebRTC](./webrtc.md).

SRS is primarily used in the Live streaming and WebRTC fields. In the live streaming domain, SRS supports typical 
protocols such as RTMP, HLS, SRT, MPEG-DASH, and HTTP-FLV. In the WebRTC field, SRS supports protocols like WebRTC, 
WHIP, and WHEP. SRS facilitates protocol conversion for both Live streaming and WebRTC. As a media server, SRS 
typically works alongside other open-source projects such as FFmpeg, OBS, and WebRTC. Oryx as an out-of-the-box 
media solution, incorporating numerous open-source projects and tools, please refer to the [introduction](./getting-started-oryx.md#introduction) 
of Oryx.

SRS provides an [HTTP API](./http-api.md) open interface to query system and stream status. It also supports 
[HTTP Callback](./http-callback.md) for callback capabilities, actively notifying your system and implementing 
stream authentication and business customization (such as dynamic DVR). SRS also supports the official 
[Prometheus Exporter](./exporter.md) for integration with cloud-native monitoring systems, offering powerful 
observability. SRS supports session-level [traceable logs](./log.md), greatly reducing system maintenance costs.

If you are new to audio, video, and streaming media or new to SRS, we recommend reading [Getting Started](./getting-started.md) 
and [Learning Path](/guide). Please take the time to read the following documentation, as reading and 
familiarizing yourself with the documentation is a basic requirement of the community. If you encounter any 
problems, please first search in the [FAQ](../../../faq), then in [Issues](https://github.com/ossrs/srs/issues) and 
[Discussions](https://github.com/ossrs/srs/discussions) to find answers to almost all questions.

SRS is developed using ANSI C++ (98) and only uses basic C++ capabilities. It can run on multiple platforms 
such as Linux, Windows, and macOS. We recommend using Ubuntu 20+ for development and debugging. The image 
we provide [ossrs/srs](https://hub.docker.com/r/ossrs/srs) is also built on Ubuntu 20 (focal).

> Note: To solve the long connection and complex state machine problems in complex streaming media processing, 
> SRS uses [ST(State Threads)](https://github.com/ossrs/state-threads) coroutine technology (similar 
> to [Goroutine](https://go.dev/doc/effective_go#goroutines)) and continuously enhances and maintains 
> ST's capabilities, supporting multiple platforms such as Linux, Windows, macOS, and various CPU 
> architectures like X86_64, ARMv7, AARCH64, M1, RISCV, LOONGARCH, and MIPS.

## Features

Functionality is often a major concern for people and the richness of features is an important reason for choosing a
project. You can view the detailed feature list at [Features](https://github.com/ossrs/srs/blob/develop/trunk/doc/Features.md#features). 
We have listed the main features' versions, along with related Issue and PR links.

Additionally, in the detailed description of [Milestones](/product), the supported features for each major version 
are introduced.

> Note: If you want to see the Issues for each milestone, you can check them at [Milestones](https://github.com/ossrs/srs/milestones).

Please note that although not many, SRS still marks some features as [Deprecated](https://github.com/ossrs/srs/blob/develop/trunk/doc/Features.md#features). 
You can search for 'Deprecated' or 'Removed' on the page. We will also explain in detail why we are removing a 
particular feature.

If you want to know about the features we are currently working on, you can join our [Discord](/contact#discussion) 
and [Blog](../../../blog). Once new features are completed, we will post articles on Discord and Blog, so stay tuned.

## Who's using SRS?

SRS users are spread all over the world, and we welcome everyone to showcase their SRS applications 
in [SRS Use Cases](https://github.com/ossrs/srs/discussions/3771).

## Governance

We welcome everyone to participate in the development and maintenance of SRS. We recommend starting by
resolving issues from [Contribute](https://github.com/ossrs/srs/contribute) and [submitting PRs](/how-to-file-pr).
All contributors will be showcased in [Contributors](https://github.com/ossrs/srs#authors).

SRS is a non-commercial open-source community where active developers have their own jobs and contribute to SRS's 
development in their spare time.

Since the SRS system is highly efficient, we can spend minimal time making continuous improvements, delivering 
feature-rich and stable high-quality products. Customizing based on SRS is also easy.

We are a global open-source community with developer communities both domestically and abroad. We welcome developers 
to join us:

* Great sense of accomplishment: Your code can impact global users, change the audio and video industry, and transform various sectors as SRS is widely used.
* Solid technical progress: You can interact with top audio and video developers worldwide, master high-quality software development skills, and mutually enhance technical capabilities.

SRS currently uses the following techniques and rules to ensure high quality and efficiency:

* Long-term discussions on architecture and solutions. For significant features and plans, extensive discussions are required, such as the 7-year discussion on [HEVC/H.265](https://github.com/ossrs/srs/issues/465) support.
* Careful and thorough code reviews. Each pull request must be approved by at least two TOCs and developers and pass all Actions before merging.
* Comprehensive unit tests (over 500), code coverage (around 60%), black-box testing, etc., ensuring ample testing time with one year of development and one year of testing.
* Full pipeline: Each pull request has a pipeline, and each release is automatically completed by the pipeline.

We welcome you to join us. For more information, please visit [Contribute](https://github.com/ossrs/srs/contribute)
and submit a pull request as required.

## Milestone

SRS releases a major version approximately every two years, with one year for development and one year
for stability improvement. For more details, please refer to [Milestone](/product).

If you want to use SRS online, it's recommended to use the stable version. If you want to use new features, use 
the development version.

SRS has branches based on versions, such as:

* [develop](https://github.com/ossrs/srs/tree/develop) SRS 6.0, development branch, unstable, but with the most new features.
* [5.0release](https://github.com/ossrs/srs/tree/5.0release#releases) SRS 5.0, currently stable, depending on the branch's status.
* [4.0release](https://github.com/ossrs/srs/tree/4.0release#releases) SRS 4.0, currently the stable branch, and will become more stable over time.

To determine if a branch is stable, check the Releases tag, such as [SRS 4.0](https://github.com/ossrs/srs/tree/4.0release#releases):

* 2022-06-11, Release v4.0-r0, this is a stable release version.
* 2021-12-01, Release v4.0-b0, this is a relatively stable beta version, also known as a public test version.
* 2021-11-15, Release v4.0.198, this version is an unstable development version.

> Note: In addition to beta versions, there are alpha versions, such as `v5.0-a0`, which are less stable internal 
> test versions compared to beta.

> Note: Each alpha, beta, and release version will correspond to a specific version number, such as `v5.0-a0` 
> corresponding to `v5.0.98`.

For SRS, generally, once it reaches the beta version, it can be used online.

## Strategy

SRS doesn't develop client-side applications because there are already mature and large open-source communities like 
FFmpeg, OBS, VLC, and WebRTC. SRS collaborates with these communities and uses their products.

In addition to the SRS server, they also work on Oryx and WordPress plugins, with the main goal of creating 
simpler application methods for different industries, including:

* [Oryx](https://github.com/ossrs/oryx): Oryx(SRS Stack) is an out-of-the-box, single-machine video cloud solution that includes FFmpeg and SRS. It's designed for users who aren't familiar with command lines and allows them to set up audio and video applications through Tencent Cloud images or BaoTa with mouse operations.
* [WordPress-Plugin-SrsPlayer](https://github.com/ossrs/WordPress-Plugin-SrsPlayer): This plugin is for the publishing industry, such as personal blogs and media websites, making it easy for users to utilize audio and video capabilities.
* [srs-unity](https://github.com/ossrs/srs-unity): This project is for the gaming industry, integrating Unity's WebRTC SDK to use audio and video capabilities.

SRS will continue to improve its toolchain. Developers may not use SRS but might have used the SB stress testing tool:

* [srs-bench](https://github.com/ossrs/srs-bench): An audio and video stress testing tool that supports RTMP, FLV, WebRTC, GB28181, etc., with plans for future improvements.
* [state-threads](https://github.com/ossrs/state-threads): A C coroutine library that can be considered a C version of Go. It's a small but powerful server library that will be continuously improved.
* [tea](https://github.com/ossrs/tea): This project explores eBPF for network simulation in weak network conditions and load balancing.

SRS aims to continuously improve audio and video toolchains, solutions, and scenario-based capabilities, making it 
possible for various industries to utilize audio and video capabilities.

## Sponsors

SRS is committed to building a non-profit open-source project and community. We provide special community
support for friends who sponsor SRS. Please see [Sponsor](/contact#donation).

Audio and video developers often face challenges, and they might be used to the close support from cloud 
service providers. When joining an open-source community, it might feel unfamiliar.

Don't panic when encountering issues. Most problems have solutions that can be found in the [FAQ](../../../faq) 
or the documentation [Docs](./getting-started.md).

You can also join the Discord channel through [Support](/contact) to communicate with other developers. 
However, please follow community guidelines, or you won't receive help.

As developers, we must learn to read documentation, investigate issues, and then discuss them within the community.

For advanced developers, we suggest becoming a `Backer/Sponsor`. See [Support](/contact#donation).

SRS has no commercial plans. We are currently working hard to build a global, active developer community. 
The value of open-source will grow, and community support will increase.

## About Oryx

Oryx is a lightweight, open-source video cloud solution based on Go, Reactjs, SRS, FFmpeg, WebRTC,
and more. For more details, please refer to [Oryx](./getting-started-oryx.md).

---

### Skills Internal Docs For Srs References Cpp Docs Doc Low Latency (`skills/internal-docs-for-srs/references/cpp-docs/doc/low-latency.md`)

---
title: Low Latency
sidebar_label: Low Latency
hide_title: false
hide_table_of_contents: false
---

# Low Latency Live Stream

The RTMP and HLS can cover all requires for internet live stream,
read  [DeliveryHLS](./hls.md),
while RTMP is designed for low latency live stream.

The deploy for low latency, read [Usage: Realtime](./sample-realtime.md)

## Use Scenario

The low latency use scenario:
* Live show.
* Video meeting.
* Other, for example, monitor, education.

## Latency

RTMP is design for low latency:
* Adobe flash player is good at play RTMP stream.
* RTMP is stable enough for longtime publish and play on PC.
* Low latency, about 0.8-3s.
* For RTMP is base on TCP, the latency maybe very large for network issue.

## HLS LowLatency

HLS has a bigger delay than RTMP, usually more than 5 seconds. If not set up properly, it can be over 15 seconds.

If you want to reduce the HLS delay, please check out [HLS LowLatency](./hls.md#hls-low-latency).

## Benchmark

We use the clock of mobile phone to test the latency,
read [RTMP latency benchmark](http://blog.csdn.net/win_lin/article/details/12615591)

When netowork is ok:
* RTMP can ensure 0.8-3s latency.
* The RTMP cluster add 0.3s latency for each level.
* The latency of nginx-rtmp is larger than SRS, maybe the cache or multiple process issue.
* The gop cache always make the latency larger, but SRS can disable the gop cache.
* The bufferTime of flash client should set to small, see NetStream.bufferTime.

## Min-Latency

When min-latency is enabled, SRS will diable the mr(merged-read) and use timeout cond wait, to send about 1-2 video packets when got it.

We can got 0.1s latency for vp6 video only stream, read [#257](https://github.com/ossrs/srs/issues/257#issuecomment-66773208). The config:

```
vhost mrw.srs.com {
    # whether enable min delay mode for vhost.
    # for min latence mode:
    # 1. disable the publish.mr for vhost.
    # 2. use timeout for cond wait for consumer queue.
    # @see https://github.com/ossrs/srs/issues/257
    # default: off
    min_latency     off;
}
```

For example to deploy realtime stream, read [wiki]([EN](./sample-realtime.md), [CN](./sample-realtime.md)).

## Merged-Read

The perfromance of RTMP read is very low, because we must read 1byte chunk type, then chunk header, finally payload. So SRS 1.0 only supports 1000 publisher, and 2700 player. SRS 2.0 supports 4500 publisher, and 10000 player.

To improve the read performance, SRS2.0 introduced the merged-read, which read Nms packets from socket then parsed in buffer. The config:

```
# the MR(merged-read) setting for publisher.
vhost mrw.srs.com {
    # the config for FMLE/Flash publisher, which push RTMP to SRS.
    publish {
        # about MR, read https://github.com/ossrs/srs/issues/241
        # when enabled the mr, SRS will read as large as possible.
        # default: off
        mr          off;
        # the latency in ms for MR(merged-read),
        # the performance+ when latency+, and memory+,
        #       memory(buffer) = latency * kbps / 8
        # for example, latency=500ms, kbps=3000kbps, each publish connection will consume
        #       memory = 500 * 3000 / 8 = 187500B = 183KB
        # when there are 2500 publisher, the total memory of SRS atleast:
        #       183KB * 2500 = 446MB
        # the value recomment is [300, 2000]
        # default: 350
        mr_latency  350;
    }
}
```

That is, when merged-read enabled, the read buffer of SRS is `latency` ms, the latency also increase to this value.

For low latency, user should disable merged-read, SRS will recv and parse the packet immediately.

## Merged-Write

SRS always use merged-write to send packets. This algorithm can improve about 500% performance, for example, SRS 1.0 writev a packet which supports 2700 clients, while SRS 2.0 writev multiple packets and supports 10000 clients.

User can config the merged write pacets in ms, recomment to use default value:

```
# the MW(merged-write) settings for player.
vhost mrw.srs.com {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # set the MW(merged-write) latency in ms.
        # SRS always set mw on, so we just set the latency value.
        # the latency of stream >= mw_latency + mr_latency
        # the value recomment is [300, 1800]
        # default: 350
        mw_latency      350;
    }
}
```

User can config this to 100ms for very low latency.

## GOP-Cache

The gop is the gop between two I frame.

SRS use gop-cache to cache the last gop for the live stream,
when client play stream, SRS can send the last gop to client
to enable the client to start play immediately.

Config of srs:

```bash
# the listen ports, split by space.
listen              1935;
vhost __defaultVhost__ {
    # for play client, both RTMP and other stream clients,
    # for instance, the HTTP FLV stream clients.
    play {
        # whether cache the last gop.
        # if on, cache the last gop and dispatch to client,
        #   to enabled fast startup for client, client play immediately.
        # if off, send the latest media data to client,
        #   client need to wait for the next Iframe to decode and show the video.
        # set to off if requires min delay;
        # set to on if requires client fast startup.
        # default: on
        gop_cache       off;
    }
}
```

Read about the min.delay.com in `conf/full.conf`.

## Low Latency config

Recoment to use the bellow config for low latency application:

```bash
# the listen ports, split by space.
listen              1935;
vhost __defaultVhost__ {
    tcp_nodelay     on;
    min_latency     on;

    play {
        gop_cache       off;
        queue_length    10;
        mw_latency      100;
    }

    publish {
        mr off;
    }
}
```

## Benchmark Data

SRS: 0.9.55

Encoder: FMLE, video(h264, profile=baseline, level=3.1, keyframe-frequency=5seconds), fps=15, input=640x480, 
output(500kbps, 640x480), no audio output.

Network: Publish to aliyun qindao server.

SRS config:

```bash
listen              1935;
vhost __defaultVhost__ {
    enabled         on;
    play {
        gop_cache       off;
    }
    hls {
        enabled         on;
        hls_path        ./objs/nginx/html;
        hls_fragment    5;
        hls_window      20;
    }
}
```

Latency: RTMP 2s, HLS 24s.

Read: 

## Edge Benchmark Data

SRS RTMP cluster almost not add more latency.

Read 

Winlin 2015.8

---

### Skills Internal Docs For Srs References Cpp Docs Doc Nginx For Hls (`skills/internal-docs-for-srs/references/cpp-docs/doc/nginx-for-hls.md`)

---
title: HLS Cluster
sidebar_label: HLS Cluster
hide_title: false
hide_table_of_contents: false
---

# Nginx for HLS

Edge Cluster is designed to solve the problem of many people watching, and it can support a large number of people watching live streams. Please note:

* SRS Edge only supports live streaming protocols, such as RTMP or HTTP-FLV, etc. Refer to [RTMP Edge Cluster](./sample-rtmp-cluster.md).
* SRS Edge does not support sliced live streams like HLS or DASH. Essentially, they are not streams but file distribution.
* SRS Edge does not support WebRTC stream distribution, as this is not the design goal of Edge. WebRTC has its own clustering method, refer to [#2091](https://github.com/ossrs/srs/issues/2091).

This article describes the edge cluster for HLS or DASH slices, which is based on NGINX implementation, so it is also called NGINX Edge Cluster.

## Oryx

The NGINX edge cluster can work together with the Oryx to achieve HLS distribution. For more details, please refer to [Oryx HLS CDN](https://github.com/ossrs/oryx/tree/main/scripts/nginx-hls-cdn).

## NGINX Edge Cluster

The NGINX edge cluster is essentially a reverse proxy with caching, also known as NGINX Proxy with Cache.

```text
+------------+          +------------+          +------------+          +------------+
+ FFmpeg/OBS +--RTMP-->-+ SRS Origin +--HLS-->--+ NGINX      +--HLS-->--+ Visitors   +
+------------+          +------------+          + Servers    +          +------------+
                                                +------------+          
```

You only need to configure the caching strategy of NGINX, no additional plugins are needed, as NGINX itself supports it.

```bash
http {
    # For Proxy Cache.
    proxy_cache_path  /tmp/nginx-cache levels=1:2 keys_zone=srs_cache:8m max_size=1000m inactive=600m;
    proxy_temp_path /tmp/nginx-cache/tmp; 

    server {
        listen       8081;
        # For Proxy Cache.
        proxy_cache_valid  404      10s;
        proxy_cache_lock on;
        proxy_cache_lock_age 300s;
        proxy_cache_lock_timeout 300s;
        proxy_cache_min_uses 1;

        location ~ /.+/.*\.(m3u8)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri$args;
            proxy_cache_valid  200 302  10s;
        }
        location ~ /.+/.*\.(ts)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri;
            proxy_cache_valid  200 302  60m;
        }
    }
}
```

> Note: You can configure the cache directory `proxy_cache_path` and `proxy_temp_path` to be accessible directories.

> Note: Generally, do not modify the `location` configuration unless you know what it means. If you want to change it, make sure it runs first before making changes.

You must not configure it as a pure Proxy, as this will pass the load through to SRS, and the number of clients the system supports will still be limited by SRS.

After enabling Cache, no matter how much load NGINX has, SRS will only have one stream. In this way, we can expand multiple NGINX to support a large number of concurrent viewers.

For example, a 1Mbps HLS stream, with 1000 clients playing on NGINX, the bandwidth of NGINX would be 1Gbps, while SRS would only have 1Mbps.

If we expand to 10 NGINX, each with 10Gbps bandwidth, the total system bandwidth would be 100Gbps, capable of supporting 100,000 concurrent viewers, with SRS bandwidth consumption only at 10Mbps.

How to verify that the system is working properly? This is where Benchmark comes in.

## Benchmark

How to stress test this system? You can use [srs-bench](https://github.com/ossrs/srs-bench#usage), which is very convenient to use and can be started directly with Docker:

```bash
docker run --rm -it --network=host --name sb ossrs/srs:sb \
  ./objs/sb_hls_load -c 500 \
  -r http://your_server_public_ipv4/live/livestream.m3u8
```

And you can also stress test RTMP and HTTP-FLV:

```bash
docker run --rm -it --network=host --name sb ossrs/srs:sb \
  ./objs/sb_http_load -c 500 \
  -r http://your_server_public_ipv4/live/livestream.flv
```

> Note: Each SB simulated client concurrency is between 500 and 1000, depending on the CPU not exceeding 80%. You can start multiple processes for stress testing.

Now let's get our hands on creating an HLS cluster.

## Example

Now let's use Docker to build an HLS distribution cluster.

First, start the SRS origin server:

```bash
env SRS_RTMP_LISTEN=1935 SRS_HTTP_SERVER_ENABLED=on SRS_VHOST_HLS_ENABLED=on \
  SRS_VHOST_HLS_HLS_CTX=off SRS_VHOST_HLS_HLS_TS_CTX=off \
  ./objs/srs -e
```

Then, start the NGINX origin server:

```bash
nginx -c $(pwd)/conf/hls.edge.conf
```

Finally, push the stream to the origin server:

```bash
ffmpeg -re -i doc/source.flv -c copy \
  -f flv rtmp://127.0.0.1/live/livestream
```

Play HLS:

* SRS origin server: http://127.0.0.1:8080/live/livestream.m3u8
* NGINX edge: http://127.0.0.1:8081/live/livestream.m3u8

Start the stress test and get HLS from NGINX:

```bash
docker run --rm -it --network=host --name sb ossrs/srs:sb \
  ./objs/sb_hls_load -c 500 \
  -r http://192.168.0.14:8081/live/livestream.m3u8
```

However, the pressure on SRS is not significant, and the CPU consumption is all on NGINX.

The NGINX edge cluster successfully solved the HLS distribution problem. If you also need to do low-latency live streaming and distribute HTTP-FLV, how to do it? What if you want to support HTTPS HLS or HTTPS-FLV?

NGINX has no problem at all. Now let's see how to work with the SRS Edge Server to implement HTTP-FLV and HLS distribution through NGINX.

## Work with SRS Edge Server

The NGINX edge cluster can also work with the SRS Edge Server to achieve HLS and HTTP-FLV distribution.

```text
+------------+           +------------+
| SRS Origin +--RTMP-->--+ SRS Edge   +
+-----+------+           +----+-------+
      |                       |               +------------+
      |                       +---HTTP-FLV->--+   NGINX    +              +-----------+
      |                                       +   Edge     +--HLS/FLV-->--+ Visitors  +
      +-------HLS--->-------------------------+   Servers  +              +-----------+
                                              +------------+
```

It's very simple to implement. All you need to do is deploy an SRS on the NGINX server and have NGINX work in reverse proxy mode.

```bash
# For SRS streaming, for example:
#   http://r.ossrs.net/live/livestream.flv
location ~ /.+/.*\.(flv)$ {
   proxy_pass http://127.0.0.1:8080$request_uri;
}
```

In this way, HLS is managed by NGINX for caching and back-to-source, while FLV is cached and back-to-source by SRS Edge.

Although this architecture is good, in fact, NGINX can directly serve as an HLS origin server, which can provide even higher performance. Is it possible? No problem at all. Let's see how to use NGINX to distribute HLS completely.

## NGINX Origin Server

Since HLS is just a regular file, it can also be directly used with NGINX as an HLS origin server.

In a super high-concurrency NGINX Edge cluster, a small data center-level cluster can also be formed, with centralized back-to-source from a specific NGINX, which can support even higher concurrency.

Using NGINX to distribute HLS files is actually very simple, you only need to set the root:

```bash
  # For HLS delivery
  location ~ /.+/.*\.(m3u8)$ {
    root /usr/local/srs/objs/nginx/html;
    add_header Cache-Control "public, max-age=10";
  }
  location ~ /.+/.*\.(ts)$ {
    root /usr/local/srs/objs/nginx/html;
    add_header Cache-Control "public, max-age=86400";
  }
```

> Note: Here we set the cache time for m3u8 to 10 seconds, which needs to be adjusted according to the size of the segment.

> Note: Since SRS currently supports HLS variant and implements HLS playback statistics, it is not as efficient as NGINX. See [#2995](https://github.com/ossrs/srs/issues/2995)

> Note: SRS should set `Cache-Control` because the segment service can dynamically set the correct cache time to reduce latency. See [#2991](https://github.com/ossrs/srs/issues/2991)

## Debugging

How to determine if the cache is effective? You can add a field `upstream_cache_status` in the NGINX log and analyze the NGINX log to determine if the cache is effective:

```bash
log_format  main  '$upstream_cache_status $remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
access_log  /var/log/nginx/access.log main;
```

The first field is the cache status, which can be analyzed using the following command, for example, to only view the cache status of TS files:

```bash
cat /var/log/nginx/access.log | grep '.ts HTTP' \
  | awk '{print $1}' | sort | uniq -c | sort -r
```

You can see which ones are HIT cache, so you don't need to download files from SRS, but directly get files from NGINX.

You can also directly add this field to the response header, so you can see in the browser whether each request has HIT:

```bash
add_header X-Cache-Status $upstream_cache_status;
```

> Note: Regarding the cache effective time, refer to the definition of the field [proxy_cache_valid](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid), in fact, if the source station specifies `Cache-Control`, it will override this configuration.

## aaPanel Configuration

If you are using aaPanel, you can add a new site, and then write the following configuration in the site's configuration:

```bash
    # For Proxy Cache.
    proxy_cache_path  /tmp/nginx-cache levels=1:2 keys_zone=srs_cache:8m max_size=1000m inactive=600m;
    proxy_temp_path /tmp/nginx-cache/tmp; 

    server {
        listen       80;
        server_name your.domain.com;

        # For Proxy Cache.
        proxy_cache_valid  404      10s;
        proxy_cache_lock on;
        proxy_cache_lock_age 300s;
        proxy_cache_lock_timeout 300s;
        proxy_cache_min_uses 1;

        location ~ /.+/.*\.(m3u8)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri$args;
            proxy_cache_valid  200 302  10s;
        }
        location ~ /.+/.*\.(ts)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri;
            proxy_cache_valid  200 302  60m;
        }
    }
```

> Note: Generally, when adding a new site in aaPanel, it listens to port 80, and the domain server_name is the domain name you fill in yourself. Other configurations are the same as the aaPanel settings. Alternatively, you can also add the above cache and location configurations to the site settings in aaPanel.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Origin Cluster (`skills/internal-docs-for-srs/references/cpp-docs/doc/origin-cluster.md`)

---
title: Origin Cluster
sidebar_label: Origin Cluster
hide_title: false
hide_table_of_contents: false
---

# OriginCluster

The SRS origin cluster is a group of origin servers intended for handling a large number of streams.

The new origin cluster is designed as a collection of proxy servers that load balance and proxy to a 
set of origin servers. For more information, see [Discussion #3634](https://github.com/ossrs/srs/discussions/3634). 
If you prefer to use the old origin cluster, please switch to a version before SRS 6.0.

## Introduction

You can deploy multiple SRS origin servers, to handle a large number of streams. The proxy server is
used as a load balancer for these origin servers:

```text
                                       +--------------------+
                               +-------+ SRS Origin Server  +
                               +       +--------------------+
                               +
+-----------------------+      +       +--------------------+
+ SRS Proxy(Deployment) +------+-------+ SRS Origin Server  +
+-----------------------+      +       +--------------------+
                               +
                               +       +--------------------+
                               +-------+ SRS Origin Server  +
                                       +--------------------+
```

The origin cluster also enhances the scalability of the origin server. For instance, with 200 backend 
SRS origin servers, it can support 100 WebRTC streamers, each with 200 viewers, totaling 20,000 connections.
If you deploy this cluster on a server with a large number of CPU cores, it becomes a very powerful 
media server.

> Note: You are also able to deploy multiple proxy servers, or proxy to other media servers, or work 
> with edge cluster, see [Design](#design) for details.

The proxy server support almost all protocols of SRS, including RTMP, HTTP-FLV, HLS, WebRTC, and SRT. 
Please see [Protocols](#protocols) for details.

## Build

To build the proxy server, you need to have Go 1.18+ installed. Then, you can build the proxy
server by below command, and get the executable binary `bin/srs-proxy`:

```bash
git clone https://github.com/ossrs/srs.git
cd srs && make
```

> Note: You can also download the dependencies by running `go mod download` before building.

We will support the Docker image in the future, or integrate the proxy server into the Oryx 
project.

## Legacy

From SRS 7.0+, the new Origin Cluster is based on proxy server, not the old MESH based SRS servers.
However, if you want to use the old origin cluster, you can switch to SRS 6.0.

## RTMP Origin Cluster

To use the RTMP origin cluster, you need to deploy the proxy server and the origin server. 
First, start the proxy server:

```bash
env PROXY_RTMP_SERVER=1935 PROXY_HTTP_SERVER=8080 \
    PROXY_HTTP_API=1985 PROXY_WEBRTC_SERVER=8000 PROXY_SRT_SERVER=10080 \
    PROXY_SYSTEM_API=12025 PROXY_LOAD_BALANCER_TYPE=memory ./bin/srs-proxy
```

> Note: Here we use the memory load balancer, you can switch to `redis` if you want to run more
> than one proxy server.

Then, deploy three origin servers, each in its own terminal, which connects to the proxy server via port `12025`:

```bash
env SRS_RTMP_LISTEN=19351 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=19851 \
    SRS_HTTP_SERVER_ENABLED=on SRS_HTTP_SERVER_LISTEN=8081 \
    SRS_RTC_SERVER_ENABLED=on SRS_RTC_SERVER_LISTEN=8001 \
    SRS_SRT_SERVER_ENABLED=on SRS_SRT_SERVER_LISTEN=10081 \
    SRS_SRT_SERVER_TSBPDMODE=off SRS_SRT_SERVER_TLPKTDROP=off \
    SRS_HEARTBEAT_ENABLED=on SRS_HEARTBEAT_INTERVAL=9 SRS_HEARTBEAT_DEVICE_ID=origin1 \
    SRS_HEARTBEAT_URL=http://127.0.0.1:12025/api/v1/srs/register SRS_HEARTBEAT_PORTS=on \
    SRS_VHOST_HTTP_REMUX_ENABLED=on SRS_VHOST_HLS_ENABLED=on \
    SRS_VHOST_RTC_ENABLED=on SRS_VHOST_RTC_RTMP_TO_RTC=on SRS_VHOST_RTC_RTC_TO_RTMP=on \
    SRS_VHOST_SRT_ENABLED=on SRS_VHOST_SRT_SRT_TO_RTMP=on \
    ./objs/srs -e
```

```bash
env SRS_RTMP_LISTEN=19352 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=19853 \
    SRS_HTTP_SERVER_ENABLED=on SRS_HTTP_SERVER_LISTEN=8082 \
    SRS_RTC_SERVER_ENABLED=on SRS_RTC_SERVER_LISTEN=8002 \
    SRS_SRT_SERVER_ENABLED=on SRS_SRT_SERVER_LISTEN=10082 \
    SRS_SRT_SERVER_TSBPDMODE=off SRS_SRT_SERVER_TLPKTDROP=off \
    SRS_HEARTBEAT_ENABLED=on SRS_HEARTBEAT_INTERVAL=9 SRS_HEARTBEAT_DEVICE_ID=origin2 \
    SRS_HEARTBEAT_URL=http://127.0.0.1:12025/api/v1/srs/register SRS_HEARTBEAT_PORTS=on \
    SRS_VHOST_HTTP_REMUX_ENABLED=on SRS_VHOST_HLS_ENABLED=on \
    SRS_VHOST_RTC_ENABLED=on SRS_VHOST_RTC_RTMP_TO_RTC=on SRS_VHOST_RTC_RTC_TO_RTMP=on \
    SRS_VHOST_SRT_ENABLED=on SRS_VHOST_SRT_SRT_TO_RTMP=on \
    ./objs/srs -e
```

```bash
env SRS_RTMP_LISTEN=19353 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=19852 \
    SRS_HTTP_SERVER_ENABLED=on SRS_HTTP_SERVER_LISTEN=8083 \
    SRS_RTC_SERVER_ENABLED=on SRS_RTC_SERVER_LISTEN=8003 \
    SRS_SRT_SERVER_ENABLED=on SRS_SRT_SERVER_LISTEN=10083 \
    SRS_SRT_SERVER_TSBPDMODE=off SRS_SRT_SERVER_TLPKTDROP=off \
    SRS_HEARTBEAT_ENABLED=on SRS_HEARTBEAT_INTERVAL=9 SRS_HEARTBEAT_DEVICE_ID=origin3 \
    SRS_HEARTBEAT_URL=http://127.0.0.1:12025/api/v1/srs/register SRS_HEARTBEAT_PORTS=on \
    SRS_VHOST_HTTP_REMUX_ENABLED=on SRS_VHOST_HLS_ENABLED=on \
    SRS_VHOST_RTC_ENABLED=on SRS_VHOST_RTC_RTMP_TO_RTC=on SRS_VHOST_RTC_RTC_TO_RTMP=on \
    SRS_VHOST_SRT_ENABLED=on SRS_VHOST_SRT_SRT_TO_RTMP=on \
    ./objs/srs -e
```

> Note: The origin servers are independent, so it's recommended to deploy them as Deployments 
> in Kubernetes (K8s).

Now, you're able to publish RTMP stream to the proxy server:

```bash
ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

And play the RTMP stream from the proxy server:

```bash
ffplay rtmp://localhost/live/livestream
```

Or play HTTP-FLV stream from the proxy server:

```bash
ffplay http://localhost:8080/live/livestream.flv
```

Or play HLS stream from the proxy server:

```bash
ffplay http://localhost:8080/live/livestream.m3u8
``` 

Or play the WebRTC stream via [WHEP player](http://localhost:8080/players/whep.html) from proxy server.

You can also use VLC or other players to play the stream in proxy server.

## WebRTC Origin Cluster

To use the WebRTC origin cluster, you need to deploy the proxy server and the origin server.
First, start the proxy server:

```bash
env PROXY_RTMP_SERVER=1935 PROXY_HTTP_SERVER=8080 \
    PROXY_HTTP_API=1985 PROXY_WEBRTC_SERVER=8000 PROXY_SRT_SERVER=10080 \
    PROXY_SYSTEM_API=12025 PROXY_LOAD_BALANCER_TYPE=memory ./bin/srs-proxy
```

> Note: Here we use the memory load balancer, you can switch to `redis` if you want to run more
> than one proxy server.

Then, deploy the three origin servers of [RTMP Origin Cluster](#rtmp-origin-cluster), which connects to the proxy server via port `12025`.

> Note: The origin servers are independent, so it's recommended to deploy them as Deployments
> in Kubernetes (K8s).

Now, you're able to publish WebRTC stream via [WHIP publisher](http://localhost:8080/players/whip.html) to the proxy server.

And play the WebRTC stream via [WHEP player](http://localhost:8080/players/whep.html) from proxy server.

Or play the RTMP stream from the proxy server:

```bash
ffplay rtmp://localhost/live/livestream
```

Or play HTTP-FLV stream from the proxy server:

```bash
ffplay http://localhost:8080/live/livestream.flv
```

Or play HLS stream from the proxy server:

```bash
ffplay http://localhost:8080/live/livestream.m3u8
```

You can also use VLC or other players to play the stream in proxy server.

## SRT Origin Cluster

To use the SRT origin cluster, you need to deploy the proxy server and the origin server.
First, start the proxy server:

```bash
env PROXY_RTMP_SERVER=1935 PROXY_HTTP_SERVER=8080 \
    PROXY_HTTP_API=1985 PROXY_WEBRTC_SERVER=8000 PROXY_SRT_SERVER=10080 \
    PROXY_SYSTEM_API=12025 PROXY_LOAD_BALANCER_TYPE=memory ./bin/srs-proxy
```

> Note: Here we use the memory load balancer, you can switch to `redis` if you want to run more
> than one proxy server.

Then, deploy the three origin servers of [RTMP Origin Cluster](#rtmp-origin-cluster), which connects to the proxy server via port `12025`.

> Note: The origin servers are independent, so it's recommended to deploy them as Deployments
> in Kubernetes (K8s).

Now, you're able to publish SRT stream to the proxy server:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
```

And play the SRT stream from the proxy server:

```bash
ffplay 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request'
```

Or play the RTMP stream from the proxy server:

```bash
ffplay rtmp://localhost/live/livestream
```

Or play HTTP-FLV stream from the proxy server:

```bash
ffplay http://localhost:8080/live/livestream.flv
```

Or play HLS stream from the proxy server:

```bash
ffplay http://localhost:8080/live/livestream.m3u8
``` 

Or play the WebRTC stream via [WHEP player](http://localhost:8080/players/whep.html) from proxy server.

You can also use VLC or other players to play the stream in proxy server.

## Config

The proxy server is configured by environment variables. The supported environment variables for proxy
backend server are:

* `PROXY_HTTP_API`: The HTTP API port, proxy to SRS origin server. Default: `11985`
* `PROXY_HTTP_SERVER`: The HTTP streaming server, proxy to SRS origin server. Default: `18080`
* `PROXY_RTMP_SERVER`: The RTMP server, proxy to SRS origin server. Default: `11935`
* `PROXY_WEBRTC_SERVER`: The WebRTC server, proxy to SRS origin server, via UDP protocol. Default: `18000`
* `PROXY_SRT_SERVER`: The SRT server, proxy to SRS origin server. Default: `20080`

The following environment variables are about the proxy server itself:

* `PROXY_SYSTEM_API`: The system API port, allow origin server register services to proxy servers. Default: `12025`
* `PROXY_STATIC_FILES`: The files directory for static web server, like the players. Default: `../trunk/research`
* `PROXY_LOAD_BALANCER_TYPE`: The load balancer type, `memory` or `redis`. Default: `redis`

For the Redis load balancer, you need to set the following environment variables:

* `PROXY_REDIS_HOST`: The Redis host. Default: `127.0.0.1`
* `PROXY_REDIS_PORT`: The Redis port. Default: `6379`
* `PROXY_REDIS_PASSWORD`: The Redis password. Default to empty, no password.
* `PROXY_REDIS_DB`: The Redis DB. Default: `0`

For debugging, the proxy server will proxy to a default origin server, you can set the following
environment variables:

* `PROXY_DEFAULT_BACKEND_ENABLED`: Whether to enable the default backend origin server. Default: `off`
* `PROXY_DEFAULT_BACKEND_IP`: The default backend IP. Default: `127.0.0.1`
* `PROXY_DEFAULT_BACKEND_RTMP`: The default backend RTMP port. Default: `1935`
* `PROXY_DEFAULT_BACKEND_HTTP`: The default backend HTTP port. Default: `8080`
* `PROXY_DEFAULT_BACKEND_RTC`: The default backend WebRTC port via UDP. Default: `8000`
* `PROXY_DEFAULT_BACKEND_SRT`: The default backend SRT port. Default: `10080`
* `PROXY_DEFAULT_BACKEND_API`: The default backend API port. Default: `1985`

> Note: The default backend origin server, is designed for any RTMP server like nginx-rtmp, it does not
> require the origin server to register to the proxy server.

## Authentication

Configure the proxy registration API with:

* `PROXY_HTTP_API_AUTH_ENABLED`: Whether to authenticate origin registration requests. Default: `off`
* `PROXY_HTTP_API_AUTH_TYPE`: Authentication type. The proxy requires `bearer` when authentication is enabled.
* `PROXY_HTTP_API_AUTH_TOKEN`: Bearer token accepted by the proxy registration API. Required when authentication is enabled.

Configure each SRS origin to authenticate its heartbeat request with:

* `SRS_HEARTBEAT_AUTH_ENABLED`: Whether the SRS origin authenticates its heartbeat request. Default: `off`
* `SRS_HEARTBEAT_AUTH_TYPE`: Heartbeat authentication type. Use `bearer` for an authenticated proxy.
* `SRS_HEARTBEAT_AUTH_TOKEN`: Credential sent by the SRS origin. Set it to the proxy's `PROXY_HTTP_API_AUTH_TOKEN`. It is independent from `SRS_HTTP_API_AUTH_TOKEN`, which protects the origin's own HTTP API.

## Design

The proxy works with SRS origin servers, and the stream flow operates as follows:

```text
Client ----> Proxy Server ---> Origin Servers
Client ---> LB --> Proxy Servers --> Origin Servers

OBS/FFmpeg --RTMP--> K8s(Service) --Proxy--> SRS(pod A)

Browsers --FLV/HLS/SRT--> K8s(Service) --Proxy--> SRS(pod A)

Browsers --+---HTTP-API--> K8s(Service) --Proxy--> SRS(pod A)
           +---WebRTC----> K8s(Service) --Proxy--> SRS(pod A)
```

> Note: This proxy server can be deployed in Kubernetes (K8s) and can route traffic to the SRS origin
> servers. The proxy server functions as a load balancer to distribute the load among the origin servers.
> You can also use the proxy server without Kubernetes.

This is the detailed deployment process that works with the Kubernetes (K8s) system:

```text
                         +-----------------------+
                     +---+ SRS Proxy(Deployment) +------+---------------------+
+-----------------+  |   +-----------+-----------+      +                     +
| LB(K8s Service) +--+               +(Redis/MESH)      + SRS Origin Servers  +
+-----------------+  |   +-----------+-----------+      +    (Deployment)     +
                     +---+ SRS Proxy(Deployment) +------+---------------------+
                         +-----------------------+
```

> Note: There are multiple proxy servers, so they need Redis or MESH to synchronize their state. MESH means
> the proxy servers connect to each other to sync the state and should be deployed as a StatefulSet in
> Kubernetes (K8s). The Redis solution is preferable because the proxy server can be deployed as a Deployment
> in K8s, and you can also use a Redis cluster for high availability.

> Note: There are multiple origin servers, which are deployed as Deployments in Kubernetes (K8s), as there is
> no need to sync the state between origin servers. These origin servers are completely independent, making
> the system very robust. Please note that this is different from the previous origin cluster before SRS 6.0,
> which used MESH to connect to each other, and it was not a good architecture.

If you want to build an origin cluster with a single proxy server and multiple origin servers:

```text
                                       +--------------------+
                               +-------+ SRS Origin Server  +
                               +       +--------------------+
                               +
+-----------------------+      +       +--------------------+
+ SRS Proxy(Deployment) +------+-------+ SRS Origin Server  +
+-----------------------+      +       +--------------------+
                               +
                               +       +--------------------+
                               +-------+ SRS Origin Server  +
                                       +--------------------+
```

> Note: A single proxy server architecture is also useful if you only want to support many streams with a
> small number of viewers. The proxy server is very high performance and supports multiple processes.

> Note: If you want to use multiple proxy servers, you can simply deploy more and connect them to the same
> Redis server. These proxy servers will work together to support a large number of streams. This architecture
> is scalable.

With this architecture, you can support a large number of streams and then use edge servers to support
multiple viewers.

```text
+------------------+                                               +--------------------+
+ SRS Edge Server  +--+                                    +-------+ SRS Origin Server  +
+------------------+  +                                    +       +--------------------+
                      +                                    +
+------------------+  +     +-----------------------+      +       +--------------------+
+ SRS Edge Server  +--+-----+ SRS Proxy(Deployment) +------+-------+ SRS Origin Server  +
+------------------+  +     +-----------------------+      +       +--------------------+
                      +                                    +
+------------------+  +                                    +       +--------------------+
+ SRS Edge Server  +--+                                    +-------+ SRS Origin Server  +
+------------------+                                               +--------------------+
```

> Note: With this architecture, you can build a very large media system that supports a large number of
> streams and viewers. It is a complex system to maintain, so only use it if necessary.

In fact, a proxy server also works with SRS edge servers, but it is not a typical architecture.

## Protocols

Because the proxy server is a new server, not all protocols are supported yet. The supported
protocols are:

- [x] RTMP: Proxy RTMP protocol to the SRS origin server.
- [x] HTTP-FLV: Proxy HTTP-FLV protocol to the SRS origin server.
- [x] HTTP-TS: Proxy HTTP-TS protocol to the SRS origin server.
- [x] HLS: Proxy HLS protocol to the SRS origin server.
- [x] WebRTC: Proxy WebRTC(WHIP/WHEP) protocol to the SRS origin server.
- [x] SRT: Proxy SRT protocol to the SRS origin server.
- [ ] MPEG-DASH: Proxy MPEG-DASH protocol to the SRS origin server.
- [ ] RTSP: Proxy RTSP protocol to the SRS origin server.

There are also some key features not supported yet:

- [x] Single node proxy server, use memory to store state.
- [x] Redis: Connect to the Redis server to sync the state.
- [ ] MESH: Connect to other proxy servers to sync the state.
- [ ] HTTP-API: Provide an HTTP API that collects all the metrics of the origin servers.
- [ ] Exporter: Provide a Prometheus exporter that exports the metrics of the proxy server.

For a media cluster, the media server is only one part of the whole system. The control and management panel
are also very important to maintain this complex system.

## Register

The origin server can register itself to the proxy server, so the proxy server can load balance 
the backend servers. The register API is a simple HTTP API:

```bash
curl -X POST http://127.0.0.1:12025/api/v1/srs/register \
     -H "Connection: Close" \
     -H "Content-Type: application/json" \
     -H "User-Agent: curl" \
     -d '{
          "device_id": "origin2",
          "ip": "10.78.122.184",
          "server": "vid-46p14mm",
          "service": "z2s3w865",
          "pid": "42583",
          "rtmp": ["19352"],
          "http": ["8082"],
          "api": ["19853"],
          "srt": ["10082"],
          "rtc": ["udp://0.0.0.0:8001"]
        }'
#{"code":0,"pid":"53783"}
```

* `ip`: Mandatory, the IP of the backend server. Make sure the proxy server can access the backend server via this IP.
* `server`: Mandatory, the server id of backend server. For SRS, it stores in file, may not change.
* `service`: Mandatory, the service id of backend server. For SRS, it always changes when restarted.
* `pid`: Mandatory, the process id of backend server. Used to identify whether process restarted.
* `rtmp`: Mandatory, the RTMP listen endpoints of backend server. Proxy server will connect backend server via this port for RTMP protocol.
* `http`: Optional, the HTTP listen endpoints of backend server. Proxy server will connect backend server via this port for HTTP-FLV or HTTP-TS protocol.
* `api`: Optional, the HTTP API listen endpoints of backend server. Proxy server will connect backend server via this port for HTTP-API, such as WHIP and WHEP.
* `srt`: Optional, the SRT listen endpoints of backend server. Proxy server will connect backend server via this port for SRT protocol.
* `rtc`: Optional, the WebRTC listen endpoints of backend server. Proxy server will connect backend server via this port for WebRTC protocol.
* `device_id`: Optional, the device id of backend server. Used as a label for the backend server.

The listen endpoint format is `port`, or `protocol://ip:port`, or `protocol://:port`, for example:

* `1935`: Listen on port 1935 and any IP for TCP protocol.
* `tcp://:1935`: Listen on port 1935 and any IP for TCP protocol.
* `tcp://0.0.0.0:1935`: Listen on port 1935 and any IP for TCP protocol.
* `tcp://192.168.3.10:1935`: Listen on port 1935 and specified IP for TCP protocol.

You can also use SRS 5.0+ as backend server, which supports `heartbeat` feature to register itself 
to proxy server.

Furthermore, you can write a curl script to register the backend server, or a dedicate backend server 
manage service. For example, if you don't want to modify the nginx-rtmp code, you can use a isolate program 
to register the nginx-rtmp to proxy server.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Performance (`skills/internal-docs-for-srs/references/cpp-docs/doc/performance.md`)

---
title: Performance
sidebar_label: Performance 
hide_title: false
hide_table_of_contents: false
---

# Performance

There is a set of tools for performance improvement and detecting memory leaking.

> Note: All tools will hurts performance more or less, so never enable these tools unless you need to fix memory issue.

## RTC

RTC is delivering over UDP, so the first and most important configuration is for kernel network:

```bash
# Query the kernel configuration
sysctl net.core.rmem_max
sysctl net.core.rmem_default
sysctl net.core.wmem_max
sysctl net.core.wmem_default

# Set the UDP buffer to 16MB
sysctl net.core.rmem_max=16777216
sysctl net.core.rmem_default=16777216
sysctl net.core.wmem_max=16777216
sysctl net.core.wmem_default=16777216
```

> Note: For Docker, it read the configuration from host, so you only need to setup the host machine.

> Note：If need to set these configurations in docker, you must run with `--network=host`.

Or, you could also modify the file `/etc/sysctl.conf` to enalbe if when reboot:

```bash
# vi /etc/sysctl.conf
# For RTC
net.core.rmem_max=16777216
net.core.rmem_default=16777216
net.core.wmem_max=16777216
net.core.wmem_default=16777216
```

Query the network statistics and UDP packets dropping:

```bash
netstat -suna
netstat -suna && sleep 30 && netstat -suna
```

For Example:

* `224911319 packets received` The total received UDP packets.
* `65731106 receive buffer errors` The total dropped UDP packets before receiving
* `123534411 packets sent` The total sent UDP packets.
* `0 send buffer errors` The total dropped UDP packets before sending.

> Note: SRS also prints about the packets dropped in application level, for example `loss=(r:49,s:0)` which means dropped 49 packets before receiving.

> Note：Please note that you must run the command in docker container, not on host machine.

The length of UDP queue:

```bash
netstat -lpun
```

For example:

* `Recv-Q 427008` Established: The count of bytes not copied by the user program connected to this socket.
* `Send-Q 0` Established: The count of bytes not acknowledged by the remote host.

Other useful parameters of netstat:

* `--udp|-u` Filter by UDP protocol.
* `--numeric|-n` Show numerical addresses instead of trying to determine symbolic host, port or user names.
* `--statistics|-s` Show statistics.
* `--all|-a` Show  both  listening and non-listening sockets.  With the --interfaces option, show interfaces that are not up.
* `--listening|-l` Show only listening sockets.  (These are omitted by default.)
* `--program|-p` Show the PID and name of the program to which each socket belongs.

## PERF

PERF is Performance analysis tools for Linux.

Show performance bottleneck of SRS:

```
perf top -p $(pidof srs)
```

To record the data:

```
perf record -p $(pidof srs)

# Press CTRL+C after about 30s.

perf report
```

Show stack or backtrace:

```
perf record -a --call-graph fp -p $(pidof srs)
perf report --call-graph --stdio
```

> Note: Record to file by `perf report --call-graph --stdio >t.txt`。

> Remark: The stack(`-g`) does not work for SRS(ST), because ST modifies the SP.

## ASAN

[Asan](https://github.com/google/sanitizers/wiki/AddressSanitizer) is Google Address Sanitizer.

### ASAN: Usage

SRS5+ supports [ASAN](https://github.com/google/sanitizers/wiki/AddressSanitizer) by default.

If you want to disable it, please check bellow configure options:

```bash
./configure -h |grep asan
  --sanitizer=on|off        Whether build SRS with address sanitizer(asan). Default: on
  --sanitizer-static=on|off Whether build SRS with static libasan(asan). Default: off
  --sanitizer-log=on|off    Whether hijack the log for libasan(asan). Default: off
```

Enable leaks detection, see [halt_on_error](https://github.com/google/sanitizers/wiki/AddressSanitizerFlags) 
and [detect_leaks](https://github.com/google/sanitizers/wiki/SanitizerCommonFlags):

```bash
env ASAN_OPTIONS=halt_on_error=1:detect_leaks=1 SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e
```

> Note: SRS disable memory leak detection by default, because it will cause daemon to exit with error.

Highly recommend to enable ASAN because it works great.

### ASAN: Preload

If you encounter the following error:

```bash
==4181651==ASan runtime does not come first in initial library list; you should either link runtime 
to your application or manually preload it with LD_PRELOAD.
```

You should preload the ASAN library:

```bash
env LD_PRELOAD=$(find /usr -name libasan.so.5 2>/dev/null) SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e
```

> Note: Generally, the libasan.so file should be located at `/usr/lib64/libasan.so.5`

### ASAN: Options

By default, SRS use the following ASAN options:

```text
extern "C" const char *__asan_default_options() {
    return "halt_on_error=0:detect_leaks=0:alloc_dealloc_mismatch=0";
}
```

* `halt_on_error=0`: Disable halt on errors by halt_on_error, only print messages, note that it still quit for fatal errors, see [halt_on_error](https://github.com/google/sanitizers/wiki/AddressSanitizerFlags).
* `detect_leaks=0`: Disable the memory leaking detect for daemon by detect_leaks, see [detect_leaks](https://github.com/google/sanitizers/wiki/SanitizerCommonFlags).
* `alloc_dealloc_mismatch=0`: Also disable alloc_dealloc_mismatch for gdb.

You can override the options by `ASAN_OPTIONS`:

```bash
env ASAN_OPTIONS=halt_on_error=1:detect_leaks=1:alloc_dealloc_mismatch=1 SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e
```

Note that the `ASAN_OPTIONS` will be loaded before the `main()` function, so you can set it in the shell, 
but can not set in the `main()` function.

## GPROF

GPROF is a GNU tool, see [SRS GPROF](./gprof.md) and [GNU GPROF](http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html).

Usage:
```
# Build SRS with GPROF
./configure --gprof=on && make

# Start SRS with GPROF
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e

# Or CTRL+C to stop GPROF
killall -2 srs

# To analysis result.
gprof -b ./objs/srs gmon.out
```

## GPERF

GPERF is  [google tcmalloc](https://github.com/gperftools/gperftools), please see [GPERF](./gperf.md)。

### GPERF: GCP

GCP is for CPU performance analysis, see [GCP](https://gperftools.github.io/gperftools/cpuprofile.html).

Usage:

```
# Build SRS with GCP
./configure --gperf=on --gcp=on && make

# Start SRS with GCP
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e

# Or CTRL+C to stop GCP
killall -2 srs

# To analysis cpu profile
./objs/pprof --text objs/srs gperf.srs.gcp*
```

> Note: For more details, please read [cpu-profiler](https://github.com/ossrs/srs/tree/4.0release/trunk/research/gperftools/cpu-profiler).

Install tool for graph:

```bash
yum install -y graphviz
```

Output svg graph to open by Chrome:

```bash
./objs/pprof --svg ./objs/srs gperf.srs.gcp >t.svg
```

### GPERF: GMD

GMD is for memory corrupt detecting, see [GMD](http://blog.csdn.net/win_lin/article/details/50461709).

Usage:
```
# Build SRS with GMD.
./configure --gperf=on --gmd=on && make

# Start SRS with GMD.
env TCMALLOC_PAGE_FENCE=1 SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e
```

> Note: For more details, please read [heap-defense](https://github.com/ossrs/srs/tree/4.0release/trunk/research/gperftools/heap-defense).

> Note: Need link with `libtcmalloc_debug.a` and enable env `TCMALLOC_PAGE_FENCE`.

### GPERF: GMC

GMC is for memory leaking, see [GMC](https://gperftools.github.io/gperftools/heap_checker.html).

Usage:

```
# Build SRS with GMC
./configure --gperf=on --gmc=on && make

# Start SRS with GMC
env PPROF_PATH=./objs/pprof HEAPCHECK=normal SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e 2>gmc.log

# Or CTRL+C to stop gmc
killall -2 srs

# To analysis memory leak
cat gmc.log
```

> Note: For more details, please read [heap-checker](https://github.com/ossrs/srs/tree/4.0release/trunk/research/gperftools/heap-checker).

### GPERF: GMP

GMD is for memory performance, see [GMP](https://gperftools.github.io/gperftools/heapprofile.html).

Usage:
```
# Build SRS with GMP
./configure --gperf=on --gmp=on && make

# Start SRS with GMP
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 ./objs/srs -e

# Or CTRL+C to stop gmp
killall -2 srs 

# To analysis memory profile
./objs/pprof --text objs/srs gperf.srs.gmp*
```

> Note: For more details, please read [heap-profiler](https://github.com/ossrs/srs/tree/4.0release/trunk/research/gperftools/heap-profiler).

## VALGRIND

Valgrind is a powerful tool for memory leak and other issue.

### Valgrind: Memcheck

SRS3+ also supports valgrind.

```
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 valgrind --leak-check=full --show-leak-kinds=all ./objs/srs -e
```

> Remark: For ST to support valgrind, see [state-threads](https://github.com/ossrs/state-threads#usage) and [ST#2](https://github.com/ossrs/state-threads/issues/2).

> Remark: For HTTP valgrind API, you should upgrade your SRS to required version, see [#4150](https://github.com/ossrs/srs/pull/4150).

### Valgrind: Incremental Memory Leak Detection

To use Valgrind to detect memory leaks in SRS, even though Valgrind hooks are supported in ST, there are 
still many false positives. A more reasonable approach is to have Valgrind report incremental memory leaks. 
This way, global and static variables can be avoided, and detection can be achieved without exiting the 
program. Follow these steps:

1. Compile SRS with Valgrind support: `./configure --valgrind=on && make`
1. Start SRS with memory leak detection enabled: `env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_API_LISTEN=1985 valgrind --leak-check=full --show-leak-kinds=all ./objs/srs -e`
1. Trigger memory detection by using curl to access the API and generate calibration data. There will still be many false positives, but these can be ignored: `curl http://127.0.0.1:1985/api/v1/valgrind?check=added`
1. Retry memory detection, util the valgrind leak summary is stable, no any new lost blocks.
1. Perform load testing or test the suspected leaking functionality, such as RTMP streaming: `ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://127.0.0.1/live/livestream`
1. Stop streaming and wait for SRS to clean up the Source memory, approximately 30 seconds.
1. Perform incremental memory leak detection. The reported leaks will be very accurate at this point: `curl http://127.0.0.1:1985/api/v1/valgrind?check=added`

```text
HTTP #0 11.176.19.95:42162 GET http://9.134.74.169:1985/api/v1/valgrind?check=added, content-length=-1
query check=added
==1481822== LEAK SUMMARY:
==1481822==    definitely lost: 0 (+0) bytes in 0 (+0) blocks
==1481822==    indirectly lost: 0 (+0) bytes in 0 (+0) blocks
==1481822==      possibly lost: 3,406,847 (+0) bytes in 138 (+0) blocks
==1481822==    still reachable: 18,591,709 (+0) bytes in 819 (+0) blocks
==1481822==                       of which reachable via heuristic:
==1481822==                         multipleinheritance: 536 (+0) bytes in 4 (+0) blocks
==1481822==         suppressed: 0 (+0) bytes in 0 (+0) blocks
==1481822== Reachable blocks (those to which a pointer was found) are not shown.
```

> Note: To avoid interference from the HTTP request itself on Valgrind, SRS uses a separate coroutine to perform periodic checks. Therefore, after accessing the API, you may need to wait a few seconds for the detection to be triggered.

### Valgrind: Still Reachable

Sometimes, you will receive the `still reachable` report for static or global variables, like this example:

```text
==3430715== 1,040 (+1,040) bytes in 1 (+1) blocks are still reachable in new loss record 797 of 836
==3430715==    at 0x4C3F963: calloc (vg_replace_malloc.c:1595)
==3430715==    by 0x7D8DB0: SrsConfig::get_hls_vcodec(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (srs_app_config.cpp:7156)
==3430715==    by 0x781283: SrsHlsMuxer::segment_open() (srs_app_hls.cpp:418)

# It's caused by static variable:
string SrsConfig::get_hls_vcodec(string vhost) {
    SRS_STATIC string DEFAULT = "h264";
    SrsConfDirective* conf = get_hls(vhost);
    if (!conf) {
        return DEFAULT;
```

You can easily work around this by publishing the stream, stopping it, and then triggering the memory leak detection:

1. Publish stream to initialize the static and global variables: `ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://127.0.0.1/live/livestream`
1. Trigger memory detection by using curl to access the API and generate calibration data. There will still be many false positives, but these can be ignored: `curl http://127.0.0.1:1985/api/v1/valgrind?check=added`
1. Retry memory detection, util the valgrind leak summary is stable, no any new lost blocks.
1. Perform load testing or test the suspected leaking functionality, such as RTMP streaming: `ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://127.0.0.1/live/livestream`
1. Stop streaming and wait for SRS to clean up the Source memory, approximately 30 seconds.
1. Perform incremental memory leak detection. The reported leaks will be very accurate at this point: `curl http://127.0.0.1:1985/api/v1/valgrind?check=added`

With the variables initialized, the `still reachable` report will be gone.

## Syscall

Please use [strace -c -p PID](https://man7.org/linux/man-pages/man1/strace.1.html) for syscal performance issue.

## OSX

For macOS, please use [Instruments](https://stackoverflow.com/questions/11445619/profiling-c-on-mac-os-x)

```
instruments -l 30000 -t Time\ Profiler -p 72030
```

> Remark: You can also click `Sample` button in `Active Monitor`.

## Multiple Process and Softirq

You can run softirq(Kernel Network Transmission) on CPU0, so run SRS on other CPUs:

```bash
taskset -p 0xfe $(pidof srs)
```

Or run SRS on CPU1:

```bash
taskset -pc 1 $(pidof srs)
```

Then you can run `top` and press `1` to see each CPU statistics:

```bash
top # Press 1
#%Cpu0  :  1.8 us,  1.1 sy,  0.0 ni, 90.8 id,  0.0 wa,  0.0 hi,  6.2 si,  0.0 st
#%Cpu1  : 67.6 us, 17.6 sy,  0.0 ni, 14.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
```

Or use `mpstat -P ALL`

```bash
mpstat -P ALL
#01:23:14 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
#01:23:14 PM  all   33.33    0.00    8.61    0.04    0.00    3.00    0.00    0.00    0.00   55.02
#01:23:14 PM    0    2.46    0.00    1.32    0.06    0.00    6.27    0.00    0.00    0.00   89.88
#01:23:14 PM    1   61.65    0.00   15.29    0.02    0.00    0.00    0.00    0.00    0.00   23.03
```

> Note: Use `cat /proc/softirqs` to check softirq type, please see [Introduction to deferred interrupts (Softirq, Tasklets and Workqueues)](https://0xax.gitbooks.io/linux-insides/content/Interrupts/linux-interrupts-9.html)

> Note: If SRS run with softirq at CPU0, the total CPU will be larger than total of running on different CPUs.

If you got more CPUs, you can run softirq to multiple CPUs:

```bash
# grep virtio /proc/interrupts | grep -e in -e out
 29:   64580032          0          0          0   PCI-MSI-edge      virtio0-input.0
 30:          1         49          0          0   PCI-MSI-edge      virtio0-output.0
 31:   48663403          0   11845792          0   PCI-MSI-edge      virtio0-input.1
 32:          1          0          0         52   PCI-MSI-edge      virtio0-output.1

# cat /proc/irq/29/smp_affinity
1 # Bind softirq of virtio0 incoming to CPU0.
# cat /proc/irq/30/smp_affinity
2 # Bind softirq of virtio0 outgoing to CPU1.
# cat /proc/irq/31/smp_affinity
4 # Bind softirq of virtio1 incoming to CPU2.
# cat /proc/irq/32/smp_affinity
8 # Bind softirq of virtio1 outgoing to CPU3.
```

To disable softirq balance and force to run on CPU0, see [Linux: scaling softirq among many CPU cores](http://natsys-lab.blogspot.com/2012/09/linux-scaling-softirq-among-many-cpu.html) 
and [SMP IRQ affinity](https://www.kernel.org/doc/Documentation/IRQ-affinity.txt) by:

```bash
for irq in $(grep virtio /proc/interrupts | grep -e in -e out | cut -d: -f1); do 
    echo 1 > /proc/irq/$irq/smp_affinity
done
```

> Note：Run `echo 3 > /proc/irq/$irq/smp_affinity` if bind to CPU0 and CPU1.

Then run SRS on other CPUs except CPU0:

```bash
taskset -a -p 0xfe $(pidof srs)
```

You can improve about 20% performance by bind softirq to CPU0.

You can also setup in the startup script.

## Process Priority

You can set SRS to run in higher priority:

```bash
renice -n -15 -p $(pidof srs)
```

> Note: The value of nice is `-20` to `19` and default is `0`.

To check the priority, which is the `NI` field of top:

```bash
top -n1 -p $(pidof srs)
#  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                
# 1505 root       5 -15  519920 421556   4376 S  66.7  5.3   4:41.12 srs
```

## Performance Banchmark

The performance benchmark for SRS, compare with nginx-rtmp single process.

Provides detail benchmark steps.

The latest data, read [performance](https://github.com/ossrs/srs/tree/develop#performance).

### Hardware

The client and server use lo net interface to test:

* Hardware: VirtualBox on ThinkPad T430
* OS: CentOS 6.0 x86_64 Linux 2.6.32-71.el6.x86_64
* CPU: 3 Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
* Memory: 2007MB

### OS

Login as root, set the fd limits:

* Set limit: `ulimit -HSn 10240`
* View the limit:

```bash
[root@dev6 ~]# ulimit -n
10240
```

* Restart SRS：`sudo /etc/init.d/srs restart`

### NGINX-RTMP

NGINX-RTMP version and build command.

* NGINX: nginx-1.5.7.tar.gz
* NGINX-RTMP: nginx-rtmp-module-1.0.4.tar.gz
* Read [nginx-rtmp](http://download.csdn.net/download/winlinvip/6795467)
* Build:

```bash
./configure --prefix=`pwd`/../_release \
--add-module=`pwd`/../nginx-rtmp-module-1.0.4 \
--with-http_ssl_module && make && make install
```

* Config nginx：`_release/conf/nginx.conf`

```bash
user  root;
worker_processes  1;
events {
    worker_connections  10240;
}
rtmp{
    server{
        listen 19350;
        application live{
            live on;
        }
    }
}
```

* The limit of fd:

```bash
[root@dev6 nginx-rtmp]# ulimit -n
10240
```

* Start: ``./_release/sbin/nginx``
* Check nginx started:

```bash
[root@dev6 nginx-rtmp]# netstat -anp|grep 19350
tcp        0      0 0.0.0.0:19350               0.0.0.0:*                   LISTEN      6486/nginx
```

### SRS

SRS version and build.

* SRS: [SRS 0.9](https://github.com/ossrs/srs/releases/tag/0.9)
* Build: ``./configure && make``
* Config SRS：`conf/srs.conf`

```bash
listen              1935;
max_connections     10240;
vhost __defaultVhost__ {
    gop_cache       on;
    forward         127.0.0.1:19350;
}
```

* Check limit fds:

```bash
[root@dev6 trunk]# ulimit -n
10240
```

* Start SRS: ``nohup ./objs/srs -c conf/srs.conf >/dev/null 2>&1 &``
* Check SRS started:

```bash
[root@dev6 trunk]# netstat -anp|grep "1935 "
tcp        0      0 0.0.0.0:1935                0.0.0.0:*                   LISTEN      6583/srs
```

### Publish and Play

Use centos to publish RTMP:

* Start FFMPEG:

```bash
for((;;)); do \
    ./objs/ffmpeg/bin/ffmpeg \
        -re -i doc/source.flv \
        -acodec copy -vcodec copy \
        -f flv rtmp://127.0.0.1:1935/live/livestream; \
    sleep 1; 
done
```

* SRS RTMP stream URL: `rtmp://192.168.2.101:1935/live/livestream`
* Nginx-RTMP stream URL: `rtmp://192.168.2.101:19350/live/livestream`

### Client

The RTMP load test tool, read [srs-bench](https://github.com/ossrs/srs-bench)

The sb_rtmp_load used to test RTMP load, support 800-3k concurrency for each process.

* Build: `./configure && make`
* Start: `./objs/sb_rtmp_load -c 800 -r <rtmp_url>`

### Record Data

Record data before test:

* Use top command：

```bash
srs_pid=$(pidof srs); \
nginx_pid=`ps aux|grep nginx|grep worker|awk '{print $2}'`; \
load_pids=`ps aux|grep objs|grep sb_rtmp_load|awk '{ORS=",";print $2}'`; \
top -p $load_pids$srs_pid,$nginx_pid
```

* The connections:

```bash
srs_connections=`netstat -anp|grep srs|grep ESTABLISHED|wc -l`; \
nginx_connections=`netstat -anp|grep nginx|grep ESTABLISHED|wc -l`; \
echo "srs_connections: $srs_connections"; \
echo "nginx_connections: $nginx_connections";
```

* The bandwidth in NBps:

```bash
[root@dev6 nginx-rtmp]# dstat -N lo 30
----total-cpu-usage---- -dsk/total- -net/lo- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
  0   0  96   0   0   3|   0     0 |1860B   58k|   0     0 |2996   465 
  0   1  96   0   0   3|   0     0 |1800B   56k|   0     0 |2989   463 
  0   0  97   0   0   2|   0     0 |1500B   46k|   0     0 |2979   461 
```

* The table

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| SRS | 1.0% | 3MB | 3 | - | - | - | 0.8s |
| nginx-rtmp | 0.7% | 8MB | 2 | - | - | - | 0.8s |

Memory(Mem): The memory usage in MB.

Clients(Conn): The connections/clients to server.

ExpectNbps(ENbps): The expect network bandwidth in Xbps.

ActualNbps(ANBps): The actual network bandwidth in Xbps.

srs-bench(srs-bench/sb): The mock benchmark client tool.

Latency(Lat): The latency of client.

### Benchmark SRS

Let's start performance benchmark.

* Start 500 clients

```bash
./objs/sb_rtmp_load -c 500 -r rtmp://127.0.0.1:1935/live/livestream >/dev/null &
```

* The data:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| SRS | 9.0% | 8MB | 503 | 100Mbps | 112Mbps | 12.6% | 0.8s |

* The data for 1000 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| SRS | 23.6% | 13MB | 1003 | 200Mbps | 239Mbps | 16.6% | 0.8s |

* The data for 1500 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| SRS | 38.6% | 20MB | 1503 | 300Mbps | 360Mbps | 17% | 0.8s |

* The data for 2000 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| SRS | 65.2% | 34MB | 2003 | 400Mbps | 480Mbps | 22% | 0.8s |

* The data for 2500 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| SRS | 72.9% | 38MB | 2503 | 500Mbps | 613Mbps | 24% | 0.8s |

### Benchmark NginxRTMP

Let's start performance benchmark.

* Start 500 clients:

```bash
./objs/sb_rtmp_load -c 500 -r rtmp://127.0.0.1:19350/live/livestream >/dev/null &
```
* The data for 500 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| nginx-rtmp | 8.3% | 13MB | 502 | 100Mbps | 120Mbps | 16.3% | 0.8s |

* The data for 1000 clients:

| Server | CPU | Memory | Clients | ExpectNbps | ActualNbps | srs-bench | Latency|
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| nginx-rtmp | 27.3% | 19MB | 1002 | 200Mbps | 240Mbps | 30% | 0.8s |

* The data for 1500 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| nginx-rtmp | 42.3% | 25MB | 1502 | 300Mbps | 400Mbps | 31% | 0.8s |

* The data for 2000 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| nginx-rtmp | 48.9% | 31MB | 2002 | 400Mbps | 520Mbps | 33% | 0.8s |

* The data for 2500 clients:

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| nginx-rtmp | 74.2% | 37MB | 2502 | 500Mbps | 580Mbps | 35% | 0.8s |

### Performance Compare

| Server | CPU | Mem | Conn | ENbps | ANbps | sb | Lat |
| ------ | --- | ------- | ------ | ---------- | ---------- | ------ | -------- |
| nginx-rtmp | 8.3% | 13MB | 502 | 100Mbps | 120Mbps | 16.3% | 0.8s |
| SRS | 9.0% | 8MB | 503 | 100Mbps | 112Mbps | 12.6% | 0.8s |
| nginx-rtmp | 27.3% | 19MB | 1002 | 200Mbps | 240Mbps | 30% | 0.8s |
| SRS | 23.6% | 13MB | 1003 | 200Mbps | 239Mbps | 16.6% | 0.8s |
| nginx-rtmp | 42.3% | 25MB | 1502 | 300Mbps | 400Mbps | 31% | 0.8s |
| SRS | 38.6% | 20MB | 1503 | 300Mbps | 360Mbps | 17% | 0.8s |
| nginx-rtmp | 48.9% | 31MB | 2002 | 400Mbps | 520Mbps | 33% | 0.8s |
| SRS | 65.2% | 34MB | 2003 | 400Mbps | 480Mbps | 22% | 0.8s |
| nginx-rtmp | 74.2% | 37MB | 2502 | 500Mbps | 580Mbps | 35% | 0.8s |
| SRS | 72.9% | 38MB | 2503 | 500Mbps | 613Mbps | 24% | 0.8s |

### Performance Banchmark 4k

The performance is refined to support about 4k clients.

```
[winlin@dev6 srs]$ ./objs/srs -v
0.9.130
```

```
/* Detailed source-code truncated for AI context efficiency. */
```

```
[winlin@dev6 ~]$ dstat -N lo 30
----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
  3   2  92   0   0   3|  11k   27k|   0     0 |   1B   26B|3085   443 
 32  17  33   0   0  17| 273B   60k|  69M   69M|   0     0 |4878  6652 
 34  18  32   0   0  16|   0    38k|  89M   89M|   0     0 |4591  6102 
 35  19  30   0   0  17| 137B   41k|  91M   91M|   0     0 |4682  6064 
 33  17  33   0   0  17|   0    31k|  55M   55M|   0     0 |4920  7785 
 33  18  31   0   0  17|2867B   34k|  90M   90M|   0     0 |4742  6530 
 32  18  33   0   0  17|   0    31k|  66M   66M|   0     0 |4922  7666 
 33  17  32   0   0  17| 137B   39k|  65M   65M|   0     0 |4841  7299 
 35  18  30   0   0  17|   0    28k| 100M  100M|   0     0 |4754  6752 
 32  17  33   0   0  18|   0    41k|  44M   44M|   0     0 |5130  8251 
 34  18  32   0   0  16|   0    30k| 104M  104M|   0     0 |4456  5718 
```



### Performance Banchmark 6k

SRS2.0.15, not SRS1.0, performance is refined to support 6k clients.
That is 4Gbps for 522kbps bitrate, for a single SRS process. Read https://github.com/ossrs/srs/issues/194

### Performance Banchmark 7.5k

SRS2.0.30 refined to support 7.5k clients, read https://github.com/ossrs/srs/issues/217

Winlin 2014.11

---

### Skills Internal Docs For Srs References Cpp Docs Doc Resource (`skills/internal-docs-for-srs/references/cpp-docs/doc/resource.md`)

---
title: Ports and Resource
sidebar_label: Ports and Resource
hide_title: false
hide_table_of_contents: false
---

# Resources

The resources of SRS.

## Ports

The ports used by SRS, kernel services:

* `tcp://1935`, for [RTMP live streaming server](./rtmp.md).
* `tcp://1985`, HTTP API server, for [HTTP-API](./http-api.md), [WebRTC](./webrtc.md), etc.
* `tcp://8080`, HTTP live streaming server, [HTTP-FLV](./flv.md), [HLS](./hls.md) as such.
* `udp://8000`, [WebRTC Media](./webrtc.md) server.

For optional HTTPS services, which might be provided by other web servers:

* `tcp://8088`, HTTPS live streaming server.
* `tcp://1990`, HTTPS API server.

For optional stream converter services, to push streams to SRS:

* `udp://8935`, Stream Converter: [Push MPEGTS over UDP](./streamer.md#push-mpeg-ts-over-udp) server.
* `tcp://8936`, Stream Converter: [Push HTTP-FLV](./streamer.md#push-http-flv-to-srs) server.
* `udp://10080`, Stream Converter: [Push SRT Media](https://github.com/ossrs/srs/issues/1147#issuecomment-577469119) server.

For external services to work with SRS:

* `udp://1989`, [WebRTC Signaling](https://github.com/ossrs/signaling#usage) server.

## APIs

The API used by SRS:

* `/api/v1/` The HTTP API path.
* `/rtc/v1/` The HTTP API path for RTC.
* `/sig/v1/` The [demo signaling](https://github.com/ossrs/signaling) API.

Other API used by [ossrs.net](https://ossrs.net):

* `/gif/v1` The statistic API.
* `/service/v1/` The latest available version API.
* `/ws-service/v1/` The latest available version API, by websocket.
* `/im-service/v1/` The latest available version API, by IM.
* `/code-service/v1/` The latest available version API, by Code verification.

The statistic path for [ossrs.net](https://ossrs.net):

* `/srs/xxx` The GitHub pages for [srs](https://github.com/ossrs/srs)
* `/release/xxx` The pages for [ossrs.net](https://ossrs.net)
* `/console/xxx` The pages for [console](http://ossrs.net/console/)
* `/player/xxx` The pages for [players and publishers](http://ossrs.net/players/)
* `/k8s/xxx` The template and repository deploy by K8s, like [srs-k8s-template](https://github.com/ossrs/srs-k8s-template)

## Mirrors

[Gitee](https://gitee.com/ossrs/srs), [the GIT usage](./git.md)

```
git clone https://gitee.com/ossrs/srs.git &&
cd srs && git remote set-url origin https://github.com/ossrs/srs.git && git pull
```

> Remark: For users in China, recomment to use mirror from CSDN or OSChina, because they are much faster.
[Gitlab](https://gitlab.com/winlinvip/srs-gitlab), [the GIT usage](./git.md)

```
git clone https://gitlab.com/winlinvip/srs-gitlab.git srs &&
cd srs && git remote set-url origin https://github.com/ossrs/srs.git && git pull
```

[Github](https://github.com/ossrs/srs), [the GIT usage](./git.md)

```
git clone https://github.com/ossrs/srs.git
```

| Branch | Cost | Size | CMD |
| --- | --- | --- | --- |
| 3.0release | 2m19.931s | 262MB | git clone -b 3.0release https://gitee.com/ossrs/srs.git |
| 3.0release | 0m56.515s | 95MB | git clone -b 3.0release --depth=1 https://gitee.com/ossrs/srs.git |
| develop | 2m22.430s | 234MB | git clone -b develop https://gitee.com/ossrs/srs.git |
| develop | 0m46.421s | 42MB | git clone -b develop --depth=1 https://gitee.com/ossrs/srs.git |
| min | 2m22.865s | 217MB | git clone -b min https://gitee.com/ossrs/srs.git |
| min | 0m36.472s | 11MB | git clone -b min --depth=1 https://gitee.com/ossrs/srs.git |

---

### Skills Internal Docs For Srs References Cpp Docs Doc Rtmp (`skills/internal-docs-for-srs/references/cpp-docs/doc/rtmp.md`)

---
title: RTMP
sidebar_label: RTMP
hide_title: false
hide_table_of_contents: false
---

# RTMP

RTMP is a basic and de facto standard protocol for live streaming for many years.

However, Adobe neither maintaining RTMP protocol nor contributing as an RFC protocol, so many new features
aren't supported by RTMP, such as HEVC and opus. By March 2023, the [Enhanced RTMP](https://github.com/veovera/enhanced-rtmp) 
project is finally set up, supporting HEVC and AV1. SRS and OBS now support [HEVC](https://github.com/veovera/enhanced-rtmp/issues/4) 
encoding based on Enhanced RTMP.

For live streaming producing, more recent years, SRT, WebRTC and RIST have been growing rapidly. More and
more devices supported SRT or RIST in live streaming. You're also able to use WebRTC for live streaming.

For live streaming deliver, HLS is the most common used protocol, is supported by almost all CDN and devices
such as PC, iOS, Android and tablet PC. However, HLS has large (3~5s+) latency, you could use HTTP-FLV,
HTTP-TS or WebRTC for low latency use scenario.

Today, RTMP is still used in live streaming producing, for example, OBS publish RTMP stream to YouTube, Twitch, etc.
If you want to ingest stream from a device or publish to a platform, RTMP is the right choice for compatibility.

## Usage

SRS supports RTMP by default, please run by [docker](./getting-started.md) or [build from source](./getting-started-build.md):

```bash
docker run --rm -it -p 1935:1935 --env SRS_RTMP_LISTEN=1935 ossrs/srs:8 \
  ./objs/srs -e
```

Publish stream by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) :

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

Play stream by:

* RTMP (by [VLC](https://www.videolan.org/)): `rtmp://localhost/live/livestream`

SRS supports converting RTMP to other protocols, described in next sections.

## Config

The configuration about RTMP:

```
/* Detailed source-code truncated for AI context efficiency. */
```

> Note: These configurations are for publish and play. Note that there are some other configurations in other sections,
for example, converting RTMP to [HTTP-FLV](./flv.md#config) or HTTP-TS.

## RTMPS

RTMPS (RTMP over SSL/TLS) provides secure RTMP streaming by encrypting the connection between clients and the server. This is essential for protecting sensitive content and ensuring secure communication in production environments.

SRS (v7.0.56+) supports RTMPS server functionality, allowing publishers and players to connect using encrypted RTMP connections.

To enable RTMPS, you need to configure SRS with SSL certificates and run it with RTMPS support:

```bash
env SRS_RTMP_LISTEN=1935 SRS_RTMPS_ENABLED=on SRS_RTMPS_LISTEN=1443 \
  ./objs/srs -e
```

Publish RTMPS stream by [FFmpeg](https://ffmpeg.org/download.html):

```bash
ffmpeg -re -i doc/source.flv -c copy -f flv rtmps://localhost:1443/live/livestream
```

Play RTMPS stream by [ffplay](https://ffmpeg.org/download.html):

```bash
ffplay rtmps://localhost:1443/live/livestream
```

The RTMPS configuration requires SSL certificate setup similar to other HTTPS services in SRS:

```bash
rtmp {
    # the rtmp listen ports, split by space, each listen entry is <[ip:]port>
    # for example, 192.168.1.100:1935 10.10.10.100:1935
    # where the ip is optional, default to 0.0.0.0, that is 1935 equals to 0.0.0.0:1935
    # Overwrite by env SRS_RTMP_LISTEN
    listen 1935;
    # the default chunk size is 128, max is 65536,
    # some client does not support chunk size change,
    # however, most clients support it and it can improve
    # performance about 10%.
    # Overwrite by env SRS_CHUNK_SIZE
    # default: 60000
    chunk_size 60000;
}

# SSL configuration for RTMPS
rtmps {
    # Whether rtmps is enabled.
    # Overwrite by env SRS_RTMPS_ENABLED
    # default: off
    enabled         on;
    # The rtmps listen port
    # Overwrite by env SRS_RTMPS_LISTEN
    listen          1443;
    # The SSL private key file, generated by:
    #       openssl genrsa -out server.key 2048
    # Overwrite by env SRS_RTMPS_KEY
    # default: ./conf/server.key
    key             ./conf/server.key;
    # The SSL public cert file, generated by:
    #       openssl req -new -x509 -key server.key -out server.crt -days 3650 -subj "/C=CA/ST=Toronto/L=Toronto/O=Me/OU=Me/CN=ossrs.io"
    # Overwrite by env SRS_RTMPS_CERT
    # default: ./conf/server.crt
    cert            ./conf/server.crt;
}

vhost __defaultVhost__ {
    # Standard RTMP vhost configuration applies to RTMPS as well
}
```

For testing purposes, you can generate a self-signed certificate:

```bash
# Generate private key
openssl genrsa -out server.key 2048

# Generate self-signed certificate
openssl req -new -x509 -key server.key -out server.crt -days 3650 \
    -subj "/C=CN/ST=Beijing/L=Beijing/O=Me/OU=Me/CN=localhost"
```

For production environments, use certificates from a trusted Certificate Authority (CA) or Let's Encrypt.

## IPv6

SRS (v7.0.67+) supports IPv6 for RTMP and RTMPS protocols, enabling dual-stack (IPv4/IPv6) operation. This allows clients to connect using IPv6 addresses while maintaining full compatibility with existing IPv4 infrastructure.

IPv6 support is enabled automatically when SRS detects IPv6 addresses in the configuration. You can configure SRS to listen on IPv6 addresses by specifying them in the `listen` directive:

```bash
rtmp {
    # Listen on both IPv4 and IPv6
    listen 1935 [::]:1935;
}

# For RTMPS
rtmps {
    enabled on;
    listen 1443 [::]:1443;
    key ./conf/server.key;
    cert ./conf/server.crt;
}
```

Publish RTMP stream via IPv6:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv 'rtmp://[::1]:1935/live/livestream'
```

Publish RTMPS stream via IPv6:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv 'rtmps://[::1]:1443/live/livestream'
```

Play RTMP stream via IPv6:

```bash
ffplay 'rtmp://[::1]:1935/live/livestream'
```

Play RTMPS stream via IPv6:

```bash
ffplay 'rtmps://[::1]:1443/live/livestream'
```

SRS supports dual-stack operation, allowing both IPv4 and IPv6 clients to connect simultaneously:

```bash
# Listen on both IPv4 and IPv6 addresses
listen 1935 [::]:1935;

# This allows connections from:
# - IPv4 clients: rtmp://192.168.1.100:1935/live/stream
# - IPv6 clients: rtmp://[2001:db8::1]:1935/live/stream
```

## On Demand Live Streaming

In some situations, you might want to start streaming only when someone starts watching:

1. The streaming source connects to the system but doesn't send the stream to SRS.
2. The player connects to the system and requests to play the stream.
3. The system tells the streaming source to start sending the stream to SRS.
4. The player gets the stream from SRS and plays it.

> Note: The "system" here refers to your business system, not SRS.

This is called "on-demand live streaming" or "on-demand streaming." What happens if the player stops watching?

1. The system needs to tell the streaming source to stop sending the stream.
2. Or, when the last player stops watching, SRS waits for a while and then disconnects the stream.

The second solution is recommended, as it's easier to use. Your system won't need to tell the streaming source to stop, because SRS will disconnect it automatically. You just need to enable the following configuration:

```bash
# The timeout in seconds to disconnect publisher when idle, which means no players.
# Note that 0 means no timeout or this feature is disabled.
# Note that this feature conflicts with forward, because it disconnect the publisher stream.
# Overwrite by env SRS_VHOST_PUBLISH_KICKOFF_FOR_IDLE for all vhosts.
# default: 0
kickoff_for_idle 0;
```

For more details, you can refer to [this PR](https://github.com/ossrs/srs/pull/3105).

## Converting RTMP to HLS

If want to convert RTMP to HLS, please see [HLS](./hls.md).

## Converting RTMP to HTTP-FLV

If want to convert RTMP to HTTP-FLV or HTTP-TS, please see [HTTP-FLV](./flv.md).

## Converting RTMP to WebRTC

If want to convert RTMP to WebRTC, please see [WebRTC: RTMP to RTC](./webrtc.md#rtmp-to-rtc).

## Converting RTMP to MPEGTS-DASH

If want to convert RTMP to MPEGTS-DASH, please see [DASH](./sample-dash.md).

## Converting SRT to RTMP

If want to convert SRT to RTMP, please see [SRT](./srt.md).

## Converting WebRTC to RTMP

If want to convert WebRTC to RTMP, please see [WebRTC: RTC to RTMP](./webrtc.md#rtc-to-rtmp).

## RTMP Cluster

If want to support a large set of players, please see [Edge Cluster](./edge.md).

If want to support a larget set of publishers or streams, please see [Origin Cluster](./origin-cluster.md).

Note that there are lots of solutions for [load balancing](../../../blog/load-balancing-streaming-servers).

## Low Latency RTMP

If want to support low latency RTMP stream, please see [LowLatency](./low-latency.md).

## Timestamp Jitter

SRS support correcting the timestamp for RTMP, please see [Jitter](./time-jitter.md).

If wants SRS to keep the original timestamp, you can enable [ATC](./rtmp-atc.md).

## Performance

SRS use writev for high performance RTMP delivery, please follow [benchmark](./performance.md##performance-banchmark)
to test it.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Rtsp (`skills/internal-docs-for-srs/references/cpp-docs/doc/rtsp.md`)

---
title: RTSP
sidebar_label: RTSP
hide_title: false
hide_table_of_contents: false
---

# RTSP

RTSP is a well-established protocol with nearly 30 years of history. In the security surveillance industry, many companies have implemented their own RTSP servers, but they rarely open-source them and often add proprietary extensions. While RTMP servers are readily available, finding a good RTSP server is much more challenging.

SRS initially supported the RTSP protocol in version 2.0, but only for publishing streams (ANNOUNCE → SETUP → RECORD) without playback capabilities (DESCRIBE → SETUP → PLAY). In practice, many traditional client/server applications, decoders, embedded devices, and even the latest AI vision detection systems still prefer RTSP as their primary playback protocol.

This version reuses some protocol parsing code from version 2.0, removes the publishing functionality, adds playback support, and only works with TCP transport.

For more background, please refer to the [FAQ](../../../faq#rtsp).

## Usage

First, compile and start SRS (ensure you're using version `7.0.47+`):

```bash
cd srs/trunk && ./configure --rtsp=on && make
env SRS_RTMP_LISTEN=1935 SRS_RTSP_SERVER_ENABLED=on SRS_RTSP_SERVER_LISTEN=8554 \
  SRS_VHOST_RTSP_ENABLED=on ./objs/srs -e
```
> You must enable RTSP with `--rtsp=on` during compilation (disabled by default).

Then, publish a stream using RTMP:

```bash
ffmpeg -re -i doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

Finally, play the stream using RTSP (note: only TCP transport is supported):

```bash
ffplay -rtsp_transport tcp -i rtsp://localhost:8554/live/livestream
```

## Config

Reference `conf/rtsp.conf`:

```bash
rtsp_server {
    enabled on;
    listen 8554;
}

vhost __defaultVhost__ {
    rtsp {
        enabled on;
        rtmp_to_rtsp on;
    }
}
```

## Port

The RTSP protocol consists of two parts: signaling (DESCRIBE/SETUP/PLAY, etc.) and media transport (RTP/RTCP packets).

Signaling must use TCP protocol. The default port is `554`, but some systems require `root` privileges to listen on this port, so we've changed it to `8554`.

After successful signaling, media transport begins. There are two methods: TCP or UDP. TCP reuses the socket connection established during signaling. UDP transport is not supported because it requires port allocation. If you try to use UDP as transport, it will fail:

```bash
ffplay -rtsp_transport udp -i rtsp://localhost:8554/live/livestream

[rtsp @ 0x7fbc99a14880] method SETUP failed: 461 Unsupported Transport
rtsp://localhost:8554/live/livestream: Protocol not supported

[2025-07-05 21:30:52.738][WARN][14916][7d7gf623][35] RTSP: setup failed: code=2057
(RtspTransportNotSupported) : UDP transport not supported, only TCP/interleaved mode is supported
```

There are currently no plans to support UDP transport. In practice, UDP is rarely used; the vast majority of RTSP traffic uses TCP.

## RTP

When using TCP transport, each RTP/RTCP packet has an additional 4-byte header. The first byte is fixed at `0x24`, followed by a 1-byte channel identifier, followed by a 2-byte RTP packet length. See section 10.12 `Embedded (Interleaved) Binary Data` in `RFC2326`.

## Play Before Publish

RTSP supports audio with AAC and OPUS codecs, which is significantly different from RTMP or WebRTC.

RTSP uses commands to exchange SDP and specify the audio track to play, unlike WHEP or HTTP-FLV, which use the query string of the URL. RTSP depends on the player’s behavior, making it very difficult to use and describe.

Considering the feature that allows playing the stream before publishing it, it requires generating some default parameters in the SDP. For OPUS, the sample rate is 48 kHz with 2 channels, while AAC is more complex, especially regarding the sample rate, which may be 44.1 kHz, 32 kHz, or 48 kHz.

Therefore, for RTSP, we cannot support play-then-publish. Instead, there must already be a stream when playing it, so that the audio codec is determined.

## Opus Codec

No Opus codec support for RTSP, because for RTC2RTSP, it always converts RTC to RTMP frames, then converts them to RTSP packets. Therefore, the audio codec is always AAC after converting RTC to RTMP.

This means the bridge architecture needs some changes. We need a new bridge that binds to the target protocol. For example, RTC2RTMP converts the audio codec, but RTC2RTSP keeps the original audio codec.

Furthermore, the RTC2RTMP bridge should also support bypassing the Opus codec if we use enhanced-RTMP, which supports the Opus audio codec. I think it should be configurable to either transcode or bypass the audio codec. However, this is not relevant to RTSP.

## Architecture

For the RTSP protocol parsing, we copied code from version 3.0, removed SDP, RTP, and publishing-related code, keeping only the essential `SrsRtspRequest` and `SrsRtspResponse` for handling requests and responses. We only process five methods: `OPTIONS`, `DESCRIBE`, `SETUP`, `PLAY`, and `TEARDOWN`. This is sufficient for RTSP playback.

For the business logic, `SrsRtspConnection` handles client connections and protocol interactions, `SrsRtspPlayStream` consumes data from `SrsRtspSource`, `SrsRtspSource` manages multiple `SrsRtspConsumer` instances and distributes RTP packets, and finally `SrsRtspSendTrack` sends audio and video data to clients.

## Testing

### Unit Test

```bash
./configure --utest=on & make utest
./objs/srs_utest
```

### Regression Test

```bash
cd srs/trunk/3rdparty/srs-bench
go test ./srs -mod=vendor -v -count=1 -run=TestRtmpPublish_RtspPlay
```
> Note: You need to start SRS before running regression tests.

### BlackBox Test

```bash
cd srs/trunk/3rdparty/srs-bench
go test ./blackbox -mod=vendor -v -count=1 -run=TestFast_RtmpPublish_RtspPlay_Basic
```

## TODO

The current version implements only basic functionality. Additional features like authentication, redirection, and RTCP will be planned according to actual needs, possibly in the near future.

## IPv6

SRS (v7.0.67+) supports IPv6 for RTSP protocol, enabling dual-stack (IPv4/IPv6) operation for standards-based streaming. This allows RTSP clients to connect using IPv6 addresses while maintaining full compatibility with existing IPv4 infrastructure.

IPv6 support is enabled automatically when SRS detects IPv6 addresses in the configuration. Configure the RTSP server to listen on IPv6 addresses:

```bash
rtsp_server {
    enabled on;
    # Listen on both IPv4 and IPv6 for UDP media
    listen 8554 [::]:8554;
}

vhost __defaultVhost__ {
    rtsp {
        enabled on;
        rtmp_to_rtsp on;
    }
}
```

Play RTSP stream via IPv6 using FFplay (TCP transport only):

```bash
ffplay -rtsp_transport tcp -i 'rtsp://[::1]:8554/live/livestream'
```

Play RTSP stream via IPv6 using VLC:

```bash
vlc 'rtsp://[::1]:8554/live/livestream'
```

When using IPv6 addresses in RTSP URLs, the IPv6 address must be enclosed in square brackets:

```bash
# Local IPv6 loopback
rtsp://[::1]:8554/live/livestream

# Public IPv6 address
rtsp://[2001:db8::1]:8554/live/livestream

# With authentication (if implemented)
rtsp://user:pass@[2001:db8::1]:8554/live/livestream
```

SRS supports dual-stack RTSP operation, allowing both IPv4 and IPv6 clients to connect simultaneously:

```bash
rtsp_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 8554 [::]:8554;
}
```

This configuration allows:
- IPv4 clients: `rtsp://192.168.1.100:8554/live/livestream`
- IPv6 clients: `rtsp://[2001:db8::1]:8554/live/livestream`

## References

- [rfc2326-1998-rtsp.pdf](/files/rfc2326-1998-rtsp.pdf)

---

### Skills Internal Docs For Srs References Cpp Docs Doc Security (`skills/internal-docs-for-srs/references/cpp-docs/doc/security.md`)

---
title: Security
sidebar_label: Security
hide_title: false
hide_table_of_contents: false
---

# Security

SRS provides simple security strategy to allow or deny specifies clients.

## Config

The config for security of vhost:

```
vhost your_vhost {
    # security for host to allow or deny clients.
    # @see https://github.com/ossrs/srs/issues/211   
    security {
        # whether enable the security for vhost.
        # default: off
        enabled         on;
        # the security list, each item format as:
        #       allow|deny    publish|play    all|<ip or cidr>
        # for example:
        #       allow           publish     all;
        #       deny            publish     all;
        #       allow           publish     127.0.0.1;
        #       deny            publish     127.0.0.1;
        #       allow           publish     10.0.0.0/8;
        #       deny            publish     10.0.0.0/8;
        #       allow           play        all;
        #       deny            play        all;
        #       allow           play        127.0.0.1;
        #       deny            play        127.0.0.1;
        #       allow           play        10.0.0.0/8;
        #       deny            play        10.0.0.0/8;
        # SRS apply the following simple strategies one by one:
        #       1. allow all if security disabled.
        #       2. default to deny all when security enabled.
        #       3. allow if matches allow strategy.
        #       4. deny if matches deny strategy.
        allow           play        all;
        allow           publish     all;
    }
}
```

Please see `conf/security.deny.publish.conf` for detail.

## Kickoff Client

SRS provides api to kickoff user, read [wiki](./http-api.md#kickoff-client).

## Bug

The bug about this feature, read [#211](https://github.com/ossrs/srs/issues/211)

## Reload

When reload the security config, it only effects the new clients.

Winlin 2015.1

---

### Skills Internal Docs For Srs References Cpp Docs Doc Snapshot (`skills/internal-docs-for-srs/references/cpp-docs/doc/snapshot.md`)

---
title: Snapshot
sidebar_label: Snapshot 
hide_title: false
hide_table_of_contents: false
---

# Snapshot

SRS provides workaround for snapshots:

1. HttpCallback: Use http callbacks to handle `on_publish` event to snapshot by FFMPEG, and to stop FFMPEG when got `on_unpublish` event.
1. Transcoder: Use transcoder to snapshot.

## HttpCallback

This section describes how to use http callbacks to snapshot.

First, start the sample api server:
```
cd research/api-server && go run server.go 8085
```

Second, write the config for SRS to snapshot:
```
# snapshot.conf
listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {
    http_hooks {
        enabled on;
        on_publish http://127.0.0.1:8085/api/v1/snapshots;
        on_unpublish http://127.0.0.1:8085/api/v1/snapshots;
    }
    ingest {
        enabled on;
        input {
            type file;
            url ./doc/source.flv;
        }
        ffmpeg ./objs/ffmpeg/bin/ffmpeg;
        engine {
            enabled off;
            output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
        }
    }
}
```

Thrird, start SRS and the ingest will publish RTMP stream, which will trigger the `on_publish` event, then api will snapshot:
```
./objs/srs -c snapshot.conf
```

The snapshot generate thumbnails to directory:
```
winlin:srs winlin$ ls -lh research/api-server/static-dir/live/*.png
-rw-r--r--  1 winlin  staff    73K Oct 20 13:35 livestream-001.png
-rw-r--r--  1 winlin  staff    91K Oct 20 13:35 livestream-002.png
-rw-r--r--  1 winlin  staff    11K Oct 20 13:35 livestream-003.png
-rw-r--r--  1 winlin  staff   167K Oct 20 13:35 livestream-004.png
-rw-r--r--  1 winlin  staff   172K Oct 20 13:35 livestream-005.png
-rw-r--r--  1 winlin  staff   264K Oct 20 13:35 livestream-006.png
lrwxr-xr-x  1 winlin  staff   105B Oct 20 13:35 livestream-best.png -> livestream-006.png
```

The thumbnail `live-livestream-best.png` will link to the big one to avoid blank image.

User can access it by http server: [http://localhost:8085/live/livestream-best.png](http://localhost:8085/live/livestream-best.png)

## Transcoder

The transcoder can used for snapshot:

```
listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {
    transcode {
        enabled on;
        ffmpeg ./objs/ffmpeg/bin/ffmpeg;
        engine snapshot {
            enabled on;
            iformat flv;
            vfilter {
                vf fps=1;
            }
            vcodec png;
            vparams {
                vframes 6;
            }
            acodec an;
            oformat image2;
            output ./objs/nginx/html/[app]/[stream]-%03d.png;
        }
    }
    ingest {
        enabled on;
        input {
            type file;
            url ./doc/source.flv;
        }
        ffmpeg ./objs/ffmpeg/bin/ffmpeg;
        engine {
            enabled off;
            output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
        }
    }
}
```

The thumbnails:
```
winlin:srs winlin$ ls -lh objs/nginx/html/live/*.png
-rw-r--r--  1 winlin  staff   265K Oct 20 14:52 livestream-001.png
-rw-r--r--  1 winlin  staff   265K Oct 20 14:52 livestream-002.png
-rw-r--r--  1 winlin  staff   287K Oct 20 14:52 livestream-003.png
-rw-r--r--  1 winlin  staff   235K Oct 20 14:52 livestream-004.png
-rw-r--r--  1 winlin  staff   315K Oct 20 14:52 livestream-005.png
-rw-r--r--  1 winlin  staff   405K Oct 20 14:52 livestream-006.png
```

Note: SRS never choose the best thumbnail.

Winlin 2015.10

---

### Skills Internal Docs For Srs References Cpp Docs Doc Srt (`skills/internal-docs-for-srs/references/cpp-docs/doc/srt.md`)

---
title: SRT
sidebar_label: SRT
hide_title: false
hide_table_of_contents: false
---

# SRT

SRT (Secure Reliable Transport) is a broadcasting protocol created by Haivision to replace RTMP. Many live streaming 
encoders like OBS, vMix, and FFmpeg already support SRT, and many users prefer it for streaming.

Adobe hasn't been updating the RTMP protocol or submitting it to standard organizations like RFC, so it doesn't support
many new features like HEVC or Opus. In March 2023, the Enhanced RTMP project was created, which now supports HEVC and 
AV1. SRS and OBS also support HEVC encoding based on Enhanced RTMP.

Since SRT uses TS encapsulation, it naturally supports new codecs. SRT is based on the UDP protocol, so it has lower 
latency and better performance on weak networks than RTMP. RTMP latency is usually 1-3 seconds, while SRT latency is 
300-500 milliseconds. SRT is more stable on weak networks, making it better for long-distance and outdoor broadcasting.

SRT is a core protocol of SRS. SRS has supported SRT since 2020 and improved its consistency with other core protocols
in 2022. SRT and RTMP have very high consistency in terms of callbacks and API support.

Please refer to [#1147](https://github.com/ossrs/srs/issues/1147) for the detailed research and development process.

## Usage

SRS has built-in support for SRT and can be used with [docker](./getting-started.md) or [compiled from source](./getting-started-build.md):

```bash
docker run --rm -it -p 1935:1935 -p 8080:8080 -p 10080:10080/udp \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_SERVER_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  --env SRS_SRT_SERVER_ENABLED=on --env SRS_VHOST_SRT_ENABLED=on --env SRS_VHOST_SRT_SRT_TO_RTMP=on \
  --env SRS_SRT_SERVER_LATENCY=0 --env SRS_SRT_SERVER_RECVLATENCY=0 --env SRS_SRT_SERVER_TSBPDMODE=off \
  ossrs/srs:8 ./objs/srs -e
```

Use [FFmpeg(click to download)](https://ffmpeg.org/download.html) or [OBS(click to download)](https://obsproject.com/download) to push the stream:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
```

Open the following page to play the stream (if SRS is not on your local machine, replace localhost with the server IP):

* RTMP(VLC/ffplay): `rtmp://localhost/live/livestream`
* HLS by SRS player: [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html)
* SRT(ffplay): `srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request`
* SRT(VLC): `srt://127.0.0.1:10080`

SRS supports converting SRT to other protocols, which will be described in detail below.

## Config

The configuration for SRT is as follows:

```
/* Detailed source-code truncated for AI context efficiency. */
```

> Note: These configurations are for publish and play. Note that there are some other configurations in other sections,
for example, converting RTMP to [HTTP-FLV](./flv.md#config) or HTTP-TS.

All SRT configuration parameters can be found in the [libsrt](https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#list-of-options) documentation. Below are the important parameters supported by SRS:

* `tsbpdmode`: Timestamp-based packet delivery mode. Each packet gets a timestamp, and the application reads them at the interval specified by the timestamps.
* `latency`: In milliseconds (ms). This configures both recvlatency and peerlatency to the same value. If recvlatency is set, it will be used; if peerlatency is set, it will be used.
* `recvlatency`: In milliseconds (ms). This is the receiver's buffer time length, including the time it takes for a packet to travel from the sender, through the network, to the receiver, and finally to the media application. This buffer time should be greater than RTT and prepared for multiple packet retransmissions.
    * Low-latency networks: If the application requires low latency, consider setting the parameter to less than 250ms (human perception is not affected by audio/video latency below 250ms).
    * Long-distance, high RTT: If the transmission distance is long and RTT is high, a small latency cannot be set. For important live broadcasts that don't require low latency but need smooth playback without jitter, set latency >= 3*RTT, as this includes packet retransmission and ack/nack cycles.
* `peerlatency`: In milliseconds (ms). This is the sender's setting for peerlatency, telling the receiver how long the latency buffer should be. If the receiver also sets recvlatency, the receiver will use the larger of the two values as the latency buffer length.
    * Low-latency networks: Same recommendations as for `recvlatency`.
    * Long-distance, high RTT: Same recommendations as for `recvlatency`.
* `tlpkdrop`: Whether to drop too-late packets. Since SRT is designed for audio/video transmission, the receiver sends packets to the application based on timestamps or encoding bitrate. If a packet arrives too late at the receiver (after latency timeout), it will be dropped. In live mode, tlpkdrop is true by default, as live broadcasts require low latency.
* `maxbw`: In bytes/s, the maximum sending bandwidth. `-1`: Maximum bandwidth is 1Gbps; `0`: Determined by SRTO_INPUTBW calculation (not recommended for live mode); `>0`: Bandwidth in bytes/s.
* `mss`: In bytes, the maximum size of a single sent packet. This refers to the size of IP packets, including UDP and SRT protocol packets.
* `connect_timeout`: In milliseconds (ms), the SRT connection timeout.
* `peer_idle_timeout`: In milliseconds (ms), the SRT peer timeout.
* `sendbuf`: In bytes, the SRT send buffer size.
* `recvbuf`: In bytes, the SRT receive buffer size.
* `payloadsize`: In bytes, the payload size is a multiple of 188 (the minimum size of an MPEG-TS packet), defaulting to 1316 bytes (188x7).
* `passphrase`: The SRT connection password, default is empty (no encryption). The password must be between 10-79 characters long, and the client must enter the correct password to connect successfully, or the connection will be rejected.
* `pbkeylen`: The SRT encryption key length, default is 0. The stream encryption key length can be 0/16/24/32, corresponding to different AES encryption key lengths. This parameter needs to be set when the `passphrase` option is set.
* `srt_to_rtmp`: Whether to enable SRT to RTMP conversion. After converting to RTMP, it can be played using RTMP, HTTP-FLV, and HLS protocols.

## Low Latency Mode

If you want the lowest latency and can tolerate occasional packet loss, consider this setting.

> Note: Keep in mind that SRT will retransmit lost packets. Only when the network is very bad, and packets arrive very late or not at all, will they be discarded with `tlpktdrop` enabled, causing screen glitches.

For events, activities, and TV production with long-distance streaming, the link is usually prepared in advance and is stable and dedicated. In these scenarios, a fixed latency is required, allowing a certain degree of packet loss (very low probability). Generally, the RTT of the link is detected before the stream starts and is used as a basis for configuring SRT streaming parameters.

The recommended configuration is as follows, assuming an RTT of 100ms:

```bash
srt_server {
    enabled on;
    listen 10080;
    connect_timeout 4000;
    peerlatency 300; # RTT * 3
    recvlatency 300; # RTT * 3
    latency 300; # RTT * 3
    tlpktdrop on;
    tsbpdmode on;
}
```

This section describes how to reduce the latency of SRT, which is relevant to each link. The summary is as follows:

* Pay attention to the client's Ping and CPU, which are easily overlooked but can affect latency.
* Please use Oryx as the server, as it has been adjusted and will not cause additional latency.
* An increase in RTT will affect latency. Generally, with an RTT of below 60ms, it can be stable at the expected latency.
* With an RTT of 100ms, latency is approximately 300ms, and with an RTT of 150ms, latency increases to around 430ms.
* Packet loss will affect quality. With a packet loss rate of over 10%, there will be screen flickering and dropped frames, but it does not affect latency significantly, particularly for audio.
* Currently, the lowest latency can be achieved by using vmix or Xinxiang to stream SRT and playing it with ffplay, resulting in a latency of around 200ms.
* When streaming SRT with OBS and playing it with ffplay, the latency is around 350ms.

> Special Note: Based on current tests, the latency ceiling for SRT is 300ms. Although vmix can be set to a 1ms latency, it does not work and the actual latency will only be worse, not better. However, if the network is well maintained, a latency of 300ms is sufficient.

Recommended solution for ultra high-definition, ultra low-latency, SRT live streaming:

* Streaming: Xinxiang (230ms), vMix (200ms), OBS (300ms).
* Playback: ffplay (200ms), vMix (230ms), Xinxiang (400ms).

| - | ffplay | vMix Playback | Xinxiang Playback |
| ---           | ----      |  ---         | ---           |
| vMix Push | 200ms | 300ms | - |
| OBS Push | 300ms | - | - |
| Xinxiang Push (http://www.sinsam.com/) | 230ms | - | 400ms |

Latency involves each link, below are the detailed configurations for each link. The directory is as follows:

* [CPU](https://github.com/ossrs/srs/issues/3464#lagging-cpu) Client CPU can cause latency.
* [Ping](https://github.com/ossrs/srs/issues/3464#lagging-ping) Client network RTT affects latency.
* [Encoder](https://github.com/ossrs/srs/issues/3464#lagging-encoder) Configuring encoder for low latency mode.
* [Server](https://github.com/ossrs/srs/issues/3464#lagging-server) Configuring the server for low latency.
* [SRT](https://github.com/ossrs/srs/issues/3464#lagging-srt) Special configuration for SRT servers.
* [Player](https://github.com/ossrs/srs/issues/3464#lagging-player) Configuring the player for low latency.
* [Benchmark](https://github.com/ossrs/srs/issues/3464#lagging-benchmark) Accurately measuring latency.
* [Bitrate](https://github.com/ossrs/srs/issues/3464#lagging-bitrate) Impact of different bitrates (0.5 to 6Mbps) on latency.
* [Network Jitter](https://github.com/ossrs/srs/issues/3464#lagging-jitter) Impact of packet loss and different RTT on latency.
* [Report](https://github.com/ossrs/srs/issues/3464#lagging-report) Test report.

## High Quality Mode

If you want the highest quality and can't tolerate even a small chance of screen glitches, but can accept increased latency, consider this configuration.

When using SRT on public networks, the connection can be unstable, and RTT (Round Trip Time) may change dynamically. For low-latency live streaming, you need adaptive latency and must not lose packets.

Recommended settings are as follows:

```
srt_server {
    enabled on;
    listen 10080;
    connect_timeout 4000;
    peerlatency 0;
    recvlatency 0;
    latency 0;
    tlpktdrop on;
    tsbpdmode off;
}
```

> Note: If you still experience screen glitches with the above settings, please refer to the [FFmpeg patch](https://github.com/FFmpeg/FFmpeg/commit/9099046cc76c9e3bf02f62a237b4d444cdaf5b20).

## Too-Late Packet Drop

The `tlpktdrop` (Too-Late Packet Drop) setting controls whether SRT discards packets that arrive later than the configured latency window.

When `tlpktdrop off` is combined with `tsbpdmode on`, the SRT receiver buffer can fill up with packets that cannot be recovered. Over time, iterating through this buffer to request retransmissions consumes 100% CPU, causing the server to become completely unresponsive - no new streams can be published, existing streams stop working, and even the HTTP API becomes unavailable.

**Recommended configuration:**

```
srt_server {
    enabled on;
    listen 10080;
    tlpktdrop on;
}
```

**Key points:**

* `tlpktdrop on` does NOT disable retransmission entirely. Packets within the latency window will still be retransmitted.
* With `tlpktdrop on`, if the network has severe jitter, some late packets may be dropped, causing minor video glitches.
* The trade-off is: occasional glitches (with `tlpktdrop on`) vs. potential server hang (with `tlpktdrop off` + `tsbpdmode on`).

For more details, see [#4587](https://github.com/ossrs/srs/issues/4587).

## Video codec

Currently, H264 and HEVC encoding are supported. Since SRT protocol transfers media in MPEG-TS format, which already supports HEVC encoding (streamtype 0x24), SRT can naturally transmit HEVC encoded video without any modifications.

To stream with HEVC encoding, use the following command:
```bash
ffmpeg -re -i source.mp4 -c:v libx265 -c:a copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
```

To play HEVC encoded video, use the following command:
```bash
ffplay 'srt://127.0.0.1:10080?streamid=#!::h=live/livestream,m=request'
```

## Audio codec

Currently supported encoding formats:
* AAC, with sample rates of 44100, 22050, 11025, and 5512.

## FFmpeg push SRT stream

When using FFmpeg to push AAC audio format SRT stream, it is recommended to add the `-pes_payload_size 0` parameter in the command line. This parameter prevents multiple AAC audio frames from being combined into one PES package, reducing latency and audio-video synchronization issues.

FFmpeg command line example:

```bash
ffmpeg -re -i source.mp4 -c copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
```

## SRT URL

SRT URL uses YAML format, which is different from the common URL definition.

Consider the SRS definition for RTMP address, please refer to [RTMP URL](./rtmp-url-vhost.md) definition:

* Regular RTMP format (without vhost)
    - `rtmp://hostip:port/app/stream`
    - Example: `rtmp://10.111.1.100:1935/live/livestream`
    - In this example, app="live", stream="livestream"
* Complex RTMP format (with vhost)
    - `rtmp://hostip:port/app/stream?vhost=xxx`
    - Example: `rtmp://10.111.1.100:1935/live/livestream?vhost=srs.com.cn`
    - In this example, vhost="srs.com.cn", app="live", stream="livestream"

Whether it is streaming or playing, the RTMP address is a single address, and RTMP uses protocol layer messages to determine it. `publish message` means streaming to the URL, and `play message` means playing the URL.

SRT is a transport layer protocol, so it cannot determine whether the operation on an SRT URL is streaming or playing. The SRT documentation has recommendations for streaming/playing: [AccessControl.md](https://github.com/Haivision/srt/blob/master/docs/features/access-control.md)
The key method is to use the streamid parameter to clarify the purpose of the URL, and the streamid format complies with the YAML format.

Here is an SRT URL without vhost:
* Streaming address: `srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish`
* Playing address: `srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request`
* Corresponding RTMP playing address: `rtmp://127.0.0.1/live/livestream`

Where:
* `#!::`, is the beginning, in line with the YAML format standard.
* `r`, maps to the `app/stream` in the RTMP address.
* `m`, `publish` means streaming, `request` means playing.

Here is an SRT URL with vhost support:
* Streaming address: `srt://127.0.0.1:10080?streamid=#!::h=srs.srt.com.cn,r=live/livestream,m=publish`
* Playing address: `srt://127.0.0.1:10080?streamid=#!::h=srs.srt.com.cn,r=live/livestream,m=request`
* Corresponding RTMP address: `rtmp://127.0.0.1/live/livestream?vhost=srs.srt.com.cn`

Where:
* `h`, maps to the vhost in the RTMP address

## SRT URL without streamid

Some devices do not support streamid input or do not support some special characters in streamid, such as `!`, `#`, `,`, etc. In this case, you can use only `ip:port` for streaming, such as `srt://127.0.0.1:10080`. For this URL, SRS will set the streamid to `#!::r=live/livestream,m=publish` by default.

In other words, the following two addresses are equivalent:
* `srt://127.0.0.1:10080`
* `srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish`

## SRT URL with short streamid

SRS supports a short streamid format without the `#!::` prefix for simpler URLs. When using short streamid format like `live/livestream` or just `livestream`, SRS uses the `default_mode` configuration to determine whether it's a publish or play request.

The `default_mode` configuration accepts two values:
* `publish`: Short streamid will be treated as publish/push mode.
* `request`: Short streamid will be treated as request/play/pull mode (this is the default).

For publisher-friendly setup where clients can push with simple URLs, configure `default_mode` to `publish`:

```bash
srt_server {
    enabled on;
    listen 10080;
    # Short streamid format will be treated as publisher
    default_mode publish;
}
```

With this configuration, you can publish with a simple URL:

```bash
# Publish with short streamid (uses default_mode=publish)
ffmpeg -re -i source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=live/livestream'

# Play with explicit mode (must specify m=request)
ffplay 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request'
```

For player-friendly setup where clients can play with simple URLs, use the default `default_mode=request`:

```bash
srt_server {
    enabled on;
    listen 10080;
    # Short streamid format will be treated as player (default)
    default_mode request;
}
```

With this configuration, you can play with a simple URL:

```bash
# Publish with explicit mode (must specify m=publish)
ffmpeg -re -i source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'

# Play with short streamid (uses default_mode=request)
ffplay 'srt://127.0.0.1:10080?streamid=live/livestream'
```

SRS provides two ready-to-use configuration files:
* `conf/srt.shortstreamid.publish.conf`: For publisher-friendly setup with `default_mode publish`.
* `conf/srt.shortstreamid.play.conf`: For player-friendly setup with `default_mode request`.

Note that explicit mode specification with the full `#!::` prefix always takes precedence over `default_mode`. This allows clients that support full streamid format to override the default behavior.

## Authentication

For the definition of SRT URLs, please refer to [SRT URL Schema](#srt-url).

Here is a special note on how to include authentication information, see [SRS URL: Token](./rtmp-url-vhost.md#parameters-in-url). 
If you need to include authentication information such as the secret parameter, you can specify it in the streamid, for example:

```
streamid=#!::r=live/livestream,secret=xxx
```

Here is a specific example:

```
ffmpeg -re -i doc/source.flv -c copy -f mpegts \
    'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,secret=xxx,m=publish'
```

The address for forwarding to SRS would be like this:

```
rtmp://127.0.0.1:1935/live/livestream?secret=xxx
```

## SRT Encoder

SRT Encoder is an encoder based on the SRT adaptive bitrate. It predicts low-latency outbound bandwidth based on information such as RTT, maxBw, and inflight in the SRT protocol, dynamically adjusting the encoding bitrate to be based on the network outbound bandwidth.

GitHub address: [runner365/srt_encoder](https://github.com/runner365/srt_encoder)

Based on the basic congestion control algorithm of BBR, the encoder predicts the state machine of the encoding bitrate (keep, increase, decrease) based on the minRTT, maxBw, and current inflight within one cycle (1~2 seconds).

Note:
1) This example is just a basic BBR algorithm example, and users can implement the interfaces in the CongestionCtrlI class to improve the BBR algorithm.
2) SRT is still an evolving protocol, and the accuracy of its congestion control and external parameter updates is also improving.

Easy to use, after compiling, you can directly use the ffmpeg command line.

## Coroutine Native SRT

How does SRS implement SRT? Based on coroutine-based SRT architecture, we need to adapt it to ST as SRT has its own IO scheduling, so that we can achieve the best maintainability.

* For the specific code submission, please refer to [#3010](https://github.com/ossrs/srs/pull/3010) or [1af30dea](https://github.com/ossrs/srs/commit/1af30dea324d0f1729aabd22536ea62e03497d7d)

> Note: Please note that the SRT in SRS 4.0 is a non-ST architecture, and it is implemented by launching a separate thread, which may not have the same level of maintainability as the native ST coroutine architecture.

## IPv6

SRS (v7.0.67+) supports IPv6 for SRT protocol, enabling dual-stack (IPv4/IPv6) operation for low-latency streaming. This allows SRT clients to connect using IPv6 addresses while maintaining full compatibility with existing IPv4 infrastructure.

IPv6 support is enabled automatically when SRS detects IPv6 addresses in the configuration. Configure the SRT server to listen on IPv6 addresses:

```bash
srt_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 10080 [::]:10080;

    # Other SRT parameters remain the same
    maxbw 1000000000;
    mss 1500;
    connect_timeout 4000;
    peer_idle_timeout 8000;
    default_app live;
    peerlatency 0;
    recvlatency 0;
}
```

Publish SRT stream via IPv6 using FFmpeg:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://[::1]:10080?streamid=#!::r=live/livestream,m=publish'
```

Play SRT stream via IPv6 using FFplay:

```bash
ffplay 'srt://[::1]:10080?streamid=#!::r=live/livestream,m=request'
```

When using IPv6 addresses in SRT URLs, the IPv6 address must be enclosed in square brackets:

```bash
# Publishing
srt://[2001:db8::1]:10080?streamid=#!::r=live/livestream,m=publish

# Playing
srt://[2001:db8::1]:10080?streamid=#!::r=live/livestream,m=request

# With vhost support
srt://[2001:db8::1]:10080?streamid=#!::h=srs.srt.com.cn,r=live/livestream,m=publish
```

SRS supports dual-stack SRT operation, allowing both IPv4 and IPv6 clients to connect simultaneously:

```bash
srt_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 10080 [::]:10080;
}
```

This configuration allows:
- IPv4 clients: `srt://192.168.1.100:10080?streamid=#!::r=live/stream,m=publish`
- IPv6 clients: `srt://[2001:db8::1]:10080?streamid=#!::r=live/stream,m=publish`

## VLC

VLC 3.0.17 and later support the SRT `SRTO_STREAMID` socket option. However, the structured SRS
stream ID used in this guide starts with `#`, such as `#!::r=live/livestream,m=request`, and VLC
treats that character as the beginning of a URL fragment. Therefore, do not append this SRS stream
ID directly to VLC's network URL. Use the simple URL `srt://127.0.0.1:10080` and set the stream ID
separately in VLC's SRT settings.

To set the stream ID in the VLC user interface:

1. Open VLC preferences:
   - Windows or Linux: select **Tools > Preferences**.
   - macOS: select **VLC > Settings…**. On older versions, this item may be named **Preferences…**.
2. Open the advanced settings:
   - Windows or Linux: at the bottom-left, change **Show settings** to **All**.
   - macOS: click **Show All** at the bottom-left.
3. Select **Input / Codecs > Access modules > SRT**.
4. Enter `#!::r=live/livestream,m=request` in **SRT Stream ID**.
5. Click **Save**.
6. Open the network stream:
   - Windows or Linux: select **Media > Open Network Stream**.
   - macOS: select **File > Open Network**.
7. Enter `srt://127.0.0.1:10080` and start playback.

The VLC preference is persistent and applies to later SRT connections. Change or clear it when you
need to play a different stream. You can also supply the value for one VLC invocation from the
command line:

```bash
vlc --streamid='#!::r=live/livestream,m=request' 'srt://127.0.0.1:10080'
```

For older VLC releases, or when the VLC stream ID field is empty, SRS provides a `default_streamid`
configuration option. When a client connects without setting `SRTO_STREAMID`, SRS uses this
configured default value. By default, SRS uses `#!::r=live/livestream,m=publish` for backward
compatibility, but for VLC playback you should configure it to use `m=request` mode instead.

SRS provides a ready-to-use configuration file `conf/srt.vlc.conf` optimized for VLC compatibility. 
Start SRS with this configuration:

```bash
./objs/srs -c conf/srt.vlc.conf
```

You can also set the default streamid using an environment variable, which is useful for Docker deployments:

```bash
env SRS_RTMP_LISTEN=1935 SRS_HTTP_SERVER_ENABLED=on SRS_VHOST_HTTP_REMUX_ENABLED=on \
    SRS_SRT_SERVER_ENABLED=on SRS_VHOST_SRT_ENABLED=on SRS_VHOST_SRT_SRT_TO_RTMP=on \
    SRS_SRT_SERVER_LATENCY=0 SRS_SRT_SERVER_RECVLATENCY=0 SRS_SRT_SERVER_TSBPDMODE=off \
    SRS_SRT_SERVER_DEFAULT_STREAMID="#!::r=live/livestream,m=request" \
    ./objs/srs -e
```

Here's a complete workflow example. First, publish a stream with FFmpeg (which explicitly sets streamid 
with `m=publish`):

```bash
ffmpeg -re -i ./doc/source.flv -c copy -pes_payload_size 0 -f mpegts \
  'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=publish'
```

Then either configure VLC's **SRT Stream ID** as described above, or leave that field empty to use
the server's `default_streamid`. Open the stream in VLC:

- Open VLC Media Player
- Go to Media → Open Network Stream
- Enter URL: `srt://127.0.0.1:10080`
- Click Play

You can also play with FFplay by explicitly setting the streamid:

```bash
ffplay 'srt://127.0.0.1:10080?streamid=#!::r=live/livestream,m=request'
```

The key difference between clients is how the SRS stream ID is supplied. FFmpeg, FFplay, and OBS can
include it in their URL or settings. VLC 3.0.17 and later can send it through the separate
**SRT Stream ID** setting or the `--streamid` command-line option. If VLC sends no stream ID, SRS
falls back to `default_streamid`.

## Q&A

1. Does SRS support forwarding SRT streams to Nginx?

> Yes, it is supported. You can use OBS/FFmpeg to push SRT streams to SRS, and SRS will convert the SRT stream into the RTMP protocol. Then, you can convert RTMP to HLS, FLV, WebRTC, and also forward the RTMP stream to Nginx.

---

### Skills Internal Docs For Srs References Cpp Docs Doc Webrtc (`skills/internal-docs-for-srs/references/cpp-docs/doc/webrtc.md`)

---
title: WebRTC
sidebar_label: WebRTC
hide_title: false
hide_table_of_contents: false
---

# WebRTC

WebRTC is an online real-time communication solution open-sourced by Google. In simple terms, it is an 
internet audio and video conference system. As it follows the RFC standard protocol and is supported 
by browsers, its boundaries are constantly expanding. It is used in low-latency audio and video scenarios,
such as online meetings, live streaming video chat with guests, low-latency live broadcasts, remote 
robot control, remote desktop, cloud video game, smart doorbells, and live web page streaming.

WebRTC is essentially a standard for direct communication between two web browsers, mainly consisting
of signaling and media protocols. Signaling deals with the negotiation of capabilities between two
devices, such as supported encoding and decoding abilities. Media handles the encryption and low-latency
transmission of media packets between devices. In addition, WebRTC itself also implements audio processing
technologies like 3A, network congestion control such as NACK, FEC, and GCC, audio and video encoding
and decoding, as well as smooth and low-latency playback technologies.

```bash
+----------------+                        +----------------+
+    Browser     +----<--Signaling----->--+    Browser     +
+ (like Chrome)  +----<----Media----->----+ (like Chrome)  +
+----------------+                        +----------------+
```

> Note: WebRTC is now an official RFC standard, so it is supported by various browsers. There are many
> open-source implementations, making it available not only in browsers but also in mobile browsers and
> native libraries. For simplicity, in this post, the term "browser" refers to any client or device that
> supports the WebRTC protocol.

In reality, on the internet, it's almost impossible for two browsers to communicate directly, especially 
when they're not on the same local network and are located far apart, like in different cities or countries. 
The data transfer between the two browsers goes through many network routers and firewalls, making it hard 
to ensure good transmission quality. Therefore, in practical applications, data needs to be relayed through 
servers. There are several types of WebRTC servers to help with this process:

* Signaling Server: This is a service that helps two browsers exchange SDP (Session Description Protocol) information. For multi-person conferences, room services are needed, but the main purpose is still to exchange SDP between browsers. In the streaming media field, to enable WebRTC for streaming and playback, similar to RTMP/SRT/HLS streaming, the WHIP/WHEP protocols have been designed.
* TURN Server: Relay service that helps two browsers forward media data between them. This is a transparent forwarding service without data caching, so during multi-person meetings, browsers need to transfer `N*N + N*(N-2)` copies of data. It is generally used in very few communication scenarios, such as one-on-one.
* SFU Server: Selective forwarding service with cached data on the server, allowing browsers to upload only one copy of data, which the server then replicates to other participants. SRS is an example of an SFU. For more information on SFU's role, refer to [this link](https://stackoverflow.com/a/75491178/17679565). Most current WebRTC servers are SFU servers, with `N*N` streams being transferred, reducing the amount of data transfer by `N*(N-2)` compared to TURN servers. This helps solve most transmission issues.
* MCU Server: Multipoint Control Unit Server, the server merges the streams in a conference into one, so the browser only needs to transfer `N*2` sets of data, uploading one and downloading one. However, due to the need for encoding and decoding, the number of streams supported by the server is an order of magnitude less than SFU, and it is only used in certain specific scenarios. For more details, refer to [#3625](https://github.com/ossrs/srs/discussions/3625).

We primarily focus on explaining the SFU (Selective Forwarding Unit) workflow, as it is widely used in
WebRTC servers, and it essentially functions like a browser:

```bash
+----------------+                        +---------+
+    Browser     +----<--Signaling----->--+   SFU   +
+ (like Chrome)  +----<----Media----->----+  Server +
+----------------+                        +---------+
```

> Note: Generally, SFUs have Signaling capabilities. In fact, RTMP addresses can be considered as a very
> simplified signaling protocol. However, WebRTC signaling requires more complex negotiation of media and
> transport capabilities. In complex WebRTC systems, there might be separate Signaling and Room clusters,
> but SFUs also have simplified Signaling capabilities, which may be used for communication with other
> services.

SRS is a media server that provides Signaling and SFU Server capabilities. Unlike other SFUs like Janus, 
SRS is based on streams. Even though there can be multiple participants in a room, essentially, someone is 
pushing a stream, and others are subscribing to it. This way, it avoids coupling all the streams in a room to 
a single SFU transmission and can distribute them across multiple SFU transmissions, allowing for larger 
conferences with more participants.

SRS supports signaling protocols WHIP and WHEP. For more details, please refer to the [HTTP API](#http-api) 
section. Unlike live streaming, signaling and media are separated, so you need to set up Candidates, see 
[Candidate](#config-candidate). Media uses UDP by default, but if UDP is unavailable, you can use TCP as described in 
[TCP](#webrtc-over-tcp). If you encounter issues, it could be due to incorrect Candidate settings or firewall/port 
restrictions, refer to [Connectivity](#connection-failures) and use the provided tools to check. SRS also supports 
converting between different protocols, such as streaming RTMP and viewing with WebRTC, as explained in 
[RTMP to WebRTC](#rtmp-to-rtc), or streaming with WebRTC and viewing with HLS, as described in 
[RTC to RTMP](#rtc-to-rtmp).

SRS supported the WebRTC protocol in 2020. For more information on the development process, please refer
to [#307](https://github.com/ossrs/srs/issues/307).

## Config

There are some config for WebRTC, please see `full.conf` for more:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The config `rtc_server` is global configuration for RTC, for example:
* `enabled`：Whether enable WebRTC server.
* `listen`：The udp listen port, we will reuse it for connections.
* `candidate`：The exposed candidate IPs, response in SDP candidate line. Please read [Config: Candidate](./webrtc.md#config-candidate) for detail.
* `tcp.listen`: Whether enable WebRTC over TCP. Please read [WebRTC over TCP](./webrtc.md#webrtc-over-tcp) for detail.

For each vhost, the configuration is `rtc` section, for example:
* `rtc.enabled`：Whether enable WebRTC server for this vhost.
* `rtc.rtmp_to_rtc`：Whether enable transmuxing RTMP to RTC.
* `rtc.rtc_to_rtmp`：Whether enable transmuxing RTC to RTMP.
* `rtc.stun_timeout`：The timeout in seconds for session timeout.
* `rtc.nack`：Whether support NACK for ARQ.
* `rtc.nack_prefer_rtx`：Whether to prefer RFC 4588 RTX over plain retransmission for a peer that offers it. Please read [Config: NACK and RTX](./webrtc.md#config-nack-and-rtx) for detail.
* `rtc.twcc`：Whether support TWCC for congestion feedback.
* `rtc.dtls_role`：The role of dtls when peer is actpass: passive or active.

## Config: Candidate

Please note that `candidate` is essential important, and most failure is caused by wrong `candidate`, so be careful.

The easiest method to modify the `candidate` involves indicating the `eip` in the URL. For instance, if your server 
is `192.168.3.10`, utilize this URL:

* [http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&eip=192.168.3.10](http://localhost:8080/players/whip.html?eip=192.168.3.10)

Moreover, the easiest and most direct method to modify the default UDP port `8000`, particularly when it is 
behind a load balancer or proxy, involves utilizing the `eip`. For example, if you employ UDP `18000` as the port, 
consider using this URL:

* [http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&eip=192.168.3.10:18000](http://localhost:8080/players/whip.html?eip=192.168.3.10:18000)

As it shows, `candidate` is server IP to connect to, SRS will response it in SDP answer as `candidate`, like this one:

```bash
type: answer, sdp: v=0
a=candidate:0 1 udp 2130706431 192.168.3.6 8000 typ host generation 0
```

So the `192.168.3.6 8000` is an endpoint that client could access. There be some IP you can use:
* Config as fixed IP, such as `candidate 192.168.3.6;`
* Use `ifconfig` to get server IP and pass by environment variable, such as `candidate $CANDIDATE;`
* Detect automatically, first by environment, then use server network interface IP, such as `candidate *;`, we will explain at bellow.
* Specify the `?eip=x` in URL, such as: `webrtc://192.168.3.6/live/livestream?eip=192.168.3.6`
* Normally API is provided by SRS, so you're able to use hostname of HTTP-API as `candidate`, we will explain at bellow.

Configurations for automatically detect the IP for `candidate`:
* `candidate *;` or `candidate 0.0.0.0;` means detect the network interface IP.
* `use_auto_detect_network_ip on;` If disabled, never detect the IP automatically.
* `ip_family ipv4;` To filter the IP if automatically detect.

Configurations for using HTTP-API hostname as `candidate`:
* `api_as_candidates on;` If disabled, never use HTTP API hostname as candidate.
* `resolve_api_domain on;` If hostname is domain name, resolve to IP address. Note that Firefox does not support domain name.
* `keep_api_domain on;` Whether keep the domain name to resolve it by client.

> Note: Please note that if no `candidate` specified, SRS will use one automatically detected IP.

In short, the `candidate` must be a IP address that client could connect to.

Use command `ifconfig` to retrieve the IP:

```bash
# For macOS
CANDIDATE=$(ifconfig en0 inet| grep 'inet '|awk '{print $2}')

# For CentOS
CANDIDATE=$(ifconfig eth0|grep 'inet '|awk '{print $2}')

# Directly set ip.
CANDIDATE="192.168.3.10"
```

Pass it to SRS by ENV:

```bash
env SRS_RTC_SERVER_CANDIDATE="192.168.3.10" \
  SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_SERVER_ENABLED=on \
  SRS_RTC_SERVER_ENABLED=on SRS_VHOST_RTC_ENABLED=on SRS_VHOST_HTTP_REMUX_ENABLED=on \
  ./objs/srs -e
```

Or use the config file with `candidate $CANDIDATE;`: `env CANDIDATE="192.168.3.10" ./objs/srs -c conf/rtc.conf`

For example, to run SRS in docker, and setup the CANDIDATE:

```bash
export CANDIDATE="192.168.3.10"
docker run --rm --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
  --env SRS_RTC_SERVER_ENABLED=on --env SRS_VHOST_RTC_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 8000:8000/udp \
  ossrs/srs:8 \
  objs/srs -e
```

> Note：About the usage of srs-docker, please read [srs-docker](https://github.com/ossrs/dev-docker/tree/v4#usage).

## Config: NACK and RTX

When a packet is lost, the receiver asks for it with an RTCP NACK, and the sender resends it. There are two ways to
resend:

* **Plain retransmission** sends the original packet again, on the same SSRC with the same sequence number, which the
  receiver cannot tell apart from the original.
* **RFC 4588 RTX** wraps the lost packet in a new packet on a separate RTX SSRC, with its own sequence number and
  payload type and the original sequence number, so the receiver can tell a retransmission from the original.

SRS supports both, in both directions of a session, and a per-vhost preference chooses which one it selects for a peer
that can do both:

```
vhost rtc.vhost.srs.com {
    rtc {
        nack on;
        # Whether to prefer RFC 4588 RTX when answering a NACK. This is a preference, not a
        # requirement: SRS never forces RTX on a peer that did not offer it.
        # default: off
        nack_prefer_rtx off;
    }
}
```

With `nack_prefer_rtx on`, SRS uses RTX for a peer that offers `rtx` and plain retransmission for one that does not.
With `nack_prefer_rtx off`, every peer gets plain retransmission, so you can test the fallback with the same client.
Only video uses RTX; browsers never offer `rtx` for audio.

When RTX is negotiated, the SDP answer carries the `rtx` payload and its FID group, and SRS resends lost packets on the
RTX SSRC.

## Stream URL

In SRS, both live streaming and WebRTC are based on the concept of `streams`. So, the URL definition for 
streams is very consistent. Here are some different stream addresses for various protocols in SRS, which 
you can access after installing SRS:

* Publish or play stream over RTMP: `rtmp://localhost/live/livestream`
* Play stream over HTTP-FLV: [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html)
* Play stream over HLS: [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?stream=livestream.m3u8)
* Publish stream over WHIP: [http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream](http://localhost:8080/players/whip.html)
* Play stream over WHEP: [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html)

> Remark: Since Flash is disabled, RTMP streams cannot be played in Chrome. Please use VLC to play them.

Before WHIP and WHEP were introduced, SRS supported another format with a different HTTP API format, but it 
still exchanged SDP. It is no longer recommended:

* Publish: [webrtc://localhost/live/livestream](http://localhost:8080/players/rtc_publisher.html)
* Play: [webrtc://localhost/live/livestream](http://localhost:8080/players/rtc_player.html)

> Note: SRT addresses are not provided here because their design is not in a common URL format.

## WebRTC over TCP

In many networks, UDP is not available for WebRTC, so TCP is very important to make it highly reliable. SRS supports directly TCP transport for WebRTC, not TURN, which introduce a complex network layer and system. It also makes the LoadBalancer possible to forward TCP packets, because TCP is more stable than UDP for LoadBalancer.

* All HTTP API, HTTP Stream and WebRTC over TCP reuses one TCP port, such as TCP(443) for HTTPS.
* Support directly transport over UDP or TCP, no dependency of TURN, no extra system and resource cost.
* Works very well with [Proxy(Not Implemented)](https://github.com/ossrs/srs/issues/3138) and [Cluster(Not Implemented)](https://github.com/ossrs/srs/issues/2091), for load balancing and system capacity.

Run SRS with WebRTC over TCP, by default the port is 8000:

```bash
docker run --rm -it -p 8080:8080 -p 1985:1985 -p 8000:8000 \
  -e CANDIDATE="192.168.3.82" \
  -e SRS_RTC_SERVER_TCP_ENABLED=on \
  -e SRS_RTC_SERVER_PROTOCOL=tcp \
  -e SRS_RTC_SERVER_TCP_LISTEN=8000 \
  ossrs/srs:v5
```

Please use [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/download) to publish stream:

```bash
ffmpeg -re -i ./doc/source.flv -c copy -f flv rtmp://localhost/live/livestream
```

* Play WebRTC over TCP: [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html?autostart=true)
* Play HTTP FLV: [http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true)
* Play HLS: [http://localhost:8080/live/livestream.m3u8](http://localhost:8080/players/srs_player.html?stream=livestream.m3u8&autostart=true)

> Note: We config SRS by environment variables, you're able to use config file also.

> Note: We use dedicated TCP port, for example, HTTP API(1985), HTTP Stream(8080) and WebRTC over TCP(8000), you're able to reuse one TCP port at HTTP Stream(8080).

## HTTP API

SRS supports WHIP and WHEP protocols. After installing SRS, you can test it with the following links:

* To use WHIP for streaming: [http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream](http://localhost:8080/players/whip.html)
* To use WHEP for playback: [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html)

For details on the protocols, refer to [WHIP](./http-api.md#webrtc-publish) and [WHEP](./http-api.md#webrtc-play).
Bellow is the workflow:

[](https://www.figma.com/file/fA75Nl6Fr6v8hsrJba5Xrn/How-Does-WHIP%2FWHEP-Work%3F?type=whiteboard&node-id=0-1)

### Authentication

SRS optionally supports Bearer authentication for WHIP and WHEP signaling. It
is disabled for RTC by default. Enable `http_api.auth`, set its type to
`bearer`, configure a token, and explicitly enable RTC Bearer authentication:

```bash
env SRS_RTMP_LISTEN=1935 SRS_HTTP_API_ENABLED=on SRS_HTTP_SERVER_ENABLED=on \
    SRS_RTC_SERVER_ENABLED=on SRS_VHOST_RTC_ENABLED=on SRS_VHOST_HTTP_REMUX_ENABLED=on \
    SRS_HTTP_API_AUTH_ENABLED=on \
    SRS_HTTP_API_AUTH_TYPE=bearer \
    SRS_HTTP_API_AUTH_TOKEN=srs-api-token \
    SRS_HTTP_API_AUTH_RTC_BEARER_ENABLED=on \
    ./objs/srs -e
```

The WHIP or WHEP client must send the token in the HTTP request:

```text
Authorization: Bearer srs-api-token
```

Basic authentication does not apply to WHIP or WHEP. When RTC Bearer
authentication is disabled, SRS can use HTTP callbacks alone for WebRTC
authorization: `on_publish` handles WHIP publishing and `on_play` handles WHEP
playback. Bearer authentication and HTTP callbacks can also be enabled together;
the request must first pass Bearer authentication and then be accepted by the
callback. See [HTTP API Authentication](./http-api.md#authentication) and
[HTTP Callback](./http-callback.md).

If you install SRS on a Mac or Linux, you can test the local SRS service with localhost. However, if you're using 
Windows, a remote Linux server, or need to test on other devices, you must use HTTPS for WHIP streaming, while 
WHEP can still use HTTP. To enable SRS HTTPS, refer to [HTTPS API](./http-api.md#https-api), or use a web server 
proxy like Nginx by referring to [HTTPS Proxy](./http-api.md#http-and-https-proxy).

If you need to test if the HTTP API is working properly, you can use the `curl` tool. For more details, please
refer to [Connectivity Check](#connection-failures).

## Connection Failures

Some developer come to SRS community to get help, because they get error when use OBS WHIP to connect to online WHIP
server, because online server must use HTTPS and the UDP port might be more available, and it's hard to debug or
login to the online server for privacy or network issue.

So we find some ways to troubleshoot the connection failures in OBS WHIP, generally it's caused by HTTPS API setup
or UDP port not available issue.

Use curl to test WHIP HTTP or HTTPS API:

```bash
curl "http://localhost:1985/rtc/v1/whip/?ice-ufrag=6pk11386&ice-pwd=l91z529147ri9163933p51c4&app=live&stream=livestream-$(date +%s)" \
  -H 'Origin: http://localhost' -H 'Referer: http://localhost' \
  -H 'Accept: */*' -H 'Content-type: application/sdp' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' \
  --data-raw $'v=0\r\na=group:BUNDLE 0 1\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:J8X7\r\na=ice-pwd:Dpq7/fW/osYcPeLsCW2Ek1JH\r\na=setup:actpass\r\na=mid:0\r\na=sendonly\r\na=msid:- audio\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=ssrc:3184534672 cname:stream\r\nm=video 9 UDP/TLS/RTP/SAVPF 106\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:J8X7\r\na=ice-pwd:Dpq7/fW/osYcPeLsCW2Ek1JH\r\na=setup:actpass\r\na=mid:1\r\na=sendonly\r\na=msid:- video\r\na=rtcp-mux\r\na=rtpmap:106 H264/90000\r\na=ssrc:512761356 cname:stream' \
  -v -k
```

> Note: You can replace `http://localhost` with `https://yourdomain.com` to test HTTPS API.

> Note: For Oryx, you should specify the secret, so please change the `/rtc/v1/whip?ice-ufrag=` to `/rtc/v1/whip?secret=xxx&ice-ufrag=` as such.

> Note: You can also use `eip=ip` or `eip=ip:port` to force SRS to use it as the candidate. Please see [CANDIDATE](#config-candidate) for details.

The answer contains the candidate, the UDP server IP, such as `127.0.0.1`:

```
a=candidate:0 1 udp 2130706431 127.0.0.1 8000 typ host generation 0
```

Use `nc` to send UDP packet to SRS WHIP server:

```bash
echo -en "\x00\x01\x00\x50\x21\x12\xa4\x42\x74\x79\x6d\x7a\x41\x51\x2b\x2f\x4a\x4b\x77\x52\x00\x06\x00\x0d\x36\x70\x6b\x31\x31\x33\x38\x36\x3a\x4a\x38\x58\x37\x00\x00\x00\xc0\x57\x00\x04\x00\x01\x00\x0a\x80\x2a\x00\x08\xda\xad\x1d\xce\xe8\x95\x5a\x83\x00\x24\x00\x04\x6e\x7f\x1e\xff\x00\x08\x00\x14\x56\x8f\x1e\x1e\x4f\x5f\x17\xf9\x2e\xa1\xec\xbd\x51\xd9\xa2\x27\xe4\xfd\xda\xb1\x80\x28\x00\x04\x84\xd3\x5a\x79" \
  |nc -w 3 -u 127.0.0.1 8000 |od -Ax -c -t x1 |grep '000' && \
  echo "Success" || echo "Failed"
```

> Note: You also can use `nc` or [server.go](https://github.com/ossrs/srs/pull/3837) as the UDP server for test.

If use SRS as WHIP server, should response with:

```
0000000  001 001  \0   @   ! 022 244   B   t   y   m   z   A   Q   +   /
0000010    J   K   w   R  \0 006  \0  \r   6   p   k   1   1   3   8   6
0000020    :   J   8   X   7  \0  \0  \0  \0      \0  \b  \0 001 376   `
0000030    ầ  **  ** 027  \0  \b  \0 024 206 263   +   ŉ  ** 025   G 215
0000040    I 335   P   ^   "   7   }   N   ? 017 037 224 200   (  \0 004
0000050  303   < 250 272                                                
0000054
Success
```

> Note: Should be SRS 5.0.191+, see [#3837](https://github.com/ossrs/srs/pull/3837), you can also use
> [server.go](https://github.com/ossrs/srs/issues/2843) as the UDP server for test.

## RTMP to RTC

Please enable RTMP to WebRTC, or use `conf/rtmp2rtc.conf` as config.

```bash
export CANDIDATE="192.168.1.10"
docker run --rm --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
  --env SRS_RTC_SERVER_ENABLED=on --env SRS_VHOST_RTC_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  --env SRS_VHOST_RTC_RTMP_TO_RTC=on --env SRS_VHOST_RTC_RTC_TO_RTMP=on \
  -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 8000:8000/udp \
  ossrs/srs:8 \
  objs/srs -e
```

> Note: Please set CANDIDATE as the ip of server, please read [CANDIDATE](./webrtc.md#config-candidate).

Use FFmpeg docker to push to localhost:

```bash
docker run --rm -it ossrs/srs:encoder ffmpeg -stream_loop -1 -re -i doc/source.flv \
  -c copy -f flv rtmp://host.docker.internal/live/livestream
```

Play the stream in browser:

* WebRTC：[http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html?autostart=true)
* HTTP-FLV：[http://localhost:8080/live/livestream.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=livestream.flv&port=8080&schema=http)

## RTC to RTC

Please enable WebRTC, or use `conf/rtc.conf` as config.

```bash
export CANDIDATE="192.168.1.10"
docker run --rm --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
  --env SRS_RTC_SERVER_ENABLED=on --env SRS_VHOST_RTC_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 8000:8000/udp \
  ossrs/srs:8 \
  objs/srs -e
```

> Note: Please set CANDIDATE as the ip of server, please read [CANDIDATE](./webrtc.md#config-candidate).

Play the stream in browser:

* Publish stream over WHIP: [http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream](http://localhost:8080/players/whip.html)
* Play stream over WHEP: [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html)

> Remark: Note that if not localhost, the WebRTC publisher should be HTTPS page.

## RTC to RTMP

Please enable WebRTC to RTMP, or use `conf/rtc2rtmp.conf` as config.

```bash
export CANDIDATE="192.168.1.10"
docker run --rm --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
  --env SRS_RTC_SERVER_ENABLED=on --env SRS_VHOST_RTC_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  --env SRS_VHOST_RTC_RTMP_TO_RTC=on --env SRS_VHOST_RTC_RTC_TO_RTMP=on \
  -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 8000:8000/udp \
  ossrs/srs:8 \
  objs/srs -e
```

> Note: Please set CANDIDATE as the ip of server, please read [CANDIDATE](./webrtc.md#config-candidate).

The streams:

* Publish stream over WHIP: [http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream](http://localhost:8080/players/whip.html)
* Play stream over WHEP: [http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream](http://localhost:8080/players/whep.html)
* HTTP-FLV：[http://localhost:8080/live/show.flv](http://localhost:8080/players/srs_player.html?autostart=true&stream=show.flv)
* RTMP by VLC：rtmp://localhost/live/show

## AV1 Codec Support

SRS supports AV1 codec for WebRTC-to-WebRTC streaming since v4.0.91 ([#2324](https://github.com/ossrs/srs/pull/2324)).
AV1 is a royalty-free codec that saves 30-50% bandwidth compared to H.264. SRS implements AV1 as relay-only (SFU mode),
accepting AV1 streams via WHIP and forwarding to WHEP players without transcoding. AV1 streams cannot be converted to
RTMP/HLS or recorded to DVR.

To use AV1, add the `codec=av1` query parameter to WHIP/WHEP URLs:

* Publish: `http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&codec=av1`
* Play: `http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream&codec=av1`

Browser support: Chrome/Edge M90+, Firefox (full support), Safari (decode only). Use H.264 if you need RTMP/HLS conversion,
DVR recording, or maximum compatibility.

## VP9 Codec Support

SRS supports VP9 codec for WebRTC-to-WebRTC streaming since v7.0.123 ([#4548](https://github.com/ossrs/srs/issues/4548)).
VP9 is a royalty-free codec that saves 20-40% bandwidth compared to H.264. VP9 works better than H.264/H.265 with congestion control
in WebRTC, making it ideal for keeping streams live under network fluctuations. SRS implements VP9 as relay-only (SFU mode),
accepting VP9 streams via WHIP and forwarding to WHEP players without transcoding. VP9 streams cannot be converted to
RTMP/HLS or recorded to DVR.

To use VP9, add the `codec=vp9` query parameter to WHIP/WHEP URLs:

* Publish: `http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&codec=vp9`
* Play: `http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream&codec=vp9`

Browser support: Chrome/Edge M29+, Firefox M28+, Opera M16+. Safari does not support VP9. Use H.264 if you need RTMP/HLS conversion,
DVR recording, or Safari compatibility.

## G.711 Codec Support

SRS supports G.711 (PCMU/PCMA) audio codec for WebRTC since v7.0.124 ([#4075](https://github.com/ossrs/srs/issues/4075)).
G.711 is a widely-used, royalty-free audio codec with excellent compatibility across VoIP systems, IP cameras, and legacy telephony equipment.
SRS implements G.711 as relay-only (SFU mode), accepting G.711 audio streams via WHIP and forwarding to WHEP players without transcoding.
G.711 streams cannot be converted to RTMP/HLS or recorded to DVR.

To use G.711, add the `acodec=pcmu` or `acodec=pcma` query parameter to WHIP/WHEP URLs:

* Publish with PCMU: `http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&acodec=pcmu`
* Play with PCMU: `http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream&acodec=pcmu`
* Publish with PCMA: `http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&acodec=pcma`

You can also combine video and audio codec parameters:

* VP9 + PCMU: `http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&vcodec=vp9&acodec=pcmu`
* H.264 + PCMA: `http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream&vcodec=h264&acodec=pcma`

Browser support: All major browsers support G.711 (PCMU/PCMA). PCMU (μ-law) is prioritized over PCMA (A-law) when both are available.
Use Opus if you need RTMP/HLS conversion or DVR recording.

## SFU: One to One

Please enable WebRTC, or use `conf/rtc.conf` as config.

```bash
export CANDIDATE="192.168.1.10"
docker run --rm --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
  --env SRS_RTC_SERVER_ENABLED=on --env SRS_VHOST_RTC_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 8000:8000/udp \
  ossrs/srs:8 \
  objs/srs -e
```

> Note: Please set CANDIDATE as the ip of server, please read [CANDIDATE](./webrtc.md#config-candidate).

Then startup the signaling, please read [usage](https://github.com/ossrs/signaling#usage):

```bash
docker run --rm -p 1989:1989 ossrs/signaling:1
```

Use HTTPS proxy [httpx-static](https://github.com/ossrs/go-oryx/tree/develop/httpx-static#usage) as api gateway:

```bash
export CANDIDATE="192.168.1.10"
docker run --rm -p 80:80 -p 443:443 ossrs/httpx:1 \
    ./bin/httpx-static -http 80 -https 443 -ssk ./etc/server.key -ssc ./etc/server.crt \
          -proxy http://$CANDIDATE:1989/sig -proxy http://$CANDIDATE:1985/rtc \
          -proxy http://$CANDIDATE:8080/
```

To open [http://localhost/demos/one2one.html?autostart=true](http://localhost/demos/one2one.html?autostart=true)

Or by the IP [https://192.168.3.6/demos/one2one.html?autostart=true](https://192.168.3.6/demos/one2one.html?autostart=true)

> Note: For self-sign certificate, please type `thisisunsafe` to accept it.

## SFU: Video Room

Please follow [SFU: One to One](./webrtc.md#sfu-one-to-one), and open the bellow demo pages.

To open [http://localhost/demos/room.html?autostart=true](http://localhost/demos/room.html?autostart=true)

Or by the IP [https://192.168.3.6/demos/room.html?autostart=true](https://192.168.3.6/demos/room.html?autostart=true)

> Note: For self-sign certificate, please type `thisisunsafe` to accept it.

## Room to Live

Please follow [SFU: One to One](./webrtc.md#sfu-one-to-one), and please convert RTC to RTMP, for FFmpeg to mix the streams.

```bash
export CANDIDATE="192.168.1.10"
docker run --rm --env SRS_RTC_SERVER_CANDIDATE=$CANDIDATE \
  --env SRS_RTMP_LISTEN=1935 --env SRS_HTTP_API_ENABLED=on --env SRS_HTTP_SERVER_ENABLED=on \
  --env SRS_RTC_SERVER_ENABLED=on --env SRS_VHOST_RTC_ENABLED=on --env SRS_VHOST_HTTP_REMUX_ENABLED=on \
  --env SRS_VHOST_RTC_RTMP_TO_RTC=on --env SRS_VHOST_RTC_RTC_TO_RTMP=on \
  -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 8000:8000/udp \
  ossrs/srs:8 \
  objs/srs -e
```

If use FFmpeg to mix streams, there is a FFmpeg CLI on the demo page, for example:

```bash
ffmpeg -f flv -i rtmp://192.168.3.6/live/alice -f flv -i rtmp://192.168.3.6/live/314d0336 \
     -filter_complex "[1:v]scale=w=96:h=72[ckout];[0:v][ckout]overlay=x=W-w-10:y=H-h-10[out]" -map "[out]" \
     -c:v libx264 -profile:v high -preset medium \
     -filter_complex amix -c:a aac \
     -f flv rtmp://192.168.3.6/live/merge
```

Input:
* rtmp://192.168.3.6/live/alice
* rtmp://192.168.3.6/live/314d0336

Output:
* rtmp://192.168.3.6/live/merge

Winlin 2020.02

## IPv6

SRS (v7.0.67+) supports IPv6 for WebRTC protocols, enabling dual-stack (IPv4/IPv6) operation for both UDP and TCP media transport. This includes support for WHIP/WHEP signaling and media transmission over IPv6.

IPv6 support is enabled automatically when SRS detects IPv6 addresses in the configuration. Configure the RTC server to listen on IPv6 addresses:

```bash
rtc_server {
    enabled on;
    # Listen on both IPv4 and IPv6 for UDP media
    listen 8000 [::]:8000;

    # For WebRTC over TCP
    tcp {
        enabled on;
        listen 8000 [::]:8000;
    }
}

# HTTP API server for WHIP/WHEP over IPv6
http_api {
    enabled on;
    listen 1985 [::]:1985;
}

# HTTPS API server for secure WHIP/WHEP over IPv6
https_api {
    enabled on;
    listen 1990 [::]:1990;
    key ./conf/server.key;
    cert ./conf/server.crt;
}
```

Publish using WHIP via IPv6:
- WHIP URL: `http://[::1]:1985/rtc/v1/whip/?app=live&stream=livestream`
- Test page: [http://[::1]:8080/players/whip.html](http://[::1]:8080/players/whip.html)

Play using WHEP via IPv6:
- WHEP URL: `http://[::1]:1985/rtc/v1/whep/?app=live&stream=livestream`
- Test page: [http://[::1]:8080/players/whep.html](http://[::1]:8080/players/whep.html)

For secure connections over IPv6:

Publish using WHIP via HTTPS IPv6:
- WHIP URL: `https://[::1]:1990/rtc/v1/whip/?app=live&stream=livestream`
- Test page: [https://[::1]:8088/players/whip.html](https://[::1]:8088/players/whip.html)

Play using WHEP via HTTPS IPv6:
- WHEP URL: `https://[::1]:1990/rtc/v1/whep/?app=live&stream=livestream`
- Test page: [https://[::1]:8088/players/whep.html](https://[::1]:8088/players/whep.html)

SRS supports dual-stack WebRTC, allowing both IPv4 and IPv6 clients to connect simultaneously:

```bash
rtc_server {
    enabled on;
    # Listen on both IPv4 and IPv6
    listen 8000 [::]:8000;

    # Configure candidates for both protocols
    candidate 192.168.1.100 [2001:db8::1];
}
```

This enables:
- IPv4 clients to connect via: `http://192.168.1.100:1985/rtc/v1/whip/`
- IPv6 clients to connect via: `http://[2001:db8::1]:1985/rtc/v1/whip/`

## Known Limitation: Initial Audio Loss

When publishing WebRTC streams, you may notice that the **first 4-6 seconds of audio are missing** in recordings (DVR),
RTMP playback, or HTTP-FLV streams. This is a **known limitation** of WebRTC's audio/video synchronization mechanism,
not a bug.

**Root Cause**: WebRTC uses RTCP Sender Reports (SR) to synchronize audio and video timestamps. When a WebRTC stream
starts, both audio and video RTP packets arrive immediately. However, SRS needs RTCP Sender Reports to calculate proper
timestamps for synchronizing audio and video. The A/V sync calculation requires **TWO** RTCP Sender Reports to establish
the timing rate between RTP timestamps and system time. All RTP packets (both audio and video) with `avsync_time <= 0`
are **discarded** to avoid timestamp problems in the live source. RTCP Sender Reports typically arrive every 2-3 seconds.
After the **second** SR arrives (~4-6 seconds), the A/V sync rate is calculated, and packets start being accepted. If DVR
is configured with `dvr_wait_keyframe on`, recording starts at the first video keyframe anyway. Video keyframes typically
arrive every 2-4 seconds, so by the time the first keyframe arrives, A/V sync is often already established. However, audio
packets that arrived before sync was established are **permanently lost**.

**Why This Won't Be Fixed**: This is a **fundamental limitation** of WebRTC's A/V synchronization mechanism. The RTCP-based
A/V synchronization is essential for WebRTC. Without it, audio and video timestamps would be misaligned, causing severe sync
issues throughout the entire stream. The current design prioritizes **correct A/V synchronization** over capturing the first
few seconds. This is a reasonable trade-off for most live streaming scenarios where streams run for extended periods (minutes
to hours), losing 4-6 seconds at the start is acceptable, and perfect A/V sync throughout the stream is critical. Fixing this
would require fundamentally redesigning the WebRTC A/V sync mechanism, which is extremely complex and risky.

**Related Issues**: [#4418](https://github.com/ossrs/srs/issues/4418), [#4151](https://github.com/ossrs/srs/issues/4151),
[#4076](https://github.com/ossrs/srs/issues/4076)

---

--- METRICS ---
- Files Extracted: 94
- Estimated Token Budget: ~183647 tokens
- Canonical Reference: https://codewiki.google/github.com/ossrs/srs
