mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
Update
This commit is contained in:
commit
5b75eadc0c
24 changed files with 197 additions and 183 deletions
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
|
@ -50,8 +50,10 @@ jobs:
|
||||||
# SRS_PACKAGE_ZIP=SRS-CentOS7-x86_64-4.0.145.zip
|
# SRS_PACKAGE_ZIP=SRS-CentOS7-x86_64-4.0.145.zip
|
||||||
# SRS_PACKAGE_MD5=3880a26e30b283edf05700a4e69956e5
|
# SRS_PACKAGE_MD5=3880a26e30b283edf05700a4e69956e5
|
||||||
- name: Create package zip
|
- name: Create package zip
|
||||||
|
env:
|
||||||
|
PACKAGER: ${{ secrets.SRS_PACKAGER_BINARY }}
|
||||||
run: |
|
run: |
|
||||||
docker build --tag srs:pkg --build-arg version=$SRS_VERSION -f trunk/Dockerfile.pkg . &&
|
docker build --tag srs:pkg --build-arg version=$SRS_VERSION --build-arg SRS_AUTO_PACKAGER=$PACKAGER -f trunk/Dockerfile.pkg . &&
|
||||||
SRS_PACKAGE_ZIP=SRS-CentOS7-x86_64-$SRS_VERSION.zip &&
|
SRS_PACKAGE_ZIP=SRS-CentOS7-x86_64-$SRS_VERSION.zip &&
|
||||||
docker run --rm -v $(pwd):/output srs:pkg cp objs/$SRS_PACKAGE_ZIP /output/ &&
|
docker run --rm -v $(pwd):/output srs:pkg cp objs/$SRS_PACKAGE_ZIP /output/ &&
|
||||||
du -sh $SRS_PACKAGE_ZIP &&
|
du -sh $SRS_PACKAGE_ZIP &&
|
||||||
|
@ -73,9 +75,11 @@ jobs:
|
||||||
# Build
|
# Build
|
||||||
# Build SRS image
|
# Build SRS image
|
||||||
- name: Build SRS docker image
|
- name: Build SRS docker image
|
||||||
|
env:
|
||||||
|
PACKAGER: ${{ secrets.SRS_PACKAGER_DOCKER }}
|
||||||
run: |
|
run: |
|
||||||
echo "Release ossrs/srs:$SRS_TAG"
|
echo "Release ossrs/srs:$SRS_TAG"
|
||||||
docker build --tag ossrs/srs:$SRS_TAG -f trunk/Dockerfile .
|
docker build --tag ossrs/srs:$SRS_TAG --build-arg SRS_AUTO_PACKAGER=$PACKAGER -f trunk/Dockerfile .
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Docker
|
# Docker
|
||||||
|
|
|
@ -125,6 +125,7 @@ A big `THANK YOU` also goes to:
|
||||||
|
|
||||||
## Releases
|
## Releases
|
||||||
|
|
||||||
|
* 2022-01-13, Release [v4.0-b3](https://github.com/ossrs/srs/releases/tag/v4.0-b3), v4.0-b3, 4.0 beta3, v4.0.229, 144393 lines.
|
||||||
* 2022-01-03, Release [v4.0-b2](https://github.com/ossrs/srs/releases/tag/v4.0-b2), v4.0-b2, 4.0 beta2, v4.0.215, 144278 lines.
|
* 2022-01-03, Release [v4.0-b2](https://github.com/ossrs/srs/releases/tag/v4.0-b2), v4.0-b2, 4.0 beta2, v4.0.215, 144278 lines.
|
||||||
* 2021-12-19, Release [v4.0-b1](https://github.com/ossrs/srs/releases/tag/v4.0-b1), v4.0-b1, 4.0 beta1, v4.0.206, 144126 lines.
|
* 2021-12-19, Release [v4.0-b1](https://github.com/ossrs/srs/releases/tag/v4.0-b1), v4.0-b1, 4.0 beta1, v4.0.206, 144126 lines.
|
||||||
* 2021-12-01, Release [v4.0-b0](https://github.com/ossrs/srs/releases/tag/v4.0-b0), v4.0-b0, 4.0 beta0, v4.0.201, 144022 lines.
|
* 2021-12-01, Release [v4.0-b0](https://github.com/ossrs/srs/releases/tag/v4.0-b0), v4.0-b0, 4.0 beta0, v4.0.201, 144022 lines.
|
||||||
|
|
|
@ -3,6 +3,8 @@ FROM ossrs/srs:dev AS build
|
||||||
# Install depends tools.
|
# Install depends tools.
|
||||||
RUN yum install -y gcc make gcc-c++ patch unzip perl git
|
RUN yum install -y gcc make gcc-c++ patch unzip perl git
|
||||||
|
|
||||||
|
ARG SRS_AUTO_PACKAGER
|
||||||
|
|
||||||
# Build and install SRS.
|
# Build and install SRS.
|
||||||
COPY . /srs
|
COPY . /srs
|
||||||
WORKDIR /srs/trunk
|
WORKDIR /srs/trunk
|
||||||
|
|
|
@ -2,13 +2,11 @@ FROM ossrs/srs:dev
|
||||||
|
|
||||||
# version=4.0.145
|
# version=4.0.145
|
||||||
ARG version
|
ARG version
|
||||||
|
ARG SRS_AUTO_PACKAGER
|
||||||
|
|
||||||
# Install depends tools.
|
# Install depends tools.
|
||||||
RUN yum install -y zip
|
RUN yum install -y zip
|
||||||
|
|
||||||
# Setup the packager env.
|
|
||||||
ENV SRS_AUTO_PACKAGER ossrs
|
|
||||||
|
|
||||||
# Build and install SRS.
|
# Build and install SRS.
|
||||||
ADD srs-server-${version}.tar.gz /srs
|
ADD srs-server-${version}.tar.gz /srs
|
||||||
WORKDIR /srs/srs-server-${version}/trunk
|
WORKDIR /srs/srs-server-${version}/trunk
|
||||||
|
|
|
@ -177,6 +177,7 @@ fi
|
||||||
# prefix
|
# prefix
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
echo "#define SRS_PREFIX \"${SRS_PREFIX}\"" >> $SRS_AUTO_HEADERS_H
|
echo "#define SRS_PREFIX \"${SRS_PREFIX}\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
echo "#define SRS_DEFAULT_CONFIG \"${SRS_DEFAULT_CONFIG}\"" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
echo "" >> $SRS_AUTO_HEADERS_H
|
echo "" >> $SRS_AUTO_HEADERS_H
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ SRS_FFMPEG_TOOL=NO
|
||||||
SRS_FFMPEG_FIT=RESERVED
|
SRS_FFMPEG_FIT=RESERVED
|
||||||
# arguments
|
# arguments
|
||||||
SRS_PREFIX=/usr/local/srs
|
SRS_PREFIX=/usr/local/srs
|
||||||
|
SRS_DEFAULT_CONFIG=conf/srs.conf
|
||||||
SRS_JOBS=1
|
SRS_JOBS=1
|
||||||
SRS_STATIC=NO
|
SRS_STATIC=NO
|
||||||
# If enabled, link shared libraries for libst.so which uses MPL license.
|
# If enabled, link shared libraries for libst.so which uses MPL license.
|
||||||
|
@ -127,6 +128,7 @@ Features:
|
||||||
--ffmpeg-fit=on|off Whether enable the FFmpeg fit(source code). Default: $(value2switch $SRS_FFMPEG_FIT)
|
--ffmpeg-fit=on|off Whether enable the FFmpeg fit(source code). Default: $(value2switch $SRS_FFMPEG_FIT)
|
||||||
|
|
||||||
--prefix=<path> The absolute installation path. Default: $SRS_PREFIX
|
--prefix=<path> The absolute installation path. Default: $SRS_PREFIX
|
||||||
|
--config=<path> The default config file for SRS. Default: $SRS_DEFAULT_CONFIG
|
||||||
--gcov=on|off Whether enable the GCOV compiler options. Default: $(value2switch $SRS_GCOV)
|
--gcov=on|off Whether enable the GCOV compiler options. Default: $(value2switch $SRS_GCOV)
|
||||||
--debug=on|off Whether enable the debug code, may hurt performance. Default: $(value2switch $SRS_DEBUG)
|
--debug=on|off Whether enable the debug code, may hurt performance. Default: $(value2switch $SRS_DEBUG)
|
||||||
--debug-stats=on|off Whether enable the debug stats, may hurt performance. Default: $(value2switch $SRS_DEBUG_STATS)
|
--debug-stats=on|off Whether enable the debug stats, may hurt performance. Default: $(value2switch $SRS_DEBUG_STATS)
|
||||||
|
@ -220,6 +222,7 @@ function parse_user_option() {
|
||||||
|
|
||||||
--jobs) SRS_JOBS=${value} ;;
|
--jobs) SRS_JOBS=${value} ;;
|
||||||
--prefix) SRS_PREFIX=${value} ;;
|
--prefix) SRS_PREFIX=${value} ;;
|
||||||
|
--config) SRS_DEFAULT_CONFIG=${value} ;;
|
||||||
|
|
||||||
--static) SRS_STATIC=$(switch2value $value) ;;
|
--static) SRS_STATIC=$(switch2value $value) ;;
|
||||||
--cpu) SRS_CROSS_BUILD_CPU=${value} ;;
|
--cpu) SRS_CROSS_BUILD_CPU=${value} ;;
|
||||||
|
@ -495,6 +498,7 @@ function regenerate_options() {
|
||||||
SRS_AUTO_USER_CONFIGURE=`echo $opt`
|
SRS_AUTO_USER_CONFIGURE=`echo $opt`
|
||||||
# regenerate the options for default values.
|
# regenerate the options for default values.
|
||||||
SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}"
|
SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}"
|
||||||
|
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --config=$SRS_DEFAULT_CONFIG"
|
||||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --hls=$(value2switch $SRS_HLS)"
|
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --hls=$(value2switch $SRS_HLS)"
|
||||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --hds=$(value2switch $SRS_HDS)"
|
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --hds=$(value2switch $SRS_HDS)"
|
||||||
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --dvr=$(value2switch $SRS_DVR)"
|
SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --dvr=$(value2switch $SRS_DVR)"
|
||||||
|
|
48
trunk/conf/vm.conf
Normal file
48
trunk/conf/vm.conf
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
listen 1935;
|
||||||
|
max_connections 1000;
|
||||||
|
daemon on;
|
||||||
|
srs_log_tank file;
|
||||||
|
|
||||||
|
# For LightHouse VM to run SRS, never enable docker.
|
||||||
|
in_docker off;
|
||||||
|
disable_daemon_for_docker off;
|
||||||
|
auto_reload_for_docker off;
|
||||||
|
|
||||||
|
http_server {
|
||||||
|
enabled on;
|
||||||
|
listen 8080;
|
||||||
|
dir ./objs/nginx/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
http_api {
|
||||||
|
enabled on;
|
||||||
|
listen 1985;
|
||||||
|
}
|
||||||
|
stats {
|
||||||
|
network 0;
|
||||||
|
}
|
||||||
|
rtc_server {
|
||||||
|
enabled on;
|
||||||
|
listen 8000; # UDP port
|
||||||
|
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
|
||||||
|
candidate $CANDIDATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
vhost __defaultVhost__ {
|
||||||
|
hls {
|
||||||
|
enabled on;
|
||||||
|
}
|
||||||
|
http_remux {
|
||||||
|
enabled on;
|
||||||
|
mount [vhost]/[app]/[stream].flv;
|
||||||
|
}
|
||||||
|
rtc {
|
||||||
|
enabled on;
|
||||||
|
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
|
||||||
|
rtmp_to_rtc on;
|
||||||
|
# @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
|
||||||
|
rtc_to_rtmp on;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
4
trunk/configure
vendored
4
trunk/configure
vendored
|
@ -460,6 +460,7 @@ CXXFLAGS = ${CXXFLAGS}
|
||||||
|
|
||||||
# install prefix.
|
# install prefix.
|
||||||
SRS_PREFIX=${SRS_PREFIX}
|
SRS_PREFIX=${SRS_PREFIX}
|
||||||
|
SRS_DEFAULT_CONFIG=${SRS_DEFAULT_CONFIG}
|
||||||
__REAL_INSTALL=\$(DESTDIR)\$(SRS_PREFIX)
|
__REAL_INSTALL=\$(DESTDIR)\$(SRS_PREFIX)
|
||||||
|
|
||||||
default: server
|
default: server
|
||||||
|
@ -592,11 +593,12 @@ install:
|
||||||
@mkdir -p \$(__REAL_INSTALL)/etc/init.d
|
@mkdir -p \$(__REAL_INSTALL)/etc/init.d
|
||||||
@cp -f etc/init.d/srs \$(__REAL_INSTALL)/etc/init.d
|
@cp -f etc/init.d/srs \$(__REAL_INSTALL)/etc/init.d
|
||||||
@sed -i "s|^ROOT=.*|ROOT=\"\$(SRS_PREFIX)\"|g" \$(__REAL_INSTALL)/etc/init.d/srs
|
@sed -i "s|^ROOT=.*|ROOT=\"\$(SRS_PREFIX)\"|g" \$(__REAL_INSTALL)/etc/init.d/srs
|
||||||
|
@sed -i "s|^CONFIG=.*|CONFIG=\"\$(SRS_DEFAULT_CONFIG)\"|g" \$(__REAL_INSTALL)/etc/init.d/srs
|
||||||
@echo "Now copy systemctl service files"
|
@echo "Now copy systemctl service files"
|
||||||
@mkdir -p \$(__REAL_INSTALL)/usr/lib/systemd/system
|
@mkdir -p \$(__REAL_INSTALL)/usr/lib/systemd/system
|
||||||
@cp -f usr/lib/systemd/system/srs.service \$(__REAL_INSTALL)/usr/lib/systemd/system/srs.service
|
@cp -f usr/lib/systemd/system/srs.service \$(__REAL_INSTALL)/usr/lib/systemd/system/srs.service
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "@see: https://github.com/ossrs/srs/wiki/v3_CN_LinuxService"
|
@echo "@see: https://github.com/ossrs/srs/wiki/v4_CN_LinuxService"
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,14 @@ The changelog for SRS.
|
||||||
|
|
||||||
## SRS 4.0 Changelog
|
## SRS 4.0 Changelog
|
||||||
|
|
||||||
* v4.0, 2022-01-20, Merge [#2863](https://github.com/ossrs/srs/pull/2863): RTC: fix play crash or no stream for rtmp2rtc tips.(#2863). v4.0.220
|
* v4.0, 2022-01-13, Merge [#2872](https://github.com/ossrs/srs/pull/2872): RTC: fix play rtc judge for config rtc2rtmp on. (#2872). v4.0.229
|
||||||
|
* v4.0, 2022-01-13, Support configure with --config as default config file. v4.0.227
|
||||||
|
* v4.0, 2022-01-13, For [#2880](https://github.com/ossrs/srs/pull/2880): Add SrsAutoFreeH to release ptr with hooks. (#2880). v4.0.226
|
||||||
|
* v4.0, 2022-01-13, Support api_port to specify the WebRTC API port. v4.0.224
|
||||||
|
* v4.0, 2022-01-13, Merge [#2873](https://github.com/ossrs/srs/pull/2873): LiveSource: Refine fetch for external exposed interface. (#2873). v4.0.223
|
||||||
|
* v4.0, 2022-01-13, Add conf/vm.conf for cloud virtual machine. v4.0.222
|
||||||
|
* v4.0, 2022-01-12, Refine the running homepage. v4.0.221
|
||||||
|
* v4.0, 2022-01-12, Merge [#2863](https://github.com/ossrs/srs/pull/2863): RTC: fix play crash or no stream for rtmp2rtc tips. (#2863). v4.0.220
|
||||||
* v4.0, 2022-01-05, For [#2717](https://github.com/ossrs/srs/issues/2717): When reopening segment, never update the duration. (#2717). v4.0.219
|
* v4.0, 2022-01-05, For [#2717](https://github.com/ossrs/srs/issues/2717): When reopening segment, never update the duration. (#2717). v4.0.219
|
||||||
* v4.0, 2022-01-04, Discover api server and ip as candidates. v4.0.218
|
* v4.0, 2022-01-04, Discover api server and ip as candidates. v4.0.218
|
||||||
* v4.0, 2022-01-04, Install test-on self-sign certificate. v4.0.217
|
* v4.0, 2022-01-04, Install test-on self-sign certificate. v4.0.217
|
||||||
|
|
|
@ -1,127 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
### BEGIN INIT INFO
|
|
||||||
# Provides: ossrs-api(srs-api)
|
|
||||||
# Required-Start: $all
|
|
||||||
# Required-Stop: $all
|
|
||||||
# Default-Start: 2 3 4 5
|
|
||||||
# Default-Stop: 0 1 6
|
|
||||||
# Short-Description: ossrs-api(srs-api)
|
|
||||||
# Description: https://github.com/ossrs/srs
|
|
||||||
### END INIT INFO
|
|
||||||
|
|
||||||
# the config of ROOT, user must modify it when start srs from other directory,
|
|
||||||
# it's ok to use the script by command ./etc/init.d/ossrs
|
|
||||||
ROOT="./"
|
|
||||||
APP="python ./research/api-server/server.py"
|
|
||||||
CONFIG="8085"
|
|
||||||
|
|
||||||
########################################################################
|
|
||||||
# utility functions
|
|
||||||
########################################################################
|
|
||||||
RED="\\033[31m"
|
|
||||||
GREEN="\\033[32m"
|
|
||||||
YELLOW="\\033[33m"
|
|
||||||
BLACK="\\033[0m"
|
|
||||||
POS="\\033[60G"
|
|
||||||
|
|
||||||
ok_msg(){
|
|
||||||
echo -e "${1}${POS}${BLACK}[${GREEN} OK ${BLACK}]"
|
|
||||||
}
|
|
||||||
|
|
||||||
failed_msg(){
|
|
||||||
echo -e "${1}${POS}${BLACK}[${RED}FAILED${BLACK}]"
|
|
||||||
}
|
|
||||||
|
|
||||||
# load process info of srs-api
|
|
||||||
# @set variable $srs_api_id to the process id.
|
|
||||||
# @return 0, if process exists; otherwise:
|
|
||||||
# 1, for srs-api not exists.
|
|
||||||
# @set variable $error_msg if error.
|
|
||||||
load_process_info() {
|
|
||||||
srs_api_id=`ps aux|grep python|grep research|grep "api-server"|awk '{print $2}'`
|
|
||||||
if [[ -z $srs_api_id ]]; then error_msg="srs-api process does not exists"; return 1; fi
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
# if exists, exit.
|
|
||||||
load_process_info
|
|
||||||
if [[ 0 -eq $? ]]; then failed_msg "SRS-api started(pid ${srs_api_id}), should not start it again."; return 0; fi
|
|
||||||
|
|
||||||
# not exists, start server
|
|
||||||
ok_msg "Starting SRS-api..."
|
|
||||||
# TODO: FIXME: set limit by, for instance, "ulimit -HSn 10000"
|
|
||||||
# TODO: FIXME: write log to, for instance, the same dir of log.
|
|
||||||
# TODO: FIXME: support daemon, without nohup.
|
|
||||||
(cd ${ROOT}; nohup ${APP} ${CONFIG} >/dev/null 2>&1 &)
|
|
||||||
|
|
||||||
# check again after start server
|
|
||||||
load_process_info
|
|
||||||
ret=$?; if [[ 0 -eq $? ]]; then ok_msg "SRS-api started(pid ${srs_api_id})"; return 0; fi
|
|
||||||
|
|
||||||
failed_msg "SRS-api not started"
|
|
||||||
return $ret
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
# not start, exit
|
|
||||||
load_process_info
|
|
||||||
if [[ 0 -ne $? ]]; then failed_msg "SRS-api not start."; return 0; fi
|
|
||||||
|
|
||||||
ok_msg "Stopping SRS-api(pid ${srs_api_id})..."
|
|
||||||
|
|
||||||
# process exists, kill util stop
|
|
||||||
for((;;)); do
|
|
||||||
load_process_info
|
|
||||||
if [[ 0 -eq $? ]]; then
|
|
||||||
kill -s SIGKILL ${srs_api_id} 2>/dev/null
|
|
||||||
ret=$?; if [[ 0 -ne $ret ]]; then failed_msg "send signal SIGKILL failed ret=$ret"; return $ret; fi
|
|
||||||
sleep 0.1
|
|
||||||
else
|
|
||||||
ok_msg "SRS-api stopped"
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
sleep 0.1
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# get the status of srs-api process
|
|
||||||
# @return 0 if srs-api is running; otherwise, 1 for stopped.
|
|
||||||
status() {
|
|
||||||
load_process_info
|
|
||||||
ret=$?; if [[ 0 -eq $ret ]]; then echo "SRS-api(pid ${srs_api_id}) is running."; return 0; fi
|
|
||||||
|
|
||||||
echo "SRS-api is stopped"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
menu() {
|
|
||||||
case "$1" in
|
|
||||||
start)
|
|
||||||
start
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
stop
|
|
||||||
;;
|
|
||||||
restart)
|
|
||||||
stop
|
|
||||||
start
|
|
||||||
;;
|
|
||||||
status)
|
|
||||||
status
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: $0 {start|stop|status|restart}"
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
menu $1
|
|
||||||
|
|
||||||
code=$?
|
|
||||||
exit ${code}
|
|
|
@ -3,24 +3,70 @@
|
||||||
<head>
|
<head>
|
||||||
<title>SRS</title>
|
<title>SRS</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
.span6 {
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
background-color: rgb(246 248 250);
|
||||||
|
padding: 8px;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 85%;
|
||||||
|
line-height: 1.45;
|
||||||
|
border-radius: 6px;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h3><a href="https://github.com/ossrs/srs">SRS</a> works!</h3>
|
<div>
|
||||||
<p>
|
<h3><a href="https://github.com/ossrs/srs">SRS</a> works!</h3>
|
||||||
Click <a id="en" href="#">here</a> to enter SRS console.<br/>
|
<p>
|
||||||
点击进入<a id="cn" href="#">SRS控制台</a>
|
Click <a id="enConsole" href="#">here</a> to enter SRS console.<br/>
|
||||||
</p>
|
点击进入<a id="cnConsole" href="#">SRS控制台</a>
|
||||||
<p>
|
</p>
|
||||||
Click <a href="players/?autostart=true">here</a> to start SRS player.<br/>
|
<p>
|
||||||
点击进入<a href="players/?autostart=true">SRS播放器</a>
|
Publish stream by <a href="https://ffmpeg.org/download.html">FFmpeg</a> or <a href="https://obsproject.com/download">OBS</a>:<br/>
|
||||||
</p>
|
请使用工具<a href="https://ffmpeg.org/download.html">FFmpeg</a>或者<a href="https://obsproject.com/download">OBS</a>推流到下面地址:
|
||||||
<p><a href="https://github.com/ossrs/srs">SRS Team © 2021</a></p>
|
<pre id="url" class="code span6"></pre>
|
||||||
<script type="text/javascript">
|
</p>
|
||||||
// http://localhost:8080/console/ng_index.html#/connect?port=1985
|
<p>
|
||||||
// http://localhost:8080/console/ng_index.html#/summaries?port=1985
|
Click <a id="enPlayer" href="#">here</a> to start SRS player.<br/>
|
||||||
var en_url = window.location.protocol + "//" + window.location.host + "/console/en_index.html#/summaries?port=1985";
|
点击进入<a id="cnPlayer" href="#">SRS播放器</a>
|
||||||
var cn_url = window.location.protocol + "//" + window.location.host + "/console/ng_index.html#/summaries?port=1985";
|
</p>
|
||||||
document.getElementById("en").setAttribute('href', en_url);
|
<p><a href="https://github.com/ossrs/srs">SRS Team © 2022</a></p>
|
||||||
document.getElementById("cn").setAttribute('href', cn_url);
|
</div>
|
||||||
</script>
|
<script type="text/javascript">
|
||||||
|
// Build RTMP url.
|
||||||
|
if (true) {
|
||||||
|
const rtmpUrl = `rtmp://${window.location.hostname}/live/livestream`;
|
||||||
|
document.getElementById('url').innerText = rtmpUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build console url.
|
||||||
|
if (true) {
|
||||||
|
// The prefix for default website.
|
||||||
|
const prefix = `${window.location.protocol}//${window.location.host}`;
|
||||||
|
// If not 8080, user should proxy to the default port.
|
||||||
|
const query = parseInt(window.location.port) === 8080 ? `?port=1985` : '';
|
||||||
|
const enUrl = `${prefix}/console/en_index.html#/summaries${query}`;
|
||||||
|
const cnUrl = `${prefix}/console/ng_index.html#/summaries${query}`;
|
||||||
|
document.getElementById("enConsole").setAttribute('href', enUrl);
|
||||||
|
document.getElementById("cnConsole").setAttribute('href', cnUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The player url.
|
||||||
|
if (true) {
|
||||||
|
const prefix = `players/?schema=${window.location.protocol.replace(':', '')}`;
|
||||||
|
const httpPort = window.location.port || (window.location.protocol === 'http:' ? 80 : 443);
|
||||||
|
// If not 8080, user should proxy both stream and API to the default port.
|
||||||
|
const query = parseInt(window.location.port) === 8080 ? '' : `&port=${httpPort}&api=${httpPort}`;
|
||||||
|
document.getElementById("enPlayer").setAttribute('href', `${prefix}${query}`);
|
||||||
|
document.getElementById("cnPlayer").setAttribute('href', `${prefix}${query}`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -24,7 +24,7 @@ function update_nav() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special extra params, such as auth_key.
|
// Special extra params, such as auth_key.
|
||||||
function user_extra_params(query, params) {
|
function user_extra_params(query, params, rtc) {
|
||||||
var queries = params || [];
|
var queries = params || [];
|
||||||
|
|
||||||
for (var key in query.user_query) {
|
for (var key in query.user_query) {
|
||||||
|
@ -90,6 +90,8 @@ function build_default_flv_url() {
|
||||||
function build_default_rtc_url(query) {
|
function build_default_rtc_url(query) {
|
||||||
// The format for query string to overwrite configs of server.
|
// The format for query string to overwrite configs of server.
|
||||||
console.log('?eip=x.x.x.x to overwrite candidate. 覆盖服务器candidate(外网IP)配置');
|
console.log('?eip=x.x.x.x to overwrite candidate. 覆盖服务器candidate(外网IP)配置');
|
||||||
|
console.log('?api=x to overwrite WebRTC API(1985).');
|
||||||
|
console.log('?schema=http|https to overwrite WebRTC API protocol.');
|
||||||
|
|
||||||
var server = (!query.server)? window.location.hostname:query.server;
|
var server = (!query.server)? window.location.hostname:query.server;
|
||||||
var vhost = (!query.vhost)? window.location.hostname:query.vhost;
|
var vhost = (!query.vhost)? window.location.hostname:query.vhost;
|
||||||
|
@ -104,7 +106,7 @@ function build_default_rtc_url(query) {
|
||||||
if (query.schema && window.location.protocol !== query.schema + ':') {
|
if (query.schema && window.location.protocol !== query.schema + ':') {
|
||||||
queries.push('schema=' + query.schema);
|
queries.push('schema=' + query.schema);
|
||||||
}
|
}
|
||||||
queries = user_extra_params(query, queries);
|
queries = user_extra_params(query, queries, true);
|
||||||
|
|
||||||
var uri = "webrtc://" + server + api + "/" + app + "/" + stream + "?" + queries.join('&');
|
var uri = "webrtc://" + server + api + "/" + app + "/" + stream + "?" + queries.join('&');
|
||||||
while (uri.lastIndexOf("?") === uri.length - 1) {
|
while (uri.lastIndexOf("?") === uri.length - 1) {
|
||||||
|
|
|
@ -185,6 +185,12 @@ function SrsRtcPublisherAsync() {
|
||||||
|
|
||||||
var port = a.port;
|
var port = a.port;
|
||||||
if (!port) {
|
if (!port) {
|
||||||
|
// Finger out by webrtc url, if contains http or https port, to overwrite default 1985.
|
||||||
|
if (schema === 'webrtc' && url.indexOf(`webrtc://${a.host}:`) === 0) {
|
||||||
|
port = (url.indexOf(`webrtc://${a.host}:80`) === 0) ? 80 : 443;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess by schema.
|
||||||
if (schema === 'http') {
|
if (schema === 'http') {
|
||||||
port = 80;
|
port = 80;
|
||||||
} else if (schema === 'https') {
|
} else if (schema === 'https') {
|
||||||
|
@ -267,6 +273,7 @@ function SrsRtcPlayerAsync() {
|
||||||
// webrtc://r.ossrs.net/live/livestream
|
// webrtc://r.ossrs.net/live/livestream
|
||||||
// or specifies the API port:
|
// or specifies the API port:
|
||||||
// webrtc://r.ossrs.net:11985/live/livestream
|
// webrtc://r.ossrs.net:11985/live/livestream
|
||||||
|
// webrtc://r.ossrs.net:80/live/livestream
|
||||||
// or autostart the play:
|
// or autostart the play:
|
||||||
// webrtc://r.ossrs.net/live/livestream?autostart=true
|
// webrtc://r.ossrs.net/live/livestream?autostart=true
|
||||||
// or change the app from live to myapp:
|
// or change the app from live to myapp:
|
||||||
|
@ -413,6 +420,12 @@ function SrsRtcPlayerAsync() {
|
||||||
|
|
||||||
var port = a.port;
|
var port = a.port;
|
||||||
if (!port) {
|
if (!port) {
|
||||||
|
// Finger out by webrtc url, if contains http or https port, to overwrite default 1985.
|
||||||
|
if (schema === 'webrtc' && url.indexOf(`webrtc://${a.host}:`) === 0) {
|
||||||
|
port = (url.indexOf(`webrtc://${a.host}:80`) === 0) ? 80 : 443;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess by schema.
|
||||||
if (schema === 'http') {
|
if (schema === 'http') {
|
||||||
port = 80;
|
port = 80;
|
||||||
} else if (schema === 'https') {
|
} else if (schema === 'https') {
|
||||||
|
|
|
@ -129,7 +129,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "see: https://github.com/ossrs/srs/wiki/v3_CN_LinuxService"
|
echo "see: https://github.com/ossrs/srs/wiki/v4_CN_LinuxService"
|
||||||
echo "install success, you can start SRS on CentOS6:"
|
echo "install success, you can start SRS on CentOS6:"
|
||||||
echo -e "${GREEN} sudo /etc/init.d/srs start${BLACK}"
|
echo -e "${GREEN} sudo /etc/init.d/srs start${BLACK}"
|
||||||
echo "or CentOS7:"
|
echo "or CentOS7:"
|
||||||
|
|
|
@ -50,7 +50,7 @@ const char* _srs_version = "XCORE-" RTMP_SIG_SRS_SERVER;
|
||||||
#define SRS_CONF_PERFER_TRUE(conf_arg) conf_arg != "off"
|
#define SRS_CONF_PERFER_TRUE(conf_arg) conf_arg != "off"
|
||||||
|
|
||||||
// default config file.
|
// default config file.
|
||||||
#define SRS_CONF_DEFAULT_COFNIG_FILE "conf/srs.conf"
|
#define SRS_CONF_DEFAULT_COFNIG_FILE SRS_DEFAULT_CONFIG
|
||||||
|
|
||||||
// '\n'
|
// '\n'
|
||||||
#define SRS_LF (char)SRS_CONSTS_LF
|
#define SRS_LF (char)SRS_CONSTS_LF
|
||||||
|
|
|
@ -186,8 +186,15 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
|
||||||
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_);
|
||||||
|
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
|
// For RTMP to RTC, fail if disabled and RTMP is active, see https://github.com/ossrs/srs/issues/2728
|
||||||
if (!_srs_config->get_rtc_from_rtmp(ruc.req_->vhost)) {
|
if (!is_rtc_stream_active && !_srs_config->get_rtc_from_rtmp(ruc.req_->vhost)) {
|
||||||
SrsLiveSource* rtmp = _srs_sources->fetch(ruc.req_);
|
SrsLiveSource* rtmp = _srs_sources->fetch(ruc.req_);
|
||||||
if (rtmp && !rtmp->inactive()) {
|
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());
|
||||||
|
|
|
@ -1183,20 +1183,20 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest* r, SrsRtcSourceDescripti
|
||||||
}
|
}
|
||||||
source->set_publish_stream(this);
|
source->set_publish_stream(this);
|
||||||
|
|
||||||
|
// TODO: FIMXE: Check it in SrsRtcConnection::add_publisher?
|
||||||
|
SrsLiveSource *rtmp = _srs_sources->fetch(r);
|
||||||
|
if (rtmp && !rtmp->can_publish(false)) {
|
||||||
|
return srs_error_new(ERROR_SYSTEM_STREAM_BUSY, "rtmp stream %s busy", r->get_stream_url().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// Bridge to rtmp
|
// Bridge to rtmp
|
||||||
#if defined(SRS_RTC) && defined(SRS_FFMPEG_FIT)
|
#if defined(SRS_RTC) && defined(SRS_FFMPEG_FIT)
|
||||||
bool rtc_to_rtmp = _srs_config->get_rtc_to_rtmp(req_->vhost);
|
bool rtc_to_rtmp = _srs_config->get_rtc_to_rtmp(req_->vhost);
|
||||||
if (rtc_to_rtmp) {
|
if (rtc_to_rtmp) {
|
||||||
SrsLiveSource *rtmp = NULL;
|
|
||||||
if ((err = _srs_sources->fetch_or_create(r, _srs_hybrid->srs()->instance(), &rtmp)) != srs_success) {
|
if ((err = _srs_sources->fetch_or_create(r, _srs_hybrid->srs()->instance(), &rtmp)) != srs_success) {
|
||||||
return srs_error_wrap(err, "create source");
|
return srs_error_wrap(err, "create source");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: FIMXE: Check it in SrsRtcConnection::add_publisher?
|
|
||||||
if (!rtmp->can_publish(false)) {
|
|
||||||
return srs_error_new(ERROR_SYSTEM_STREAM_BUSY, "rtmp stream %s busy", r->get_stream_url().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable GOP cache for RTC2RTMP bridger, to keep the streams in sync,
|
// Disable GOP cache for RTC2RTMP bridger, to keep the streams in sync,
|
||||||
// especially for stream merging.
|
// especially for stream merging.
|
||||||
rtmp->set_cache(false);
|
rtmp->set_cache(false);
|
||||||
|
|
|
@ -256,6 +256,10 @@ srs_error_t SrsRtcSourceManager::fetch_or_create(SrsRequest* r, SrsRtcSource** p
|
||||||
|
|
||||||
SrsRtcSource* source = NULL;
|
SrsRtcSource* source = NULL;
|
||||||
if ((source = fetch(r)) != NULL) {
|
if ((source = fetch(r)) != NULL) {
|
||||||
|
// we always update the request of resource,
|
||||||
|
// for origin auth is on, the token in request maybe invalid,
|
||||||
|
// and we only need to update the token of request, it's simple.
|
||||||
|
source->update_auth(r);
|
||||||
*pps = source;
|
*pps = source;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -291,11 +295,6 @@ SrsRtcSource* SrsRtcSourceManager::fetch(SrsRequest* r)
|
||||||
|
|
||||||
source = pool[stream_url];
|
source = pool[stream_url];
|
||||||
|
|
||||||
// we always update the request of resource,
|
|
||||||
// for origin auth is on, the token in request maybe invalid,
|
|
||||||
// and we only need to update the token of request, it's simple.
|
|
||||||
source->update_auth(r);
|
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,9 +112,8 @@ public:
|
||||||
// @param r the client request.
|
// @param r the client request.
|
||||||
// @param pps the matched source, if success never be NULL.
|
// @param pps the matched source, if success never be NULL.
|
||||||
virtual srs_error_t fetch_or_create(SrsRequest* r, SrsRtcSource** pps);
|
virtual srs_error_t fetch_or_create(SrsRequest* r, SrsRtcSource** pps);
|
||||||
private:
|
public:
|
||||||
// Get the exists source, NULL when not exists.
|
// Get the exists source, NULL when not exists.
|
||||||
// update the request and return the exists source.
|
|
||||||
virtual SrsRtcSource* fetch(SrsRequest* r);
|
virtual SrsRtcSource* fetch(SrsRequest* r);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1713,6 +1713,10 @@ srs_error_t SrsLiveSourceManager::fetch_or_create(SrsRequest* r, ISrsLiveSourceH
|
||||||
|
|
||||||
SrsLiveSource* source = NULL;
|
SrsLiveSource* source = NULL;
|
||||||
if ((source = fetch(r)) != NULL) {
|
if ((source = fetch(r)) != NULL) {
|
||||||
|
// we always update the request of resource,
|
||||||
|
// for origin auth is on, the token in request maybe invalid,
|
||||||
|
// and we only need to update the token of request, it's simple.
|
||||||
|
source->update_auth(r);
|
||||||
*pps = source;
|
*pps = source;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1751,11 +1755,6 @@ SrsLiveSource* SrsLiveSourceManager::fetch(SrsRequest* r)
|
||||||
|
|
||||||
source = pool[stream_url];
|
source = pool[stream_url];
|
||||||
|
|
||||||
// we always update the request of resource,
|
|
||||||
// for origin auth is on, the token in request maybe invalid,
|
|
||||||
// and we only need to update the token of request, it's simple.
|
|
||||||
source->update_auth(r);
|
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -450,7 +450,6 @@ public:
|
||||||
virtual srs_error_t fetch_or_create(SrsRequest* r, ISrsLiveSourceHandler* h, SrsLiveSource** pps);
|
virtual srs_error_t fetch_or_create(SrsRequest* r, ISrsLiveSourceHandler* h, SrsLiveSource** pps);
|
||||||
public:
|
public:
|
||||||
// Get the exists source, NULL when not exists.
|
// Get the exists source, NULL when not exists.
|
||||||
// update the request and return the exists source.
|
|
||||||
virtual SrsLiveSource* fetch(SrsRequest* r);
|
virtual SrsLiveSource* fetch(SrsRequest* r);
|
||||||
public:
|
public:
|
||||||
// dispose and cycle all sources.
|
// dispose and cycle all sources.
|
||||||
|
|
|
@ -30,13 +30,16 @@
|
||||||
// where the char* pstr = new char[size].
|
// where the char* pstr = new char[size].
|
||||||
// To delete object.
|
// To delete object.
|
||||||
#define SrsAutoFree(className, instance) \
|
#define SrsAutoFree(className, instance) \
|
||||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false)
|
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, NULL)
|
||||||
// To delete array.
|
// To delete array.
|
||||||
#define SrsAutoFreeA(className, instance) \
|
#define SrsAutoFreeA(className, instance) \
|
||||||
impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true, false)
|
impl_SrsAutoFree<className> _auto_free_array_##instance(&instance, true, false, NULL)
|
||||||
// Use free instead of delete.
|
// Use free instead of delete.
|
||||||
#define SrsAutoFreeF(className, instance) \
|
#define SrsAutoFreeF(className, instance) \
|
||||||
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, true)
|
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, true, NULL)
|
||||||
|
// Use hook instead of delete.
|
||||||
|
#define SrsAutoFreeH(className, instance, hook) \
|
||||||
|
impl_SrsAutoFree<className> _auto_free_##instance(&instance, false, false, hook)
|
||||||
// The template implementation.
|
// The template implementation.
|
||||||
template<class T>
|
template<class T>
|
||||||
class impl_SrsAutoFree
|
class impl_SrsAutoFree
|
||||||
|
@ -45,11 +48,16 @@ private:
|
||||||
T** ptr;
|
T** ptr;
|
||||||
bool is_array;
|
bool is_array;
|
||||||
bool _use_free;
|
bool _use_free;
|
||||||
|
void (*_hook)(T*);
|
||||||
public:
|
public:
|
||||||
impl_SrsAutoFree(T** p, bool array, bool use_free) {
|
// If use_free, use free(void*) to release the p.
|
||||||
|
// If specified hook, use hook(p) to release it.
|
||||||
|
// Use delete to release p, or delete[] if p is an array.
|
||||||
|
impl_SrsAutoFree(T** p, bool array, bool use_free, void (*hook)(T*)) {
|
||||||
ptr = p;
|
ptr = p;
|
||||||
is_array = array;
|
is_array = array;
|
||||||
_use_free = use_free;
|
_use_free = use_free;
|
||||||
|
_hook = hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~impl_SrsAutoFree() {
|
virtual ~impl_SrsAutoFree() {
|
||||||
|
@ -59,6 +67,8 @@ public:
|
||||||
|
|
||||||
if (_use_free) {
|
if (_use_free) {
|
||||||
free(*ptr);
|
free(*ptr);
|
||||||
|
} else if (_hook) {
|
||||||
|
_hook(*ptr);
|
||||||
} else {
|
} else {
|
||||||
if (is_array) {
|
if (is_array) {
|
||||||
delete[] *ptr;
|
delete[] *ptr;
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 4
|
#define VERSION_MAJOR 4
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 220
|
#define VERSION_REVISION 229
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -126,8 +126,8 @@ srs_error_t do_main(int argc, char** argv)
|
||||||
// config already applied to log.
|
// config already applied to log.
|
||||||
srs_trace2(TAG_MAIN, "%s, %s", RTMP_SIG_SRS_SERVER, RTMP_SIG_SRS_LICENSE);
|
srs_trace2(TAG_MAIN, "%s, %s", RTMP_SIG_SRS_SERVER, RTMP_SIG_SRS_LICENSE);
|
||||||
srs_trace("authors: %sand %s", RTMP_SIG_SRS_AUTHORS, SRS_CONSTRIBUTORS);
|
srs_trace("authors: %sand %s", RTMP_SIG_SRS_AUTHORS, SRS_CONSTRIBUTORS);
|
||||||
srs_trace("cwd=%s, work_dir=%s, build: %s, configure: %s, uname: %s, osx: %d",
|
srs_trace("cwd=%s, work_dir=%s, build: %s, configure: %s, uname: %s, osx: %d, pkg: %s",
|
||||||
_srs_config->cwd().c_str(), cwd.c_str(), SRS_BUILD_DATE, SRS_USER_CONFIGURE, SRS_UNAME, SRS_OSX_BOOL);
|
_srs_config->cwd().c_str(), cwd.c_str(), SRS_BUILD_DATE, SRS_USER_CONFIGURE, SRS_UNAME, SRS_OSX_BOOL, SRS_PACKAGER);
|
||||||
srs_trace("configure detail: " SRS_CONFIGURE);
|
srs_trace("configure detail: " SRS_CONFIGURE);
|
||||||
#ifdef SRS_EMBEDED_TOOL_CHAIN
|
#ifdef SRS_EMBEDED_TOOL_CHAIN
|
||||||
srs_trace("crossbuild tool chain: " SRS_EMBEDED_TOOL_CHAIN);
|
srs_trace("crossbuild tool chain: " SRS_EMBEDED_TOOL_CHAIN);
|
||||||
|
|
Loading…
Reference in a new issue