diff --git a/AUTHORS.txt b/AUTHORS.txt index 89d65917f..6755f273b 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -52,4 +52,5 @@ CONTRIBUTORS ordered by first contribution. * xialixin * alphonsetai * Michael.Ma -* lam2003 \ No newline at end of file +* lam2003 +* runner365 \ No newline at end of file diff --git a/README.md b/README.md index b0cf323d5..a37ee269a 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # SRS -![](http://ossrs.net/gif/v1/sls.gif?site=github.com&path=/srs/srs3) -[![](https://circleci.com/gh/ossrs/srs/tree/3.0release.svg?style=svg&circle-token=1ef1d5b5b0cde6c8c282ed856a18199f9e8f85a9)](https://circleci.com/gh/ossrs/srs/tree/3.0release) -[![](https://codecov.io/gh/ossrs/srs/branch/3.0release/graph/badge.svg)](https://codecov.io/gh/ossrs/srs/branch/3.0release) +![](http://ossrs.net/gif/v1/sls.gif?site=github.com&path=/srs/develop) +[![](https://circleci.com/gh/ossrs/srs/tree/develop.svg?style=svg&circle-token=1ef1d5b5b0cde6c8c282ed856a18199f9e8f85a9)](https://circleci.com/gh/ossrs/srs/tree/develop) +[![](https://codecov.io/gh/ossrs/srs/branch/develop/graph/badge.svg)](https://codecov.io/gh/ossrs/srs/branch/develop) [![](https://cloud.githubusercontent.com/assets/2777660/22814959/c51cbe72-ef92-11e6-81cc-32b657b285d5.png)](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat) -SRS/3.0,[OuXuli][release3],是一个流媒体直播集群,高效、稳定、易用,简单而快乐。
+SRS/4.0,[Leo][release4],是一个流媒体直播集群,高效、稳定、易用,简单而快乐。
SRS(Simple RTMP Server) is a live streaming cluster, high efficiency, stable and simple. > Remark: Although SRS is licenced under [MIT][LICENSE], but there are some depended libraries which are distributed using their own licenses, please read [License Mixing][LicenseMixing]. @@ -47,32 +47,36 @@ docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 ossrs/srs:3 **From here,** strongly recommend to read bellow wikis: * Usage: How to delivery RTMP?([CN][v1_CN_SampleRTMP], [EN][v1_EN_SampleRTMP]) -* Usage: How to delivery RTMP Edge Cluster?([CN][v3_CN_SampleRTMPCluster], [EN][v3_EN_SampleRTMPCluster]) -* Usage: How to create a RTMP Origin Cluster?([CN][v3_CN_SampleOriginCluster], [EN][v3_EN_SampleOriginCluster]) -* Usage: How to delivery HTTP FLV Live Streaming?([CN][v3_CN_SampleHttpFlv], [EN][v3_EN_SampleHttpFlv]) -* Usage: How to delivery HTTP FLV Live Streaming Cluster?([CN][v3_CN_SampleHttpFlvCluster], [EN][v3_EN_SampleHttpFlvCluster]) +* Usage: How to delivery RTMP-Edge Cluster?([CN][v3_CN_SampleRTMPCluster], [EN][v3_EN_SampleRTMPCluster]) +* Usage: How to create a RTMP-Origin Cluster?([CN][v3_CN_SampleOriginCluster], [EN][v3_EN_SampleOriginCluster]) +* Usage: How to delivery HTTP-FLV?([CN][v3_CN_SampleHttpFlv], [EN][v3_EN_SampleHttpFlv]) +* Usage: How to delivery HTTP-FLV Cluster?([CN][v3_CN_SampleHttpFlvCluster], [EN][v3_EN_SampleHttpFlvCluster]) * Usage: How to delivery HLS?([CN][v3_CN_SampleHLS], [EN][v3_EN_SampleHLS]) -* Usage: How to delivery HLS for other codec?([CN][v3_CN_SampleTranscode2HLS], [EN][v3_EN_SampleTranscode2HLS]) -* Usage: How to transode RTMP stream by FFMPEG?([CN][v2_CN_SampleFFMPEG], [EN][v2_EN_SampleFFMPEG]) +* Usage: How to transcode to h.264+aac for HLS?([CN][v3_CN_SampleTranscode2HLS], [EN][v3_EN_SampleTranscode2HLS]) +* Usage: How to transode stream by FFMPEG?([CN][v2_CN_SampleFFMPEG], [EN][v2_EN_SampleFFMPEG]) * Usage: How to forward stream to other servers?([CN][v3_CN_SampleForward], [EN][v3_EN_SampleForward]) -* Usage: How to deploy in low lantency mode?([CN][v3_CN_SampleRealtime], [EN][v3_EN_SampleRealtime]) -* Usage: How to ingest file/stream/device to RTMP?([CN][v1_CN_SampleIngest], [EN][v1_EN_SampleIngest]) +* Usage: How to enable low lantency live streaming?([CN][v3_CN_SampleRealtime], [EN][v3_EN_SampleRealtime]) +* Usage: How to ingest file/stream/device to SRS?([CN][v1_CN_SampleIngest], [EN][v1_EN_SampleIngest]) * Usage: How to delivery HLS by SRS HTTP server?([CN][v3_CN_SampleHTTP], [EN][v3_EN_SampleHTTP]) +* Usage: How to delivery DASH(Experimental)?([CN][v3_CN_SampleDASH], [EN][v3_EN_SampleDASH]) +* Usage: How to transmux SRT(Experimental) to live streaming?([CN][v4_CN_SampleSRT], [EN][v4_EN_SampleSRT]) * Usage: How to publish h.264 raw stream as RTMP? ([CN][v3_CN_SrsLibrtmp2], [EN][v3_EN_SrsLibrtmp2]) -* Usage: How to improve edge performance by multiple CPUs? ([CN][v3_CN_REUSEPORT], [EN][v3_EN_REUSEPORT]) -* Usage: Why choose SRS? About the milestone and product plan? ([CN][v1_CN_Product], [EN][v1_EN_Product]) -* Usage: How to file bug or chat with us? ([CN][v1_CN_Contact], [EN][v1_EN_Contact]) +* Usage: How to enable multiple processes? ([CN][v3_CN_REUSEPORT], [EN][v3_EN_REUSEPORT]) +* Usage: Why SRS? What's the milestones? ([CN][v1_CN_Product], [EN][v1_EN_Product]) +* Usage: Want to contact us? ([CN][v1_CN_Contact], [EN][v1_EN_Contact]) Or file an issue [here](https://github.com/ossrs/srs/issues/new)? ## Wiki Please select according to languages: -* [SRS 3.0 English Wiki][v3_EN_Home] -* [SRS 3.0 Chinese Wiki][v3_CN_Home] +* [SRS 4.0 English Wiki][v4_EN_Home] +* [SRS 4.0 Chinese Wiki][v4_CN_Home] For previous versions, please read: +* [SRS 3.0 English Wiki][v3_EN_Home] +* [SRS 3.0 Chinese Wiki][v3_CN_Home] * [SRS 2.0 English Wiki][v2_EN_Home] * [SRS 2.0 Chinese Wiki][v2_CN_Home] * [SRS 1.0 English Wiki][v1_EN_Home] @@ -127,6 +131,7 @@ For previous versions, please read: - [x] [Experimental] Support a simple [mgmt console][console], please read [srs-ngb][srs-ngb]. - [x] [Experimental] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp]) - [x] [Experimental] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319]. +- [x] [Experimental] Support SRT server, read [#1147][bug #1147]. - [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]) and [#1535][bug #1535]. - [x] [Deprecated] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]), please read [#1535][bug #1535]. - [x] [Deprecated] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication, please read [#1535][bug #1535]. @@ -137,6 +142,8 @@ For previous versions, please read: - [ ] Support UDP protocol such as QUIC or KCP in cluster. - [ ] Support H.264+Opus codec for WebRTC. - [ ] Support publishing stream by WebRTC. +- [ ] Support change user to run SRS, [#1111][bug #1111]. +- [ ] Support HLS variant, [#463][bug #463]. - [ ] Support playing stream by WebRTC. > Remark: About the milestone and product plan, please read ([CN][v1_CN_Product], [EN][v1_EN_Product]) wiki. @@ -144,6 +151,10 @@ For previous versions, please read: +## V4 changes + +* v4.0, 2020-01-24, Fix [#1147][bug #1147], support SRT(Secure Reliable Transport). 4.0.1 + ## V3 changes * v3.0, 2020-01-25, Fix [#1108][bug #1108], reap DVR tmp file when unpublish. 3.0.106 @@ -1002,13 +1013,13 @@ SRS always use the simplest architecture to solve complex domain problems. ## Modularity Architecture ``` -+------------------------------------------------------+ -| SRS server | Programs in Main or Research | -+------------------------------------------------------+ -| App(For SRS) | Modules(1) | research/librtmp | -+------------------------------------------------------+ -| Service(C/S apps over ST) | Libs(Export librtmp) | -+------------------------------------------------------+ ++----------------+-------------------------------------+ +| SRS/SRT server | Programs in Main or Research | ++----------------+--+------------+---------------------+ +| App(For SRS) | Modules(1) | research/librtmp | ++-------------------+------------+---------------------+ +| Service(C/S apps over ST) | srs-librtmp | ++--------------------------------+---------------------+ | Protocol Stack(RTMP/HTTP/RTSP/JSON/AMF/Format) | +------------------------------------------------------+ | Kernel(File, Codec, Stream, LB services) | @@ -1027,31 +1038,33 @@ Remark: +---------+ +----------+ | Publish | | Deliver | +---|-----+ +----|-----+ -+----------------------+-------------------------+----------------+ -| Input | SRS(Simple RTMP Server) | Output | -+----------------------+-------------------------+----------------+ -| | +-> DASH -------------+-> DASH player | -| Encoder(1) | +-> RTMP/HDS --------+-> Flash player | -| (FMLE,FFMPEG, -rtmp-+->-+-> HLS/HTTP ---------+-> M3U8 player | -| Flash,XSPLIT, | +-> FLV/MP3/Aac/Ts ---+-> HTTP player | -| ......) | +-> Fowarder ---------+-> RTMP server | -| | +-> Transcoder -------+-> RTMP server | -| | +-> EXEC(5) ----------+-> External app | -| | +-> DVR --------------+-> FLV file | -| | +-> BandwidthTest ----+-> Flash | -+----------------------+ | | -| MediaSource(2) | | | -| (RTSP,FILE, | | | -| HTTP,HLS, --pull-+->-- Ingester(3) -(rtmp)-+-> SRS | -| Device, | | | -| ......) | | | -+----------------------+ | | -| MediaSource(2) | | | -| (RTSP,FILE, | | | -| HTTP,HLS, --push-+->-- Streamer(4) -(rtmp)-+-> SRS | -| Device, | | | -| ......) | | | -+----------------------+-------------------------+----------------+ ++----------------------+----------------------------+----------------+ +| Input | SRS(Simple RTMP Server) | Output | ++----------------------+----------------------------+----------------+ +| | +-> DASH ----------------+-> DASH player | +| Encoder(1) | +-> RTMP/HDS -----------+-> Flash player | +| (FMLE,FFMPEG, -rtmp-+->-+-> HLS/HTTP ------------+-> M3U8 player | +| Flash,XSPLIT, | +-> FLV/MP3/Aac/Ts ------+-> HTTP player | +| ......) | +-> Fowarder ------------+-> RTMP server | +| | +-> Transcoder ----------+-> RTMP server | +| | +-> EXEC(5) -------------+-> External app | +| | +-> DVR -----------------+-> FLV file | +| | +-> BandwidthTest -------+-> Flash | ++----------------------+ | | +| MediaSource(2) | | | +| (RTSP,FILE, | | | +| HTTP,HLS, --pull-+->-- Ingester(3) -(rtmp)----+-> SRS | +| Device, | | | +| ......) | | | ++----------------------+ | | +| MediaSource(2) | | | +| (RTSP,FILE, | | | +| HTTP,HLS, --push-+->- StreamCaster(4) -(rtmp)-+-> SRS | +| Device, | | | +| ......) | | | ++----------------------+ | | +| FFMPEG --push(srt)--+->- SRTModule(5) ---(rtmp)-+-> SRS | ++----------------------+----------------------------+----------------+ ``` @@ -1062,6 +1075,7 @@ Remark: 1. Ingester: Forks a ffmpeg(or other tools) to ingest as rtmp to SRS, please read [Ingest][v1_CN_Ingest]. 1. Streamer: Remuxs other protocols to RTMP, please read [Streamer][v2_CN_Streamer]. 1. EXEC: Like NGINX-RTMP, EXEC forks external tools for events, please read [ng-exec][v3_CN_NgExec]. +1. SRTModule: A isolate module which run in [hybrid](https://github.com/ossrs/srs/issues/1147#issuecomment-577574883) model. ## AUTHORS @@ -1213,6 +1227,8 @@ Winlin [v2_EN_Home]: https://github.com/ossrs/srs/wiki/v2_EN_Home [v3_CN_Home]: https://github.com/ossrs/srs/wiki/v3_CN_Home [v3_EN_Home]: https://github.com/ossrs/srs/wiki/v3_EN_Home +[v4_CN_Home]: https://github.com/ossrs/srs/wiki/v4_CN_Home +[v4_EN_Home]: https://github.com/ossrs/srs/wiki/v4_EN_Home [donation0]: http://winlinvip.github.io/srs.release/donation/index.html [donation1]: http://ossrs.net/srs.release/donation/index.html [donation2]: http://ossrs.net/srs.release/donation/paypal.html @@ -1611,6 +1627,9 @@ Winlin [bug #1580]: https://github.com/ossrs/srs/issues/1580 [bug #1547]: https://github.com/ossrs/srs/issues/1547 [bug #1221]: https://github.com/ossrs/srs/issues/1221 +[bug #1111]: https://github.com/ossrs/srs/issues/1111 +[bug #463]: https://github.com/ossrs/srs/issues/463 +[bug #1147]: https://github.com/ossrs/srs/issues/1147 [bug #1108]: https://github.com/ossrs/srs/issues/1108 [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx @@ -1683,4 +1702,5 @@ Winlin [branch2]: https://github.com/ossrs/srs/tree/2.0release [release2]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release20 [release3]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release30 +[release4]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release40 diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index bf183c0a6..3105f7fdf 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -385,6 +385,22 @@ if [ $SRS_FFMPEG_TOOL = YES ]; then if [ ! -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]; then echo "build ffmpeg-4.1 failed."; exit -1; fi fi +##################################################################################### +# SRT module, https://github.com/ossrs/srs/issues/1147#issuecomment-577469119 +##################################################################################### +if [[ $SRS_SRT == YES ]]; then + if [[ -f /usr/local/lib64/libsrt.a && ! -f ${SRS_OBJS}/srt/lib/libsrt.a ]]; then + mkdir -p ${SRS_OBJS}/srt/lib && ln -sf /usr/local/lib64/libsrt.a ${SRS_OBJS}/srt/lib/libsrt.a + mkdir -p ${SRS_OBJS}/srt/include && ln -sf /usr/local/include/srt ${SRS_OBJS}/srt/include/ + fi + if [[ -f ${SRS_OBJS}/srt/lib/libsrt.a ]]; then + echo "libsrt-1.4.1 is ok."; + else + echo "no libsrt, please use srs-docker or build from source https://github.com/ossrs/srs/issues/1147#issuecomment-577469119"; + exit -1; + fi +fi + ##################################################################################### # build research code, librtmp ##################################################################################### diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh index 7c5a69780..13ffe88b1 100755 --- a/trunk/auto/options.sh +++ b/trunk/auto/options.sh @@ -111,51 +111,32 @@ SRS_EXTRA_FLAGS= function show_help() { cat << END -Options: - -h, --help print this message - - --with-ssl enable rtmp complex handshake, requires openssl-devel installed. - --with-hds enable hds streaming, mux RTMP to F4M/F4V files. - --with-nginx enable delivery HTTP stream with nginx. - --with-stream-caster enable stream caster to serve other stream over other protocol. - --with-ffmpeg enable transcoding tool ffmpeg. - --with-transcode enable transcoding features. - --with-ingest enable ingest features. - --with-stat enable the data statistic, for http api. - --with-librtmp enable srs-librtmp, library for client. - --with-research build the research tools. - --with-utest build the utest for SRS. - --with-srt build the srt for SRS. - --with-gperf build SRS with gperf tools(no gmd/gmc/gmp/gcp, with tcmalloc only). - --with-gmc build memory check for SRS with gperf tools. - --with-gmd build memory defense(corrupt memory) for SRS with gperf tools. - --with-gmp build memory profile for SRS with gperf tools. - --with-gcp build cpu profile for SRS with gperf tools. - --with-gprof build SRS with gprof(GNU profile tool). - --with-arm-ubuntu12 cross build SRS on ubuntu12 for armhf(v7cpu). - --with-mips-ubuntu12 cross build SRS on ubuntu12 for mips. - - --without-ssl disable rtmp complex handshake. - --without-hds disable hds, the adobe http dynamic streaming. - --without-nginx disable delivery HTTP stream with nginx. - --without-stream-caster disable stream caster, only listen and serve RTMP/HTTP. - --without-ffmpeg disable the ffmpeg transcode tool feature. - --without-transcode disable the transcoding feature. - --without-ingest disable the ingest feature. - --without-stat disable the data statistic feature. - --without-librtmp disable srs-librtmp, library for client. - --without-research do not build the research tools. - --without-utest do not build the utest for SRS. - --without-srt do not build the srt for SRS. - --without-gperf do not build SRS with gperf tools(without tcmalloc and gmd/gmc/gmp/gcp). - --without-gmc do not build memory check for SRS with gperf tools. - --without-gmd do not build memory defense for SRS with gperf tools. - --without-gmp do not build memory profile for SRS with gperf tools. - --without-gcp do not build cpu profile for SRS with gperf tools. - --without-gprof do not build srs with gprof(GNU profile tool). - --without-arm-ubuntu12 do not cross build srs on ubuntu12 for armhf(v7cpu). - --without-mips-ubuntu12 do not cross build srs on ubuntu12 for mips. - +Presets: + --x86-64, --x86-x64 [default] For x86/x64 cpu, common pc and servers. + --arm Enable crossbuild for ARM, should also set bellow toolchain options. + --mips Enable crossbuild for MIPS + +Features: + -h, --help Print this message and exit 0. + + --with-ssl Enable rtmp complex handshake, requires openssl-devel installed. + --with-hds Enable hds streaming, mux RTMP to F4M/F4V files. + --with-stream-caster Enable stream caster to serve other stream over other protocol. + --with-stat Enable the data statistic, for http api. + --with-librtmp Enable srs-librtmp, library for client. + --with-research Build the research tools. + --with-utest Build the utest for SRS. + --with-srt Build the srt for SRS. + + --without-ssl Disable rtmp complex handshake. + --without-hds Disable hds, the adobe http dynamic streaming. + --without-stream-caster Disable stream caster, only listen and serve RTMP/HTTP. + --without-stat Disable the data statistic feature. + --without-librtmp Disable srs-librtmp, library for client. + --without-research Do not build the research tools. + --without-utest Do not build the utest for SRS. + --without-srt Do not build the srt for SRS. + --prefix= The absolute installation path for srs. Default: $SRS_PREFIX --static Whether add '-static' to link options. --gcov Whether enable the GCOV compiler options. @@ -529,9 +510,9 @@ apply_user_detail_options function regenerate_options() { # save all config options to macro to write to auto headers file - SRS_AUTO_USER_CONFIGURE="$opt" + SRS_AUTO_USER_CONFIGURE=`echo $opt` # regenerate the options for default values. -SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}" + SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}" if [ $SRS_HLS = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-hls"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-hls"; fi if [ $SRS_HDS = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-hds"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-hds"; fi if [ $SRS_DVR = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-dvr"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-dvr"; fi diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 1160877a4..b4f0f95c3 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -247,6 +247,18 @@ stream_caster { listen 8936; } +############################################################################################# +# SRT server section +############################################################################################# +# @doc https://github.com/ossrs/srs/issues/1147#issuecomment-577607026 +srt_server { + # whether SRT server is enabled. + # default: off + enabled on; + # The UDP listen port for SRT. + listen 10080; +} + ############################################################################################# # Kafka sections ############################################################################################# diff --git a/trunk/conf/srt.conf b/trunk/conf/srt.conf index 9dc1e564e..d648b16b3 100644 --- a/trunk/conf/srt.conf +++ b/trunk/conf/srt.conf @@ -20,7 +20,7 @@ srt_server { listen 10080; } -# @doc https://github.com/ossrs/srs/issues/1147#issuecomment-577492117 +# @doc https://github.com/ossrs/srs/issues/1147#issuecomment-577607026 vhost __defaultVhost__ { } vhost srs.srt.com.cn { diff --git a/trunk/configure b/trunk/configure index 98b340db2..ad446a761 100755 --- a/trunk/configure +++ b/trunk/configure @@ -162,12 +162,12 @@ if [ $SRS_GPERF_MD = YES ]; then fi # srt code path if [[ $SRS_SRT == YES ]]; then - LibSRTRoot="${SRS_WORKDIR}/src/srt" + LibSRTRoot="${SRS_WORKDIR}/src/srt"; LibSRTfile="${SRS_OBJS_DIR}/srt/lib/libsrt.a" fi # the link options, always use static link SrsLinkOptions="-ldl"; if [[ $SRS_SRT == YES ]]; then - SrsLinkOptions="${SrsLinkOptions} -pthread -lsrt"; + SrsLinkOptions="${SrsLinkOptions} -pthread"; fi if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == YES ]]; then SrsLinkOptions="${SrsLinkOptions} -lssl -lcrypto"; @@ -245,9 +245,6 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then MODULE_ID="APP" MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE") ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibSSLRoot}) - if [[ $SRS_SRT == YES ]]; then - ModuleLibIncs+=("${LibSRTRoot[*]}") - fi MODULE_FILES=("srs_app_server" "srs_app_conn" "srs_app_rtmp_conn" "srs_app_source" "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream" "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" @@ -258,7 +255,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" "srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec" "srs_app_hourglass" "srs_app_dash" "srs_app_fragment" "srs_app_dvr" - "srs_app_coworkers") + "srs_app_coworkers" "srs_app_hybrid") DEFINES="" # add each modules for app for SRS_MODULE in ${SRS_MODULES[*]}; do @@ -326,6 +323,9 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then # # all depends libraries ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibGperfFile}) + if [[ $SRS_SRT == YES ]]; then + ModuleLibFiles+=("${LibSRTfile[*]}") + fi # all depends objects MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${SERVICE_OBJS[@]} ${APP_OBJS[@]} ${SERVER_OBJS[@]}" ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS_DIR} ${LibGperfRoot} ${LibSSLRoot}) @@ -339,6 +339,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then # # For modules, without the app module. MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${PROTOCOL_OBJS[@]} ${SERVICE_OBJS[@]} ${MAIN_OBJS[@]}" + ModuleLibFiles=(${LibSTfile} ${LibSSLfile} ${LibGperfFile}) # for SRS_MODULE in ${SRS_MODULES[*]}; do . $SRS_MODULE/config @@ -363,6 +364,9 @@ if [ $SRS_UTEST = YES ]; then ModuleLibIncs+=("${LibSRTRoot[*]}") fi ModuleLibFiles=(${LibSTfile} ${LibSSLfile}) + if [[ $SRS_SRT == YES ]]; then + ModuleLibFiles+=("${LibSRTfile[*]}") + fi MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP") if [[ $SRS_SRT == YES ]]; then MODULE_DEPENDS+=("SRT") @@ -624,6 +628,11 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then else echo -e "${GREEN}Warning: HDS is disabled.${BLACK}" fi + if [ $SRS_SRT = YES ]; then + echo -e "${YELLOW}Experiment: SRT is enabled. https://github.com/ossrs/srs/issues/1147${BLACK}" + else + echo -e "${GREEN}Warning: SRT is disabled.${BLACK}" + fi if [ $SRS_DVR = YES ]; then echo -e "${GREEN}DVR is enabled.${BLACK}" else diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 0fa544fab..04c1f2032 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3391,9 +3391,7 @@ srs_error_t SrsConfig::parse_argv(int& i, char** argv) void SrsConfig::print_help(char** argv) { printf( - RTMP_SIG_SRS_SERVER ", " RTMP_SIG_SRS_URL ", licensed under " RTMP_SIG_SRS_LICENSE - ", built at " SRS_AUTO_BUILD_DATE ", configured by " SRS_AUTO_USER_CONFIGURE - ", which means " SRS_AUTO_CONFIGURE "\n""\n" + "%s, %s, %s, created by %s\n\n" "Usage: %s <-h?vVgG>|<[-t] -c filename>\n" "Options:\n" " -?, -h : Show this help and exit 0.\n" @@ -3403,9 +3401,12 @@ void SrsConfig::print_help(char** argv) " -c filename : Use config file to start server.\n" "For example:\n" " %s -v\n" - " %s -t -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n" - " %s -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n", - argv[0], argv[0], argv[0], argv[0]); + " %s -t -c %s\n" + " %s -c %s\n", + RTMP_SIG_SRS_SERVER, RTMP_SIG_SRS_URL, RTMP_SIG_SRS_LICENSE, + RTMP_SIG_SRS_AUTHORS, + argv[0], argv[0], argv[0], SRS_CONF_DEFAULT_COFNIG_FILE, + argv[0], SRS_CONF_DEFAULT_COFNIG_FILE); } srs_error_t SrsConfig::parse_file(const char* filename) diff --git a/trunk/src/app/srs_app_hybrid.cpp b/trunk/src/app/srs_app_hybrid.cpp new file mode 100644 index 000000000..cd8147327 --- /dev/null +++ b/trunk/src/app/srs_app_hybrid.cpp @@ -0,0 +1,185 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2020 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include +#include + +using namespace std; + +ISrsHybridServer::ISrsHybridServer() +{ +} + +ISrsHybridServer::~ISrsHybridServer() +{ +} + +SrsServerAdapter::SrsServerAdapter() +{ + srs = new SrsServer(); +} + +SrsServerAdapter::~SrsServerAdapter() +{ + srs_freep(srs); +} + +srs_error_t SrsServerAdapter::initialize() +{ + srs_error_t err = srs_success; + return err; +} + +srs_error_t SrsServerAdapter::run() +{ + srs_error_t err = srs_success; + + // Initialize the whole system, set hooks to handle server level events. + if ((err = srs->initialize(NULL)) != srs_success) { + return srs_error_wrap(err, "server initialize"); + } + + if ((err = srs->initialize_st()) != srs_success) { + return srs_error_wrap(err, "initialize st"); + } + + if ((err = srs->acquire_pid_file()) != srs_success) { + return srs_error_wrap(err, "acquire pid file"); + } + + if ((err = srs->initialize_signal()) != srs_success) { + return srs_error_wrap(err, "initialize signal"); + } + + if ((err = srs->listen()) != srs_success) { + return srs_error_wrap(err, "listen"); + } + + if ((err = srs->register_signal()) != srs_success) { + return srs_error_wrap(err, "register signal"); + } + + if ((err = srs->http_handle()) != srs_success) { + return srs_error_wrap(err, "http handle"); + } + + if ((err = srs->ingest()) != srs_success) { + return srs_error_wrap(err, "ingest"); + } + + if ((err = srs->cycle()) != srs_success) { + return srs_error_wrap(err, "main cycle"); + } + + return err; +} + +void SrsServerAdapter::stop() +{ +} + +SrsHybridServer::SrsHybridServer() +{ +} + +SrsHybridServer::~SrsHybridServer() +{ + vector::iterator it; + for (it = servers.begin(); it != servers.end(); ++it) { + ISrsHybridServer* server = *it; + srs_freep(server); + } + servers.clear(); +} + +void SrsHybridServer::register_server(ISrsHybridServer* svr) +{ + servers.push_back(svr); +} + +srs_error_t SrsHybridServer::initialize() +{ + srs_error_t err = srs_success; + + // init st + if ((err = srs_st_init()) != srs_success) { + return srs_error_wrap(err, "initialize st failed"); + } + + vector::iterator it; + for (it = servers.begin(); it != servers.end(); ++it) { + ISrsHybridServer* server = *it; + + if ((err = server->initialize()) != srs_success) { + return srs_error_wrap(err, "init server"); + } + } + + return err; +} + +srs_error_t SrsHybridServer::run() +{ + srs_error_t err = srs_success; + + // Run master server in this main thread. + SrsServerAdapter* master_server = NULL; + + vector::iterator it; + for (it = servers.begin(); it != servers.end(); ++it) { + ISrsHybridServer* server = *it; + + if (!master_server) { + master_server = dynamic_cast(server); + if (master_server) { + continue; + } + } + + if ((err = server->run()) != srs_success) { + return srs_error_wrap(err, "run server"); + } + } + + if (master_server) { + return master_server->run(); + } + + return err; +} + +void SrsHybridServer::stop() +{ + vector::iterator it; + for (it = servers.begin(); it != servers.end(); ++it) { + ISrsHybridServer* server = *it; + server->stop(); + } +} + +SrsHybridServer* _srs_hybrid = new SrsHybridServer(); + diff --git a/trunk/src/app/srs_app_hybrid.hpp b/trunk/src/app/srs_app_hybrid.hpp new file mode 100644 index 000000000..383456660 --- /dev/null +++ b/trunk/src/app/srs_app_hybrid.hpp @@ -0,0 +1,80 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2020 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SRS_APP_HYBRID_HPP +#define SRS_APP_HYBRID_HPP + +#include + +#include + +class SrsServer; + +// The hibrid server interfaces, we could register many servers. +class ISrsHybridServer +{ +public: + ISrsHybridServer(); + virtual ~ISrsHybridServer(); +public: + // Only ST initialized before each server, we could fork processes as such. + virtual srs_error_t initialize() = 0; + // Run each server, should never block except the SRS master server. + virtual srs_error_t run() = 0; + // Stop each server, should do cleanup, for example, kill processes forked by server. + virtual void stop() = 0; +}; + +// The SRS server adapter, the master server. +class SrsServerAdapter : public ISrsHybridServer +{ +private: + SrsServer* srs; +public: + SrsServerAdapter(); + virtual ~SrsServerAdapter(); +public: + virtual srs_error_t initialize(); + virtual srs_error_t run(); + virtual void stop(); +}; + +// The hybrid server manager. +class SrsHybridServer +{ +private: + std::vector servers; +public: + SrsHybridServer(); + virtual ~SrsHybridServer(); +public: + virtual void register_server(ISrsHybridServer* svr); +public: + virtual srs_error_t initialize(); + virtual srs_error_t run(); + virtual void stop(); +}; + +extern SrsHybridServer* _srs_hybrid; + +#endif diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 85666ce2d..9a51ded50 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -565,11 +565,6 @@ srs_error_t SrsServer::initialize_st() { srs_error_t err = srs_success; - // init st - if ((err = srs_st_init()) != srs_success) { - return srs_error_wrap(err, "initialize st failed"); - } - // @remark, st alloc segment use mmap, which only support 32757 threads, // if need to support more, for instance, 100k threads, define the macro MALLOC_STACK. // TODO: FIXME: maybe can use "sysctl vm.max_map_count" to refine. @@ -688,11 +683,6 @@ srs_error_t SrsServer::listen() if ((err = conn_manager->start()) != srs_success) { return srs_error_wrap(err, "connection manager"); } -#ifdef SRS_AUTO_SRT - if ((err = listen_srt()) != srs_success) { - return srs_error_wrap(err, "srt listen"); - } -#endif return err; } @@ -1009,32 +999,6 @@ srs_error_t SrsServer::do_cycle() return err; } -#ifdef SRS_AUTO_SRT -srs_error_t SrsServer::listen_srt() { - srs_error_t err = srs_success; - - if(_srs_config->get_srt_enabled()) { - srs_trace("srt server is enabled..."); - unsigned short srt_port = _srs_config->get_srt_listen_port(); - srs_trace("srt server listen port:%d", srt_port); - err = srt2rtmp::get_instance()->init(); - if (err != srs_success) { - srs_error_wrap(err, "srt start srt2rtmp error"); - return err; - } - - srt_ptr = std::make_shared(srt_port); - if (!srt_ptr) { - srs_error_wrap(err, "srt listen %d", srt_port); - } - srt_ptr->start(); - } else { - srs_trace("srt server is disabled..."); - } - return err; -} -#endif - srs_error_t SrsServer::listen_rtmp() { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index e08a5f8d9..fd8cbe3ad 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -36,10 +36,6 @@ #include #include #include -#ifdef SRS_AUTO_SRT -#include -#include -#endif class SrsServer; class SrsConnection; @@ -213,10 +209,6 @@ private: SrsHttpHeartbeat* http_heartbeat; SrsIngester* ingester; SrsCoroutineManager* conn_manager; -#ifdef SRS_AUTO_SRT - // srt server - SRT_SERVER_PTR srt_ptr; -#endif private: // The pid file fd, lock the file write when server is running. // @remark the init.d script should cleanup the pid file, when stop service, @@ -287,10 +279,6 @@ private: virtual srs_error_t listen_http_api(); virtual srs_error_t listen_http_stream(); virtual srs_error_t listen_stream_caster(); -#ifdef SRS_AUTO_SRT - //start listen srt udp port - virtual srs_error_t listen_srt(); -#endif // Close the listeners for specified type, // Remove the listen object from manager. virtual void close_listeners(SrsListenerType type); diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 2bca91cdf..d1febe177 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -25,9 +25,9 @@ #define SRS_CORE_HPP // The version config. -#define VERSION_MAJOR 3 +#define VERSION_MAJOR 4 #define VERSION_MINOR 0 -#define VERSION_REVISION 106 +#define VERSION_REVISION 1 // The macros generated by configure script. #include @@ -41,7 +41,8 @@ #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_CODE "OuXuli" #define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs" -#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" +#define RTMP_SIG_SRS_LICENSE "MIT" +#define RTMP_SIG_SRS_AUTHORS "winlin,wenjie,runner365" #define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION) #define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY "/" RTMP_SIG_SRS_VERSION "(" RTMP_SIG_SRS_CODE ")" diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index e0570240e..190346e89 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -48,10 +48,15 @@ using namespace std; #include #include #include +#include + +#ifdef SRS_AUTO_SRT +#include +#endif // pre-declare -srs_error_t run(SrsServer* svr); -srs_error_t run_master(SrsServer* svr); +srs_error_t run_directly_or_daemon(); +srs_error_t run_hybrid_server(); void show_macro_features(); string srs_getenv(const char* name); @@ -119,6 +124,7 @@ srs_error_t do_main(int argc, char** argv) // config already applied to log. srs_trace("%s, %s", RTMP_SIG_SRS_SERVER, RTMP_SIG_SRS_LICENSE); + srs_trace("authors: %s", RTMP_SIG_SRS_AUTHORS); srs_trace("contributors: %s", SRS_AUTO_CONSTRIBUTORS); srs_trace("cwd=%s, work_dir=%s, build: %s, configure: %s, uname: %s", _srs_config->cwd().c_str(), cwd.c_str(), SRS_AUTO_BUILD_DATE, SRS_AUTO_USER_CONFIGURE, SRS_AUTO_UNAME); @@ -177,10 +183,7 @@ srs_error_t do_main(int argc, char** argv) // features show_macro_features(); - SrsServer* svr = new SrsServer(); - SrsAutoFree(SrsServer, svr); - - if ((err = run(svr)) != srs_success) { + if ((err = run_directly_or_daemon()) != srs_success) { return srs_error_wrap(err, "run"); } @@ -351,18 +354,13 @@ string srs_getenv(const char* name) return ""; } -srs_error_t run(SrsServer* svr) +srs_error_t run_directly_or_daemon() { srs_error_t err = srs_success; - - // Initialize the whole system, set hooks to handle server level events. - if ((err = svr->initialize(NULL)) != srs_success) { - return srs_error_wrap(err, "server initialize"); - } // If not daemon, directly run master. if (!_srs_config->get_daemon()) { - if ((err = run_master(svr)) != srs_success) { + if ((err = run_hybrid_server()) != srs_success) { return srs_error_wrap(err, "run master"); } return srs_success; @@ -399,49 +397,35 @@ srs_error_t run(SrsServer* svr) // son srs_trace("son(daemon) process running."); - if ((err = run_master(svr)) != srs_success) { + if ((err = run_hybrid_server()) != srs_success) { return srs_error_wrap(err, "daemon run master"); } return err; } -srs_error_t run_master(SrsServer* svr) +srs_error_t run_hybrid_server() { srs_error_t err = srs_success; - - if ((err = svr->initialize_st()) != srs_success) { - return srs_error_wrap(err, "initialize st"); - } - - if ((err = svr->initialize_signal()) != srs_success) { - return srs_error_wrap(err, "initialize signal"); - } - - if ((err = svr->acquire_pid_file()) != srs_success) { - return srs_error_wrap(err, "acquire pid file"); - } - - if ((err = svr->listen()) != srs_success) { - return srs_error_wrap(err, "listen"); - } - - if ((err = svr->register_signal()) != srs_success) { - return srs_error_wrap(err, "register signal"); - } - - if ((err = svr->http_handle()) != srs_success) { - return srs_error_wrap(err, "http handle"); - } - - if ((err = svr->ingest()) != srs_success) { - return srs_error_wrap(err, "ingest"); + + _srs_hybrid->register_server(new SrsServerAdapter()); +#ifdef SRS_AUTO_SRT + _srs_hybrid->register_server(new SrtServerAdapter()); +#endif + + // Do some system initialize. + if ((err = _srs_hybrid->initialize()) != srs_success) { + return srs_error_wrap(err, "hybrid initialize"); } - - if ((err = svr->cycle()) != srs_success) { - return srs_error_wrap(err, "main cycle"); + + // Should run util hybrid servers all done. + if ((err = _srs_hybrid->run()) != srs_success) { + return srs_error_wrap(err, "hybrid run"); } - + + // After all done, stop and cleanup. + _srs_hybrid->stop(); + return err; } diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index bec1ad35c..a530316cd 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -2399,6 +2399,7 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); + data->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHORS)); if (server_ip) { data->set("srs_server_ip", SrsAmf0Any::str(server_ip)); diff --git a/trunk/src/srt/srt_server.cpp b/trunk/src/srt/srt_server.cpp index b938f3678..021f714ec 100644 --- a/trunk/src/srt/srt_server.cpp +++ b/trunk/src/srt/srt_server.cpp @@ -199,3 +199,55 @@ void srt_server::on_work() } } } + +SrtServerAdapter::SrtServerAdapter() +{ +} + +SrtServerAdapter::~SrtServerAdapter() +{ +} + +srs_error_t SrtServerAdapter::initialize() +{ + srs_error_t err = srs_success; + + // TODO: FIXME: We could fork processes here, because here only ST is initialized. + + return err; +} + +srs_error_t SrtServerAdapter::run() +{ + srs_error_t err = srs_success; + + // TODO: FIXME: We could start a coroutine to dispatch SRT task to processes. + + if(_srs_config->get_srt_enabled()) { + srs_trace("srt server is enabled..."); + unsigned short srt_port = _srs_config->get_srt_listen_port(); + srs_trace("srt server listen port:%d", srt_port); + err = srt2rtmp::get_instance()->init(); + if (err != srs_success) { + return srs_error_wrap(err, "srt start srt2rtmp error"); + } + + srt_ptr = std::make_shared(srt_port); + if (!srt_ptr) { + return srs_error_wrap(err, "srt listen %d", srt_port); + } + } else { + srs_trace("srt server is disabled..."); + } + + if(_srs_config->get_srt_enabled()) { + srt_ptr->start(); + } + + return err; +} + +void SrtServerAdapter::stop() +{ + // TODO: FIXME: If forked processes, we should do cleanup. +} diff --git a/trunk/src/srt/srt_server.hpp b/trunk/src/srt/srt_server.hpp index 7201b7263..27bb3bdfb 100644 --- a/trunk/src/srt/srt_server.hpp +++ b/trunk/src/srt/srt_server.hpp @@ -1,10 +1,13 @@ #ifndef SRT_SERVER_H #define SRT_SERVER_H + #include #include #include +#include + class srt_handle; class srt_server { @@ -34,4 +37,17 @@ private: typedef std::shared_ptr SRT_SERVER_PTR; +class SrtServerAdapter : public ISrsHybridServer +{ +private: + SRT_SERVER_PTR srt_ptr; +public: + SrtServerAdapter(); + virtual ~SrtServerAdapter(); +public: + virtual srs_error_t initialize(); + virtual srs_error_t run(); + virtual void stop(); +}; + #endif//SRT_SERVER_H \ No newline at end of file