mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Merge 3.0release
This commit is contained in:
commit
341d1e9aab
30 changed files with 1430 additions and 138 deletions
|
@ -2,13 +2,13 @@ version: 2
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
docker:
|
docker:
|
||||||
- image: ossrs/dev
|
- image: ossrs/srs:dev
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: cd trunk && ./configure && make
|
- run: cd trunk && ./configure && make
|
||||||
test:
|
test:
|
||||||
docker:
|
docker:
|
||||||
- image: ossrs/dev
|
- image: ossrs/srs:dev
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: cd trunk && ./configure --gcov && make && ./objs/srs_utest && bash auto/coverage.sh
|
- run: cd trunk && ./configure --gcov && make && ./objs/srs_utest && bash auto/coverage.sh
|
||||||
|
|
21
.github/ISSUE_TEMPLATE/---.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/---.md
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
name: 提功能
|
||||||
|
about: 提功能需求,支持新的特性。
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**你的功能是解决某个问题?**
|
||||||
|
请详细描述你的问题,例如在使用现有功能时碰到了困难。
|
||||||
|
|
||||||
|
**描述你期望的解决方案**
|
||||||
|
请详细描述你期望发生什么事情。
|
||||||
|
|
||||||
|
**请描述你考虑过的实现方法**
|
||||||
|
请描述你考虑过的实现方法。
|
||||||
|
|
||||||
|
**环境**
|
||||||
|
1. SRS的版本:'...'
|
||||||
|
1. 操作系统:'...'
|
37
.github/ISSUE_TEMPLATE/-bug.md
vendored
Normal file
37
.github/ISSUE_TEMPLATE/-bug.md
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
name: 提Bug
|
||||||
|
about: 描述一个Bug帮助改进系统
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**描述**
|
||||||
|
描述你遇到了什么问题。
|
||||||
|
|
||||||
|
**环境**
|
||||||
|
1. 操作系统:```...```
|
||||||
|
1. 编码器(工具和版本):```...```
|
||||||
|
1. 播放器(工具和版本):```...```
|
||||||
|
1. SRS版本: ```...```
|
||||||
|
1. SRS的日志如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
......
|
||||||
|
```
|
||||||
|
|
||||||
|
**重现**
|
||||||
|
重现Bug的步骤如下:
|
||||||
|
1. 启动SRS,运行 ```...```
|
||||||
|
1. 推流,运行 ```...```
|
||||||
|
1. 播放,运行 ```...```
|
||||||
|
1. 操作 ```...```
|
||||||
|
1. 重现了Bug,关键信息如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**期望行为**
|
||||||
|
描述你期望发生的事情。
|
175
README.md
175
README.md
|
@ -1,44 +1,19 @@
|
||||||
# Simple-RTMP-Server
|
# SRS
|
||||||
|
|
||||||
|

|
||||||
[](https://circleci.com/gh/ossrs/srs/tree/develop)
|
[](https://circleci.com/gh/ossrs/srs/tree/develop)
|
||||||
[](https://codecov.io/gh/ossrs/srs/branch/develop)
|
[](https://codecov.io/gh/ossrs/srs/branch/develop)
|
||||||
[](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
|
[](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
|
||||||
|
|
||||||
SRS/3.0,[OuXuli][release3],是一个简单的流媒体直播集群,简单的快乐。<br/>
|
SRS/3.0,[OuXuli][release3],是一个简单的流媒体直播集群,简单的快乐。<br/>
|
||||||
SRS is a simple live streaming cluster, a simple joy.
|
SRS(Simple RTMP Server) is a simple live streaming cluster, a simple joy.
|
||||||
|
|
||||||
Download binaries from github.io: [Centos6-x86_64][centos0], [more...][more0]<br/>
|
|
||||||
Download binaries from ossrs.net: [Centos6-x86_64][centos1], [more...][more1]<br/>
|
|
||||||
About the wiki of SRS/3.0, please read [Chinese][srs_CN] or [English][srs_EN].
|
|
||||||
|
|
||||||
> Remark: Although SRS is licenced under [MIT][LICENSE], but there are some depended libraries which are distributed using their own licenses, please read [License Mixing][LicenseMixing].
|
> Remark: Although SRS is licenced under [MIT][LICENSE], but there are some depended libraries which are distributed using their own licenses, please read [License Mixing][LicenseMixing].
|
||||||
|
|
||||||
Enjoy it!
|
|
||||||
|
|
||||||
## Content
|
|
||||||
|
|
||||||
* [Usage](#usage)
|
|
||||||
* [Wiki](#srs-30-wiki)
|
|
||||||
* [Features](#features)
|
|
||||||
* [v3.0 changes](#v3-changes)
|
|
||||||
* [v2.0 changes](#v2-changes)
|
|
||||||
* [v1.0 changes](#v1-changes)
|
|
||||||
* [Releases](#releases)
|
|
||||||
* [Compare](#compare)
|
|
||||||
* [Performance](#performance)
|
|
||||||
* [Architecture](#architecture)
|
|
||||||
* [System Architecture](#system-architecture)
|
|
||||||
* [Modularity Architecture](#modularity-architecture)
|
|
||||||
* [Stream Architecture](#stream-architecture)
|
|
||||||
* [Authors](#authors)
|
|
||||||
* [Mirrors](#mirrors)
|
|
||||||
* [System Requirements](#system-requirements)
|
|
||||||
|
|
||||||
<a name="product"></a>
|
<a name="product"></a>
|
||||||
|
## Usage
|
||||||
|
|
||||||
### Usage
|
**Step 1:** Get SRS.
|
||||||
|
|
||||||
<strong>Step 1:</strong> Get SRS.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/ossrs/srs &&
|
git clone https://github.com/ossrs/srs &&
|
||||||
|
@ -47,21 +22,29 @@ cd srs/trunk
|
||||||
|
|
||||||
> Note: Repository too large? Please clone from these [mirrors](#mirrors) instead.
|
> Note: Repository too large? Please clone from these [mirrors](#mirrors) instead.
|
||||||
|
|
||||||
<strong>Step 2:</strong> Build SRS.
|
**Step 2:** Build SRS.
|
||||||
|
|
||||||
```
|
```
|
||||||
./configure && make
|
./configure && make
|
||||||
```
|
```
|
||||||
|
|
||||||
> Remark: Recommend Centos6 64bits, for other OS recommend [docker][docker], please read wiki([CN][v3_CN_Build],[EN][v3_EN_Build]).
|
> Remark: Recommend Centos6 64bits, please read wiki([CN][v3_CN_Build],[EN][v3_EN_Build]).
|
||||||
|
|
||||||
<strong>Step 3:</strong> Run SRS
|
> Note: You can also build SRS in docker, please read [docker][docker-dev].
|
||||||
|
|
||||||
|
**Step 3:** Run SRS
|
||||||
|
|
||||||
```
|
```
|
||||||
./objs/srs -c conf/srs.conf
|
./objs/srs -c conf/srs.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
<strong>From here, </strong> strongly recommend to try other main use-scenarios:
|
**Whatever**, you can also directly run SRS in [docker][docker-srs3]:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 ossrs/srs:3
|
||||||
|
```
|
||||||
|
|
||||||
|
**From here,** strongly recommend to read bellow wikis:
|
||||||
|
|
||||||
* Usage: How to delivery RTMP?([CN][v1_CN_SampleRTMP], [EN][v1_EN_SampleRTMP])
|
* Usage: How to delivery RTMP?([CN][v1_CN_SampleRTMP], [EN][v1_EN_SampleRTMP])
|
||||||
* Usage: How to delivery RTMP Edge Cluster?([CN][v3_CN_SampleRTMPCluster], [EN][v3_EN_SampleRTMPCluster])
|
* Usage: How to delivery RTMP Edge Cluster?([CN][v3_CN_SampleRTMPCluster], [EN][v3_EN_SampleRTMPCluster])
|
||||||
|
@ -78,14 +61,24 @@ cd srs/trunk
|
||||||
* Usage: How to publish h.264 raw stream as RTMP? ([CN][v3_CN_SrsLibrtmp2], [EN][v3_EN_SrsLibrtmp2])
|
* Usage: How to publish h.264 raw stream as RTMP? ([CN][v3_CN_SrsLibrtmp2], [EN][v3_EN_SrsLibrtmp2])
|
||||||
* Usage: How to improve edge performance by multiple CPUs? ([CN][v3_CN_REUSEPORT], [EN][v3_EN_REUSEPORT])
|
* Usage: How to improve edge performance by multiple CPUs? ([CN][v3_CN_REUSEPORT], [EN][v3_EN_REUSEPORT])
|
||||||
* Usage: Why choose SRS? About the milestone and product plan? ([CN][v1_CN_Product], [EN][v1_EN_Product])
|
* Usage: Why choose SRS? About the milestone and product plan? ([CN][v1_CN_Product], [EN][v1_EN_Product])
|
||||||
|
* Usage: How to file bug or chat with us? ([CN][v1_CN_Contact], [EN][v1_EN_Contact])
|
||||||
|
|
||||||
### SRS 3.0 wiki
|
<a name="srs-30-wiki"></a>
|
||||||
|
## Wiki
|
||||||
|
|
||||||
Please select according to languages:
|
Please select according to languages:
|
||||||
* [SRS 3.0 English][v3_EN_Home]
|
|
||||||
* [SRS 3.0 Chinese][v3_CN_Home]
|
|
||||||
|
|
||||||
### Features
|
* [SRS 3.0 English Wiki][v3_EN_Home]
|
||||||
|
* [SRS 3.0 Chinese Wiki][v3_CN_Home]
|
||||||
|
|
||||||
|
For previous versions, please read:
|
||||||
|
|
||||||
|
* [SRS 2.0 English Wiki][v2_EN_Home]
|
||||||
|
* [SRS 2.0 Chinese Wiki][v2_CN_Home]
|
||||||
|
* [SRS 1.0 English Wiki][v1_EN_Home]
|
||||||
|
* [SRS 1.0 Chinese Wiki][v1_CN_Home]
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
- [x] Using coroutine by ST, it's really simple and stupid enough.
|
- [x] Using coroutine by ST, it's really simple and stupid enough.
|
||||||
- [x] Support cluster which consists of origin ([CN][v1_CN_DeliveryRTMP],[EN][v1_EN_DeliveryRTMP]) and edge([CN][v3_CN_Edge], [EN][v3_EN_Edge]) server and uses RTMP as default transport protocol.
|
- [x] Support cluster which consists of origin ([CN][v1_CN_DeliveryRTMP],[EN][v1_EN_DeliveryRTMP]) and edge([CN][v3_CN_Edge], [EN][v3_EN_Edge]) server and uses RTMP as default transport protocol.
|
||||||
|
@ -152,8 +145,14 @@ Please select according to languages:
|
||||||
<a name="history"></a>
|
<a name="history"></a>
|
||||||
<a name="change-logs"></a>
|
<a name="change-logs"></a>
|
||||||
|
|
||||||
### V3 changes
|
## V3 changes
|
||||||
|
|
||||||
|
* <strong>v3.0, 2019-11-30, [3.0 alpha2(3.0.67)][r3.0a3] released. 110864 lines.</strong>
|
||||||
|
* v3.0, 2019-12-01, Fix [#1501][bug #1501], use request coworker for origin cluster. 3.0.67
|
||||||
|
* <strong>v3.0, 2019-11-30, [3.0 alpha2(3.0.66)][r3.0a2] released. 110831 lines.</strong>
|
||||||
|
* v3.0, 2019-11-30, Fix [#1501][bug #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-30, Cover protocol stack RTMP. 3.0.63
|
||||||
* v3.0, 2019-10-23, Cover JSON codec. 3.0.62
|
* v3.0, 2019-10-23, Cover JSON codec. 3.0.62
|
||||||
* v3.0, 2019-10-13, Use http://ossrs.net:8000 as homepage.
|
* v3.0, 2019-10-13, Use http://ossrs.net:8000 as homepage.
|
||||||
|
@ -223,8 +222,10 @@ Please select according to languages:
|
||||||
* v3.0, 2015-08-28, fix [#471][bug #471], api response the width and height. 3.0.2
|
* v3.0, 2015-08-28, fix [#471][bug #471], api response the width and height. 3.0.2
|
||||||
* v3.0, 2015-08-25, fix [#367][bug #367], support nginx-rtmp exec. 3.0.1
|
* v3.0, 2015-08-25, fix [#367][bug #367], support nginx-rtmp exec. 3.0.1
|
||||||
|
|
||||||
### V2 changes
|
## V2 changes
|
||||||
|
|
||||||
|
* <strong>v2.0, 2019-11-29, [2.0 release7(2.0.265)][r2.0r7] 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][bug #1304], Default HSTRS to on. 2.0.264
|
* v2.0, 2019-04-06, For [#1304][bug #1304], Default HSTRS to on. 2.0.264
|
||||||
* <strong>v2.0, 2019-04-05, [2.0 release6(2.0.263)][r2.0r6] released. 86994 lines.</strong>
|
* <strong>v2.0, 2019-04-05, [2.0 release6(2.0.263)][r2.0r6] released. 86994 lines.</strong>
|
||||||
* v2.0, 2019-04-05, Merge [#1312][bug #1312], Fix GCC7 build error, this statement may fall through. 2.0.263
|
* v2.0, 2019-04-05, Merge [#1312][bug #1312], Fix GCC7 build error, this statement may fall through. 2.0.263
|
||||||
|
@ -462,7 +463,7 @@ Please select according to languages:
|
||||||
* v2.0, 2014-10-18, remove supports for OSX(darwin). 2.0.1.
|
* 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.
|
* v2.0, 2014-10-16, revert github srs README to English. 2.0.0.
|
||||||
|
|
||||||
### V1 changes
|
## V1 changes
|
||||||
|
|
||||||
* <strong>v1.0, 2014-12-05, [1.0 release(1.0.10)][r1.0r0] released. 59391 lines.</strong>
|
* <strong>v1.0, 2014-12-05, [1.0 release(1.0.10)][r1.0r0] released. 59391 lines.</strong>
|
||||||
* <strong>v1.0, 2014-10-09, [1.0 beta(1.0.0)][r1.0b0] released. 59316 lines.</strong>
|
* <strong>v1.0, 2014-10-09, [1.0 beta(1.0.0)][r1.0b0] released. 59316 lines.</strong>
|
||||||
|
@ -652,8 +653,10 @@ Please select according to languages:
|
||||||
* v0.1, 2013-10-18, support rtmp message2chunk protocol(send\_message).
|
* v0.1, 2013-10-18, support rtmp message2chunk protocol(send\_message).
|
||||||
* v0.1, 2013-10-17, support rtmp chunk2message protocol(recv\_message).
|
* v0.1, 2013-10-17, support rtmp chunk2message protocol(recv\_message).
|
||||||
|
|
||||||
### Releases
|
## Releases
|
||||||
|
|
||||||
|
* 2019-11-30, [Release v3.0-a2][r3.0a3], 3.0 alpha2, 3.0.67, 110864 lines.
|
||||||
|
* 2019-11-30, [Release v3.0-a2][r3.0a2], 3.0 alpha2, 3.0.66, 110831 lines.
|
||||||
* 2019-10-07, [Release v3.0-a1][r3.0a1], 3.0 alpha1, 3.0.60, 107962 lines.
|
* 2019-10-07, [Release v3.0-a1][r3.0a1], 3.0 alpha1, 3.0.60, 107962 lines.
|
||||||
* 2019-10-04, [Release v3.0-a0][r3.0a0], 3.0 alpha0, 3.0.56, 107946 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.
|
* 2017-03-03, [Release v2.0-r0][r2.0r0], 2.0 release0, 2.0.234, 86373 lines.
|
||||||
|
@ -689,11 +692,12 @@ Please select according to languages:
|
||||||
* 2013-10-23, [Release v0.1.0][r0.1], support [rtmp FMLE/FFMPEG publish][v1_CN_DeliveryRTMP], vp6. 8287 lines.
|
* 2013-10-23, [Release v0.1.0][r0.1], support [rtmp FMLE/FFMPEG publish][v1_CN_DeliveryRTMP], vp6. 8287 lines.
|
||||||
* 2013-10-17, Created.
|
* 2013-10-17, Created.
|
||||||
|
|
||||||
### Compare
|
## Compare
|
||||||
|
|
||||||
Comparing with other media servers, SRS is much better and stronger, for details please read Product([CN][v1_CN_Compare]/[EN][v1_EN_Compare]).
|
Comparing with other media servers, SRS is much better and stronger, for details please read Product([CN][v1_CN_Compare]/[EN][v1_EN_Compare]).
|
||||||
|
|
||||||
#### Stream Delivery
|
<a name="stream-delivery"></a>
|
||||||
|
**Stream Delivery**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
|
@ -705,7 +709,8 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
||||||
| MPEG-DASH | Experiment| X | X | X | X |
|
| MPEG-DASH | Experiment| X | X | X | X |
|
||||||
| HTTP Server | Stable | Stable | X | X | Stable |
|
| HTTP Server | Stable | Stable | X | X | Stable |
|
||||||
|
|
||||||
#### Cluster
|
<a name="cluster"></a>
|
||||||
|
**Cluster**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
|
@ -715,8 +720,10 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
||||||
| Reload | Stable | X | X | X | X |
|
| Reload | Stable | X | X | X | X |
|
||||||
| Forward | Stable | X | X | X | X |
|
| Forward | Stable | X | X | X | X |
|
||||||
| ATC | Stable | X | X | X | X |
|
| ATC | Stable | X | X | X | X |
|
||||||
|
| Docker | Stable | X | X | X | X |
|
||||||
|
|
||||||
#### Stream Service
|
<a name="stream-service"></a>
|
||||||
|
**Stream Service**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
|
@ -732,7 +739,8 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
||||||
| Security | Stable | Stable | X | X | Stable |
|
| Security | Stable | Stable | X | X | Stable |
|
||||||
| Token Traverse| Stable | X | X | Stable | X |
|
| Token Traverse| Stable | X | X | Stable | X |
|
||||||
|
|
||||||
#### Efficiency
|
<a name="efficiency"></a>
|
||||||
|
**Efficiency**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
|
@ -741,7 +749,8 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
||||||
| RTMP Latency| 0.1s | 3s | 3s | 3s | 3s |
|
| RTMP Latency| 0.1s | 3s | 3s | 3s | 3s |
|
||||||
| HLS Latency | 10s | 30s | X | 30s | 30s |
|
| HLS Latency | 10s | 30s | X | 30s | 30s |
|
||||||
|
|
||||||
#### Stream Caster
|
<a name="stream-caster"></a>
|
||||||
|
**Stream Caster**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
|
@ -750,21 +759,24 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
||||||
| Push RTSP | Experiment| X | Stable | X | Stable |
|
| Push RTSP | Experiment| X | Stable | X | Stable |
|
||||||
| Push HTTP FLV | Experiment| X | X | X | X |
|
| Push HTTP FLV | Experiment| X | X | X | X |
|
||||||
|
|
||||||
#### Debug System
|
<a name="debug-system"></a>
|
||||||
|
**Debug System**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
| BW check | Stable | X | X | X | X |
|
| BW check | Stable | X | X | X | X |
|
||||||
| Tracable Log | Stable | X | X | X | X |
|
| Tracable Log | Stable | X | X | X | X |
|
||||||
|
|
||||||
#### Docs
|
<a name="docs"></a>
|
||||||
|
**Docs**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
| Demos | Stable | X | X | X | X |
|
| Demos | Stable | X | X | X | X |
|
||||||
| WIKI(EN+CN) | Stable | EN only | X | X | Stable |
|
| WIKI(EN+CN) | Stable | EN only | X | X | Stable |
|
||||||
|
|
||||||
#### Others
|
<a name="others"></a>
|
||||||
|
**Others**
|
||||||
|
|
||||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||||
|
@ -780,15 +792,16 @@ Remark:
|
||||||
1. Security: The security includes access control, token authentication and referer check.
|
1. Security: The security includes access control, token authentication and referer check.
|
||||||
1. Reload: SRS and Nginx supports reload, but nginx-rtmp doesn't.
|
1. Reload: SRS and Nginx supports reload, but nginx-rtmp doesn't.
|
||||||
|
|
||||||
### Performance
|
## Performance
|
||||||
|
|
||||||
The performance benchmark data and corelative commits are listed here.
|
The performance benchmark data and corelative commits are listed here.
|
||||||
|
|
||||||
* See also: [Performance for x86/x64 Test Guide][v1_CN_Performance].
|
* See also: [Performance for x86/x64 Test Guide][v1_CN_Performance].
|
||||||
* See also: [Performance for RaspberryPi][v1_CN_RaspberryPi].
|
* See also: [Performance for RaspberryPi][v1_CN_RaspberryPi].
|
||||||
* For multiple processes performance, read [#775: REUSEPORT][bug #775] or OriginCluster([CN](v3_EN_OriginCluster)/[EN](v3_EN_OriginCluster)) or [go-oryx][oryx].
|
* For multiple processes performance, read [#775: REUSEPORT][bug #775] or OriginCluster([CN][v3_EN_OriginCluster]/[EN][v3_EN_OriginCluster]) or [go-oryx][oryx].
|
||||||
|
|
||||||
#### Play RTMP benchmark
|
<a name="play-rtmp-benchmark"></a>
|
||||||
|
**Play RTMP benchmark**
|
||||||
|
|
||||||
The data for playing RTMP was benchmarked by [SB][srs-bench]:
|
The data for playing RTMP was benchmarked by [SB][srs-bench]:
|
||||||
|
|
||||||
|
@ -808,7 +821,8 @@ The data for playing RTMP was benchmarked by [SB][srs-bench]:
|
||||||
| 2014-12-05 | 2.0.57 | 9.0k(9000) | players | 90% | 468MB | [code][p11] |
|
| 2014-12-05 | 2.0.57 | 9.0k(9000) | players | 90% | 468MB | [code][p11] |
|
||||||
| 2014-12-07 | 2.0.67 | 10k(10000) | players | 95% | 656MB | [code][p12] |
|
| 2014-12-07 | 2.0.67 | 10k(10000) | players | 95% | 656MB | [code][p12] |
|
||||||
|
|
||||||
#### Publish RTMP benchmark
|
<a name="publish-rtmp-benchmark"></a>
|
||||||
|
**Publish RTMP benchmark**
|
||||||
|
|
||||||
The data for publishing RTMP was benchmarked by [SB][srs-bench]:
|
The data for publishing RTMP was benchmarked by [SB][srs-bench]:
|
||||||
|
|
||||||
|
@ -824,7 +838,8 @@ The data for publishing RTMP was benchmarked by [SB][srs-bench]:
|
||||||
| 2014-12-04 | 2.0.51 | 2.5k(2500) | publishers | 91% | 259MB | [code][p4] |
|
| 2014-12-04 | 2.0.51 | 2.5k(2500) | publishers | 91% | 259MB | [code][p4] |
|
||||||
| 2014-12-04 | 2.0.52 | 4.0k(4000) | publishers | 80% | 331MB | [code][p5] |
|
| 2014-12-04 | 2.0.52 | 4.0k(4000) | publishers | 80% | 331MB | [code][p5] |
|
||||||
|
|
||||||
#### Play HTTP FLV benchmark
|
<a name="play-http-flv-benchmark"></a>
|
||||||
|
**Play HTTP FLV benchmark**
|
||||||
|
|
||||||
The data for playing HTTP FLV was benchmarked by [SB][srs-bench]:
|
The data for playing HTTP FLV was benchmarked by [SB][srs-bench]:
|
||||||
|
|
||||||
|
@ -837,7 +852,8 @@ The data for playing HTTP FLV was benchmarked by [SB][srs-bench]:
|
||||||
| 2014-05-24 | 2.0.170 | 3.0k(3000) | players | 89% | 96MB | [code][p19] |
|
| 2014-05-24 | 2.0.170 | 3.0k(3000) | players | 89% | 96MB | [code][p19] |
|
||||||
| 2014-05-25 | 2.0.171 | 6.0k(6000) | players | 84% | 297MB | [code][p20] |
|
| 2014-05-25 | 2.0.171 | 6.0k(6000) | players | 84% | 297MB | [code][p20] |
|
||||||
|
|
||||||
#### Latency benchmark
|
<a name="latency-benchmark"></a>
|
||||||
|
**Latency benchmark**
|
||||||
|
|
||||||
The latency between encoder and player with realtime config([CN][v3_CN_LowLatency], [EN][v3_EN_LowLatency]):
|
The latency between encoder and player with realtime config([CN][v3_CN_LowLatency], [EN][v3_EN_LowLatency]):
|
||||||
|
|
|
|
||||||
|
@ -854,7 +870,8 @@ We used FMLE as encoder for benchmark. The latency of server was 0.1s+,
|
||||||
and the bottleneck was the encoder. For more information, read
|
and the bottleneck was the encoder. For more information, read
|
||||||
[bug #257][bug #257-c0].
|
[bug #257][bug #257-c0].
|
||||||
|
|
||||||
#### HLS overhead
|
<a name="hls-overhead"></a>
|
||||||
|
**HLS overhead**
|
||||||
|
|
||||||
About the overhead of HLS overhead, we compared FFMPEG and SRS.
|
About the overhead of HLS overhead, we compared FFMPEG and SRS.
|
||||||
|
|
||||||
|
@ -890,7 +907,7 @@ SRS always use the simplest architecture to solve complex domain problems.
|
||||||
* Modularity arch: the main modularity of SRS.
|
* Modularity arch: the main modularity of SRS.
|
||||||
* Stream arch: the stream dispatch arch of SRS.
|
* Stream arch: the stream dispatch arch of SRS.
|
||||||
|
|
||||||
### System Architecture
|
## System Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
+------------------------------------------------------+
|
+------------------------------------------------------+
|
||||||
|
@ -908,7 +925,7 @@ SRS always use the simplest architecture to solve complex domain problems.
|
||||||
+------------------------------------------------------+
|
+------------------------------------------------------+
|
||||||
```
|
```
|
||||||
|
|
||||||
### Modularity Architecture
|
## Modularity Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
+------------------------------------------------------+
|
+------------------------------------------------------+
|
||||||
|
@ -930,7 +947,7 @@ Remark:
|
||||||
|
|
||||||
1. Modules: SRS supports code-level modularity, read [modules][modules].
|
1. Modules: SRS supports code-level modularity, read [modules][modules].
|
||||||
|
|
||||||
### Stream Architecture
|
## Stream Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
+---------+ +----------+
|
+---------+ +----------+
|
||||||
|
@ -972,7 +989,7 @@ Remark:
|
||||||
1. Streamer: Remuxs other protocols to RTMP, please read [Streamer][v2_CN_Streamer].
|
1. Streamer: Remuxs other protocols to RTMP, please read [Streamer][v2_CN_Streamer].
|
||||||
1. EXEC: Like NGINX-RTMP, EXEC forks external tools for events, please read [ng-exec][v3_CN_NgExec].
|
1. EXEC: Like NGINX-RTMP, EXEC forks external tools for events, please read [ng-exec][v3_CN_NgExec].
|
||||||
|
|
||||||
### AUTHORS
|
## AUTHORS
|
||||||
|
|
||||||
There are two types of people that have contributed to the SRS project:
|
There are two types of people that have contributed to the SRS project:
|
||||||
|
|
||||||
|
@ -992,12 +1009,12 @@ A big THANK YOU goes to:
|
||||||
* [FFMPEG][FFMPEG] and [libx264][libx264] group for SRS to use as transcoder.
|
* [FFMPEG][FFMPEG] and [libx264][libx264] group for SRS to use as transcoder.
|
||||||
* Guido van Rossum for creating Python for api-server for SRS.
|
* Guido van Rossum for creating Python for api-server for SRS.
|
||||||
|
|
||||||
### Mirrors
|
## Mirrors
|
||||||
|
|
||||||
OSChina: [http://git.oschina.net/winlinvip/srs.oschina][oschina], the GIT usage([CN][v1_CN_Git], [EN][v1_EN_Git])
|
OSChina: [https://gitee.com/winlinvip/srs.oschina][oschina], the GIT usage([CN][v1_CN_Git], [EN][v1_EN_Git])
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://git.oschina.net/winlinvip/srs.oschina.git
|
git clone https://gitee.com/winlinvip/srs.oschina.git
|
||||||
```
|
```
|
||||||
|
|
||||||
> Remark: For users in China, recomment to use mirror from CSDN or OSChina, because they are much faster.
|
> Remark: For users in China, recomment to use mirror from CSDN or OSChina, because they are much faster.
|
||||||
|
@ -1014,13 +1031,12 @@ Gitlab: [https://gitlab.com/winlinvip/srs-gitlab][gitlab], the GIT usage([CN][v1
|
||||||
git clone https://gitlab.com/winlinvip/srs-gitlab.git
|
git clone https://gitlab.com/winlinvip/srs-gitlab.git
|
||||||
```
|
```
|
||||||
|
|
||||||
### System Requirements
|
## System Requirements
|
||||||
|
|
||||||
Supported operating systems and hardware:
|
Supported operating systems and hardware:
|
||||||
|
|
||||||
* All Linux, both 32 and 64 bits
|
* All Linux, both 32 and 64 bits
|
||||||
* Apple OSX(Darwin), both 32 and 64bits.
|
* Other OS, such as Windows, please use [docker][docker-srs3].
|
||||||
* All hardwares with x86/x86_64/arm/mips cpu.
|
|
||||||
|
|
||||||
Beijing, 2013.10<br/>
|
Beijing, 2013.10<br/>
|
||||||
Winlin
|
Winlin
|
||||||
|
@ -1064,7 +1080,7 @@ Winlin
|
||||||
[libx264]: http://www.videolan.org/
|
[libx264]: http://www.videolan.org/
|
||||||
[srs]: https://github.com/ossrs/srs
|
[srs]: https://github.com/ossrs/srs
|
||||||
[csdn]: https://code.csdn.net/winlinvip/srs-csdn
|
[csdn]: https://code.csdn.net/winlinvip/srs-csdn
|
||||||
[oschina]: http://git.oschina.net/winlinvip/srs.oschina
|
[oschina]: https://gitee.com/winlinvip/srs.oschina
|
||||||
[srs-dolphin]: https://github.com/ossrs/srs-dolphin
|
[srs-dolphin]: https://github.com/ossrs/srs-dolphin
|
||||||
[oryx]: https://github.com/ossrs/go-oryx
|
[oryx]: https://github.com/ossrs/go-oryx
|
||||||
[srs-bench]: https://github.com/ossrs/srs-bench
|
[srs-bench]: https://github.com/ossrs/srs-bench
|
||||||
|
@ -1074,7 +1090,8 @@ Winlin
|
||||||
[console]: http://ossrs.net:1985/console
|
[console]: http://ossrs.net:1985/console
|
||||||
[player]: http://ossrs.net:8000/players/srs_player.html
|
[player]: http://ossrs.net:8000/players/srs_player.html
|
||||||
[modules]: https://github.com/ossrs/srs/blob/develop/trunk/modules/readme.txt
|
[modules]: https://github.com/ossrs/srs/blob/develop/trunk/modules/readme.txt
|
||||||
[docker]: https://github.com/ossrs/srs-docker/tree/centos#usage
|
[docker-srs3]: https://github.com/ossrs/srs-docker#srs3
|
||||||
|
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage
|
||||||
|
|
||||||
[v1_CN_Git]: https://github.com/ossrs/srs/wiki/v1_CN_Git
|
[v1_CN_Git]: https://github.com/ossrs/srs/wiki/v1_CN_Git
|
||||||
[v1_EN_Git]: https://github.com/ossrs/srs/wiki/v1_EN_Git
|
[v1_EN_Git]: https://github.com/ossrs/srs/wiki/v1_EN_Git
|
||||||
|
@ -1112,10 +1129,14 @@ Winlin
|
||||||
[v1_EN_Sample]: https://github.com/ossrs/srs/wiki/v1_EN_Sample
|
[v1_EN_Sample]: https://github.com/ossrs/srs/wiki/v1_EN_Sample
|
||||||
[v1_CN_Product]: https://github.com/ossrs/srs/wiki/v1_CN_Product
|
[v1_CN_Product]: https://github.com/ossrs/srs/wiki/v1_CN_Product
|
||||||
[v1_EN_Product]: https://github.com/ossrs/srs/wiki/v1_EN_Product
|
[v1_EN_Product]: https://github.com/ossrs/srs/wiki/v1_EN_Product
|
||||||
[v1-wiki-cn]: https://github.com/ossrs/srs/wiki/v1-wiki-cn
|
[v1-wiki-cn]: https://github.com/ossrs/srs/wiki/v1_CN_Home
|
||||||
[v1-wiki-en]: https://github.com/ossrs/srs/wiki/v1-wiki-en
|
[v1-wiki-en]: https://github.com/ossrs/srs/wiki/v1_EN_Home
|
||||||
[v2-wiki-cn]: https://github.com/ossrs/srs/wiki/v2-wiki-cn
|
[v2-wiki-cn]: https://github.com/ossrs/srs/wiki/v2_CN_Home
|
||||||
[v2-wiki-en]: https://github.com/ossrs/srs/wiki/v2-wiki-en
|
[v2-wiki-en]: https://github.com/ossrs/srs/wiki/v2_EN_Home
|
||||||
|
[v1_CN_Home]: https://github.com/ossrs/srs/wiki/v1_CN_Home
|
||||||
|
[v1_EN_Home]: https://github.com/ossrs/srs/wiki/v1_EN_Home
|
||||||
|
[v2_CN_Home]: https://github.com/ossrs/srs/wiki/v2_CN_Home
|
||||||
|
[v2_EN_Home]: https://github.com/ossrs/srs/wiki/v2_EN_Home
|
||||||
[v3_CN_Home]: https://github.com/ossrs/srs/wiki/v3_CN_Home
|
[v3_CN_Home]: https://github.com/ossrs/srs/wiki/v3_CN_Home
|
||||||
[v3_EN_Home]: https://github.com/ossrs/srs/wiki/v3_EN_Home
|
[v3_EN_Home]: https://github.com/ossrs/srs/wiki/v3_EN_Home
|
||||||
[donation0]: http://winlinvip.github.io/srs.release/donation/index.html
|
[donation0]: http://winlinvip.github.io/srs.release/donation/index.html
|
||||||
|
@ -1489,6 +1510,7 @@ Winlin
|
||||||
[bug #1087]: https://github.com/ossrs/srs/issues/1087
|
[bug #1087]: https://github.com/ossrs/srs/issues/1087
|
||||||
[bug #1051]: https://github.com/ossrs/srs/issues/1051
|
[bug #1051]: https://github.com/ossrs/srs/issues/1051
|
||||||
[bug #1093]: https://github.com/ossrs/srs/issues/1093
|
[bug #1093]: https://github.com/ossrs/srs/issues/1093
|
||||||
|
[bug #1501]: https://github.com/ossrs/srs/issues/1501
|
||||||
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
|
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
|
||||||
|
|
||||||
[bug #1111]: https://github.com/ossrs/srs/issues/1111
|
[bug #1111]: https://github.com/ossrs/srs/issues/1111
|
||||||
|
@ -1497,8 +1519,11 @@ Winlin
|
||||||
|
|
||||||
[exo #828]: https://github.com/google/ExoPlayer/pull/828
|
[exo #828]: https://github.com/google/ExoPlayer/pull/828
|
||||||
|
|
||||||
|
[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.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
|
||||||
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
|
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
|
||||||
|
[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.0r6]: https://github.com/ossrs/srs/releases/tag/v2.0-r6
|
||||||
[r2.0r5]: https://github.com/ossrs/srs/releases/tag/v2.0-r5
|
[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.0r4]: https://github.com/ossrs/srs/releases/tag/v2.0-r4
|
||||||
|
@ -1540,6 +1565,8 @@ Winlin
|
||||||
|
|
||||||
|
|
||||||
[contact]: https://github.com/ossrs/srs/wiki/v1_CN_Contact
|
[contact]: https://github.com/ossrs/srs/wiki/v1_CN_Contact
|
||||||
|
[v1_CN_Contact]: https://github.com/ossrs/srs/wiki/v1_CN_Contact
|
||||||
|
[v1_EN_Contact]: https://github.com/ossrs/srs/wiki/v1_EN_Contact
|
||||||
[more0]: http://winlinvip.github.io/srs.release/releases/
|
[more0]: http://winlinvip.github.io/srs.release/releases/
|
||||||
[more1]: http://ossrs.net:8000/srs.release/releases/
|
[more1]: http://ossrs.net:8000/srs.release/releases/
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/jwplayer'/>
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/osmf'/>
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/bwt'/>
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/chat'/>
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/srsplayer'/>
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/srspublisher'/>
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<img src='https://srs.cn-beijing.log.aliyuncs.com/logstores/ossrs-net/track_ua.gif?APIVersion=0.6.0&site=ossrs.net&path=/player/vlc'/>
|
||||||
<div class="navbar navbar-fixed-top">
|
<div class="navbar navbar-fixed-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -58,7 +58,7 @@ SrsCoWorkers* SrsCoWorkers::instance()
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsJsonAny* SrsCoWorkers::dumps(string vhost, string app, string stream)
|
SrsJsonAny* SrsCoWorkers::dumps(string vhost, string coworker, string app, string stream)
|
||||||
{
|
{
|
||||||
SrsRequest* r = find_stream_info(vhost, app, stream);
|
SrsRequest* r = find_stream_info(vhost, app, stream);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
|
@ -66,22 +66,42 @@ SrsJsonAny* SrsCoWorkers::dumps(string vhost, string app, string stream)
|
||||||
return SrsJsonAny::null();
|
return SrsJsonAny::null();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> service_ports = _srs_config->get_listens();
|
// The service port parsing from listen port.
|
||||||
if (service_ports.empty()) {
|
string listen_host;
|
||||||
return SrsJsonAny::null();
|
int listen_port = SRS_CONSTS_RTMP_DEFAULT_PORT;
|
||||||
}
|
vector<string> listen_hostports = _srs_config->get_listens();
|
||||||
|
if (!listen_hostports.empty()) {
|
||||||
|
string list_hostport = listen_hostports.at(0);
|
||||||
|
|
||||||
string service_ip = srs_get_public_internet_address();
|
if (list_hostport.find(":") != string::npos) {
|
||||||
string service_hostport = service_ports.at(0);
|
srs_parse_hostport(list_hostport, listen_host, listen_port);
|
||||||
|
|
||||||
int service_port = SRS_CONSTS_RTMP_DEFAULT_PORT;
|
|
||||||
if (service_hostport.find(":") != string::npos) {
|
|
||||||
string service_host;
|
|
||||||
srs_parse_hostport(service_hostport, service_host, service_port);
|
|
||||||
} else {
|
} else {
|
||||||
service_port = ::atoi(service_hostport.c_str());
|
listen_port = ::atoi(list_hostport.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The ip of server, we use the request coworker-host as ip, if listen host is localhost or loopback.
|
||||||
|
// For example, the server may behind a NAT(192.x.x.x), while its ip is a docker ip(172.x.x.x),
|
||||||
|
// we should use the NAT(192.x.x.x) address as it's the exposed ip.
|
||||||
|
// @see https://github.com/ossrs/srs/issues/1501
|
||||||
|
string service_ip;
|
||||||
|
if (listen_host != SRS_CONSTS_LOCALHOST && listen_host != SRS_CONSTS_LOOPBACK && listen_host != SRS_CONSTS_LOOPBACK6) {
|
||||||
|
service_ip = listen_host;
|
||||||
|
}
|
||||||
|
if (service_ip.empty()) {
|
||||||
|
int coworker_port;
|
||||||
|
string coworker_host = coworker;
|
||||||
|
if (coworker.find(":") != string::npos) {
|
||||||
|
srs_parse_hostport(coworker, coworker_host, coworker_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
service_ip = coworker_host;
|
||||||
|
}
|
||||||
|
if (service_ip.empty()) {
|
||||||
|
service_ip = srs_get_public_internet_address();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The backend API endpoint.
|
||||||
string backend = _srs_config->get_http_api_listen();
|
string backend = _srs_config->get_http_api_listen();
|
||||||
if (backend.find(":") == string::npos) {
|
if (backend.find(":") == string::npos) {
|
||||||
backend = service_ip + ":" + backend;
|
backend = service_ip + ":" + backend;
|
||||||
|
@ -90,9 +110,12 @@ SrsJsonAny* SrsCoWorkers::dumps(string vhost, string app, string stream)
|
||||||
// The routers to detect loop and identify path.
|
// The routers to detect loop and identify path.
|
||||||
SrsJsonArray* routers = SrsJsonAny::array()->append(SrsJsonAny::str(backend.c_str()));
|
SrsJsonArray* routers = SrsJsonAny::array()->append(SrsJsonAny::str(backend.c_str()));
|
||||||
|
|
||||||
|
srs_trace("Redirect vhost=%s, path=%s/%s to ip=%s, port=%d, api=%s",
|
||||||
|
vhost.c_str(), app.c_str(), stream.c_str(), service_ip.c_str(), listen_port, backend.c_str());
|
||||||
|
|
||||||
return SrsJsonAny::object()
|
return SrsJsonAny::object()
|
||||||
->set("ip", SrsJsonAny::str(service_ip.c_str()))
|
->set("ip", SrsJsonAny::str(service_ip.c_str()))
|
||||||
->set("port", SrsJsonAny::integer(service_port))
|
->set("port", SrsJsonAny::integer(listen_port))
|
||||||
->set("vhost", SrsJsonAny::str(r->vhost.c_str()))
|
->set("vhost", SrsJsonAny::str(r->vhost.c_str()))
|
||||||
->set("api", SrsJsonAny::str(backend.c_str()))
|
->set("api", SrsJsonAny::str(backend.c_str()))
|
||||||
->set("routers", routers);
|
->set("routers", routers);
|
||||||
|
|
|
@ -46,7 +46,7 @@ private:
|
||||||
public:
|
public:
|
||||||
static SrsCoWorkers* instance();
|
static SrsCoWorkers* instance();
|
||||||
public:
|
public:
|
||||||
virtual SrsJsonAny* dumps(std::string vhost, std::string app, std::string stream);
|
virtual SrsJsonAny* dumps(std::string vhost, std::string coworker, std::string app, std::string stream);
|
||||||
private:
|
private:
|
||||||
virtual SrsRequest* find_stream_info(std::string vhost, std::string app, std::string stream);
|
virtual SrsRequest* find_stream_info(std::string vhost, std::string app, std::string stream);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -100,11 +100,14 @@ srs_error_t SrsEdgeRtmpUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb)
|
||||||
string _schema, _vhost, _app, _stream, _param, _host;
|
string _schema, _vhost, _app, _stream, _param, _host;
|
||||||
srs_discovery_tc_url(redirect, _schema, _host, _vhost, _app, _stream, _port, _param);
|
srs_discovery_tc_url(redirect, _schema, _host, _vhost, _app, _stream, _port, _param);
|
||||||
|
|
||||||
srs_warn("RTMP redirect %s:%d to %s:%d stream=%s", server.c_str(), port, _host.c_str(), _port, _stream.c_str());
|
|
||||||
server = _host;
|
server = _host;
|
||||||
port = _port;
|
port = _port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remember the current selected server.
|
||||||
|
selected_ip = server;
|
||||||
|
selected_port = port;
|
||||||
|
|
||||||
// support vhost tranform for edge,
|
// support vhost tranform for edge,
|
||||||
// @see https://github.com/ossrs/srs/issues/372
|
// @see https://github.com/ossrs/srs/issues/372
|
||||||
std::string vhost = _srs_config->get_vhost_edge_transform_vhost(req->vhost);
|
std::string vhost = _srs_config->get_vhost_edge_transform_vhost(req->vhost);
|
||||||
|
@ -144,6 +147,12 @@ void SrsEdgeRtmpUpstream::close()
|
||||||
srs_freep(sdk);
|
srs_freep(sdk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsEdgeRtmpUpstream::selected(string& server, int& port)
|
||||||
|
{
|
||||||
|
server = selected_ip;
|
||||||
|
port = selected_port;
|
||||||
|
}
|
||||||
|
|
||||||
void SrsEdgeRtmpUpstream::set_recv_timeout(srs_utime_t tm)
|
void SrsEdgeRtmpUpstream::set_recv_timeout(srs_utime_t tm)
|
||||||
{
|
{
|
||||||
sdk->set_recv_timeout(tm);
|
sdk->set_recv_timeout(tm);
|
||||||
|
@ -160,7 +169,7 @@ SrsEdgeIngester::SrsEdgeIngester()
|
||||||
edge = NULL;
|
edge = NULL;
|
||||||
req = NULL;
|
req = NULL;
|
||||||
|
|
||||||
upstream = new SrsEdgeRtmpUpstream(redirect);
|
upstream = new SrsEdgeRtmpUpstream("");
|
||||||
lb = new SrsLbRoundRobin();
|
lb = new SrsLbRoundRobin();
|
||||||
trd = new SrsDummyCoroutine();
|
trd = new SrsDummyCoroutine();
|
||||||
}
|
}
|
||||||
|
@ -244,6 +253,7 @@ srs_error_t SrsEdgeIngester::do_cycle()
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
std::string redirect;
|
||||||
while (true) {
|
while (true) {
|
||||||
if ((err = trd->pull()) != srs_success) {
|
if ((err = trd->pull()) != srs_success) {
|
||||||
return srs_error_wrap(err, "do cycle pull");
|
return srs_error_wrap(err, "do cycle pull");
|
||||||
|
@ -252,10 +262,6 @@ srs_error_t SrsEdgeIngester::do_cycle()
|
||||||
srs_freep(upstream);
|
srs_freep(upstream);
|
||||||
upstream = new SrsEdgeRtmpUpstream(redirect);
|
upstream = new SrsEdgeRtmpUpstream(redirect);
|
||||||
|
|
||||||
// we only use the redict once.
|
|
||||||
// reset the redirect to empty, for maybe the origin changed.
|
|
||||||
redirect = "";
|
|
||||||
|
|
||||||
if ((err = source->on_source_id_changed(_srs_context->get_id())) != srs_success) {
|
if ((err = source->on_source_id_changed(_srs_context->get_id())) != srs_success) {
|
||||||
return srs_error_wrap(err, "on source id changed");
|
return srs_error_wrap(err, "on source id changed");
|
||||||
}
|
}
|
||||||
|
@ -268,10 +274,20 @@ srs_error_t SrsEdgeIngester::do_cycle()
|
||||||
return srs_error_wrap(err, "notify edge play");
|
return srs_error_wrap(err, "notify edge play");
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ingest();
|
// set to larger timeout to read av data from origin.
|
||||||
|
upstream->set_recv_timeout(SRS_EDGE_INGESTER_TIMEOUT);
|
||||||
|
|
||||||
|
err = ingest(redirect);
|
||||||
|
|
||||||
// retry for rtmp 302 immediately.
|
// retry for rtmp 302 immediately.
|
||||||
if (srs_error_code(err) == ERROR_CONTROL_REDIRECT) {
|
if (srs_error_code(err) == ERROR_CONTROL_REDIRECT) {
|
||||||
|
int port;
|
||||||
|
string server;
|
||||||
|
upstream->selected(server, port);
|
||||||
|
|
||||||
|
string url = req->get_stream_url();
|
||||||
|
srs_warn("RTMP redirect %s from %s:%d to %s", url.c_str(), server.c_str(), port, redirect.c_str());
|
||||||
|
|
||||||
srs_error_reset(err);
|
srs_error_reset(err);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -286,15 +302,16 @@ srs_error_t SrsEdgeIngester::do_cycle()
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsEdgeIngester::ingest()
|
srs_error_t SrsEdgeIngester::ingest(string& redirect)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
SrsPithyPrint* pprint = SrsPithyPrint::create_edge();
|
SrsPithyPrint* pprint = SrsPithyPrint::create_edge();
|
||||||
SrsAutoFree(SrsPithyPrint, pprint);
|
SrsAutoFree(SrsPithyPrint, pprint);
|
||||||
|
|
||||||
// set to larger timeout to read av data from origin.
|
// we only use the redict once.
|
||||||
upstream->set_recv_timeout(SRS_EDGE_INGESTER_TIMEOUT);
|
// reset the redirect to empty, for maybe the origin changed.
|
||||||
|
redirect = "";
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
@ -318,7 +335,7 @@ srs_error_t SrsEdgeIngester::ingest()
|
||||||
srs_assert(msg);
|
srs_assert(msg);
|
||||||
SrsAutoFree(SrsCommonMessage, msg);
|
SrsAutoFree(SrsCommonMessage, msg);
|
||||||
|
|
||||||
if ((err = process_publish_message(msg)) != srs_success) {
|
if ((err = process_publish_message(msg, redirect)) != srs_success) {
|
||||||
return srs_error_wrap(err, "process message");
|
return srs_error_wrap(err, "process message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,7 +343,7 @@ srs_error_t SrsEdgeIngester::ingest()
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg)
|
srs_error_t SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg, string& redirect)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,7 @@ public:
|
||||||
virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket) = 0;
|
virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket) = 0;
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
public:
|
public:
|
||||||
|
virtual void selected(std::string& server, int& port) = 0;
|
||||||
virtual void set_recv_timeout(srs_utime_t tm) = 0;
|
virtual void set_recv_timeout(srs_utime_t tm) = 0;
|
||||||
virtual void kbps_sample(const char* label, int64_t age) = 0;
|
virtual void kbps_sample(const char* label, int64_t age) = 0;
|
||||||
};
|
};
|
||||||
|
@ -91,6 +92,10 @@ private:
|
||||||
// use this <ip[:port]> as upstream.
|
// use this <ip[:port]> as upstream.
|
||||||
std::string redirect;
|
std::string redirect;
|
||||||
SrsSimpleRtmpClient* sdk;
|
SrsSimpleRtmpClient* sdk;
|
||||||
|
private:
|
||||||
|
// Current selected server, the ip:port.
|
||||||
|
std::string selected_ip;
|
||||||
|
int selected_port;
|
||||||
public:
|
public:
|
||||||
// @param rediect, override the server. ignore if empty.
|
// @param rediect, override the server. ignore if empty.
|
||||||
SrsEdgeRtmpUpstream(std::string r);
|
SrsEdgeRtmpUpstream(std::string r);
|
||||||
|
@ -101,6 +106,7 @@ public:
|
||||||
virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket);
|
virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket);
|
||||||
virtual void close();
|
virtual void close();
|
||||||
public:
|
public:
|
||||||
|
virtual void selected(std::string& server, int& port);
|
||||||
virtual void set_recv_timeout(srs_utime_t tm);
|
virtual void set_recv_timeout(srs_utime_t tm);
|
||||||
virtual void kbps_sample(const char* label, int64_t age);
|
virtual void kbps_sample(const char* label, int64_t age);
|
||||||
};
|
};
|
||||||
|
@ -115,8 +121,6 @@ private:
|
||||||
SrsCoroutine* trd;
|
SrsCoroutine* trd;
|
||||||
SrsLbRoundRobin* lb;
|
SrsLbRoundRobin* lb;
|
||||||
SrsEdgeUpstream* upstream;
|
SrsEdgeUpstream* upstream;
|
||||||
// For RTMP 302 redirect.
|
|
||||||
std::string redirect;
|
|
||||||
public:
|
public:
|
||||||
SrsEdgeIngester();
|
SrsEdgeIngester();
|
||||||
virtual ~SrsEdgeIngester();
|
virtual ~SrsEdgeIngester();
|
||||||
|
@ -131,8 +135,8 @@ public:
|
||||||
private:
|
private:
|
||||||
virtual srs_error_t do_cycle();
|
virtual srs_error_t do_cycle();
|
||||||
private:
|
private:
|
||||||
virtual srs_error_t ingest();
|
virtual srs_error_t ingest(std::string& redirect);
|
||||||
virtual srs_error_t process_publish_message(SrsCommonMessage* msg);
|
virtual srs_error_t process_publish_message(SrsCommonMessage* msg, std::string& redirect);
|
||||||
};
|
};
|
||||||
|
|
||||||
// The edge used to forward stream to origin.
|
// The edge used to forward stream to origin.
|
||||||
|
|
|
@ -1290,6 +1290,7 @@ srs_error_t SrsGoApiClusters::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
|
||||||
string vhost = r->query_get("vhost");
|
string vhost = r->query_get("vhost");
|
||||||
string app = r->query_get("app");
|
string app = r->query_get("app");
|
||||||
string stream = r->query_get("stream");
|
string stream = r->query_get("stream");
|
||||||
|
string coworker = r->query_get("coworker");
|
||||||
data->set("query", SrsJsonAny::object()
|
data->set("query", SrsJsonAny::object()
|
||||||
->set("ip", SrsJsonAny::str(ip.c_str()))
|
->set("ip", SrsJsonAny::str(ip.c_str()))
|
||||||
->set("vhost", SrsJsonAny::str(vhost.c_str()))
|
->set("vhost", SrsJsonAny::str(vhost.c_str()))
|
||||||
|
@ -1297,7 +1298,7 @@ srs_error_t SrsGoApiClusters::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess
|
||||||
->set("stream", SrsJsonAny::str(stream.c_str())));
|
->set("stream", SrsJsonAny::str(stream.c_str())));
|
||||||
|
|
||||||
SrsCoWorkers* coworkers = SrsCoWorkers::instance();
|
SrsCoWorkers* coworkers = SrsCoWorkers::instance();
|
||||||
data->set("origin", coworkers->dumps(vhost, app, stream));
|
data->set("origin", coworkers->dumps(vhost, coworker, app, stream));
|
||||||
|
|
||||||
return srs_api_response(w, r, obj->dumps());
|
return srs_api_response(w, r, obj->dumps());
|
||||||
}
|
}
|
||||||
|
@ -1342,7 +1343,7 @@ srs_error_t SrsHttpApi::do_cycle()
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
srs_trace("api get peer ip success. ip=%s", ip.c_str());
|
srs_trace("API server client, ip=%s", ip.c_str());
|
||||||
|
|
||||||
// initialize parser
|
// initialize parser
|
||||||
if ((err = parser->initialize(HTTP_REQUEST, true)) != srs_success) {
|
if ((err = parser->initialize(HTTP_REQUEST, true)) != srs_success) {
|
||||||
|
|
|
@ -610,7 +610,8 @@ srs_error_t SrsRtmpConn::playing(SrsSource* source)
|
||||||
int port;
|
int port;
|
||||||
string host;
|
string host;
|
||||||
string url = "http://" + coworkers.at(i) + "/api/v1/clusters?"
|
string url = "http://" + coworkers.at(i) + "/api/v1/clusters?"
|
||||||
+ "vhost=" + req->vhost + "&ip=" + req->host + "&app=" + req->app + "&stream=" + req->stream;
|
+ "vhost=" + req->vhost + "&ip=" + req->host + "&app=" + req->app + "&stream=" + req->stream
|
||||||
|
+ "&coworker=" + coworkers.at(i);
|
||||||
if ((err = SrsHttpHooks::discover_co_workers(url, host, port)) != srs_success) {
|
if ((err = SrsHttpHooks::discover_co_workers(url, host, port)) != srs_success) {
|
||||||
return srs_error_wrap(err, "discover coworkers, url=%s", url.c_str());
|
return srs_error_wrap(err, "discover coworkers, url=%s", url.c_str());
|
||||||
}
|
}
|
||||||
|
@ -1179,7 +1180,8 @@ srs_error_t SrsRtmpConn::do_token_traverse_auth(SrsRtmpClient* client)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for token tranverse, always take the debug info(which carries token).
|
// for token tranverse, always take the debug info(which carries token).
|
||||||
if ((err = client->connect_app(req->app, req->tcUrl, req, true, NULL)) != srs_success) {
|
SrsServerInfo si;
|
||||||
|
if ((err = client->connect_app(req->app, req->tcUrl, req, true, &si)) != srs_success) {
|
||||||
return srs_error_wrap(err, "rtmp: connect tcUrl");
|
return srs_error_wrap(err, "rtmp: connect tcUrl");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
// The version config.
|
// The version config.
|
||||||
#define VERSION_MAJOR 3
|
#define VERSION_MAJOR 3
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 63
|
#define VERSION_REVISION 67
|
||||||
|
|
||||||
// The macros generated by configure script.
|
// The macros generated by configure script.
|
||||||
#include <srs_auto_headers.hpp>
|
#include <srs_auto_headers.hpp>
|
||||||
|
|
|
@ -116,6 +116,8 @@
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
#define SRS_CONSTS_NULL_FILE "/dev/null"
|
#define SRS_CONSTS_NULL_FILE "/dev/null"
|
||||||
#define SRS_CONSTS_LOCALHOST "127.0.0.1"
|
#define SRS_CONSTS_LOCALHOST "127.0.0.1"
|
||||||
|
#define SRS_CONSTS_LOOPBACK "0.0.0.0"
|
||||||
|
#define SRS_CONSTS_LOOPBACK6 "::"
|
||||||
|
|
||||||
// The signal defines.
|
// The signal defines.
|
||||||
// To reload the config file and apply new config.
|
// To reload the config file and apply new config.
|
||||||
|
|
|
@ -81,7 +81,7 @@ std::string SrsCplxError::description() {
|
||||||
|
|
||||||
next = this;
|
next = this;
|
||||||
while (next) {
|
while (next) {
|
||||||
ss << "thread #" << next->cid << ": "
|
ss << "thread [" << next->cid << "]: "
|
||||||
<< next->func << "() [" << next->file << ":" << next->line << "]"
|
<< next->func << "() [" << next->file << ":" << next->line << "]"
|
||||||
<< "[errno=" << next->rerrno << "]";
|
<< "[errno=" << next->rerrno << "]";
|
||||||
|
|
||||||
|
|
|
@ -284,6 +284,11 @@ int SrsSharedPtrMessage::count()
|
||||||
|
|
||||||
bool SrsSharedPtrMessage::check(int stream_id)
|
bool SrsSharedPtrMessage::check(int stream_id)
|
||||||
{
|
{
|
||||||
|
// Ignore error when message has no payload.
|
||||||
|
if (!ptr) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// we donot use the complex basic header,
|
// we donot use the complex basic header,
|
||||||
// ensure the basic header is 1bytes.
|
// ensure the basic header is 1bytes.
|
||||||
if (ptr->header.perfer_cid < 2) {
|
if (ptr->header.perfer_cid < 2) {
|
||||||
|
|
|
@ -68,3 +68,8 @@ void SrsSimpleStream::append(const char* bytes, int size)
|
||||||
|
|
||||||
data.insert(data.end(), bytes, bytes + size);
|
data.insert(data.end(), bytes, bytes + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SrsSimpleStream::append(SrsSimpleStream* src)
|
||||||
|
{
|
||||||
|
append(src->bytes(), src->length());
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
* @remark assert size is positive.
|
* @remark assert size is positive.
|
||||||
*/
|
*/
|
||||||
virtual void append(const char* bytes, int size);
|
virtual void append(const char* bytes, int size);
|
||||||
|
virtual void append(SrsSimpleStream* src);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -231,9 +231,9 @@ string srs_any_address_for_listener()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ipv6_active && !ipv4_active) {
|
if (ipv6_active && !ipv4_active) {
|
||||||
return "::";
|
return SRS_CONSTS_LOOPBACK6;
|
||||||
}
|
}
|
||||||
return "0.0.0.0";
|
return SRS_CONSTS_LOOPBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void srs_parse_endpoint(string hostport, string& ip, int& port)
|
void srs_parse_endpoint(string hostport, string& ip, int& port)
|
||||||
|
|
|
@ -979,10 +979,8 @@ srs_error_t SrsProtocol::read_basic_header(char& fmt, int& cid)
|
||||||
// 2-63, 1B chunk header
|
// 2-63, 1B chunk header
|
||||||
if (cid > 1) {
|
if (cid > 1) {
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
// 64-319, 2B chunk header
|
// 64-319, 2B chunk header
|
||||||
if (cid == 0) {
|
} else if (cid == 0) {
|
||||||
if ((err = in_buffer->grow(skt, 1)) != srs_success) {
|
if ((err = in_buffer->grow(skt, 1)) != srs_success) {
|
||||||
return srs_error_wrap(err, "basic header requires 2 bytes");
|
return srs_error_wrap(err, "basic header requires 2 bytes");
|
||||||
}
|
}
|
||||||
|
@ -990,7 +988,9 @@ srs_error_t SrsProtocol::read_basic_header(char& fmt, int& cid)
|
||||||
cid = 64;
|
cid = 64;
|
||||||
cid += (uint8_t)in_buffer->read_1byte();
|
cid += (uint8_t)in_buffer->read_1byte();
|
||||||
// 64-65599, 3B chunk header
|
// 64-65599, 3B chunk header
|
||||||
} else if (cid == 1) {
|
} else {
|
||||||
|
srs_assert(cid == 1);
|
||||||
|
|
||||||
if ((err = in_buffer->grow(skt, 2)) != srs_success) {
|
if ((err = in_buffer->grow(skt, 2)) != srs_success) {
|
||||||
return srs_error_wrap(err, "basic header requires 3 bytes");
|
return srs_error_wrap(err, "basic header requires 3 bytes");
|
||||||
}
|
}
|
||||||
|
@ -998,9 +998,6 @@ srs_error_t SrsProtocol::read_basic_header(char& fmt, int& cid)
|
||||||
cid = 64;
|
cid = 64;
|
||||||
cid += (uint8_t)in_buffer->read_1byte();
|
cid += (uint8_t)in_buffer->read_1byte();
|
||||||
cid += ((uint8_t)in_buffer->read_1byte()) * 256;
|
cid += ((uint8_t)in_buffer->read_1byte()) * 256;
|
||||||
} else {
|
|
||||||
srs_error("invalid path, impossible basic header.");
|
|
||||||
srs_assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -43,7 +43,11 @@ SrsThreadContext::~SrsThreadContext()
|
||||||
|
|
||||||
int SrsThreadContext::generate_id()
|
int SrsThreadContext::generate_id()
|
||||||
{
|
{
|
||||||
static int id = 100;
|
static int id = 0;
|
||||||
|
|
||||||
|
if (id == 0) {
|
||||||
|
id = (100 + ((int)(int64_t)this)%1000);
|
||||||
|
}
|
||||||
|
|
||||||
int gid = id++;
|
int gid = id++;
|
||||||
cache[srs_thread_self()] = gid;
|
cache[srs_thread_self()] = gid;
|
||||||
|
|
|
@ -139,7 +139,8 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
|
||||||
// upnode server identity will show in the connect_app of client.
|
// upnode server identity will show in the connect_app of client.
|
||||||
// @see https://github.com/ossrs/srs/issues/160
|
// @see https://github.com/ossrs/srs/issues/160
|
||||||
// the debug_srs_upnode is config in vhost and default to true.
|
// the debug_srs_upnode is config in vhost and default to true.
|
||||||
if ((err = client->connect_app(req->app, tc_url, req, debug, NULL)) != srs_success) {
|
SrsServerInfo si;
|
||||||
|
if ((err = client->connect_app(req->app, tc_url, req, debug, &si)) != srs_success) {
|
||||||
return srs_error_wrap(err, "connect app tcUrl=%s, debug=%d", tc_url.c_str(), debug);
|
return srs_error_wrap(err, "connect app tcUrl=%s, debug=%d", tc_url.c_str(), debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ MockBufferIO::MockBufferIO()
|
||||||
{
|
{
|
||||||
rtm = stm = SRS_UTIME_NO_TIMEOUT;
|
rtm = stm = SRS_UTIME_NO_TIMEOUT;
|
||||||
rbytes = sbytes = 0;
|
rbytes = sbytes = 0;
|
||||||
|
in_err = out_err = srs_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
MockBufferIO::~MockBufferIO()
|
MockBufferIO::~MockBufferIO()
|
||||||
|
@ -109,6 +110,10 @@ MockBufferIO* MockBufferIO::append(string data)
|
||||||
|
|
||||||
srs_error_t MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
|
srs_error_t MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
|
||||||
{
|
{
|
||||||
|
if (in_err != srs_success) {
|
||||||
|
return srs_error_copy(in_err);
|
||||||
|
}
|
||||||
|
|
||||||
if (in_buffer.length() < (int)size) {
|
if (in_buffer.length() < (int)size) {
|
||||||
return srs_error_new(ERROR_SOCKET_READ, "read");
|
return srs_error_new(ERROR_SOCKET_READ, "read");
|
||||||
}
|
}
|
||||||
|
@ -124,6 +129,10 @@ srs_error_t MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread)
|
||||||
|
|
||||||
srs_error_t MockBufferIO::write(void* buf, size_t size, ssize_t* nwrite)
|
srs_error_t MockBufferIO::write(void* buf, size_t size, ssize_t* nwrite)
|
||||||
{
|
{
|
||||||
|
if (out_err != srs_success) {
|
||||||
|
return srs_error_copy(out_err);
|
||||||
|
}
|
||||||
|
|
||||||
sbytes += size;
|
sbytes += size;
|
||||||
if (nwrite) {
|
if (nwrite) {
|
||||||
*nwrite = size;
|
*nwrite = size;
|
||||||
|
@ -166,6 +175,10 @@ srs_error_t MockBufferIO::writev(const iovec *iov, int iov_size, ssize_t* nwrite
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
|
if (out_err != srs_success) {
|
||||||
|
return srs_error_copy(out_err);
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t total = 0;
|
ssize_t total = 0;
|
||||||
for (int i = 0; i <iov_size; i++) {
|
for (int i = 0; i <iov_size; i++) {
|
||||||
const iovec& pi = iov[i];
|
const iovec& pi = iov[i];
|
||||||
|
@ -187,6 +200,10 @@ srs_error_t MockBufferIO::writev(const iovec *iov, int iov_size, ssize_t* nwrite
|
||||||
|
|
||||||
srs_error_t MockBufferIO::read(void* buf, size_t size, ssize_t* nread)
|
srs_error_t MockBufferIO::read(void* buf, size_t size, ssize_t* nread)
|
||||||
{
|
{
|
||||||
|
if (in_err != srs_success) {
|
||||||
|
return srs_error_copy(in_err);
|
||||||
|
}
|
||||||
|
|
||||||
if (in_buffer.length() <= 0) {
|
if (in_buffer.length() <= 0) {
|
||||||
return srs_error_new(ERROR_SOCKET_READ, "read");
|
return srs_error_new(ERROR_SOCKET_READ, "read");
|
||||||
}
|
}
|
||||||
|
@ -199,6 +216,7 @@ srs_error_t MockBufferIO::read(void* buf, size_t size, ssize_t* nread)
|
||||||
*nread = available;
|
*nread = available;
|
||||||
}
|
}
|
||||||
in_buffer.erase(available);
|
in_buffer.erase(available);
|
||||||
|
|
||||||
return srs_success;
|
return srs_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,10 @@ public:
|
||||||
SrsSimpleStream in_buffer;
|
SrsSimpleStream in_buffer;
|
||||||
// data buffer for socket send.
|
// data buffer for socket send.
|
||||||
SrsSimpleStream out_buffer;
|
SrsSimpleStream out_buffer;
|
||||||
|
public:
|
||||||
|
// Mock error for io.
|
||||||
|
srs_error_t in_err;
|
||||||
|
srs_error_t out_err;
|
||||||
public:
|
public:
|
||||||
MockBufferIO();
|
MockBufferIO();
|
||||||
virtual ~MockBufferIO();
|
virtual ~MockBufferIO();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue