Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: brewswang/srs
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4.0release
Choose a base ref
...
head repository: ossrs/srs
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4.0release
Choose a head ref
Able to merge. These branches can be automatically merged.

Commits on May 25, 2022

  1. Copy the full SHA
    0304e78 View commit details

Commits on Jun 15, 2022

  1. Copy the full SHA
    1f0ea3f View commit details
  2. Copy the full SHA
    d9352ec View commit details

Commits on Jun 29, 2022

  1. Copy the full SHA
    cd85a96 View commit details

Commits on Jul 2, 2022

  1. Copy the full SHA
    7d0d2af View commit details

Commits on Jul 31, 2022

  1. Copy the full SHA
    d57e9c7 View commit details
  2. Copy the full SHA
    7b23a42 View commit details

Commits on Aug 10, 2022

  1. Copy the full SHA
    febd45d View commit details

Commits on Aug 17, 2022

  1. Copy the full SHA
    f9941a3 View commit details

Commits on Aug 24, 2022

  1. STAT: Add kbps for client.

    winlinvip committed Aug 24, 2022
    Copy the full SHA
    41155b7 View commit details
  2. Copy the full SHA
    8e6d207 View commit details
  3. Copy the full SHA
    9923c74 View commit details
  4. Copy the full SHA
    fe20027 View commit details
  5. Copy the full SHA
    d5293e3 View commit details

Commits on Aug 26, 2022

  1. Copy the full SHA
    cdccdf7 View commit details

Commits on Aug 29, 2022

  1. Copy the full SHA
    88ba3d2 View commit details

Commits on Sep 2, 2022

  1. Copy the full SHA
    4a225c5 View commit details

Commits on Sep 3, 2022

  1. Copy the full SHA
    34196ea View commit details
  2. Copy the full SHA
    e0c8c19 View commit details

Commits on Sep 6, 2022

  1. Copy the full SHA
    15610ca View commit details

Commits on Sep 9, 2022

  1. WebRTC: Fix missing type in track desc when backup H.264 payload type…

    … is chosen.
    
    Signed-off-by: faicker <faicker.mo@gmail.com>
    
    Signed-off-by: faicker <faicker.mo@gmail.com>
    faicker authored Sep 9, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ef3347e View commit details
  2. Copy the full SHA
    1c0236a View commit details
  3. Copy the full SHA
    8ac8ae1 View commit details
  4. Copy the full SHA
    aea2bfb View commit details

Commits on Sep 16, 2022

  1. Copy the full SHA
    686f577 View commit details
  2. Copy the full SHA
    64c2ac8 View commit details
  3. Copy the full SHA
    0e68dc2 View commit details

Commits on Sep 27, 2022

  1. Copy the full SHA
    386b92e View commit details

Commits on Sep 28, 2022

  1. Copy the full SHA
    8bd8c11 View commit details

Commits on Oct 10, 2022

  1. Copy the full SHA
    7d782ee View commit details

Commits on Nov 22, 2022

  1. WebRTC: Fix no audio and video issue for Firefox. (ossrs#3079) v4.0.268

    * Remove extern SrsPps* duplicate declarations
    
    * fix(rtmp2rtc): fix video payload type for rtmp to rtc bridge (ossrs#3041)
    
    * Revert changes not belongs to this PR.
    
    * Fix naming issue, follow SRS style.
    
    * Use srs_assert instead of assert.
    
    * Fix firefox no audio issue.
    
    Co-authored-by: winlin <winlin@vip.126.com>
    johzzy and winlinvip committed Nov 22, 2022
    Copy the full SHA
    e529536 View commit details
  2. Copy the full SHA
    2573a25 View commit details

Commits on Dec 25, 2022

  1. MP3: Fix bug for TS or HLS with mp3 codec. v4.0.269 (ossrs#296) (ossr…

    …s#3333)
    
    * MP3: Fix bug for TS or HLS with mp3 codec. v4.0.269 (ossrs#296)
    
    1. Refresh HLS audio codec if changed in stream.
    2. Refresh TS audio codec if changed in stream.
    3. Fix mp3 demux bug in SrsFormat::audio_mp3_demux.
    4. Use 3(MPEG1) not 4(MPEG2) as PMT stream type, follow FFmpeg.
    5. MP3: Update utest for mp3 sample parsing.
    6. MP3: Ignore empty frame sample.
    7. UTest: Fix utest failed, do not copy files.
    winlinvip authored Dec 25, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    577cd29 View commit details

Commits on Jan 3, 2023

  1. Copy the full SHA
    55ca61e View commit details

Commits on Jul 21, 2023

  1. API: Fix HTTPS callback issue using SNI in TLS client handshake. v4.0…

    ….270 (ossrs#3695)
    
    ---------
    
    Co-authored-by: chundonglinlin <chundonglinlin@163.com>
    2 people authored and winlinvip committed Jul 21, 2023
    Copy the full SHA
    4e94300 View commit details

Commits on Aug 2, 2023

  1. Copy the full SHA
    6477f31 View commit details
  2. Copy the full SHA
    44f0c36 View commit details
Showing with 1,567 additions and 522 deletions.
  1. +236 −135 .github/workflows/release.yml
  2. +27 −1 .github/workflows/test.yml
  3. +7 −1 README.md
  4. +7 −7 trunk/3rdparty/README.md
  5. +24 −15 trunk/Dockerfile
  6. +2 −4 trunk/auto/codecov.sh
  7. +2 −5 trunk/auto/depends.sh
  8. +3 −3 trunk/auto/options.sh
  9. +1 −1 trunk/conf/clion-ingest.conf
  10. +3 −3 trunk/conf/clion.conf
  11. +1 −1 trunk/conf/dash.conf
  12. +0 −1 trunk/conf/demo.19350.conf
  13. +0 −3 trunk/conf/demo.conf
  14. +3 −3 trunk/conf/docker.conf
  15. +1 −1 trunk/conf/dvr.mp4.conf
  16. +2 −2 trunk/conf/dvr.path.conf
  17. +1 −1 trunk/conf/dvr.segment.conf
  18. +1 −1 trunk/conf/dvr.session.conf
  19. +1 −1 trunk/conf/edge.conf
  20. +1 −1 trunk/conf/edge.token.traverse.conf
  21. +1 −1 trunk/conf/edge2.conf
  22. +1 −1 trunk/conf/exec.conf
  23. +1 −1 trunk/conf/ffmpeg.transcode.conf
  24. +1 −1 trunk/conf/forward.master.conf
  25. +1 −1 trunk/conf/forward.slave.conf
  26. +41 −57 trunk/conf/full.conf
  27. +1 −1 trunk/conf/go-oryx-edge.conf
  28. +1 −1 trunk/conf/go-oryx-edge2.conf
  29. +0 −1 trunk/conf/hds.conf
  30. +1 −1 trunk/conf/hls.conf
  31. +1 −1 trunk/conf/hls.realtime.conf
  32. +1 −1 trunk/conf/http.aac.live.conf
  33. +1 −1 trunk/conf/http.flv.live.conf
  34. +1 −1 trunk/conf/http.flv.live.edge1.conf
  35. +1 −1 trunk/conf/http.flv.live.edge2.conf
  36. +1 −1 trunk/conf/http.hls.conf
  37. +0 −2 trunk/conf/http.hooks.callback.conf
  38. +1 −1 trunk/conf/http.mp3.live.conf
  39. +1 −1 trunk/conf/http.ts.live.conf
  40. +3 −3 trunk/conf/https.docker.conf
  41. +0 −2 trunk/conf/https.hooks.callback.conf
  42. +3 −3 trunk/conf/https.rtc.conf
  43. +3 −3 trunk/conf/https.rtmp2rtc.conf
  44. +3 −3 trunk/conf/https.srs.conf
  45. +1 −1 trunk/conf/ingest.conf
  46. +1 −1 trunk/conf/ingest.rtsp.conf
  47. +1 −1 trunk/conf/origin.cluster.edge.conf
  48. +1 −1 trunk/conf/origin.cluster.serverA.conf
  49. +1 −1 trunk/conf/origin.cluster.serverB.conf
  50. +1 −1 trunk/conf/origin.cluster.serverC.conf
  51. +1 −1 trunk/conf/origin.conf
  52. +1 −1 trunk/conf/push.flv.conf
  53. +1 −1 trunk/conf/push.mpegts.over.udp.conf
  54. +1 −1 trunk/conf/realtime.conf
  55. +1 −1 trunk/conf/realtime.flv.conf
  56. +3 −3 trunk/conf/rtc.conf
  57. +3 −3 trunk/conf/rtc2rtmp.conf
  58. +1 −1 trunk/conf/rtmp.conf
  59. +3 −3 trunk/conf/rtmp2rtc.conf
  60. +3 −3 trunk/conf/srs.conf
  61. +3 −3 trunk/conf/srt2rtc.conf
  62. +1 −1 trunk/conf/transcode2hls.audio.only.conf
  63. +1 −1 trunk/conf/transform.edge.conf
  64. +3 −3 trunk/conf/vm.conf
  65. +1 −1 trunk/doc/Architecture.md
  66. +21 −0 trunk/doc/CHANGELOG.md
  67. +1 −1 trunk/doc/Features.md
  68. +1 −1 trunk/doc/PERFORMANCE.md
  69. +1 −1 trunk/doc/Resources.md
  70. +4 −0 trunk/research/players/js/srs.sdk.js
  71. +156 −3 trunk/src/app/srs_app_config.cpp
  72. +6 −0 trunk/src/app/srs_app_config.hpp
  73. +7 −2 trunk/src/app/srs_app_edge.cpp
  74. +28 −0 trunk/src/app/srs_app_hls.cpp
  75. +6 −0 trunk/src/app/srs_app_hls.hpp
  76. +3 −1 trunk/src/app/srs_app_http_stream.cpp
  77. +11 −22 trunk/src/app/srs_app_latest_version.cpp
  78. +1 −0 trunk/src/app/srs_app_latest_version.hpp
  79. +173 −50 trunk/src/app/srs_app_rtc_api.cpp
  80. +20 −0 trunk/src/app/srs_app_rtc_api.hpp
  81. +104 −6 trunk/src/app/srs_app_rtc_conn.cpp
  82. +6 −2 trunk/src/app/srs_app_rtc_conn.hpp
  83. +29 −22 trunk/src/app/srs_app_rtc_sdp.cpp
  84. +54 −33 trunk/src/app/srs_app_rtc_server.cpp
  85. +9 −0 trunk/src/app/srs_app_rtc_server.hpp
  86. +72 −6 trunk/src/app/srs_app_rtc_source.cpp
  87. +91 −8 trunk/src/app/srs_app_rtc_source.hpp
  88. +12 −0 trunk/src/app/srs_app_server.cpp
  89. +84 −19 trunk/src/app/srs_app_statistic.cpp
  90. +15 −1 trunk/src/app/srs_app_statistic.hpp
  91. +1 −1 trunk/src/core/srs_core_version4.hpp
  92. +8 −10 trunk/src/kernel/srs_kernel_codec.cpp
  93. +2 −0 trunk/src/kernel/srs_kernel_consts.hpp
  94. +4 −0 trunk/src/kernel/srs_kernel_rtc_rtp.hpp
  95. +21 −4 trunk/src/kernel/srs_kernel_ts.cpp
  96. +7 −3 trunk/src/kernel/srs_kernel_ts.hpp
  97. +6 −1 trunk/src/protocol/srs_protocol_utility.cpp
  98. +6 −2 trunk/src/protocol/srs_service_http_client.cpp
  99. +1 −1 trunk/src/protocol/srs_service_http_client.hpp
  100. +4 −1 trunk/src/protocol/srs_service_http_conn.cpp
  101. +36 −3 trunk/src/utest/srs_utest_kernel.cpp
  102. +94 −0 trunk/src/utest/srs_utest_rtc.cpp
  103. +14 −0 trunk/src/utest/srs_utest_rtmp.cpp
  104. +23 −5 trunk/src/utest/srs_utest_service.cpp
371 changes: 236 additions & 135 deletions .github/workflows/release.yml

Large diffs are not rendered by default.

28 changes: 27 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -116,6 +116,8 @@ jobs:
# For coverage
- name: Run SRS covergae
if: ${{ startsWith(github.ref, 'refs/heads/') || startsWith(github.ref, 'refs/pull/') }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: |
# The hash of commit.
SRS_SHA=${{ github.sha }}
@@ -126,15 +128,39 @@ jobs:
# The github.ref is, for example, refs/pull/2536/merge
SRS_PR=$(echo ${{ github.ref }}| awk -F 'refs/pull/' '{print $2}'| awk -F '/' '{print $1}')
echo "For ref=${{ github.ref }}, sha=${{ github.sha }}, SRS_BRANCH=$SRS_BRANCH, SRS_PR=$SRS_PR, SRS_SHA=$SRS_SHA, SRS_PROJECT=$SRS_PROJECT"
docker run --rm --env SRS_BRANCH=$SRS_BRANCH --env SRS_PR=$SRS_PR --env SRS_SHA=$SRS_SHA --env SRS_PROJECT=$SRS_PROJECT \
docker run --rm --env CODECOV_TOKEN=$CODECOV_TOKEN \
--env SRS_BRANCH=$SRS_BRANCH --env SRS_PR=$SRS_PR --env SRS_SHA=$SRS_SHA --env SRS_PROJECT=$SRS_PROJECT \
srs:cov bash -c 'make utest && ./objs/srs_utest && bash auto/codecov.sh'
multile-archs:
name: actions-test-multile-archs
runs-on: ubuntu-20.04

steps:
- name: Checkout repository
uses: actions/checkout@v2

# See https://github.com/crazy-max/ghaction-docker-buildx#moved-to-docker-organization
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Build multiple archs image
run: |
docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 \
--output "type=image,push=false" \
-f trunk/Dockerfile .
done:
name: actions-test-done
needs:
- build
- utest
- coverage
- multile-archs
runs-on: ubuntu-20.04

steps:
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -131,6 +131,12 @@ A big THANK YOU goes to:

## Releases

* 2023-08-02, Release [v4.0-r5](https://github.com/ossrs/srs/releases/tag/v4.0-r5), v4.0-r5, 4.0 release5, v4.0.271, 145574 lines.
* 2022-11-22, Release [v4.0-r4](https://github.com/ossrs/srs/releases/tag/v4.0-r4), v4.0-r4, 4.0 release4, v4.0.268, 145482 lines.
* 2022-09-16, Release [v4.0-r3](https://github.com/ossrs/srs/releases/tag/v4.0-r3), v4.0-r3, 4.0 release3, v4.0.265, 145328 lines.
* 2022-08-24, Release [v4.0-r2](https://github.com/ossrs/srs/releases/tag/v4.0-r2), v4.0-r2, 4.0 release2, v4.0.257, 144890 lines.
* 2022-06-29, Release [v4.0-r1](https://github.com/ossrs/srs/releases/tag/v4.0-r1), v4.0-r1, 4.0 release1, v4.0.253, 144680 lines.
* 2022-06-11, Release [v4.0-r0](https://github.com/ossrs/srs/releases/tag/v4.0-r0), v4.0-r0, 4.0 release0, v4.0.252, 144680 lines.
* 2022-03-19, Release [v4.0-b10](https://github.com/ossrs/srs/releases/tag/v4.0-b10), v4.0-b10, 4.0 beta10, v4.0.251, 144665 lines.
* 2022-02-15, Release [v4.0-b9](https://github.com/ossrs/srs/releases/tag/v4.0-b9), v4.0-b9, 4.0 beta9, v4.0.245, 144474 lines.
* 2022-02-11, Release [v4.0-b8](https://github.com/ossrs/srs/releases/tag/v4.0-b8), v4.0-b8, 4.0 beta8, v4.0.241, 144445 lines.
@@ -433,5 +439,5 @@ Winlin
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

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

14 changes: 7 additions & 7 deletions trunk/3rdparty/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
http-parser-2.1.zip
* for srs to support http callback.
* https://github.com/joyent/http-parser
* https://github.com/ossrs/srs/wiki/LicenseMixing#http-parser
* https://ossrs.net/lts/zh-cn/license#http-parser

nginx-1.5.7.zip
* http://nginx.org/
@@ -10,7 +10,7 @@ nginx-1.5.7.zip
srt-1-fit
srt-1.4.1.tar.gz
* https://github.com/Haivision/srt/releases/tag/v1.4.1
* https://github.com/ossrs/srs/wiki/LicenseMixing#srt
* https://ossrs.net/lts/zh-cn/license#srt

openssl-1.1-fit
openssl-1.1.1b.tar.gz
@@ -21,7 +21,7 @@ openssl-OpenSSL_1_0_2u.tar.gz
* http://www.openssl.org/source/openssl-1.1.0e.tar.gz
* openssl for SRS(with-ssl) RTMP complex handshake to delivery h264+aac stream.
* SRTP depends on openssl 1.0.*, so we use both ssl versions.
* https://github.com/ossrs/srs/wiki/LicenseMixing#openssl
* https://ossrs.net/lts/zh-cn/license#openssl

CherryPy-3.2.4.zip
* sample api server for srs.
@@ -36,7 +36,7 @@ opus-1.3.1.tar.gz
* http://ffmpeg.org/releases/ffmpeg-4.2.tar.gz
* https://github.com/xiph/opus/releases/tag/v1.3.1
* To support RTMP/WebRTC transcoding.
* https://github.com/ossrs/srs/wiki/LicenseMixing#ffmpeg
* https://ossrs.net/lts/zh-cn/license#ffmpeg

gtest-fit
* google test framework.
@@ -51,14 +51,14 @@ st-1.9.zip
state-threads
state-threads-1.9.1.tar.gz
* Patched ST from https://github.com/ossrs/state-threads
* https://github.com/ossrs/srs/wiki/LicenseMixing#state-threads
* https://ossrs.net/lts/zh-cn/license#state-threads

JSON
* https://github.com/udp/json-parser
* https://github.com/ossrs/srs/wiki/LicenseMixing#json
* https://ossrs.net/lts/zh-cn/license#json

USRSCTP
* https://github.com/ossrs/srs/wiki/LicenseMixing#usrsctp
* https://ossrs.net/lts/zh-cn/license#usrsctp

links:
* state-threads:
39 changes: 24 additions & 15 deletions trunk/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
FROM ossrs/srs:dev AS build

# Install depends tools.
RUN yum install -y gcc make gcc-c++ patch unzip perl git
ARG ARCH
FROM ${ARCH}ossrs/srs:ubuntu20 AS build

ARG BUILDPLATFORM
ARG TARGETPLATFORM
ARG JOBS=2
ARG SRS_AUTO_PACKAGER
RUN echo "BUILDPLATFORM: $BUILDPLATFORM, TARGETPLATFORM: $TARGETPLATFORM, JOBS: $JOBS, PACKAGER: ${#SRS_AUTO_PACKAGER}"

# https://serverfault.com/questions/949991/how-to-install-tzdata-on-a-ubuntu-docker-image
ENV DEBIAN_FRONTEND noninteractive

# Install depends tools.
RUN apt-get update && apt-get install -y gcc make g++ patch unzip perl git

# Build and install SRS.
COPY . /srs
WORKDIR /srs/trunk
RUN ./configure --srt=on --jobs=2 && make -j2 && make install

# All config files for SRS.
RUN cp -R conf /usr/local/srs/conf && \
cp research/api-server/static-dir/index.html /usr/local/srs/objs/nginx/html/ && \
cp research/api-server/static-dir/favicon.ico /usr/local/srs/objs/nginx/html/ && \
cp research/players/crossdomain.xml /usr/local/srs/objs/nginx/html/ && \
cp -R research/console /usr/local/srs/objs/nginx/html/ && \
cp -R research/players /usr/local/srs/objs/nginx/html/ && \
cp -R 3rdparty/signaling/www/demos /usr/local/srs/objs/nginx/html/
RUN ./configure --srt=on --jobs=${JOBS} && make -j${JOBS} && make install

############################################################
# dist
############################################################
FROM centos:7 AS dist
FROM ${ARCH}ubuntu:focal AS dist

ARG BUILDPLATFORM
ARG TARGETPLATFORM
RUN echo "BUILDPLATFORM: $BUILDPLATFORM, TARGETPLATFORM: $TARGETPLATFORM"

# Expose ports for streaming @see https://github.com/ossrs/srs#ports
EXPOSE 1935 1985 8080 8000/udp 10080/udp
@@ -32,6 +35,12 @@ COPY --from=build /usr/local/bin/ffmpeg /usr/local/srs/objs/ffmpeg/bin/ffmpeg
# SRS binary, config files and srs-console.
COPY --from=build /usr/local/srs /usr/local/srs

# Test the version of binaries.
RUN ldd /usr/local/srs/objs/ffmpeg/bin/ffmpeg && \
/usr/local/srs/objs/ffmpeg/bin/ffmpeg -version && \
ldd /usr/local/srs/objs/srs && \
/usr/local/srs/objs/srs -v

# Default workdir and command.
WORKDIR /usr/local/srs
CMD ["./objs/srs", "-c", "conf/docker.conf"]
6 changes: 2 additions & 4 deletions trunk/auto/codecov.sh
Original file line number Diff line number Diff line change
@@ -36,9 +36,7 @@ fi
# Note: The right path is like:
# https://codecov.io/gh/ossrs/srs/src/3.0release/trunk/src/protocol/srs_rtmp_stack.cpp
# https://codecov.io/gh/ossrs/srs/src/20fbb4466fdc8ba5d810b8570df6004063212838/trunk/src/protocol/srs_rtmp_stack.cpp
# Remark: It takes a few minutes to sync with github, so it might not available when CircleCI is done.
# https://circleci.com/gh/ossrs/srs/tree/3.0release
cd $workdir &&
export CODECOV_TOKEN="493bba46-c468-4e73-8b45-8cdd8ff62d96" &&
bash <(curl -s https://codecov.io/bash) $CODECOV_ARGS &&
export CODECOV_TOKEN="$CODECOV_TOKEN" &&
bash <(curl -s https://codecov.io/bash) $CODECOV_ARGS -f '!*gtest*' -f '!*c++*' -f '!*ffmpeg-*-fit*' &&
echo "Done" && exit 0
7 changes: 2 additions & 5 deletions trunk/auto/depends.sh
Original file line number Diff line number Diff line change
@@ -680,11 +680,8 @@ if [[ $SRS_FFMPEG_FIT == YES ]]; then
FFMPEG_CONFIGURE="env PKG_CONFIG_PATH=$(cd ${SRS_OBJS}/${SRS_PLATFORM} && pwd)/opus/lib/pkgconfig ./configure"
fi

# If disable nasm, disable all ASMs.
nasm -v >/dev/null 2>&1 && NASM_BIN_OK=YES
if [[ $NASM_BIN_OK != YES || $SRS_NASM == NO || $SRS_CROSS_BUILD == YES ]]; then
FFMPEG_OPTIONS="--disable-asm --disable-x86asm --disable-inline-asm"
fi
# Disable all asm for FFmpeg, to compatible with ARM CPU.
FFMPEG_OPTIONS="--disable-asm --disable-x86asm --disable-inline-asm"
# Only build static libraries if no shared FFmpeg.
if [[ $SRS_SHARED_FFMPEG == YES ]]; then
FFMPEG_OPTIONS="$FFMPEG_OPTIONS --enable-shared"
6 changes: 3 additions & 3 deletions trunk/auto/options.sh
Original file line number Diff line number Diff line change
@@ -40,13 +40,13 @@ SRS_DEFAULT_CONFIG=conf/srs.conf
SRS_JOBS=1
SRS_STATIC=NO
# If enabled, link shared libraries for libst.so which uses MPL license.
# See https://github.com/ossrs/srs/wiki/LicenseMixing#state-threads
# See https://ossrs.net/lts/zh-cn/license#state-threads
SRS_SHARED_ST=NO
# If enabled, link shared libraries for libsrt.so which uses MPL license.
# See https://github.com/ossrs/srs/wiki/LicenseMixing#srt
# See https://ossrs.net/lts/zh-cn/license#srt
SRS_SHARED_SRT=NO
# If enabled, link shared libraries for FFmpeg which is LGPL license.
# See https://github.com/ossrs/srs/wiki/LicenseMixing#ffmpeg
# See https://ossrs.net/lts/zh-cn/license#ffmpeg
SRS_SHARED_FFMPEG=NO
# whether enable the gcov
SRS_GCOV=NO
2 changes: 1 addition & 1 deletion trunk/conf/clion-ingest.conf
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ rtc_server {
# 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/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

6 changes: 3 additions & 3 deletions trunk/conf/clion.conf
Original file line number Diff line number Diff line change
@@ -25,16 +25,16 @@ rtc_server {
# 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/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
http_remux {
2 changes: 1 addition & 1 deletion trunk/conf/dash.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery dash
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleDASH
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-dash
# @see full.conf for detail config.

listen 1935;
1 change: 0 additions & 1 deletion trunk/conf/demo.19350.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# the config for srs demo
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleDemo
# @see full.conf for detail config.

listen 19350;
3 changes: 0 additions & 3 deletions trunk/conf/demo.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# the config for srs demo
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleDemo
# @see full.conf for detail config.

listen 1935;
@@ -58,8 +57,6 @@ vhost demo.srs.com {
}
http_hooks {
enabled on;
on_connect http://127.0.0.1:8085/api/v1/clients;
on_close http://127.0.0.1:8085/api/v1/clients;
on_publish http://127.0.0.1:8085/api/v1/streams;
on_unpublish http://127.0.0.1:8085/api/v1/streams;
on_play http://127.0.0.1:8085/api/v1/sessions;
6 changes: 3 additions & 3 deletions trunk/conf/docker.conf
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ http_server {
rtc_server {
enabled on;
listen 8000;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}
vhost __defaultVhost__ {
@@ -32,9 +32,9 @@ vhost __defaultVhost__ {
}
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
}
2 changes: 1 addition & 1 deletion trunk/conf/dvr.mp4.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to dvr in session mode
# @see https://github.com/ossrs/srs/wiki/v3_CN_DVR
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/dvr
# @see full.conf for detail config.

listen 1935;
4 changes: 2 additions & 2 deletions trunk/conf/dvr.path.conf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# the config for srs to dvr in custom path.
# @see https://github.com/ossrs/srs/wiki/v3_CN_DVR#custom-path
# @see https://github.com/ossrs/srs/wiki/v3_EN_DVR#custom-path
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/dvr#custom-path
# @see https://ossrs.io/lts/en-us/docs/v4/doc/dvr#custom-path
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/dvr.segment.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to dvr in segment mode
# @see https://github.com/ossrs/srs/wiki/v3_CN_DVR
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/dvr
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/dvr.session.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to dvr in session mode
# @see https://github.com/ossrs/srs/wiki/v3_CN_DVR
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/dvr
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/edge.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-edge cluster
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/edge
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/edge.token.traverse.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs for token traverse authentication
# @see https://github.com/ossrs/srs/wiki/v1_CN_DRM
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/drm
# @see full.conf for detail config.

listen 1935
2 changes: 1 addition & 1 deletion trunk/conf/edge2.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-edge cluster
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/edge
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/exec.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to support nginx-rtmp exec.
# @see https://github.com/ossrs/srs/wiki/v3_CN_NgExec
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/nginx-exec
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/ffmpeg.transcode.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs use ffmpeg to transcode
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleFFMPEG
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-ffmpeg
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/forward.master.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to forward
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleForward
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-forward
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/forward.slave.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to forward
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleForward
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-forward
# @see full.conf for detail config.

listen 19350;
98 changes: 41 additions & 57 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# all config for srs

# The id of server, for stat and api identification.
# Note that SRS will generate a random id if not configured.
# Overwrite by env SRS_SERVER_ID
server_id srs-ie193id;

#############################################################################################
# RTMP sections
#############################################################################################
@@ -121,6 +126,12 @@ tcmalloc_release_rate 0.8;
# Default: on
query_latest_version on;

# First wait when qlv(query latest version), in seconds.
# Only available when qlv is enabled.
# Overwrite by env SRS_FIRST_WAIT_FOR_QLV
# Default: 300
first_wait_for_qlv 300;

# For system circuit breaker.
circuit_breaker {
# Whether enable the circuit breaker.
@@ -360,8 +371,8 @@ srt_server {
# The UDP listen port for SRT.
listen 10080;
# For detail parameters, please read wiki:
# https://github.com/ossrs/srs/wiki/v4_CN_SRTParams
# https://github.com/ossrs/srs/wiki/v4_EN_SRTParams
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/srt-params
# @see https://ossrs.io/lts/en-us/docs/v4/doc/srt-params
maxbw 1000000000;
connect_timeout 4000;
peerlatency 300;
@@ -383,24 +394,30 @@ rtc_server {
listen 8000;
# The exposed candidate IPs, response in SDP candidate line. It can be:
# * Retrieve server IP automatically, from all network interfaces.
# eth0 Retrieve server IP by specified network interface name. # TODO: Implements it.
# $CANDIDATE Read the IP from ENV variable, use * if not set.
# x.x.x.x A specified IP address or DNS name, which can be access by client such as Chrome.
# You can specific more than one interface name:
# eth0 eth1 Use network interface eth0 and eth1. # TODO: Implements it.
# Also by IP or DNS names:
# 192.168.1.3 10.1.2.3 rtc.me # TODO: Implements it.
# And by multiple ENV variables:
# $CANDIDATE $EIP # TODO: Implements it.
# @remark For Firefox, the candidate MUST be IP, MUST NOT be DNS name.
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# x.x.x.x A specified IP address or DNS name, use * if 0.0.0.0.
# @remark For Firefox, the candidate MUST be IP, MUST NOT be DNS name, see https://bugzilla.mozilla.org/show_bug.cgi?id=1239006
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/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;
# If use api as CANDIDATE, whether resolve the api hostname.
# Note that use original domain name as CANDIDATE, which might make Firefox failed, see https://bugzilla.mozilla.org/show_bug.cgi?id=1239006
# Note that if hostname is IPv4 address, always directly use it.
# Default: on
resolve_api_domain on;
# If use api as CANDIDATE, whether keep original api domain name as CANDIDATE.
# Note that use original domain name as CANDIDATE, which might make Firefox failed, see https://bugzilla.mozilla.org/show_bug.cgi?id=1239006
# Default: off
keep_api_domain off;
# Whether use network interface IP which is detected automatically, filtered by ip_family.
# Note that browser might fail if no CANDIDATE specified.
# Default: on
use_auto_detect_network_ip on;
# The IP family filter for auto discover candidate, it can be:
# ipv4 Filter IP v4 candidates.
# ipv6 Filter IP v6 candidates.
@@ -599,7 +616,7 @@ vhost cluster.srs.com {
# it's strongly recommend to open the debug_srs_upnode,
# when connect to upnode, it will take the debug info,
# for example, the id, source id, pid.
# please see: https://github.com/ossrs/srs/wiki/v1_CN_SrsLog
# please see https://ossrs.net/lts/zh-cn/docs/v4/doc/log
# default: on
debug_srs_upnode on;

@@ -611,7 +628,7 @@ vhost cluster.srs.com {

# For origin (mode local) cluster, the co-worker's HTTP APIs.
# This origin will connect to co-workers and communicate with them.
# please read: https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
# please see https://ossrs.io/lts/en-us/docs/v4/doc/origin-cluster
# TODO: FIXME: Support reload.
coworkers 127.0.0.1:9091 127.0.0.1:9092;
}
@@ -1027,39 +1044,6 @@ vhost hooks.callback.srs.com {
# whether the http hooks enable.
# default off.
enabled on;
# when client connect to vhost/app, call the hook,
# the request in the POST data string is a object encode by json:
# {
# "action": "on_connect",
# "client_id": 1985,
# "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
# "tcUrl": "rtmp://video.test.com/live?key=d2fa801d08e3f90ed1e1670e6e52651a",
# "pageUrl": "http://www.test.com/live.html", "server_id": "vid-werty"
# }
# if valid, the hook must return HTTP code 200(Status OK) and response
# an int value specifies the error code(0 corresponding to success):
# 0
# support multiple api hooks, format:
# on_connect http://xxx/api0 http://xxx/api1 http://xxx/apiN
# @remark For SRS4, the HTTPS url is supported, for example:
# on_connect https://xxx/api0 https://xxx/api1 https://xxx/apiN
on_connect http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;
# when client close/disconnect to vhost/app/stream, call the hook,
# the request in the POST data string is a object encode by json:
# {
# "action": "on_close",
# "client_id": 1985,
# "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
# "send_bytes": 10240, "recv_bytes": 10240, "server_id": "vid-werty"
# }
# if valid, the hook must return HTTP code 200(Status OK) and response
# an int value specifies the error code(0 corresponding to success):
# 0
# support multiple api hooks, format:
# on_close http://xxx/api0 http://xxx/api1 http://xxx/apiN
# @remark For SRS4, the HTTPS url is supported, for example:
# on_close https://xxx/api0 https://xxx/api1 https://xxx/apiN
on_close http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;
# when client(encoder) publish to vhost/app/stream, call the hook,
# the request in the POST data string is a object encode by json:
# {
@@ -1296,8 +1280,8 @@ vhost hls.srs.com {
# [timestamp],replace this const to current UNIX timestamp in ms.
# [seq], the sequence number of ts.
# [duration], replace this const to current ts duration.
# @see https://github.com/ossrs/srs/wiki/v2_CN_DVR#custom-path
# @see https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS#hls-config
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/dvr#custom-path
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-hls#hls-config
# default: [app]/[stream]-[seq].ts
hls_ts_file [app]/[stream]-[seq].ts;
# whether use floor for the hls_ts_file path generation.
@@ -1381,8 +1365,8 @@ vhost hls.srs.com {

# on_hls, never config in here, should config in http_hooks.
# for the hls http callback, @see http_hooks.on_hls of vhost hooks.callback.srs.com
# @read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS#http-callback
# @read https://github.com/ossrs/srs/wiki/v2_EN_DeliveryHLS#http-callback
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-hls#http-callback
# @see https://ossrs.io/lts/en-us/docs/v4/doc/delivery-hls#http-callback

# on_hls_notify, never config in here, should config in http_hooks.
# we support the variables to generate the notify url:
@@ -1391,8 +1375,8 @@ vhost hls.srs.com {
# [param], replace with the param.
# [ts_url], replace with the ts url.
# for the hls http callback, @see http_hooks.on_hls_notify of vhost hooks.callback.srs.com
# @read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS#on-hls-notify
# @read https://github.com/ossrs/srs/wiki/v2_EN_DeliveryHLS#on-hls-notify
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-hls#on-hls-notify
# @see https://ossrs.io/lts/en-us/docs/v4/doc/delivery-hls#on-hls-notify
}
}
# the vhost with hls disabled.
@@ -1481,8 +1465,8 @@ vhost dvr.srs.com {
# dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].mp4;
# =>
# dvr_path ./objs/nginx/html/live/livestream.1420254068776.mp4;
# @see https://github.com/ossrs/srs/wiki/v3_CN_DVR#custom-path
# @see https://github.com/ossrs/srs/wiki/v3_EN_DVR#custom-path
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/dvr#custom-path
# @see https://ossrs.io/lts/en-us/docs/v4/doc/dvr#custom-path
# segment,session apply it.
# default: ./objs/nginx/html/[app]/[stream].[timestamp].flv
dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].flv;
@@ -1514,8 +1498,8 @@ vhost dvr.srs.com {

# on_dvr, never config in here, should config in http_hooks.
# for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com
# @read https://github.com/ossrs/srs/wiki/v2_CN_DVR#http-callback
# @read https://github.com/ossrs/srs/wiki/v2_EN_DVR#http-callback
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/dvr#http-callback
# @see https://ossrs.io/lts/en-us/docs/v4/doc/dvr#http-callback
}
}

2 changes: 1 addition & 1 deletion trunk/conf/go-oryx-edge.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-edge cluster
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/edge
# @see full.conf for detail config.

listen 19351;
2 changes: 1 addition & 1 deletion trunk/conf/go-oryx-edge2.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-edge cluster
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/edge
# @see full.conf for detail config.

listen 19352;
1 change: 0 additions & 1 deletion trunk/conf/hds.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# the config for srs to delivery hds
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleHDS
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/hls.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery hls
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleHLS
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-hls
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/hls.realtime.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery realtime RTMP stream
# @see https://github.com/ossrs/srs/wiki/v2_CN_SampleRealtime
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-realtime
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/http.aac.live.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to remux rtmp to aac live stream.
# @see https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-http-flv
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/http.flv.live.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to remux rtmp to flv live stream.
# @see https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-http-flv
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/http.flv.live.edge1.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to remux rtmp to flv live stream.
# @see https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-http-flv
# @see full.conf for detail config.

listen 19351;
2 changes: 1 addition & 1 deletion trunk/conf/http.flv.live.edge2.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to remux rtmp to flv live stream.
# @see https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-http-flv
# @see full.conf for detail config.

listen 19352;
2 changes: 1 addition & 1 deletion trunk/conf/http.hls.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery hls
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleHLS
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-hls
# @see full.conf for detail config.

listen 1935;
2 changes: 0 additions & 2 deletions trunk/conf/http.hooks.callback.conf
Original file line number Diff line number Diff line change
@@ -8,8 +8,6 @@ srs_log_tank console;
vhost __defaultVhost__ {
http_hooks {
enabled on;
on_connect http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;
on_close http://127.0.0.1:8085/api/v1/clients http://localhost:8085/api/v1/clients;
on_publish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
on_unpublish http://127.0.0.1:8085/api/v1/streams http://localhost:8085/api/v1/streams;
on_play http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions;
2 changes: 1 addition & 1 deletion trunk/conf/http.mp3.live.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to remux rtmp to mp3 live stream.
# @see https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-http-flv
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/http.ts.live.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to remux rtmp to ts live stream.
# @see https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHttpStream
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/delivery-http-flv
# @see full.conf for detail config.

listen 1935;
6 changes: 3 additions & 3 deletions trunk/conf/https.docker.conf
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

@@ -46,9 +46,9 @@ vhost __defaultVhost__ {
}
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
}
2 changes: 0 additions & 2 deletions trunk/conf/https.hooks.callback.conf
Original file line number Diff line number Diff line change
@@ -9,8 +9,6 @@ srs_log_tank console;
vhost __defaultVhost__ {
http_hooks {
enabled on;
on_connect https://127.0.0.1:443/api/v1/clients;
on_close https://127.0.0.1:443/api/v1/clients;
on_publish https://127.0.0.1:443/api/v1/streams;
on_unpublish https://127.0.0.1:443/api/v1/streams;
on_play https://127.0.0.1:443/api/v1/sessions;
6 changes: 3 additions & 3 deletions trunk/conf/https.rtc.conf
Original file line number Diff line number Diff line change
@@ -32,16 +32,16 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
http_remux {
6 changes: 3 additions & 3 deletions trunk/conf/https.rtmp2rtc.conf
Original file line number Diff line number Diff line change
@@ -32,16 +32,16 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
http_remux {
6 changes: 3 additions & 3 deletions trunk/conf/https.srs.conf
Original file line number Diff line number Diff line change
@@ -32,7 +32,7 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

@@ -46,9 +46,9 @@ vhost __defaultVhost__ {
}
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
}
2 changes: 1 addition & 1 deletion trunk/conf/ingest.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# use ffmpeg to ingest file/stream/device to SRS
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleIngest
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-ingest
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/ingest.rtsp.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# use ffmpeg to ingest file/stream/device to SRS
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleIngest
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-ingest
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/origin.cluster.edge.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-edge cluster
# @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
# @see https://ossrs.io/lts/en-us/docs/v4/doc/origin-cluster
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/origin.cluster.serverA.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-origin cluster
# @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
# @see https://ossrs.io/lts/en-us/docs/v4/doc/origin-cluster
# @see full.conf for detail config.

listen 19350;
2 changes: 1 addition & 1 deletion trunk/conf/origin.cluster.serverB.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-origin cluster
# @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
# @see https://ossrs.io/lts/en-us/docs/v4/doc/origin-cluster
# @see full.conf for detail config.

listen 19351;
2 changes: 1 addition & 1 deletion trunk/conf/origin.cluster.serverC.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-origin cluster
# @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
# @see https://ossrs.io/lts/en-us/docs/v4/doc/origin-cluster
# @see full.conf for detail config.

listen 19352;
2 changes: 1 addition & 1 deletion trunk/conf/origin.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-edge cluster
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/edge
# @see full.conf for detail config.

listen 19350;
2 changes: 1 addition & 1 deletion trunk/conf/push.flv.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# push HTTP FLV to SRS.
# @see https://github.com/ossrs/srs/wiki/v2_CN_Streamer#push-http-flv-to-srs
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/streamer#push-http-flv-to-srs
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/push.mpegts.over.udp.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# push MPEG-TS over UDP to SRS.
# @see https://github.com/ossrs/srs/wiki/v2_CN_Streamer#push-mpeg-ts-over-udp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/streamer#push-mpeg-ts-over-udp
# @see https://github.com/ossrs/srs/issues/250#issuecomment-72321769
# @see full.conf for detail config.

2 changes: 1 addition & 1 deletion trunk/conf/realtime.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery realtime RTMP stream
# @see https://github.com/ossrs/srs/wiki/v2_CN_SampleRealtime
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-realtime
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/realtime.flv.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery realtime RTMP stream
# @see https://github.com/ossrs/srs/wiki/v2_CN_SampleRealtime
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-realtime
# @see full.conf for detail config.

listen 1935;
6 changes: 3 additions & 3 deletions trunk/conf/rtc.conf
Original file line number Diff line number Diff line change
@@ -22,16 +22,16 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
http_remux {
6 changes: 3 additions & 3 deletions trunk/conf/rtc2rtmp.conf
Original file line number Diff line number Diff line change
@@ -20,16 +20,16 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
http_remux {
2 changes: 1 addition & 1 deletion trunk/conf/rtmp.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery RTMP
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleRTMP
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-rtmp
# @see full.conf for detail config.

listen 1935;
6 changes: 3 additions & 3 deletions trunk/conf/rtmp2rtc.conf
Original file line number Diff line number Diff line change
@@ -20,16 +20,16 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
http_remux {
6 changes: 3 additions & 3 deletions trunk/conf/srs.conf
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ http_server {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}
vhost __defaultVhost__ {
@@ -31,9 +31,9 @@ vhost __defaultVhost__ {
}
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
}
6 changes: 3 additions & 3 deletions trunk/conf/srt2rtc.conf
Original file line number Diff line number Diff line change
@@ -32,17 +32,17 @@ rtc_server {
# 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/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

# @doc https://github.com/ossrs/srs/issues/1147#issuecomment-577607026
vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
http_remux {
2 changes: 1 addition & 1 deletion trunk/conf/transcode2hls.audio.only.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs to delivery hls
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleHLS
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/sample-hls
# @see full.conf for detail config.

listen 1935;
2 changes: 1 addition & 1 deletion trunk/conf/transform.edge.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# the config for srs origin-edge cluster
# @see https://github.com/ossrs/srs/wiki/v2_CN_Edge#transform-vhost
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/edge#transform-vhost
# @see full.conf for detail config.

listen 1935;
6 changes: 3 additions & 3 deletions trunk/conf/vm.conf
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ stats {
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}

@@ -39,9 +39,9 @@ vhost __defaultVhost__ {
}
rtc {
enabled on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc on;
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp on;
}
}
2 changes: 1 addition & 1 deletion trunk/doc/Architecture.md
Original file line number Diff line number Diff line change
@@ -293,7 +293,7 @@ Supported operating systems and hardware:
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

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

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
21 changes: 21 additions & 0 deletions trunk/doc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -8,10 +8,31 @@ The changelog for SRS.

## SRS 4.0 Changelog

* v4.0, 2023-08-02, Fix [#3749](https://github.com/ossrs/srs/issues/3749): HLS: Ignore empty NALU to avoid error. v4.0.271
* v4.0, 2023-07-21, Merge [#3695](https://github.com/ossrs/srs/pull/3695): API: Fix HTTPS callback issue using SNI in TLS client handshake. v4.0.270 (#3695)
* v4.0, 2022-12-24, For [#296](https://github.com/ossrs/srs/issues/296): MP3: Fix bug for TS or HLS with mp3 codec. v4.0.269
* v4.0, 2022-11-22, Pick [#3079](https://github.com/ossrs/srs/issues/3079): WebRTC: Fix no audio and video issue for Firefox. v4.0.268
* v4.0, 2022-10-10, For [#2901](https://github.com/ossrs/srs/issues/2901): Edge: Fast disconnect and reconnect. v4.0.267
* v4.0, 2022-09-27, For [#3167](https://github.com/ossrs/srs/issues/3167): WebRTC: Refine sequence jitter algorithm. v4.0.266
* v4.0, 2022-09-16, For [#3179](https://github.com/ossrs/srs/issues/3179): WebRTC: Make sure the same m-lines order for offer and answer. v4.0.265
* v4.0, 2022-09-09, For [#3174](https://github.com/ossrs/srs/issues/3174): WebRTC: Support Unity to publish or play stream. v4.0.264
* v4.0, 2022-09-09, Fix [#3093](https://github.com/ossrs/srs/issues/3093): WebRTC: Ignore unknown fmtp for h.264. v4.0.263
* v4.0, 2022-09-06, Fix [#3170](https://github.com/ossrs/srs/issues/3170): WebRTC: Support WHIP(WebRTC-HTTP ingestion protocol). v4.0.262
* v4.0, 2022-09-03, Fix HTTP url parsing bug. v4.0.261
* v4.0, 2022-09-03, For [#3167](https://github.com/ossrs/srs/issues/3167): WebRTC: Play stucked when republish. v4.0.260
* v4.0, 2022-09-02, For [#307](https://github.com/ossrs/srs/issues/307): WebRTC: Support use domain name as CANDIDATE. v4.0.259
* v4.0, 2022-08-29, Copy libxml2-dev for FFmpeg. v4.0.258
* v4.0, 2022-08-24, STAT: Support config server_id and generate one if empty. v4.0.257
* v4.0, 2022-08-24, For [#2136](https://github.com/ossrs/srs/issues/2136): API: Cleanup no active streams for statistics. v4.0.256
* v4.0, 2022-08-17, RTMP URL supports domain in stream parameters. v4.0.255
* v4.0, 2022-08-10, Fix server id generator bug. v4.0.254
* v4.0, 2022-06-29, Update SRS image for r.ossrs.net. v4.0.253
* v4.0, 2022-06-11, For [#3058](https://github.com/ossrs/srs/pull/3058): Docker: Support x86_64, armv7 and aarch64 docker image (#3058). v4.0.252
* v4.0, 2022-03-19, For [#2893](https://github.com/ossrs/srs/pull/2893): SRT: Decouple publish with play url (#2893). v4.0.251
* v4.0, 2022-03-19, Merge [#2908](https://github.com/ossrs/srs/pull/2908): SRT: url supports multiple QueryStrings (#2908). v4.0.250
* v4.0, 2022-03-17, SRT: Support debug and run with CLion. v4.0.249
* v4.0, 2022-03-15, Merge [#2966](https://github.com/ossrs/srs/pull/2966): Bugfix: Fix rtcp nack blp encode bug (#2966). v4.0.248
* v4.0, 2022-03-11, Merge [#2914](https://github.com/ossrs/srs/pull/2914): Security: Enable CIDR for allow/deny play/publish.
* v4.0, 2022-03-07, RTC: Identify the WebRTC publisher in param for hooks. v4.0.247
* v4.0, 2022-03-07, SRT: Append vhost to stream, not app. v4.0.246
* v4.0, 2022-02-15, Fix warnings for uuid. v4.0.245
2 changes: 1 addition & 1 deletion trunk/doc/Features.md
Original file line number Diff line number Diff line change
@@ -304,7 +304,7 @@ The features of SRS.
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

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

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
2 changes: 1 addition & 1 deletion trunk/doc/PERFORMANCE.md
Original file line number Diff line number Diff line change
@@ -408,7 +408,7 @@ Winlin 2021
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

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

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
2 changes: 1 addition & 1 deletion trunk/doc/Resources.md
Original file line number Diff line number Diff line change
@@ -318,7 +318,7 @@ git clone https://github.com/ossrs/srs.git
[v4_EN_Contact]: https://github.com/ossrs/srs/wiki/v4_EN_Contact

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

[release2]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release20
[release3]: https://github.com/ossrs/srs/wiki/v4_CN_Product#release30
4 changes: 4 additions & 0 deletions trunk/research/players/js/srs.sdk.js
Original file line number Diff line number Diff line change
@@ -54,6 +54,8 @@ function SrsRtcPublisherAsync() {
var conf = self.__internal.prepareUrl(url);
self.pc.addTransceiver("audio", {direction: "sendonly"});
self.pc.addTransceiver("video", {direction: "sendonly"});
//self.pc.addTransceiver("video", {direction: "sendonly"});
//self.pc.addTransceiver("audio", {direction: "sendonly"});

if (!navigator.mediaDevices && window.location.protocol === 'http:' && window.location.hostname !== 'localhost') {
throw new SrsError('HttpsRequiredError', `Please use HTTPS or localhost to publish, read https://github.com/ossrs/srs/issues/2762#issuecomment-983147576`);
@@ -303,6 +305,8 @@ function SrsRtcPlayerAsync() {
var conf = self.__internal.prepareUrl(url);
self.pc.addTransceiver("audio", {direction: "recvonly"});
self.pc.addTransceiver("video", {direction: "recvonly"});
//self.pc.addTransceiver("video", {direction: "recvonly"});
//self.pc.addTransceiver("audio", {direction: "recvonly"});

var offer = await self.pc.createOffer();
await self.pc.setLocalDescription(offer);
159 changes: 156 additions & 3 deletions trunk/src/app/srs_app_config.cpp
Original file line number Diff line number Diff line change
@@ -58,6 +58,9 @@ const char* _srs_version = "XCORE-" RTMP_SIG_SRS_SERVER;
// '\r'
#define SRS_CR (char)SRS_CONSTS_CR

// Overwrite the config by env.
#define SRS_OVERWRITE_BY_ENV_SECONDS(key) if (getenv(key)) return ::atoi(getenv(key)) * SRS_UTIME_SECONDS

/**
* dumps the ingest/transcode-engine in @param dir to amf0 object @param engine.
* @param dir the transcode or ingest config directive.
@@ -2466,11 +2469,11 @@ srs_error_t SrsConfig::check_normal_config()
&& n != "max_connections" && n != "daemon" && n != "heartbeat"
&& n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms"
&& n != "http_server" && n != "stream_caster" && n != "rtc_server" && n != "srt_server"
&& n != "utc_time" && n != "work_dir" && n != "asprocess"
&& n != "utc_time" && n != "work_dir" && n != "asprocess" && n != "server_id"
&& n != "ff_log_level" && n != "grace_final_wait" && n != "force_grace_quit"
&& 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 != "query_latest_version" && n != "first_wait_for_qlv"
&& 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 +2545,8 @@ 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 != "api_as_candidates") {
&& n != "ip_family" && n != "api_as_candidates" && n != "resolve_api_domain"
&& n != "keep_api_domain" && n != "use_auto_detect_network_ip") {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal rtc_server.%s", n.c_str());
}
}
@@ -3028,6 +3032,90 @@ SrsConfDirective* SrsConfig::get_root()
return root;
}

string srs_server_id_path(string pid_file)
{
string path = srs_string_replace(pid_file, ".pid", ".id");
if (!srs_string_ends_with(path, ".id")) {
path += ".id";
}
return path;
}

string srs_try_read_file(string path) {
srs_error_t err = srs_success;

SrsFileReader r;
if ((err = r.open(path)) != srs_success) {
srs_freep(err);
return "";
}

static char buf[1024];
ssize_t nn = 0;
if ((err = r.read(buf, sizeof(buf), &nn)) != srs_success) {
srs_freep(err);
return "";
}

if (nn > 0) {
return string(buf, nn);
}
return "";
}

void srs_try_write_file(string path, string content) {
srs_error_t err = srs_success;

SrsFileWriter w;
if ((err = w.open(path)) != srs_success) {
srs_freep(err);
return;
}

if ((err = w.write((void*)content.data(), content.length(), NULL)) != srs_success) {
srs_freep(err);
return;
}
}

string SrsConfig::get_server_id()
{
static string DEFAULT = "";

// Try to read DEFAULT from server id file.
if (DEFAULT.empty()) {
DEFAULT = srs_try_read_file(srs_server_id_path(get_pid_file()));
}

// Generate a random one if empty.
if (DEFAULT.empty()) {
DEFAULT = srs_generate_stat_vid();
}

// Get the server id from env, config or DEFAULT.
string server_id;

if (getenv("SRS_SERVER_ID")) {
server_id = getenv("SRS_SERVER_ID");
}

SrsConfDirective* conf = root->get("server_id");
if (conf) {
server_id = conf->arg0();
}

if (server_id.empty()) {
server_id = DEFAULT;
}

// Write server id to tmp file.
if (!server_id.empty()) {
srs_try_write_file(srs_server_id_path(get_pid_file()), server_id);
}

return server_id;
}

int SrsConfig::get_max_connections()
{
static int DEFAULT = 1000;
@@ -3128,6 +3216,20 @@ bool SrsConfig::whether_query_latest_version()
return SRS_CONF_PERFER_TRUE(conf->arg0());
}

srs_utime_t SrsConfig::first_wait_for_qlv()
{
SRS_OVERWRITE_BY_ENV_SECONDS("SRS_FIRST_WAIT_FOR_QLV");

static srs_utime_t DEFAULT = 5 * 60 * SRS_UTIME_SECONDS;

SrsConfDirective* conf = root->get("first_wait_for_qlv");
if (!conf) {
return DEFAULT;
}

return ::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS;
}

bool SrsConfig::empty_ip_ok()
{
static bool DEFAULT = true;
@@ -3561,6 +3663,57 @@ bool SrsConfig::get_api_as_candidates()
return SRS_CONF_PERFER_TRUE(conf->arg0());
}

bool SrsConfig::get_resolve_api_domain()
{
static bool DEFAULT = true;

SrsConfDirective* conf = root->get("rtc_server");
if (!conf) {
return DEFAULT;
}

conf = conf->get("resolve_api_domain");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}

return SRS_CONF_PERFER_TRUE(conf->arg0());
}

bool SrsConfig::get_keep_api_domain()
{
static bool DEFAULT = false;

SrsConfDirective* conf = root->get("rtc_server");
if (!conf) {
return DEFAULT;
}

conf = conf->get("keep_api_domain");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}

return SRS_CONF_PERFER_FALSE(conf->arg0());
}

bool SrsConfig::get_use_auto_detect_network_ip()
{
static bool DEFAULT = true;

SrsConfDirective* conf = root->get("rtc_server");
if (!conf) {
return DEFAULT;
}

conf = conf->get("use_auto_detect_network_ip");
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";
6 changes: 6 additions & 0 deletions trunk/src/app/srs_app_config.hpp
Original file line number Diff line number Diff line change
@@ -388,6 +388,8 @@ class SrsConfig
// Whether user use full.conf
virtual bool is_full_config();
public:
// Get the server id, generated a random one if not configured.
virtual std::string get_server_id();
// Get the max connections limit of system.
// If exceed the max connection, SRS will disconnect the connection.
// @remark, linux will limit the connections of each process,
@@ -419,6 +421,7 @@ class SrsConfig
virtual bool get_asprocess();
// Whether query the latest available version of SRS.
virtual bool whether_query_latest_version();
virtual srs_utime_t first_wait_for_qlv();
// Whether empty client IP is ok.
virtual bool empty_ip_ok();
// Get the start wait in ms for gracefully quit.
@@ -470,6 +473,9 @@ class SrsConfig
virtual int get_rtc_server_listen();
virtual std::string get_rtc_server_candidates();
virtual bool get_api_as_candidates();
virtual bool get_resolve_api_domain();
virtual bool get_keep_api_domain();
virtual bool get_use_auto_detect_network_ip();
virtual std::string get_rtc_server_ip_family();
virtual bool get_rtc_server_ecdsa();
virtual bool get_rtc_server_encrypt();
9 changes: 7 additions & 2 deletions trunk/src/app/srs_app_edge.cpp
Original file line number Diff line number Diff line change
@@ -201,8 +201,8 @@ void SrsEdgeIngester::stop()
{
trd->stop();
upstream->close();
// notice to unpublish.

// Notify source to un-publish if exists.
if (source) {
source->on_unpublish();
}
@@ -232,6 +232,11 @@ srs_error_t SrsEdgeIngester::cycle()
srs_freep(err);
}

// Check whether coroutine is stopped, see https://github.com/ossrs/srs/issues/2901
if ((err = trd->pull()) != srs_success) {
return srs_error_wrap(err, "edge ingester");
}

srs_usleep(SRS_EDGE_INGESTER_CIMS);
}

28 changes: 28 additions & 0 deletions trunk/src/app/srs_app_hls.cpp
Original file line number Diff line number Diff line change
@@ -202,6 +202,7 @@ SrsHlsMuxer::SrsHlsMuxer()
async = new SrsAsyncCallWorker();
context = new SrsTsContext();
segments = new SrsFragmentWindow();
latest_acodec_ = SrsAudioCodecIdForbidden;

memset(key, 0, 16);
memset(iv, 0, 16);
@@ -263,6 +264,24 @@ int SrsHlsMuxer::deviation()
return deviation_ts;
}

SrsAudioCodecId SrsHlsMuxer::latest_acodec()
{
// If current context writer exists, we query from it.
if (current && current->tscw) return current->tscw->acodec();

// Get the configured or updated config.
return latest_acodec_;
}

void SrsHlsMuxer::set_latest_acodec(SrsAudioCodecId v)
{
// Refresh the codec in context writer for current segment.
if (current && current->tscw) current->tscw->set_acodec(v);

// Refresh the codec for future segments.
latest_acodec_ = v;
}

srs_error_t SrsHlsMuxer::initialize()
{
return srs_success;
@@ -371,6 +390,8 @@ srs_error_t SrsHlsMuxer::segment_open()
srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str());
}
}
// Now that we know the latest audio codec in stream, use it.
if (latest_acodec_ != SrsAudioCodecIdForbidden) default_acodec = latest_acodec_;

// load the default vcodec from config.
SrsVideoCodecId default_vcodec = SrsVideoCodecIdAVC;
@@ -963,6 +984,13 @@ srs_error_t SrsHlsController::on_sequence_header()
srs_error_t SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts)
{
srs_error_t err = srs_success;

// Refresh the codec ASAP.
if (muxer->latest_acodec() != frame->acodec()->id) {
srs_trace("HLS: Switch audio codec %d(%s) to %d(%s)", muxer->latest_acodec(), srs_audio_codec_id2str(muxer->latest_acodec()).c_str(),
frame->acodec()->id, srs_audio_codec_id2str(frame->acodec()->id).c_str());
muxer->set_latest_acodec(frame->acodec()->id);
}

// write audio to cache.
if ((err = tsmc->cache_audio(frame, pts)) != srs_success) {
6 changes: 6 additions & 0 deletions trunk/src/app/srs_app_hls.hpp
Original file line number Diff line number Diff line change
@@ -156,6 +156,9 @@ class SrsHlsMuxer
SrsHlsSegment* current;
// The ts context, to keep cc continous between ts.
SrsTsContext* context;
private:
// Latest audio codec, parsed from stream.
SrsAudioCodecId latest_acodec_;
public:
SrsHlsMuxer();
virtual ~SrsHlsMuxer();
@@ -166,6 +169,9 @@ class SrsHlsMuxer
virtual std::string ts_url();
virtual srs_utime_t duration();
virtual int deviation();
public:
SrsAudioCodecId latest_acodec();
void set_latest_acodec(SrsAudioCodecId v);
public:
// Initialize the hls muxer.
virtual srs_error_t initialize();
4 changes: 3 additions & 1 deletion trunk/src/app/srs_app_http_stream.cpp
Original file line number Diff line number Diff line change
@@ -773,7 +773,9 @@ void SrsLiveStream::http_hooks_on_stop(ISrsHttpMessage* r)
srs_error_t SrsLiveStream::streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs)
{
srs_error_t err = srs_success;


// TODO: In gop cache, we know both the audio and video codec, so we should notice the encoder, which might depends
// on setting the correct codec information, for example, HTTP-TS or HLS will write PMT.
for (int i = 0; i < nb_msgs; i++) {
SrsSharedPtrMessage* msg = msgs[i];

33 changes: 11 additions & 22 deletions trunk/src/app/srs_app_latest_version.cpp
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_app_http_client.hpp>
#include <srs_app_utility.hpp>
#include <srs_app_uuid.hpp>
#include <srs_app_statistic.hpp>

#include <unistd.h>
#include <sstream>
@@ -189,16 +190,8 @@ srs_error_t SrsLatestVersion::start()
return srs_success;
}

if (true) {
uuid_t uuid;
uuid_generate_time(uuid);

char buf[32];
for (int i = 0; i < 16; i++) {
snprintf(buf + i * 2, sizeof(buf), "%02x", uuid[i]);
}
server_id_ = string(buf, sizeof(buf));
}
server_id_ = SrsStatistic::instance()->server_id();
session_id_ = srs_generate_stat_vid();

return trd_->start();
}
@@ -208,15 +201,10 @@ srs_error_t SrsLatestVersion::cycle()
srs_error_t err = srs_success;

if (true) {
srs_utime_t first_random_wait = 0;
srs_random_generate((char *) &first_random_wait, 8);
first_random_wait = srs_utime_t(uint64_t((first_random_wait + srs_update_system_time() + getpid())) % (5 * 60)) * SRS_UTIME_SECONDS; // in s.

// Only report after 5+ minutes.
first_random_wait += 5 * 60 * SRS_UTIME_SECONDS;

srs_trace("Startup query id=%s, eip=%s, wait=%ds", server_id_.c_str(), srs_get_public_internet_address().c_str(), srsu2msi(first_random_wait) / 1000);
srs_usleep(first_random_wait);
srs_utime_t first_wait_for_qlv = _srs_config->first_wait_for_qlv();
string pip = srs_get_public_internet_address();
srs_trace("Startup query id=%s, session=%s, eip=%s, wait=%ds", server_id_.c_str(), session_id_.c_str(), pip.c_str(), srsu2msi(first_wait_for_qlv) / 1000);
srs_usleep(first_wait_for_qlv);
}

while (true) {
@@ -231,8 +219,8 @@ srs_error_t SrsLatestVersion::cycle()
srs_freep(err); // Ignore any error.
}

srs_trace("Finish query id=%s, eip=%s, match=%s, stable=%s, cost=%dms, url=%s",
server_id_.c_str(), srs_get_public_internet_address().c_str(), match_version_.c_str(),
srs_trace("Finish query id=%s, session=%s, eip=%s, match=%s, stable=%s, cost=%dms, url=%s",
server_id_.c_str(), session_id_.c_str(), srs_get_public_internet_address().c_str(), match_version_.c_str(),
stable_version_.c_str(), srsu2msi(srs_update_system_time() - starttime), url.c_str());

srs_usleep(3600 * SRS_UTIME_SECONDS); // Every an hour.
@@ -249,11 +237,12 @@ srs_error_t SrsLatestVersion::query_latest_version(string& url)
stringstream ss;
ss << "http://api.ossrs.net/service/v1/releases?"
<< "version=v" << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION
<< "&id=" << server_id_ << "&role=srs"
<< "&id=" << server_id_ << "&session=" << session_id_ << "&role=srs"
<< "&eip=" << srs_get_public_internet_address()
<< "&ts=" << srs_get_system_time()
<< "&alive=" << srsu2ms(srs_get_system_time() - srs_get_system_startup_time()) / 1000;
srs_build_features(ss);
SrsStatistic::instance()->dumps_hints_kv(ss);
url = ss.str();

SrsHttpUri uri;
1 change: 1 addition & 0 deletions trunk/src/app/srs_app_latest_version.hpp
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@ class SrsLatestVersion : public ISrsCoroutineHandler
private:
SrsCoroutine* trd_;
std::string server_id_;
std::string session_id_;
private:
std::string match_version_;
std::string stable_version_;
223 changes: 173 additions & 50 deletions trunk/src/app/srs_app_rtc_api.cpp
Original file line number Diff line number Diff line change
@@ -121,7 +121,7 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe

srs_parse_rtmp_url(streamurl, ruc.req_->tcUrl, ruc.req_->stream);

srs_discovery_tc_url(ruc.req_->tcUrl, ruc.req_->schema, ruc.req_->host, ruc.req_->vhost,
srs_discovery_tc_url(ruc.req_->tcUrl, ruc.req_->schema, ruc.req_->host, ruc.req_->vhost,
ruc.req_->app, ruc.req_->stream, ruc.req_->port, ruc.req_->param);

// discovery vhost, resolve the vhost from config
@@ -130,10 +130,6 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
ruc.req_->vhost = parsed_vhost->arg0();
}

if ((err = http_hooks_on_play(ruc.req_)) != srs_success) {
return srs_error_wrap(err, "RTC: http_hooks_on_play");
}

// For client to specifies the candidate(EIP) of server.
string eip = r->query_get("eip");
if (eip.empty()) {
@@ -144,9 +140,11 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
string srtp = r->query_get("encrypt");
string dtls = r->query_get("dtls");

srs_trace("RTC play %s, api=%s, tid=%s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, codec=%s, srtp=%s, dtls=%s",
streamurl.c_str(), api.c_str(), tid.c_str(), clientip.c_str(), ruc.req_->app.c_str(), ruc.req_->stream.c_str(), remote_sdp_str.length(),
eip.c_str(), codec.c_str(), srtp.c_str(), dtls.c_str()
srs_trace(
"RTC play %s, api=%s, tid=%s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, codec=%s, srtp=%s, dtls=%s",
streamurl.c_str(), api.c_str(), tid.c_str(), clientip.c_str(), ruc.req_->app.c_str(),
ruc.req_->stream.c_str(), remote_sdp_str.length(),
eip.c_str(), codec.c_str(), srtp.c_str(), dtls.c_str()
);

ruc.eip_ = eip;
@@ -161,6 +159,7 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
}

// TODO: FIXME: It seems remote_sdp doesn't represents the full SDP information.
ruc.remote_sdp_str_ = remote_sdp_str;
if ((err = ruc.remote_sdp_.parse(remote_sdp_str)) != srs_success) {
return srs_error_wrap(err, "parse sdp failed: %s", remote_sdp_str.c_str());
}
@@ -169,42 +168,64 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
return srs_error_wrap(err, "remote sdp check failed");
}

if ((err = http_hooks_on_play(ruc.req_)) != srs_success) {
return srs_error_wrap(err, "RTC: http_hooks_on_play");
}

if ((err = serve_http(w, r, &ruc)) != srs_success) {
return srs_error_wrap(err, "serve");
}

res->set("code", SrsJsonAny::integer(ERROR_SUCCESS));
res->set("server", SrsJsonAny::str(SrsStatistic::instance()->server_id().c_str()));

// TODO: add candidates in response json?
res->set("sdp", SrsJsonAny::str(ruc.local_sdp_str_.c_str()));
res->set("sessionid", SrsJsonAny::str(ruc.session_id_.c_str()));

return err;
}

srs_error_t SrsGoApiRtcPlay::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsRtcUserConfig* ruc)
{
srs_error_t err = srs_success;

SrsSdp local_sdp;

// Config for SDP and session.
local_sdp.session_config_.dtls_role = _srs_config->get_rtc_dtls_role(ruc.req_->vhost);
local_sdp.session_config_.dtls_version = _srs_config->get_rtc_dtls_version(ruc.req_->vhost);
local_sdp.session_config_.dtls_role = _srs_config->get_rtc_dtls_role(ruc->req_->vhost);
local_sdp.session_config_.dtls_version = _srs_config->get_rtc_dtls_version(ruc->req_->vhost);

// Whether enabled.
bool server_enabled = _srs_config->get_rtc_server_enabled();
bool rtc_enabled = _srs_config->get_rtc_enabled(ruc.req_->vhost);
bool rtc_enabled = _srs_config->get_rtc_enabled(ruc->req_->vhost);
if (server_enabled && !rtc_enabled) {
srs_warn("RTC disabled in vhost %s", ruc.req_->vhost.c_str());
srs_warn("RTC disabled in vhost %s", ruc->req_->vhost.c_str());
}
if (!server_enabled || !rtc_enabled) {
return srs_error_new(ERROR_RTC_DISABLED, "Disabled server=%d, rtc=%d, vhost=%s",
server_enabled, rtc_enabled, ruc.req_->vhost.c_str());
server_enabled, rtc_enabled, ruc->req_->vhost.c_str());
}

// Whether RTC stream is active.
bool is_rtc_stream_active = false;
if (true) {
SrsRtcSource* source = _srs_rtc_sources->fetch(ruc.req_);
SrsRtcSource* source = _srs_rtc_sources->fetch(ruc->req_);
is_rtc_stream_active = (source && !source->can_publish());
}

// For RTMP to RTC, fail if disabled and RTMP is active, see https://github.com/ossrs/srs/issues/2728
if (!is_rtc_stream_active && !_srs_config->get_rtc_from_rtmp(ruc.req_->vhost)) {
SrsLiveSource* rtmp = _srs_sources->fetch(ruc.req_);
if (!is_rtc_stream_active && !_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());
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) {
return srs_error_wrap(err, "create session, dtls=%u, srtp=%u, eip=%s", ruc.dtls_, ruc.srtp_, eip.c_str());
if ((err = server_->create_session(ruc, local_sdp, &session)) != srs_success) {
return srs_error_wrap(err, "create session, dtls=%u, srtp=%u, eip=%s", ruc->dtls_, ruc->srtp_, ruc->eip_.c_str());
}

ostringstream os;
@@ -216,17 +237,12 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
// Filter the \r\n to \\r\\n for JSON.
string local_sdp_escaped = srs_string_replace(local_sdp_str.c_str(), "\r\n", "\\r\\n");

res->set("code", SrsJsonAny::integer(ERROR_SUCCESS));
res->set("server", SrsJsonAny::str(SrsStatistic::instance()->server_id().c_str()));

// TODO: add candidates in response json?

res->set("sdp", SrsJsonAny::str(local_sdp_str.c_str()));
res->set("sessionid", SrsJsonAny::str(session->username().c_str()));
ruc->local_sdp_str_ = local_sdp_str;
ruc->session_id_ = session->username();

srs_trace("RTC username=%s, dtls=%u, srtp=%u, offer=%dB, answer=%dB", session->username().c_str(),
ruc.dtls_, ruc.srtp_, remote_sdp_str.length(), local_sdp_escaped.length());
srs_trace("RTC remote offer: %s", srs_string_replace(remote_sdp_str.c_str(), "\r\n", "\\r\\n").c_str());
ruc->dtls_, ruc->srtp_, ruc->remote_sdp_str_.length(), local_sdp_escaped.length());
srs_trace("RTC remote offer: %s", srs_string_replace(ruc->remote_sdp_str_.c_str(), "\r\n", "\\r\\n").c_str());
srs_trace("RTC local answer: %s", local_sdp_escaped.c_str());

return err;
@@ -333,8 +349,7 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt
srs_error_t err = srs_success;

// For each RTC session, we use short-term HTTP connection.
SrsHttpHeader* hdr = w->header();
hdr->set("Connection", "Close");
w->header()->set("Connection", "Close");

// Parse req, the request json object, from body.
SrsJsonObject* req = NULL;
@@ -406,10 +421,6 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt
ruc.req_->vhost = parsed_vhost->arg0();
}

if ((err = http_hooks_on_publish(ruc.req_)) != srs_success) {
return srs_error_wrap(err, "RTC: http_hooks_on_publish");
}

// For client to specifies the candidate(EIP) of server.
string eip = r->query_get("eip");
if (eip.empty()) {
@@ -428,35 +439,58 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt
ruc.dtls_ = ruc.srtp_ = true;

// TODO: FIXME: It seems remote_sdp doesn't represents the full SDP information.
ruc.remote_sdp_str_ = remote_sdp_str;
if ((err = ruc.remote_sdp_.parse(remote_sdp_str)) != srs_success) {
return srs_error_wrap(err, "parse sdp failed: %s", remote_sdp_str.c_str());
}

if ((err = check_remote_sdp(ruc.remote_sdp_)) != srs_success) {
if ((err = serve_http(w, r, &ruc)) != srs_success) {
return srs_error_wrap(err, "serve");
}

res->set("code", SrsJsonAny::integer(ERROR_SUCCESS));
res->set("server", SrsJsonAny::str(SrsStatistic::instance()->server_id().c_str()));

// TODO: add candidates in response json?
res->set("sdp", SrsJsonAny::str(ruc.local_sdp_str_.c_str()));
res->set("sessionid", SrsJsonAny::str(ruc.session_id_.c_str()));

return err;
}

srs_error_t SrsGoApiRtcPublish::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsRtcUserConfig* ruc)
{
srs_error_t err = srs_success;

if ((err = check_remote_sdp(ruc->remote_sdp_)) != srs_success) {
return srs_error_wrap(err, "remote sdp check failed");
}

if ((err = http_hooks_on_publish(ruc->req_)) != srs_success) {
return srs_error_wrap(err, "RTC: http_hooks_on_publish");
}

SrsSdp local_sdp;

// TODO: FIXME: move to create_session.
// Config for SDP and session.
local_sdp.session_config_.dtls_role = _srs_config->get_rtc_dtls_role(ruc.req_->vhost);
local_sdp.session_config_.dtls_version = _srs_config->get_rtc_dtls_version(ruc.req_->vhost);
local_sdp.session_config_.dtls_role = _srs_config->get_rtc_dtls_role(ruc->req_->vhost);
local_sdp.session_config_.dtls_version = _srs_config->get_rtc_dtls_version(ruc->req_->vhost);

// Whether enabled.
bool server_enabled = _srs_config->get_rtc_server_enabled();
bool rtc_enabled = _srs_config->get_rtc_enabled(ruc.req_->vhost);
bool rtc_enabled = _srs_config->get_rtc_enabled(ruc->req_->vhost);
if (server_enabled && !rtc_enabled) {
srs_warn("RTC disabled in vhost %s", ruc.req_->vhost.c_str());
srs_warn("RTC disabled in vhost %s", ruc->req_->vhost.c_str());
}
if (!server_enabled || !rtc_enabled) {
return srs_error_new(ERROR_RTC_DISABLED, "Disabled server=%d, rtc=%d, vhost=%s",
server_enabled, rtc_enabled, ruc.req_->vhost.c_str());
server_enabled, rtc_enabled, 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) {
if ((err = server_->create_session(ruc, local_sdp, &session)) != srs_success) {
return srs_error_wrap(err, "create session");
}

@@ -469,17 +503,12 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt
// Filter the \r\n to \\r\\n for JSON.
string local_sdp_escaped = srs_string_replace(local_sdp_str.c_str(), "\r\n", "\\r\\n");

res->set("code", SrsJsonAny::integer(ERROR_SUCCESS));
res->set("server", SrsJsonAny::str(SrsStatistic::instance()->server_id().c_str()));

// TODO: add candidates in response json?

res->set("sdp", SrsJsonAny::str(local_sdp_str.c_str()));
res->set("sessionid", SrsJsonAny::str(session->username().c_str()));
ruc->local_sdp_str_ = local_sdp_str;
ruc->session_id_ = session->username();

srs_trace("RTC username=%s, offer=%dB, answer=%dB", session->username().c_str(),
remote_sdp_str.length(), local_sdp_escaped.length());
srs_trace("RTC remote offer: %s", srs_string_replace(remote_sdp_str.c_str(), "\r\n", "\\r\\n").c_str());
ruc->remote_sdp_str_.length(), local_sdp_escaped.length());
srs_trace("RTC remote offer: %s", srs_string_replace(ruc->remote_sdp_str_.c_str(), "\r\n", "\\r\\n").c_str());
srs_trace("RTC local answer: %s", local_sdp_escaped.c_str());

return err;
@@ -545,6 +574,100 @@ srs_error_t SrsGoApiRtcPublish::http_hooks_on_publish(SrsRequest* req)
return err;
}

SrsGoApiRtcWhip::SrsGoApiRtcWhip(SrsRtcServer* server)
{
publish_ = new SrsGoApiRtcPublish(server);
play_ = new SrsGoApiRtcPlay(server);
}

SrsGoApiRtcWhip::~SrsGoApiRtcWhip()
{
srs_freep(publish_);
srs_freep(play_);
}

srs_error_t SrsGoApiRtcWhip::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
{
srs_error_t err = srs_success;

// For each RTC session, we use short-term HTTP connection.
w->header()->set("Connection", "Close");

string remote_sdp_str;
if ((err = r->body_read_all(remote_sdp_str)) != srs_success) {
return srs_error_wrap(err, "read sdp");
}

string clientip;
if (clientip.empty()){
clientip = dynamic_cast<SrsHttpMessage*>(r)->connection()->remote_ip();
// Overwrite by ip from proxy.
string oip = srs_get_original_ip(r);
if (!oip.empty()) {
clientip = oip;
}
}

// For client to specifies the candidate(EIP) of server.
string eip = r->query_get("eip");
if (eip.empty()) {
eip = r->query_get("candidate");
}
string codec = r->query_get("codec");
string app = r->query_get("app");
string stream = r->query_get("stream");
string action = r->query_get("action");
if (action.empty()) {
action = "publish";
}
if (srs_string_ends_with(r->path(), "/whip-play/")) {
action = "play";
}

// The RTC user config object.
SrsRtcUserConfig ruc;
ruc.req_->ip = clientip;
ruc.req_->host = r->host();
ruc.req_->vhost = ruc.req_->host;
ruc.req_->app = app.empty() ? "live" : app;
ruc.req_->stream = stream.empty() ? "livestream" : stream;

// discovery vhost, resolve the vhost from config
SrsConfDirective* parsed_vhost = _srs_config->get_vhost(ruc.req_->vhost);
if (parsed_vhost) {
ruc.req_->vhost = parsed_vhost->arg0();
}

srs_trace("RTC whip %s %s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, codec=%s",
action.c_str(), ruc.req_->get_stream_url().c_str(), clientip.c_str(), ruc.req_->app.c_str(), ruc.req_->stream.c_str(),
remote_sdp_str.length(), eip.c_str(), codec.c_str()
);

ruc.eip_ = eip;
ruc.codec_ = codec;
ruc.publish_ = (action == "publish");
ruc.dtls_ = ruc.srtp_ = true;

// TODO: FIXME: It seems remote_sdp doesn't represents the full SDP information.
ruc.remote_sdp_str_ = remote_sdp_str;
if ((err = ruc.remote_sdp_.parse(remote_sdp_str)) != srs_success) {
return srs_error_wrap(err, "parse sdp failed: %s", remote_sdp_str.c_str());
}

err = action == "publish" ? publish_->serve_http(w, r, &ruc) : play_->serve_http(w, r, &ruc);
if (err != srs_success) {
return srs_error_wrap(err, "serve");
}

if (ruc.local_sdp_str_.empty()) {
return srs_go_http_error(w, SRS_CONSTS_HTTP_InternalServerError);
}

string sdp = ruc.local_sdp_str_;
w->header()->set("Content-Type", "application/sdp");
return w->write((char*)sdp.data(), (int)sdp.length());
}

SrsGoApiRtcNACK::SrsGoApiRtcNACK(SrsRtcServer* server)
{
server_ = server;
20 changes: 20 additions & 0 deletions trunk/src/app/srs_app_rtc_api.hpp
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
class SrsRtcServer;
class SrsRequest;
class SrsSdp;
class SrsRtcUserConfig;

class SrsGoApiRtcPlay : public ISrsHttpHandler
{
@@ -26,6 +27,9 @@ class SrsGoApiRtcPlay : public ISrsHttpHandler
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
private:
virtual srs_error_t do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsJsonObject* res);
public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsRtcUserConfig* ruc);
private:
srs_error_t check_remote_sdp(const SrsSdp& remote_sdp);
private:
virtual srs_error_t http_hooks_on_play(SrsRequest* req);
@@ -42,11 +46,27 @@ class SrsGoApiRtcPublish : public ISrsHttpHandler
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
private:
virtual srs_error_t do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsJsonObject* res);
public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, SrsRtcUserConfig* ruc);
private:
srs_error_t check_remote_sdp(const SrsSdp& remote_sdp);
private:
virtual srs_error_t http_hooks_on_publish(SrsRequest* req);
};

// See https://datatracker.ietf.org/doc/draft-ietf-wish-whip/
class SrsGoApiRtcWhip : public ISrsHttpHandler
{
private:
SrsGoApiRtcPublish* publish_;
SrsGoApiRtcPlay* play_;
public:
SrsGoApiRtcWhip(SrsRtcServer* server);
virtual ~SrsGoApiRtcWhip();
public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
};

class SrsGoApiRtcNACK : public ISrsHttpHandler
{
private:
110 changes: 104 additions & 6 deletions trunk/src/app/srs_app_rtc_conn.cpp
Original file line number Diff line number Diff line change
@@ -510,10 +510,12 @@ srs_error_t SrsRtcPlayStream::initialize(SrsRequest* req, std::map<uint32_t, Srs

void SrsRtcPlayStream::on_stream_change(SrsRtcSourceDescription* desc)
{
if (!desc) return;

// Refresh the relation for audio.
// TODO: FIMXE: Match by label?
if (desc && desc->audio_track_desc_ && audio_tracks_.size() == 1) {
if (! audio_tracks_.empty()) {
if (!audio_tracks_.empty()) {
uint32_t ssrc = desc->audio_track_desc_->ssrc_;
SrsRtcAudioSendTrack* track = audio_tracks_.begin()->second;

@@ -525,7 +527,7 @@ void SrsRtcPlayStream::on_stream_change(SrsRtcSourceDescription* desc)
// Refresh the relation for video.
// TODO: FIMXE: Match by label?
if (desc && desc->video_track_descs_.size() == 1) {
if (! video_tracks_.empty()) {
if (!video_tracks_.empty()) {
SrsRtcTrackDescription* vdesc = desc->video_track_descs_.at(0);
uint32_t ssrc = vdesc->ssrc_;
SrsRtcVideoSendTrack* track = video_tracks_.begin()->second;
@@ -534,6 +536,15 @@ void SrsRtcPlayStream::on_stream_change(SrsRtcSourceDescription* desc)
video_tracks_.insert(make_pair(ssrc, track));
}
}

// Request keyframe(PLI) when stream changed.
if (desc->audio_track_desc_) {
pli_worker_->request_keyframe(desc->audio_track_desc_->ssrc_, cid_);
}
for (vector<SrsRtcTrackDescription*>::iterator it = desc->video_track_descs_.begin(); it != desc->video_track_descs_.end(); ++it) {
SrsRtcTrackDescription* vdesc = *it;
pli_worker_->request_keyframe(vdesc->ssrc_, cid_);
}
}

srs_error_t SrsRtcPlayStream::on_reload_vhost_play(string vhost)
@@ -1981,7 +1992,7 @@ srs_error_t SrsRtcConnection::add_publisher(SrsRtcUserConfig* ruc, SrsSdp& local
return srs_error_wrap(err, "publish negotiate");
}

if ((err = generate_publish_local_sdp(req, local_sdp, stream_desc, ruc->remote_sdp_.is_unified())) != srs_success) {
if ((err = generate_publish_local_sdp(req, local_sdp, stream_desc, ruc->remote_sdp_.is_unified(), ruc->audio_before_video_)) != srs_success) {
return srs_error_wrap(err, "generate local sdp");
}

@@ -2047,7 +2058,7 @@ srs_error_t SrsRtcConnection::add_player(SrsRtcUserConfig* ruc, SrsSdp& local_sd
++it;
}

if ((err = generate_play_local_sdp(req, local_sdp, stream_desc, ruc->remote_sdp_.is_unified())) != srs_success) {
if ((err = generate_play_local_sdp(req, local_sdp, stream_desc, ruc->remote_sdp_.is_unified(), ruc->audio_before_video_)) != srs_success) {
return srs_error_wrap(err, "generate local sdp");
}

@@ -2842,9 +2853,14 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
// TODO: FIME: Should check packetization-mode=1 also.
bool has_42e01f = srs_sdp_has_h264_profile(remote_sdp, "42e01f");

// How many video descriptions we have parsed.
int nn_any_video_parsed = 0;

for (int i = 0; i < (int)remote_sdp.media_descs_.size(); ++i) {
const SrsMediaDesc& remote_media_desc = remote_sdp.media_descs_.at(i);

if (remote_media_desc.is_video()) nn_any_video_parsed++;

SrsRtcTrackDescription* track_desc = new SrsRtcTrackDescription();
SrsAutoFree(SrsRtcTrackDescription, track_desc);

@@ -2867,6 +2883,9 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
}

if (remote_media_desc.is_audio()) {
// Update the ruc, which is about user specified configuration.
ruc->audio_before_video_ = !nn_any_video_parsed;

// TODO: check opus format specific param
std::vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("opus");
if (payloads.empty()) {
@@ -2966,6 +2985,9 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
SrsVideoPayload* video_payload = new SrsVideoPayload(payload.payload_type_, payload.encoding_name_, payload.clock_rate_);
video_payload->set_h264_param_desc(payload.format_specific_param_);

// Set the codec parameter for H.264, to make Unity happy.
video_payload->h264_param_ = h264_param;

// TODO: FIXME: Only support some transport algorithms.
for (int k = 0; k < (int)payload.rtcp_fb_.size(); ++k) {
const string& rtcp_fb = payload.rtcp_fb_.at(k);
@@ -3015,6 +3037,7 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
}
}

track_desc->type_ = "video";
track_desc->set_codec_payload((SrsCodecPayload*)video_payload);
srs_warn("choose backup H.264 payload type=%d", payload.payload_type_);
}
@@ -3023,6 +3046,11 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
//local_media_desc.payload_types_.back().rtcp_fb_.push_back("rrtr");
}

// Error if track desc is invalid, that is failed to match SDP, for example, we require H264 but no H264 found.
if (track_desc->type_.empty() || !track_desc->media_) {
return srs_error_new(ERROR_RTC_SDP_EXCHANGE, "no match for track=%s, mid=%s, tracker=%s", remote_media_desc.type_.c_str(), remote_media_desc.mid_.c_str(), remote_media_desc.msid_tracker_.c_str());
}

// TODO: FIXME: use one parse payload from sdp.

track_desc->create_auxiliary_payload(remote_media_desc.find_media_with_encoding_name("red"));
@@ -3044,6 +3072,8 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
stream_desc->audio_track_desc_ = track_desc_copy;
} else if (remote_media_desc.is_video()) {
stream_desc->video_track_descs_.push_back(track_desc_copy);
} else {
srs_freep(track_desc_copy);
}
}
track_id = ssrc_info.msid_tracker_;
@@ -3069,7 +3099,7 @@ srs_error_t SrsRtcConnection::negotiate_publish_capability(SrsRtcUserConfig* ruc
return err;
}

srs_error_t SrsRtcConnection::generate_publish_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan)
srs_error_t SrsRtcConnection::generate_publish_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan, bool audio_before_video)
{
srs_error_t err = srs_success;

@@ -3094,6 +3124,29 @@ srs_error_t SrsRtcConnection::generate_publish_local_sdp(SrsRequest* req, SrsSdp

local_sdp.group_policy_ = "BUNDLE";

if (audio_before_video) {
if ((err = generate_publish_local_sdp_for_audio(local_sdp, stream_desc)) != srs_success) {
return srs_error_wrap(err, "audio");
}
if ((err = generate_publish_local_sdp_for_video(local_sdp, stream_desc, unified_plan)) != srs_success) {
return srs_error_wrap(err, "video");
}
} else {
if ((err = generate_publish_local_sdp_for_video(local_sdp, stream_desc, unified_plan)) != srs_success) {
return srs_error_wrap(err, "video");
}
if ((err = generate_publish_local_sdp_for_audio(local_sdp, stream_desc)) != srs_success) {
return srs_error_wrap(err, "audio");
}
}

return err;
}

srs_error_t SrsRtcConnection::generate_publish_local_sdp_for_audio(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc)
{
srs_error_t err = srs_success;

// generate audio media desc
if (stream_desc->audio_track_desc_) {
SrsRtcTrackDescription* audio_track = stream_desc->audio_track_desc_;
@@ -3128,6 +3181,13 @@ srs_error_t SrsRtcConnection::generate_publish_local_sdp(SrsRequest* req, SrsSdp
local_media_desc.payload_types_.push_back(payload->generate_media_payload_type());
}

return err;
}

srs_error_t SrsRtcConnection::generate_publish_local_sdp_for_video(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan)
{
srs_error_t err = srs_success;

for (int i = 0; i < (int)stream_desc->video_track_descs_.size(); ++i) {
SrsRtcTrackDescription* video_track = stream_desc->video_track_descs_.at(i);

@@ -3191,9 +3251,14 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRtcUserConfig* ruc, s
return srs_error_wrap(err, "fetch rtc source");
}

// How many video descriptions we have parsed.
int nn_any_video_parsed = 0;

for (int i = 0; i < (int)remote_sdp.media_descs_.size(); ++i) {
const SrsMediaDesc& remote_media_desc = remote_sdp.media_descs_.at(i);

if (remote_media_desc.is_video()) nn_any_video_parsed++;

// Whether feature enabled in remote extmap.
int remote_twcc_id = 0;
if (true) {
@@ -3209,6 +3274,9 @@ srs_error_t SrsRtcConnection::negotiate_play_capability(SrsRtcUserConfig* ruc, s
std::vector<SrsRtcTrackDescription*> track_descs;
SrsMediaPayloadType remote_payload(0);
if (remote_media_desc.is_audio()) {
// Update the ruc, which is about user specified configuration.
ruc->audio_before_video_ = !nn_any_video_parsed;

// TODO: check opus format specific param
vector<SrsMediaPayloadType> payloads = remote_media_desc.find_media_with_encoding_name("opus");
if (payloads.empty()) {
@@ -3368,7 +3436,7 @@ void video_track_generate_play_offer(SrsRtcTrackDescription* track, string mid,
}
}

srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan)
srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan, bool audio_before_video)
{
srs_error_t err = srs_success;

@@ -3395,6 +3463,29 @@ srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& l

std::string cname = srs_random_str(16);

if (audio_before_video) {
if ((err = generate_play_local_sdp_for_audio(local_sdp, stream_desc, cname)) != srs_success) {
return srs_error_wrap(err, "audio");
}
if ((err = generate_play_local_sdp_for_video(local_sdp, stream_desc, unified_plan, cname)) != srs_success) {
return srs_error_wrap(err, "video");
}
} else {
if ((err = generate_play_local_sdp_for_video(local_sdp, stream_desc, unified_plan, cname)) != srs_success) {
return srs_error_wrap(err, "video");
}
if ((err = generate_play_local_sdp_for_audio(local_sdp, stream_desc, cname)) != srs_success) {
return srs_error_wrap(err, "audio");
}
}

return err;
}

srs_error_t SrsRtcConnection::generate_play_local_sdp_for_audio(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, std::string cname)
{
srs_error_t err = srs_success;

// generate audio media desc
if (stream_desc->audio_track_desc_) {
SrsRtcTrackDescription* audio_track = stream_desc->audio_track_desc_;
@@ -3454,6 +3545,13 @@ srs_error_t SrsRtcConnection::generate_play_local_sdp(SrsRequest* req, SrsSdp& l
}
}

return err;
}

srs_error_t SrsRtcConnection::generate_play_local_sdp_for_video(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan, std::string cname)
{
srs_error_t err = srs_success;

for (int i = 0; i < (int)stream_desc->video_track_descs_.size(); ++i) {
SrsRtcTrackDescription* track = stream_desc->video_track_descs_[i];

8 changes: 6 additions & 2 deletions trunk/src/app/srs_app_rtc_conn.hpp
Original file line number Diff line number Diff line change
@@ -568,11 +568,15 @@ class SrsRtcConnection : public ISrsResource, public ISrsDisposingHandler, publi
srs_error_t on_binding_request(SrsStunPacket* r);
// publish media capabilitiy negotiate
srs_error_t negotiate_publish_capability(SrsRtcUserConfig* ruc, SrsRtcSourceDescription* stream_desc);
srs_error_t generate_publish_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan);
srs_error_t generate_publish_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan, bool audio_before_video);
srs_error_t generate_publish_local_sdp_for_audio(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc);
srs_error_t generate_publish_local_sdp_for_video(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan);
// play media capabilitiy negotiate
//TODO: Use StreamDescription to negotiate and remove first negotiate_play_capability function
srs_error_t negotiate_play_capability(SrsRtcUserConfig* ruc, std::map<uint32_t, SrsRtcTrackDescription*>& sub_relations);
srs_error_t generate_play_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan);
srs_error_t generate_play_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan, bool audio_before_video);
srs_error_t generate_play_local_sdp_for_audio(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, std::string cname);
srs_error_t generate_play_local_sdp_for_video(SrsSdp& local_sdp, SrsRtcSourceDescription* stream_desc, bool unified_plan, std::string cname);
srs_error_t create_player(SrsRequest* request, std::map<uint32_t, SrsRtcTrackDescription*> sub_relations);
srs_error_t create_publisher(SrsRequest* request, SrsRtcSourceDescription* stream_desc);
};
51 changes: 29 additions & 22 deletions trunk/src/app/srs_app_rtc_sdp.cpp
Original file line number Diff line number Diff line change
@@ -56,32 +56,39 @@ static void skip_first_spaces(std::string& str)
srs_error_t srs_parse_h264_fmtp(const std::string& fmtp, H264SpecificParam& h264_param)
{
srs_error_t err = srs_success;
std::vector<std::string> vec = split_str(fmtp, ";");

std::vector<std::string> vec = srs_string_split(fmtp, ";");
for (size_t i = 0; i < vec.size(); ++i) {
std::vector<std::string> kv = split_str(vec[i], "=");
if (kv.size() == 2) {
if (kv[0] == "profile-level-id") {
h264_param.profile_level_id = kv[1];
} else if (kv[0] == "packetization-mode") {
// 6.3. Non-Interleaved Mode
// This mode is in use when the value of the OPTIONAL packetization-mode
// media type parameter is equal to 1. This mode SHOULD be supported.
// It is primarily intended for low-delay applications. Only single NAL
// unit packets, STAP-As, and FU-As MAY be used in this mode. STAP-Bs,
// MTAPs, and FU-Bs MUST NOT be used. The transmission order of NAL
// units MUST comply with the NAL unit decoding order.
// @see https://tools.ietf.org/html/rfc6184#section-6.3
h264_param.packetization_mode = kv[1];
} else if (kv[0] == "level-asymmetry-allowed") {
h264_param.level_asymmerty_allow = kv[1];
} else {
return srs_error_new(ERROR_RTC_SDP_DECODE, "invalid h264 param=%s", kv[0].c_str());
}
} else {
return srs_error_new(ERROR_RTC_SDP_DECODE, "invalid h264 param=%s", vec[i].c_str());
std::vector<std::string> kv = srs_string_split(vec[i], "=");
if (kv.size() != 2) continue;

if (kv[0] == "profile-level-id") {
h264_param.profile_level_id = kv[1];
} else if (kv[0] == "packetization-mode") {
// 6.3. Non-Interleaved Mode
// This mode is in use when the value of the OPTIONAL packetization-mode
// media type parameter is equal to 1. This mode SHOULD be supported.
// It is primarily intended for low-delay applications. Only single NAL
// unit packets, STAP-As, and FU-As MAY be used in this mode. STAP-Bs,
// MTAPs, and FU-Bs MUST NOT be used. The transmission order of NAL
// units MUST comply with the NAL unit decoding order.
// @see https://tools.ietf.org/html/rfc6184#section-6.3
h264_param.packetization_mode = kv[1];
} else if (kv[0] == "level-asymmetry-allowed") {
h264_param.level_asymmerty_allow = kv[1];
}
}

if (h264_param.profile_level_id.empty()) {
return srs_error_new(ERROR_RTC_SDP_DECODE, "no h264 param: profile-level-id");
}
if (h264_param.packetization_mode.empty()) {
return srs_error_new(ERROR_RTC_SDP_DECODE, "no h264 param: packetization-mode");
}
if (h264_param.level_asymmerty_allow.empty()) {
return srs_error_new(ERROR_RTC_SDP_DECODE, "no h264 param: level-asymmetry-allowed");
}

return err;
}

87 changes: 54 additions & 33 deletions trunk/src/app/srs_app_rtc_server.cpp
Original file line number Diff line number Diff line change
@@ -158,28 +158,35 @@ srs_error_t api_server_as_candidates(string api, set<string>& candidate_ips)
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();
string hostname = api;
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;
}

// Whether add domain name.
if (!srs_is_ipv4(hostname) && _srs_config->get_keep_api_domain()) {
candidate_ips.insert(hostname);
}

// 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;
if (!srs_is_ipv4(hostname) && _srs_config->get_resolve_api_domain()) {
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);
}

// Try to add the API server ip as candidates.
candidate_ips.insert(ip);
// If hostname is IP, use it.
if (srs_is_ipv4(hostname)) {
candidate_ips.insert(hostname);
}

return err;
}
@@ -195,8 +202,8 @@ static set<string> discover_candidates(SrsRtcUserConfig* ruc)
}

// 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());
if ((err = api_server_as_candidates(ruc->req_->host, candidate_ips)) != srs_success) {
srs_warn("ignore discovering ip from api %s, err %s", ruc->req_->host.c_str(), srs_error_summary(err).c_str());
srs_freep(err);
}

@@ -207,29 +214,32 @@ static set<string> discover_candidates(SrsRtcUserConfig* ruc)
return candidate_ips;
}

// Discover from local network interface addresses.
// All automatically detected IP list.
vector<SrsIPAddress*>& ips = srs_get_local_ips();
if (ips.empty()) {
return candidate_ips;
}

// We try to find the best match candidates, no loopback.
string family = _srs_config->get_rtc_server_ip_family();
for (int i = 0; i < (int)ips.size(); ++i) {
SrsIPAddress* ip = ips[i];
if (ip->is_loopback) {
continue;
}

if (family == "ipv4" && !ip->is_ipv4) {
continue;
}
if (family == "ipv6" && ip->is_ipv4) {
continue;
// Discover from local network interface addresses.
if (_srs_config->get_use_auto_detect_network_ip()) {
// We try to find the best match candidates, no loopback.
string family = _srs_config->get_rtc_server_ip_family();
for (int i = 0; i < (int) ips.size(); ++i) {
SrsIPAddress* ip = ips[i];
if (ip->is_loopback) {
continue;
}

if (family == "ipv4" && !ip->is_ipv4) {
continue;
}
if (family == "ipv6" && ip->is_ipv4) {
continue;
}

candidate_ips.insert(ip->ip);
srs_trace("Best matched ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str());
}

candidate_ips.insert(ip->ip);
srs_trace("Best matched ip=%s, ifname=%s", ip->ip.c_str(), ip->ifname.c_str());
}

if (!candidate_ips.empty()) {
@@ -248,7 +258,7 @@ static set<string> discover_candidates(SrsRtcUserConfig* ruc)
return candidate_ips;
}

// We use the first one.
// We use the first one, to make sure there will be at least one CANDIDATE.
if (candidate_ips.empty()) {
SrsIPAddress* ip = ips[0];
candidate_ips.insert(ip->ip);
@@ -280,6 +290,7 @@ SrsRtcUserConfig::SrsRtcUserConfig()
req_ = new SrsRequest();
publish_ = false;
dtls_ = srtp_ = true;
audio_before_video_ = false;
}

SrsRtcUserConfig::~SrsRtcUserConfig()
@@ -495,6 +506,16 @@ srs_error_t SrsRtcServer::listen_api()
return srs_error_wrap(err, "handle publish");
}

// Generally, WHIP is a publishing protocol, but it can be also used as playing.
if ((err = http_api_mux->handle("/rtc/v1/whip/", new SrsGoApiRtcWhip(this))) != srs_success) {
return srs_error_wrap(err, "handle whip");
}

// We create another mount, to support play with the same query string as publish.
if ((err = http_api_mux->handle("/rtc/v1/whip-play/", new SrsGoApiRtcWhip(this))) != srs_success) {
return srs_error_wrap(err, "handle whip play");
}

#ifdef SRS_SIMULATOR
if ((err = http_api_mux->handle("/rtc/v1/nack/", new SrsGoApiRtcNACK(this))) != srs_success) {
return srs_error_wrap(err, "handle nack");
@@ -577,7 +598,7 @@ srs_error_t SrsRtcServer::do_create_session(SrsRtcUserConfig* ruc, SrsSdp& local
set<string> candidates = discover_candidates(ruc);
for (set<string>::iterator it = candidates.begin(); it != candidates.end(); ++it) {
string hostname; int port = listen_port;
srs_parse_hostport(*it, hostname,port);
srs_parse_hostport(*it, hostname, port);
local_sdp.add_candidate(hostname, port, "host");
}

9 changes: 9 additions & 0 deletions trunk/src/app/srs_app_rtc_server.hpp
Original file line number Diff line number Diff line change
@@ -75,16 +75,25 @@ class SrsRtcUserConfig
{
public:
// Original variables from API.
std::string remote_sdp_str_;
SrsSdp remote_sdp_;
std::string eip_;
std::string codec_;
std::string api_;

// Session data.
std::string local_sdp_str_;
std::string session_id_;

// Generated data.
SrsRequest* req_;
bool publish_;
bool dtls_;
bool srtp_;

// The order of audio and video, or whether audio is before video. Please make sure the order is match for offer and
// answer, or client might fail at setRemoveDescription(answer). See https://github.com/ossrs/srs/issues/3179
bool audio_before_video_;
public:
SrsRtcUserConfig();
virtual ~SrsRtcUserConfig();
Loading