diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index bbcbbe7d6..000000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
-
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
-
-**Additional context**
-Add any other context or screenshots about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/issue_template.md
similarity index 100%
rename from .github/ISSUE_TEMPLATE/bug_report.md
rename to .github/issue_template.md
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index bb06d534e..9353fdf47 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -89,6 +89,8 @@ jobs:
docker push ossrs/srs:$SRS_TAG
docker tag ossrs/srs:$SRS_TAG ossrs/srs:$SRS_MAJOR
docker push ossrs/srs:$SRS_MAJOR
+ docker tag ossrs/srs:$SRS_TAG ossrs/srs:latest
+ docker push ossrs/srs:latest
# Aliyun ACR
- name: Login Aliyun docker hub
uses: aliyun/acr-login@v1
@@ -106,6 +108,8 @@ jobs:
docker push registry.cn-hangzhou.aliyuncs.com/ossrs/srs:v$SRS_MAJOR
docker tag ossrs/srs:$SRS_TAG registry.cn-hangzhou.aliyuncs.com/ossrs/srs:$SRS_MAJOR
docker push registry.cn-hangzhou.aliyuncs.com/ossrs/srs:$SRS_MAJOR
+ docker tag ossrs/srs:$SRS_TAG registry.cn-hangzhou.aliyuncs.com/ossrs/srs:latest
+ docker push registry.cn-hangzhou.aliyuncs.com/ossrs/srs:latest
################################################################
# K8S
@@ -132,10 +136,21 @@ jobs:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: |
- ${{ github.event.head_commit.message }}
+ [${{ github.event.head_commit.message }}](https://github.com/ossrs/srs/commit/${{ github.sha }})
## Resource
* Source: ${{ env.SRS_SOURCE_MD5 }} [${{ env.SRS_SOURCE_TAR }}](https://github.com/ossrs/srs/releases/download/${{ env.SRS_TAG }}/${{ env.SRS_SOURCE_TAR }})
* Binary: ${{ env.SRS_PACKAGE_MD5 }} [${{ env.SRS_PACKAGE_ZIP }}](https://github.com/ossrs/srs/releases/download/${{ env.SRS_TAG }}/${{ env.SRS_PACKAGE_ZIP }})
+ ## Docker
+ * China: [docker pull registry.cn-hangzhou.aliyuncs.com/ossrs/srs:latest](https://github.com/ossrs/srs/wiki/v4_CN_Home#docker)
+ * China: [docker pull registry.cn-hangzhou.aliyuncs.com/ossrs/srs:${{ env.SRS_MAJOR }}](https://github.com/ossrs/srs/wiki/v4_CN_Home#docker)
+ * China: [docker pull registry.cn-hangzhou.aliyuncs.com/ossrs/srs:${{ env.SRS_TAG }}](https://github.com/ossrs/srs/wiki/v4_CN_Home#docker)
+ * Global: [docker pull ossrs/srs:latest](https://github.com/ossrs/srs/wiki/v4_EN_Home#docker)
+ * Global: [docker pull ossrs/srs:${{ env.SRS_MAJOR }}](https://github.com/ossrs/srs/wiki/v4_EN_Home#docker)
+ * Global: [docker pull ossrs/srs:${{ env.SRS_TAG }}](https://github.com/ossrs/srs/wiki/v4_EN_Home#docker)
+ ## Doc
+ * [快速入门](https://github.com/ossrs/srs/wiki/v4_CN_Home#getting-started) or [Getting Started](https://github.com/ossrs/srs/wiki/v4_EN_Home#getting-started)
+ * [中文Wiki首页](https://github.com/ossrs/srs/wiki/v4_CN_Home) or [Wiki home](https://github.com/ossrs/srs/wiki/v4_EN_Home)
+ * [FAQ](https://github.com/ossrs/srs/issues/2716), [Features](https://github.com/ossrs/srs/blob/${{ github.sha }}/trunk/doc/Features.md#features) or [ChangeLogs](https://github.com/ossrs/srs/blob/${{ github.sha }}/trunk/doc/CHANGELOG.md#changelog)
draft: false
prerelease: false
# Upload release source files
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index b2ac7d659..1e1fa2525 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -12,7 +12,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v2
- # Build for CentOS7
+ # Build for CentOS 7
- name: Build on CentOS7, baseline
run: DOCKER_BUILDKIT=1 docker build -f trunk/Dockerfile.builds --target centos7-baseline .
- name: Build on CentOS7, with SRT
@@ -23,7 +23,10 @@ jobs:
run: DOCKER_BUILDKIT=1 docker build -f trunk/Dockerfile.builds --target centos7-no-asm .
- name: Build on CentOS7, C++98, no FFmpeg
run: DOCKER_BUILDKIT=1 docker build -f trunk/Dockerfile.builds --target centos7-ansi-no-ffmpeg .
- # Build for CentOS8
+ # Build for CentOS 6
+ - name: Build on CentOS6, baseline
+ run: DOCKER_BUILDKIT=1 docker build -f trunk/Dockerfile.builds --target centos6-baseline .
+ # Build for CentOS 8
- name: Build on CentOS8, baseline
run: DOCKER_BUILDKIT=1 docker build -f trunk/Dockerfile.builds --target centos8-baseline .
- name: Build on CentOS8, with SRT
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d17a7da13..b08e2cd72 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,5 +1,5 @@
Welome to contribute to SRS!
-1. Please read [FAQ](https://github.com/ossrs/srs/issues/2716) before file new PR.
-2. Fix some [issues](https://github.com/ossrs/srs/issues), then follow the [guide](https://github.com/ossrs/srs/wiki/HowToFilePR).
+1. Please read **Contribution([CN](https://github.com/ossrs/srs/issues/2866#contribution) EN)** before file new PR.
+2. Please start from fixing some [issues](https://github.com/ossrs/srs/issues), then follow the [guide](https://github.com/ossrs/srs/wiki/HowToFilePR).
3. We will review your PR ASAP.
diff --git a/README.md b/README.md
index 6ffca35b0..5884efe13 100755
--- a/README.md
+++ b/README.md
@@ -5,17 +5,15 @@
[](https://github.com/ossrs/srs/actions/workflows/release.yml?query=workflow%3ARelease)
[](https://github.com/ossrs/srs/actions?query=workflow%3ATest+branch%3Adevelop)
[](https://codecov.io/gh/ossrs/srs/branch/develop)
-[](../../wikis/Contact#wechat)
-[](https://github.com/ossrs/srs/issues/2716)
-[](http://mulanos.cn)
-[](https://alternativeto.net/software/srs/about/)
-[](https://www.facebook.com/winlinvip)
-[](https://twitter.com/winlinvip)
+[](../../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://www.twitch.tv/winlinvip)
[](https://discord.gg/yZ4BnPmHAd)
[](https://opencollective.com/srs-server/contribute)
-[](https://stackoverflow.com/questions/tagged/simple-realtime-server)
+[](https://stackoverflow.com/questions/tagged/simple-realtime-server)
+[](https://hub.docker.com/r/ossrs/srs/tags)
SRS/5.0,[Bee](https://github.com/ossrs/srs/wiki/Product#release50) 是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT。
@@ -23,7 +21,7 @@ SRS/5.0 is a simple, high efficiency and realtime video server, supports RTMP/We
SRS is licenced under [MIT](https://github.com/ossrs/srs/blob/develop/LICENSE), but some depended libraries are distributed using their [own licenses](https://github.com/ossrs/srs/wiki/LicenseMixing).
-[](https://gitee.com/winlinvip/srs-wiki/raw/master/images/SRS-Overview-4.0.png)
+[](https://ossrs.net/wiki/images/SRS-Overview-4.0.png)
> Note: If image load fail, please see it at [here](https://www.processon.com/view/link/619f29791efad425fd699fd2).
@@ -31,7 +29,7 @@ SRS is licenced under [MIT](https://github.com/ossrs/srs/blob/develop/LICENSE),
## Usage
-Build SRS from source or **docker([CN](https://github.com/ossrs/srs/wiki/v4_CN_Home#docker) / [EN](https://github.com/ossrs/srs/wiki/v4_EN_Home#docker))**, please read **Wiki: Gettting 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))**:
+Build SRS from source:
```
git clone -b develop https://gitee.com/ossrs/srs.git &&
@@ -45,15 +43,31 @@ by [FFmpeg](https://ffmpeg.org/download.html) or [OBS](https://obsproject.com/do
ffmpeg -re -i ./doc/source.flv -c copy -f flv -y rtmp://localhost/live/livestream
```
-> Note: It's also able to [publish by H5](http://localhost:8080/players/rtc_publisher.html?autostart=true) if WebRTC is enabled.
-
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))**,
+> 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.
+
@@ -111,6 +125,7 @@ A big `THANK YOU` also goes to:
## Releases
+* 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.
diff --git a/trunk/3rdparty/st-srs/README.md b/trunk/3rdparty/st-srs/README.md
index e04a6c961..551a02b7c 100644
--- a/trunk/3rdparty/st-srs/README.md
+++ b/trunk/3rdparty/st-srs/README.md
@@ -160,8 +160,8 @@ bash auto/coverage.sh
* Programming notes: http://ossrs.github.io/state-threads/docs/notes.html
* [How to porting ST to other OS/CPU?](https://github.com/ossrs/state-threads/issues/22)
-* About setjmp and longjmp, read [setjmp](https://gitee.com/winlinvip/srs-wiki/raw/master/images/st-setjmp.jpg).
-* About the stack structure, read [stack](https://gitee.com/winlinvip/srs-wiki/raw/master/images/st-stack.jpg)
+* About setjmp and longjmp, read [setjmp](https://ossrs.net/wiki/images/st-setjmp.jpg).
+* About the stack structure, read [stack](https://ossrs.net/wiki/images/st-stack.jpg)
* About asm code comments, read [#91d530e](https://github.com/ossrs/state-threads/commit/91d530e#diff-ed9428b14ff6afda0e9ab04cc91d4445R25).
* About the scheduler, read [#13-scheduler](https://github.com/ossrs/state-threads/issues/13#issuecomment-616025527).
* About the IO event system, read [#13-IO](https://github.com/ossrs/state-threads/issues/13#issuecomment-616096568).
diff --git a/trunk/Dockerfile.builds b/trunk/Dockerfile.builds
index ea91ac2c6..73f113893 100644
--- a/trunk/Dockerfile.builds
+++ b/trunk/Dockerfile.builds
@@ -19,6 +19,11 @@ FROM ossrs/srs:dev AS centos7-ansi-no-ffmpeg
COPY . /srs
RUN cd /srs/trunk && ./configure --jobs=2 --cxx11=off --cxx14=off --ffmpeg-fit=off && make -j2
+########################################################
+FROM ossrs/srs:dev6 AS centos6-baseline
+COPY . /srs
+RUN cd /srs/trunk && ./configure --jobs=2 && make -j2
+
########################################################
FROM ossrs/srs:dev8 AS centos8-baseline
COPY . /srs
diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh
index 2e4bfcb98..32287810d 100755
--- a/trunk/auto/depends.sh
+++ b/trunk/auto/depends.sh
@@ -392,6 +392,10 @@ fi
if [[ $SRS_OSX == YES ]]; then
_ST_MAKE=darwin-debug && _ST_OBJ="DARWIN_`uname -r`_DBG"
fi
+# For Ubuntu, the epoll detection might be fail.
+if [[ $OS_IS_UBUNTU == YES ]]; then
+ _ST_EXTRA_CFLAGS="$_ST_EXTRA_CFLAGS -DMD_HAVE_EPOLL"
+fi
# Whether enable debug stats.
if [[ $SRS_DEBUG_STATS == YES ]]; then
_ST_EXTRA_CFLAGS="$_ST_EXTRA_CFLAGS -DDEBUG_STATS"
@@ -474,6 +478,15 @@ ln -sf `pwd`/research/api-server/static-dir/index.html ${SRS_OBJS}/nginx/html/in
# nginx.html to detect whether nginx is alive
echo "Nginx is ok." > ${SRS_OBJS}/nginx/html/nginx.html
+#####################################################################################
+# Generate default self-sign certificate for HTTPS server, test only.
+#####################################################################################
+if [[ ! -f conf/server.key || ! -f conf/server.crt ]]; then
+ openssl genrsa -out conf/server.key 2048
+ openssl req -new -x509 -key conf/server.key -out conf/server.crt -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=Me/OU=Me/CN=ossrs.net"
+ echo "Generate test-only self-sign certificate files"
+fi
+
#####################################################################################
# cherrypy for http hooks callback, CherryPy-3.2.4
#####################################################################################
diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf
index 90523841b..c9652896e 100644
--- a/trunk/conf/full.conf
+++ b/trunk/conf/full.conf
@@ -77,6 +77,10 @@ asprocess off;
# default: on
empty_ip_ok on;
+# Whether in docker. When SRS starting, it will detect the docker, however
+# it might detect failed, then read this config.
+# Default: off
+in_docker off;
# 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.
@@ -392,6 +396,11 @@ rtc_server {
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# default: *
candidate *;
+ # If api_as_candidates is on, SRS would try to use the IP of api server, specified by srs.sdk.js request:
+ # api:string "http://r.ossrs.net:1985/rtc/v1/play/"
+ # in this case, the r.ossrs.net and 39.107.238.185 will be added as candidates.
+ # Default: on
+ api_as_candidates on;
# The IP family filter for auto discover candidate, it can be:
# ipv4 Filter IP v4 candidates.
# ipv6 Filter IP v6 candidates.
diff --git a/trunk/conf/https.docker.conf b/trunk/conf/https.docker.conf
new file mode 100644
index 000000000..8170185eb
--- /dev/null
+++ b/trunk/conf/https.docker.conf
@@ -0,0 +1,55 @@
+
+listen 1935;
+max_connections 1000;
+daemon off;
+srs_log_tank console;
+
+http_server {
+ enabled on;
+ listen 8080;
+ dir ./objs/nginx/html;
+ https {
+ enabled on;
+ listen 8088;
+ key ./conf/server.key;
+ cert ./conf/server.crt;
+ }
+}
+
+http_api {
+ enabled on;
+ listen 1985;
+ https {
+ enabled on;
+ listen 1990;
+ key ./conf/server.key;
+ cert ./conf/server.crt;
+ }
+}
+stats {
+ network 0;
+}
+rtc_server {
+ enabled on;
+ listen 8000; # UDP port
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
+ candidate $CANDIDATE;
+}
+
+vhost __defaultVhost__ {
+ hls {
+ enabled on;
+ }
+ http_remux {
+ enabled on;
+ mount [vhost]/[app]/[stream].flv;
+ }
+ rtc {
+ enabled on;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
+ rtmp_to_rtc off;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
+ rtc_to_rtmp off;
+ }
+}
+
diff --git a/trunk/conf/https.rtc.conf b/trunk/conf/https.rtc.conf
index 5ceb9048d..368a21252 100644
--- a/trunk/conf/https.rtc.conf
+++ b/trunk/conf/https.rtc.conf
@@ -31,20 +31,22 @@ stats {
}
rtc_server {
enabled on;
- # Listen at udp://8000
- listen 8000;
- #
- # The $CANDIDATE means fetch from env, if not configed, use * as default.
- #
- # The * means retrieving server IP automatically, from all network interfaces,
- # @see https://github.com/ossrs/srs/issues/307#issuecomment-599028124
+ listen 8000; # UDP port
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
candidate $CANDIDATE;
}
vhost __defaultVhost__ {
rtc {
enabled on;
- keep_bframe off;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
+ rtmp_to_rtc off;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
+ rtc_to_rtmp off;
+ }
+ http_remux {
+ enabled on;
+ mount [vhost]/[app]/[stream].flv;
}
}
diff --git a/trunk/conf/https.rtmp2rtc.conf b/trunk/conf/https.rtmp2rtc.conf
new file mode 100644
index 000000000..079458e50
--- /dev/null
+++ b/trunk/conf/https.rtmp2rtc.conf
@@ -0,0 +1,52 @@
+
+listen 1935;
+max_connections 1000;
+daemon off;
+srs_log_tank console;
+
+http_server {
+ enabled on;
+ listen 8080;
+ dir ./objs/nginx/html;
+ https {
+ enabled on;
+ listen 8088;
+ key ./conf/server.key;
+ cert ./conf/server.crt;
+ }
+}
+
+http_api {
+ enabled on;
+ listen 1985;
+ https {
+ enabled on;
+ listen 1990;
+ key ./conf/server.key;
+ cert ./conf/server.crt;
+ }
+}
+stats {
+ network 0;
+}
+rtc_server {
+ enabled on;
+ listen 8000; # UDP port
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
+ candidate $CANDIDATE;
+}
+
+vhost __defaultVhost__ {
+ rtc {
+ enabled on;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
+ rtmp_to_rtc on;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
+ rtc_to_rtmp on;
+ }
+ http_remux {
+ enabled on;
+ mount [vhost]/[app]/[stream].flv;
+ }
+}
+
diff --git a/trunk/conf/https.srs.conf b/trunk/conf/https.srs.conf
new file mode 100644
index 000000000..8170185eb
--- /dev/null
+++ b/trunk/conf/https.srs.conf
@@ -0,0 +1,55 @@
+
+listen 1935;
+max_connections 1000;
+daemon off;
+srs_log_tank console;
+
+http_server {
+ enabled on;
+ listen 8080;
+ dir ./objs/nginx/html;
+ https {
+ enabled on;
+ listen 8088;
+ key ./conf/server.key;
+ cert ./conf/server.crt;
+ }
+}
+
+http_api {
+ enabled on;
+ listen 1985;
+ https {
+ enabled on;
+ listen 1990;
+ key ./conf/server.key;
+ cert ./conf/server.crt;
+ }
+}
+stats {
+ network 0;
+}
+rtc_server {
+ enabled on;
+ listen 8000; # UDP port
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
+ candidate $CANDIDATE;
+}
+
+vhost __defaultVhost__ {
+ hls {
+ enabled on;
+ }
+ http_remux {
+ enabled on;
+ mount [vhost]/[app]/[stream].flv;
+ }
+ rtc {
+ enabled on;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
+ rtmp_to_rtc off;
+ # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
+ rtc_to_rtmp off;
+ }
+}
+
diff --git a/trunk/configure b/trunk/configure
index ec7220d6b..efcdbf7bb 100755
--- a/trunk/configure
+++ b/trunk/configure
@@ -587,6 +587,7 @@ install:
@echo "Now copy srs conf files"
@mkdir -p \$(__REAL_INSTALL)/conf
@cp -f conf/*.conf \$(__REAL_INSTALL)/conf
+ @cp -f conf/server.key conf/server.crt \$(__REAL_INSTALL)/conf
@echo "Now copy init.d script files"
@mkdir -p \$(__REAL_INSTALL)/etc/init.d
@cp -f etc/init.d/srs \$(__REAL_INSTALL)/etc/init.d
diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index 170e08f5d..25d306570 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -30,6 +30,14 @@ The changelog for SRS.
## SRS 4.0 Changelog
+* v4.0, 2022-01-20, 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
diff --git a/trunk/doc/Resources.md b/trunk/doc/Resources.md
index 0c90b6748..e90922f4d 100644
--- a/trunk/doc/Resources.md
+++ b/trunk/doc/Resources.md
@@ -45,6 +45,15 @@ Other API used by [ossrs.net](https://ossrs.net):
* `/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])
diff --git a/trunk/scripts/git.commit.sh b/trunk/scripts/git.commit.sh
index 509da3c3c..0de1cfe2d 100755
--- a/trunk/scripts/git.commit.sh
+++ b/trunk/scripts/git.commit.sh
@@ -1,5 +1,8 @@
#!/bin/bash
-#for file in $(git remote); do echo ""; git push $file $@; done
-for file in $(git remote -v|grep -v https|grep push|awk '{print $1}'); do echo ""; echo "git push $file $@"; git push $file $@; done
+for file in $(git remote -v|grep -v https|grep -v gb28181|grep push|awk '{print $1}'); do
+ echo "";
+ echo "git push $file $@";
+ git push $file $@;
+done
diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp
index 2ce0a67d5..3f0a4469e 100644
--- a/trunk/src/app/srs_app_config.cpp
+++ b/trunk/src/app/srs_app_config.cpp
@@ -2471,7 +2471,7 @@ srs_error_t SrsConfig::check_normal_config()
&& n != "grace_start_wait" && n != "empty_ip_ok" && n != "disable_daemon_for_docker"
&& n != "inotify_auto_reload" && n != "auto_reload_for_docker" && n != "tcmalloc_release_rate"
&& n != "query_latest_version"
- && n != "circuit_breaker" && n != "is_full"
+ && n != "circuit_breaker" && n != "is_full" && n != "in_docker"
) {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal directive %s", n.c_str());
}
@@ -2542,7 +2542,7 @@ srs_error_t SrsConfig::check_normal_config()
string n = conf->at(i)->name;
if (n != "enabled" && n != "listen" && n != "dir" && n != "candidate" && n != "ecdsa"
&& n != "encrypt" && n != "reuseport" && n != "merge_nalus" && n != "black_hole"
- && n != "ip_family") {
+ && n != "ip_family" && n != "api_as_candidates") {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal rtc_server.%s", n.c_str());
}
}
@@ -2999,6 +2999,18 @@ bool SrsConfig::get_daemon()
return SRS_CONF_PERFER_TRUE(conf->arg0());
}
+bool SrsConfig::get_in_docker()
+{
+ static bool DEFAULT = false;
+
+ SrsConfDirective* conf = root->get("in_docker");
+ if (!conf) {
+ return DEFAULT;
+ }
+
+ return SRS_CONF_PERFER_FALSE(conf->arg0());
+}
+
bool SrsConfig::is_full_config()
{
static bool DEFAULT = false;
@@ -3532,6 +3544,23 @@ std::string SrsConfig::get_rtc_server_candidates()
return conf->arg0();
}
+bool SrsConfig::get_api_as_candidates()
+{
+ static bool DEFAULT = true;
+
+ SrsConfDirective* conf = root->get("rtc_server");
+ if (!conf) {
+ return DEFAULT;
+ }
+
+ conf = conf->get("api_as_candidates");
+ if (!conf || conf->arg0().empty()) {
+ return DEFAULT;
+ }
+
+ return SRS_CONF_PERFER_TRUE(conf->arg0());
+}
+
std::string SrsConfig::get_rtc_server_ip_family()
{
static string DEFAULT = "ipv4";
diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp
index e7927c0e5..1bb829d26 100644
--- a/trunk/src/app/srs_app_config.hpp
+++ b/trunk/src/app/srs_app_config.hpp
@@ -382,6 +382,8 @@ public:
// If true, SRS will run in daemon mode, fork and fork to reap the
// grand-child process to init process.
virtual bool get_daemon();
+ // Whether srs in docker.
+ virtual bool get_in_docker();
private:
// Whether user use full.conf
virtual bool is_full_config();
@@ -467,6 +469,7 @@ public:
virtual bool get_rtc_server_enabled(SrsConfDirective* conf);
virtual int get_rtc_server_listen();
virtual std::string get_rtc_server_candidates();
+ virtual bool get_api_as_candidates();
virtual std::string get_rtc_server_ip_family();
virtual bool get_rtc_server_ecdsa();
virtual bool get_rtc_server_encrypt();
diff --git a/trunk/src/app/srs_app_dvr.cpp b/trunk/src/app/srs_app_dvr.cpp
index f6a031fb5..ca0ec64a6 100644
--- a/trunk/src/app/srs_app_dvr.cpp
+++ b/trunk/src/app/srs_app_dvr.cpp
@@ -745,6 +745,7 @@ SrsDvrSegmentPlan::SrsDvrSegmentPlan()
{
cduration = 0;
wait_keyframe = false;
+ reopening_segment_ = false;
}
SrsDvrSegmentPlan::~SrsDvrSegmentPlan()
@@ -845,6 +846,12 @@ srs_error_t SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* shared_video, SrsFo
srs_error_t SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
{
srs_error_t err = srs_success;
+
+ // When reopening the segment, never update the duration, because there is actually no media data.
+ // @see https://github.com/ossrs/srs/issues/2717
+ if (reopening_segment_) {
+ return err;
+ }
srs_assert(segment);
@@ -879,8 +886,11 @@ srs_error_t SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
return srs_error_wrap(err, "segment open");
}
- // update sequence header
- if ((err = hub->on_dvr_request_sh()) != srs_success) {
+ // When update sequence header, set the reopening state to prevent infinitely recursive call.
+ reopening_segment_ = true;
+ err = hub->on_dvr_request_sh();
+ reopening_segment_ = false;
+ if (err != srs_success) {
return srs_error_wrap(err, "request sh");
}
diff --git a/trunk/src/app/srs_app_dvr.hpp b/trunk/src/app/srs_app_dvr.hpp
index 6dca12631..8801d4686 100644
--- a/trunk/src/app/srs_app_dvr.hpp
+++ b/trunk/src/app/srs_app_dvr.hpp
@@ -198,6 +198,8 @@ private:
// in config, in srs_utime_t
srs_utime_t cduration;
bool wait_keyframe;
+ // Whether reopening the DVR file.
+ bool reopening_segment_;
public:
SrsDvrSegmentPlan();
virtual ~SrsDvrSegmentPlan();
diff --git a/trunk/src/app/srs_app_latest_version.cpp b/trunk/src/app/srs_app_latest_version.cpp
index f1ae0e0d8..cd1a1ba88 100644
--- a/trunk/src/app/srs_app_latest_version.cpp
+++ b/trunk/src/app/srs_app_latest_version.cpp
@@ -207,7 +207,7 @@ srs_error_t SrsLatestVersion::cycle()
string url;
srs_utime_t starttime = srs_update_system_time();
if ((err = query_latest_version(url)) != srs_success) {
- srs_warn("query err %s", srs_error_desc(err).c_str());
+ srs_trace("query release err %s", srs_error_summary(err).c_str());
srs_freep(err); // Ignore any error.
}
diff --git a/trunk/src/app/srs_app_listener.cpp b/trunk/src/app/srs_app_listener.cpp
index 556c7baaf..20fdad419 100755
--- a/trunk/src/app/srs_app_listener.cpp
+++ b/trunk/src/app/srs_app_listener.cpp
@@ -652,7 +652,7 @@ srs_error_t SrsUdpMuxListener::cycle()
if (pps_last > 10000 || pps_average > 10000) {
pps_unit = "(w)"; pps_last /= 10000; pps_average /= 10000;
} else if (pps_last > 1000 || pps_average > 1000) {
- pps_unit = "(k)"; pps_last /= 10000; pps_average /= 10000;
+ pps_unit = "(k)"; pps_last /= 1000; pps_average /= 1000;
}
srs_trace("<- RTC RECV #%d, udp %" PRId64 ", pps %d/%d%s, schedule %" PRId64,
diff --git a/trunk/src/app/srs_app_rtc_api.cpp b/trunk/src/app/srs_app_rtc_api.cpp
index df0ae4b52..bce9c9b31 100644
--- a/trunk/src/app/srs_app_rtc_api.cpp
+++ b/trunk/src/app/srs_app_rtc_api.cpp
@@ -117,6 +117,7 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
// The RTC user config object.
SrsRtcUserConfig ruc;
ruc.req_->ip = clientip;
+ ruc.api_ = api;
srs_parse_rtmp_url(streamurl, ruc.req_->tcUrl, ruc.req_->stream);
@@ -185,6 +186,14 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
server_enabled, rtc_enabled, ruc.req_->vhost.c_str());
}
+ // For RTMP to RTC, fail if disabled and RTMP is active, see https://github.com/ossrs/srs/issues/2728
+ if (!_srs_config->get_rtc_from_rtmp(ruc.req_->vhost)) {
+ SrsLiveSource* rtmp = _srs_sources->fetch(ruc.req_);
+ if (rtmp && !rtmp->inactive()) {
+ return srs_error_new(ERROR_RTC_DISABLED, "Disabled rtmp_to_rtc of %s, see #2728", ruc.req_->vhost.c_str());
+ }
+ }
+
// TODO: FIXME: When server enabled, but vhost disabled, should report error.
SrsRtcConnection* session = NULL;
if ((err = server_->create_session(&ruc, local_sdp, &session)) != srs_success) {
@@ -375,6 +384,7 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt
// The RTC user config object.
SrsRtcUserConfig ruc;
ruc.req_->ip = clientip;
+ ruc.api_ = api;
srs_parse_rtmp_url(streamurl, ruc.req_->tcUrl, ruc.req_->stream);
diff --git a/trunk/src/app/srs_app_rtc_server.cpp b/trunk/src/app/srs_app_rtc_server.cpp
index 6986cf1fd..1d262587c 100644
--- a/trunk/src/app/srs_app_rtc_server.cpp
+++ b/trunk/src/app/srs_app_rtc_server.cpp
@@ -6,6 +6,7 @@
#include
+#include
using namespace std;
#include
@@ -149,18 +150,65 @@ bool srs_is_rtcp(const uint8_t* data, size_t len)
return (len >= 12) && (data[0] & 0x80) && (data[1] >= 192 && data[1] <= 223);
}
-static std::vector get_candidate_ips()
+srs_error_t api_server_as_candidates(string api, set& candidate_ips)
{
- std::vector candidate_ips;
+ srs_error_t err = srs_success;
+ if (api.empty() || !_srs_config->get_api_as_candidates()) {
+ return err;
+ }
+
+ SrsHttpUri uri;
+ if ((err = uri.initialize(api)) != srs_success) {
+ return srs_error_wrap(err, "parse %s", api.c_str());
+ }
+
+ string hostname = uri.get_host();
+ if (hostname.empty() || hostname == SRS_CONSTS_LOCALHOST_NAME) {
+ return err;
+ }
+ if (hostname == SRS_CONSTS_LOCALHOST || hostname == SRS_CONSTS_LOOPBACK || hostname == SRS_CONSTS_LOOPBACK6) {
+ return err;
+ }
+
+ // Try to parse the domain name if not IP.
+ int family = 0;
+ string ip = srs_dns_resolve(hostname, family);
+ if (ip.empty() || ip == SRS_CONSTS_LOCALHOST || ip == SRS_CONSTS_LOOPBACK || ip == SRS_CONSTS_LOOPBACK6) {
+ return err;
+ }
+
+ // Try to add the API server ip as candidates.
+ candidate_ips.insert(ip);
+
+ return err;
+}
+
+static set discover_candidates(SrsRtcUserConfig* ruc)
+{
+ srs_error_t err = srs_success;
+
+ // Try to discover the eip as candidate, specified by user.
+ set candidate_ips;
+ if (!ruc->eip_.empty()) {
+ candidate_ips.insert(ruc->eip_);
+ }
+
+ // Try to discover from api of request, if api_as_candidates enabled.
+ if ((err = api_server_as_candidates(ruc->api_, candidate_ips)) != srs_success) {
+ srs_warn("ignore discovering ip from api %s, err %s", ruc->api_.c_str(), srs_error_summary(err).c_str());
+ srs_freep(err);
+ }
+
+ // If not * or 0.0.0.0, use the candidate as exposed IP.
string candidate = _srs_config->get_rtc_server_candidates();
if (candidate != "*" && candidate != "0.0.0.0") {
- candidate_ips.push_back(candidate);
+ candidate_ips.insert(candidate);
return candidate_ips;
}
- // For * or 0.0.0.0, auto discovery expose ip addresses.
- std::vector& ips = srs_get_local_ips();
+ // Discover from local network interface addresses.
+ vector& ips = srs_get_local_ips();
if (ips.empty()) {
return candidate_ips;
}
@@ -180,7 +228,7 @@ static std::vector get_candidate_ips()
continue;
}
- candidate_ips.push_back(ip->ip);
+ candidate_ips.insert(ip->ip);
srs_trace("Best matched ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str());
}
@@ -195,7 +243,7 @@ static std::vector get_candidate_ips()
continue;
}
- candidate_ips.push_back(ip->ip);
+ candidate_ips.insert(ip->ip);
srs_trace("No best matched, use first ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str());
return candidate_ips;
}
@@ -203,7 +251,7 @@ static std::vector get_candidate_ips()
// We use the first one.
if (candidate_ips.empty()) {
SrsIPAddress* ip = ips[0];
- candidate_ips.push_back(ip->ip);
+ candidate_ips.insert(ip->ip);
srs_warn("No best matched, use first ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str());
return candidate_ips;
}
@@ -524,19 +572,17 @@ srs_error_t SrsRtcServer::do_create_session(SrsRtcUserConfig* ruc, SrsSdp& local
local_sdp.set_fingerprint(_srs_rtc_dtls_certificate->get_fingerprint());
// We allows to mock the eip of server.
- if (!ruc->eip_.empty()) {
- string host;
- int port = _srs_config->get_rtc_server_listen();
- srs_parse_hostport(ruc->eip_, host, port);
-
- local_sdp.add_candidate(host, port, "host");
- srs_trace("RTC: Use candidate mock_eip %s as %s:%d", ruc->eip_.c_str(), host.c_str(), port);
- } else {
- std::vector candidate_ips = get_candidate_ips();
- for (int i = 0; i < (int)candidate_ips.size(); ++i) {
- local_sdp.add_candidate(candidate_ips[i], _srs_config->get_rtc_server_listen(), "host");
+ if (true) {
+ int listen_port = _srs_config->get_rtc_server_listen();
+ set candidates = discover_candidates(ruc);
+ for (set::iterator it = candidates.begin(); it != candidates.end(); ++it) {
+ string hostname; int port = listen_port;
+ srs_parse_hostport(*it, hostname,port);
+ local_sdp.add_candidate(hostname, port, "host");
}
- srs_trace("RTC: Use candidates %s", srs_join_vector_string(candidate_ips, ", ").c_str());
+
+ vector v = vector(candidates.begin(), candidates.end());
+ srs_trace("RTC: Use candidates %s", srs_join_vector_string(v, ", ").c_str());
}
// Setup the negotiate DTLS by config.
diff --git a/trunk/src/app/srs_app_rtc_server.hpp b/trunk/src/app/srs_app_rtc_server.hpp
index 4b27614da..d5c18be9e 100644
--- a/trunk/src/app/srs_app_rtc_server.hpp
+++ b/trunk/src/app/srs_app_rtc_server.hpp
@@ -78,6 +78,7 @@ public:
SrsSdp remote_sdp_;
std::string eip_;
std::string codec_;
+ std::string api_;
// Generated data.
SrsRequest* req_;
diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp
index 675ca7433..9ccb2e9bc 100644
--- a/trunk/src/app/srs_app_server.cpp
+++ b/trunk/src/app/srs_app_server.cpp
@@ -49,7 +49,7 @@ std::string srs_listener_type2string(SrsListenerType type)
case SrsListenerHttpStream:
return "HTTP-Server";
case SrsListenerHttpsStream:
- return "HTTP-Server";
+ return "HTTPS-Server";
case SrsListenerMpegTsOverUdp:
return "MPEG-TS over UDP";
case SrsListenerFlv:
diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp
index 659809c92..e0ecf1421 100644
--- a/trunk/src/app/srs_app_source.hpp
+++ b/trunk/src/app/srs_app_source.hpp
@@ -448,7 +448,7 @@ public:
// @param h the event handler for source.
// @param pps the matched source, if success never be NULL.
virtual srs_error_t fetch_or_create(SrsRequest* r, ISrsLiveSourceHandler* h, SrsLiveSource** pps);
-private:
+public:
// Get the exists source, NULL when not exists.
// update the request and return the exists source.
virtual SrsLiveSource* fetch(SrsRequest* r);
diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp
index d8c1aeeb1..9c5e35ac1 100644
--- a/trunk/src/core/srs_core.hpp
+++ b/trunk/src/core/srs_core.hpp
@@ -68,7 +68,7 @@ typedef SrsCplxError* srs_error_t;
#include
// The context ID, it default to a string object, we can also use other objects.
-// @remark User can directly user string as SrsContextId, we user struct to ensure the context is an object.
+// @remark User can directly use string as SrsContextId, we use struct to ensure the context is an object.
#if 1
class _SrsContextId
{
diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp
index cdc7aca52..0b2bb6fc4 100644
--- a/trunk/src/core/srs_core_version4.hpp
+++ b/trunk/src/core/srs_core_version4.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 4
#define VERSION_MINOR 0
-#define VERSION_REVISION 212
+#define VERSION_REVISION 220
#endif
diff --git a/trunk/src/kernel/srs_kernel_consts.hpp b/trunk/src/kernel/srs_kernel_consts.hpp
index 832bcbf18..ca30aa16a 100644
--- a/trunk/src/kernel/srs_kernel_consts.hpp
+++ b/trunk/src/kernel/srs_kernel_consts.hpp
@@ -107,6 +107,7 @@
///////////////////////////////////////////////////////////
#define SRS_CONSTS_NULL_FILE "/dev/null"
#define SRS_CONSTS_LOCALHOST "127.0.0.1"
+#define SRS_CONSTS_LOCALHOST_NAME "localhost"
#define SRS_CONSTS_LOOPBACK "0.0.0.0"
#define SRS_CONSTS_LOOPBACK6 "::"
diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp
index 00bb8823b..d39783b3f 100644
--- a/trunk/src/main/srs_main_server.cpp
+++ b/trunk/src/main/srs_main_server.cpp
@@ -384,6 +384,14 @@ srs_error_t run_directly_or_daemon()
{
srs_error_t err = srs_success;
+ // Try to load the config if docker detect failed.
+ if (!_srs_in_docker) {
+ _srs_in_docker = _srs_config->get_in_docker();
+ if (_srs_in_docker) {
+ srs_trace("enable in_docker by config");
+ }
+ }
+
// Load daemon from config, disable it for docker.
// @see https://github.com/ossrs/srs/issues/1594
bool run_as_daemon = _srs_config->get_daemon();
diff --git a/trunk/src/srt/srt_to_rtmp.cpp b/trunk/src/srt/srt_to_rtmp.cpp
index 55e09b02b..9e2022809 100644
--- a/trunk/src/srt/srt_to_rtmp.cpp
+++ b/trunk/src/srt/srt_to_rtmp.cpp
@@ -260,7 +260,7 @@ rtmp_client::rtmp_client(std::string key_path):_key_path(key_path)
_streamname = ret_vec[1];
}
std::stringstream url_ss;
-
+
std::vector ip_ports = _srs_config->get_listens();
int port = 0;
std::string ip;
@@ -271,24 +271,19 @@ rtmp_client::rtmp_client(std::string key_path):_key_path(key_path)
break;
}
}
- port = (port == 0) ? 1935 : port;
- if (_vhost == DEF_VHOST) {
- url_ss << "rtmp://127.0.0.1:" << port
- << "/" << _appname
- << "/" << _streamname;
- } else {
- if (_appname.find("?") == std::string::npos) {
- url_ss << "rtmp://127.0.0.1:" << port
- << "/" << _appname << "?vhost=" << _vhost
- << "/" << _streamname;
- } else {
- url_ss << "rtmp://127.0.0.1:" << port
- << "/" << _appname << "&vhost=" << _vhost
- << "/" << _streamname;
- }
- }
- _url = url_ss.str();
+ port = (port == 0) ? SRS_CONSTS_RTMP_DEFAULT_PORT : port;
+
+ std::stringstream ss;
+ ss << "rtmp://" << SRS_CONSTS_LOCALHOST;
+ ss << ":" << port;
+ ss << "/" << _appname;
+ if (_vhost != DEF_VHOST) {
+ ss << "?vhost=" << _vhost;
+ }
+ ss << "/" << _streamname;
+
+ _url = ss.str();
_h264_sps_changed = false;
_h264_pps_changed = false;