1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

fix 'output' format define; support 'host' auto get; time config use SRS internal format; support auto create stream channel on/off

This commit is contained in:
xialixin 2020-04-03 20:19:02 +08:00
parent 5e4fdfd1d4
commit 92d351ef35
6 changed files with 163 additions and 64 deletions

View file

@ -10,14 +10,20 @@ http_api {
listen 1985;
}
stats {
network 0;
}
stream_caster {
enabled on;
caster gb28181;
# 转发流到rtmp服务器地址与端口
# TODO: https://github.com/ossrs/srs/pull/1679/files#r400875104
# [stream] is VideoChannelCodecID(视频通道编码ID)
output 127.0.0.1:1935;
# [stream] is VideoChannelCodecID(视频通道编码ID) for sip
# 自动创建的道通[stream] 是chid[ssrc] [ssrc]是rtp的ssrc
# [ssrc] rtp中的ssrc
output rtmp://127.0.0.1:1935/live/[stream];
# 接收设备端rtp流的多路复用端口
listen 9000;
@ -52,8 +58,14 @@ stream_caster {
# 也就是设备端将媒体发送的地址,如果是服务器是内外网
# 需要写外网地址,
# 调用api创建stream session时返回ip地址也是host
# $CANDIDATE 是系统环境变量,从环境变量获取地址,如果没有配置,用*
# *代表指定stats network 的网卡号地址如果没有配置network默认则是第0号网卡地址
# TODO: https://github.com/ossrs/srs/pull/1679/files#r400917594
host 192.168.1.27;
host $CANDIDATE;
#根据收到ps rtp包自带创建rtmp媒体通道不需要api接口创建
#rtmp地址参数[stream] 就是通道id 格式chid[ssrc]
auto_create_channel off;
sip {
# 是否启用srs内部sip信令

View file

@ -2164,8 +2164,11 @@ srs_error_t SrsConfig::global_to_json(SrsJsonObject* obj)
sobj->set(sdir->name, sdir->dumps_arg0_to_str());
} else if (sdir->name == "auto_play") {
sobj->set(sdir->name, sdir->dumps_arg0_to_str());
} else if (sdir->name == "auto_create_channel") {
sobj->set(sdir->name, sdir->dumps_arg0_to_str());
}
}
obj->set(dir->name, sobj);
} else {
@ -3681,7 +3684,7 @@ srs_error_t SrsConfig::check_normal_config()
&& n != "listen" && n != "rtp_port_min" && n != "rtp_port_max"
&& n != "rtp_idle_timeout" && n != "sip"
&& n != "audio_enable" && n != "wait_keyframe"
&& n != "host") {
&& n != "host" && n != "auto_create_channel") {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal stream_caster.%s", n.c_str());
}
@ -4333,9 +4336,9 @@ srs_utime_t SrsConfig::get_stream_caster_gb28181_rtp_idle_timeout(SrsConfDirecti
return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
}
int SrsConfig::get_stream_caster_gb28181_ack_timeout(SrsConfDirective* conf)
srs_utime_t SrsConfig::get_stream_caster_gb28181_ack_timeout(SrsConfDirective* conf)
{
static int DEFAULT = 30;
static srs_utime_t DEFAULT = 30 * SRS_UTIME_SECONDS;
if (!conf) {
return DEFAULT;
@ -4351,12 +4354,13 @@ int SrsConfig::get_stream_caster_gb28181_ack_timeout(SrsConfDirective* conf)
return DEFAULT;
}
return ::atoi(conf->arg0().c_str());
return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
}
int SrsConfig::get_stream_caster_gb28181_keepalive_timeout(SrsConfDirective* conf)
srs_utime_t SrsConfig::get_stream_caster_gb28181_keepalive_timeout(SrsConfDirective* conf)
{
static int DEFAULT = 120;
static srs_utime_t DEFAULT = 120 * SRS_UTIME_SECONDS;
if (!conf) {
return DEFAULT;
@ -4372,22 +4376,28 @@ int SrsConfig::get_stream_caster_gb28181_keepalive_timeout(SrsConfDirective* con
return DEFAULT;
}
return ::atoi(conf->arg0().c_str());
return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS);
}
string SrsConfig::get_stream_caster_gb28181_host(SrsConfDirective* conf)
{
static string DEFAULT = "";
if (!conf) {
return DEFAULT;
}
static string DEFAULT = "*";
conf = conf->get("host");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
string eip = srs_getenv(conf->arg0());
if (!eip.empty()) {
return eip;
}
// If configed as ENV, but no ENV set, use default value.
if (srs_string_starts_with(conf->arg0(), "$")) {
return DEFAULT;
}
return conf->arg0();
}
@ -4573,6 +4583,22 @@ bool SrsConfig::get_stream_caster_gb28181_sip_invite_port_fixed(SrsConfDirective
}
bool SrsConfig::get_stream_caster_gb28181_auto_create_channel(SrsConfDirective* conf)
{
static bool DEFAULT = false;
if (!conf) {
return DEFAULT;
}
conf = conf->get("auto_create_channel");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return SRS_CONF_PERFER_FALSE(conf->arg0());
}
int SrsConfig::get_rtc_server_enabled()
{
SrsConfDirective* conf = root->get("rtc_server");

View file

@ -501,8 +501,8 @@ public:
virtual int get_stream_caster_rtp_port_max(SrsConfDirective* conf);
virtual srs_utime_t get_stream_caster_gb28181_rtp_idle_timeout(SrsConfDirective* conf);
virtual int get_stream_caster_gb28181_ack_timeout(SrsConfDirective* conf);
virtual int get_stream_caster_gb28181_keepalive_timeout(SrsConfDirective* conf);
virtual srs_utime_t get_stream_caster_gb28181_ack_timeout(SrsConfDirective* conf);
virtual srs_utime_t get_stream_caster_gb28181_keepalive_timeout(SrsConfDirective* conf);
virtual bool get_stream_caster_gb28181_audio_enable(SrsConfDirective* conf);
virtual std::string get_stream_caster_gb28181_host(SrsConfDirective* conf);
virtual std::string get_stream_caster_gb28181_serial(SrsConfDirective* conf);
@ -513,6 +513,7 @@ public:
virtual bool get_stream_caster_gb28181_sip_auto_play(SrsConfDirective* conf);
virtual int get_stream_caster_gb28181_sip_listen(SrsConfDirective* conf);
virtual bool get_stream_caster_gb28181_sip_invite_port_fixed(SrsConfDirective* conf);
virtual bool get_stream_caster_gb28181_auto_create_channel(SrsConfDirective* conf);
// rtc section
public:

View file

@ -22,11 +22,7 @@
*/
#include <srs_app_gb28181.hpp>
#include <algorithm>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
using namespace std;
@ -292,9 +288,24 @@ srs_error_t SrsGb28181PsRtpProcessor::on_udp_packet(const sockaddr* from, const
muxer = _srs_gb28181->fetch_rtmpmuxer(channel_id);
}else {
muxer = _srs_gb28181->fetch_rtmpmuxer_by_ssrc(pkt.ssrc);
}
//auto crate channel
if (!muxer && config->auto_create_channel){
//auto create channel generated id
std::stringstream ss, ss1;
ss << "chid" << pkt.ssrc;
std::string tmp_id = ss.str();
SrsGb28181StreamChannel channel;
channel.set_channel_id(tmp_id);
channel.set_port_mode(RTP_PORT_MODE_FIXED);
channel.set_ssrc(pkt.ssrc);
_srs_gb28181->create_stream_channel(&channel);
muxer = _srs_gb28181->fetch_rtmpmuxer(tmp_id);
}
if (muxer){
//TODO: fixme: the same device uses the same SSRC to send with different local ports
//record the first peer port
@ -563,12 +574,23 @@ srs_error_t SrsPsStreamDemixer::on_ps_stream(char* ps_data, int ps_size, uint32_
return err;
}
static std::string get_host_candidate_ips(SrsConfDirective* c)
{
string candidate = _srs_config->get_stream_caster_gb28181_host(c);
if (candidate == "*" || candidate == "0.0.0.0") {
std::vector<std::string> ips = srs_get_local_ips();
int index = _srs_config->get_stats_network();
return ips.at(index);
} else {
return candidate;
}
}
//Gb28181 Config
SrsGb28181Config::SrsGb28181Config(SrsConfDirective* c)
{
// TODO: FIXME: support reload.
host = _srs_config->get_stream_caster_gb28181_host(c);
host = get_host_candidate_ips(c);
output = _srs_config->get_stream_caster_output(c);
rtp_mux_port = _srs_config->get_stream_caster_listen(c);
rtp_port_min = _srs_config->get_stream_caster_rtp_port_min(c);
@ -577,6 +599,7 @@ SrsGb28181Config::SrsGb28181Config(SrsConfDirective* c)
wait_keyframe = _srs_config->get_stream_caster_gb28181_wait_keyframe(c);
audio_enable = _srs_config->get_stream_caster_gb28181_audio_enable(c);
auto_create_channel = _srs_config->get_stream_caster_gb28181_auto_create_channel(c);
//sip config
sip_enable = _srs_config->get_stream_caster_gb28181_sip_enable(c);
@ -1173,6 +1196,7 @@ SrsGb28181StreamChannel::SrsGb28181StreamChannel(){
ssrc = 0;
rtp_peer_port = 0;
rtp_peer_ip = "";
rtmp_url = "";
}
SrsGb28181StreamChannel::~SrsGb28181StreamChannel()
@ -1193,6 +1217,8 @@ void SrsGb28181StreamChannel::copy(const SrsGb28181StreamChannel *s){
rtp_peer_ip = s->get_rtp_peer_ip();
rtp_peer_port = s->get_rtp_peer_port();
rtmp_url = s->get_rtmp_url();
}
void SrsGb28181StreamChannel::dumps(SrsJsonObject* obj)
@ -1202,12 +1228,14 @@ void SrsGb28181StreamChannel::dumps(SrsJsonObject* obj)
obj->set("rtmp_port", SrsJsonAny::integer(rtmp_port));
obj->set("app", SrsJsonAny::str(app.c_str()));
obj->set("stream", SrsJsonAny::str(stream.c_str()));
obj->set("rtmp_url", SrsJsonAny::str(rtmp_url.c_str()));
obj->set("ssrc", SrsJsonAny::integer(ssrc));
obj->set("rtp_port", SrsJsonAny::integer(rtp_port));
obj->set("port_mode", SrsJsonAny::str(port_mode.c_str()));
obj->set("rtp_peer_port", SrsJsonAny::integer(rtp_peer_port));
obj->set("rtp_peer_ip", SrsJsonAny::str(rtp_peer_ip.c_str()));
}
@ -1457,18 +1485,6 @@ uint32_t SrsGb28181Manger::create_stream_channel(SrsGb28181StreamChannel *channe
return ERROR_SUCCESS;
}
if (channel->get_stream().empty()){
channel->set_stream("[stream]");
}
if (channel->get_app().empty()){
channel->set_stream("[app]");
}
if (channel->get_port_mode().empty()){
channel->set_port_mode(RTP_PORT_MODE_FIXED);
}
//create on rtmp muxer, gb28181 stream to rtmp
srs_error_t err = srs_success;
if ((err = fetch_or_create_rtmpmuxer(id, &muxer)) != srs_success){
@ -1482,6 +1498,11 @@ uint32_t SrsGb28181Manger::create_stream_channel(SrsGb28181StreamChannel *channe
//random is random allocation port
int rtp_port = 0;
std::string port_mode = channel->get_port_mode();
if (port_mode.empty()){
port_mode = RTP_PORT_MODE_FIXED;
channel->set_port_mode(port_mode);
}
if (port_mode == RTP_PORT_MODE_RANDOM){
alloc_port(&rtp_port);
@ -1503,38 +1524,75 @@ uint32_t SrsGb28181Manger::create_stream_channel(SrsGb28181StreamChannel *channe
return ERROR_GB28181_PORT_MODE_INVALID;
}
//Generate SSRC according to the hash code,
//of the string value of the id
uint32_t ssrc = generate_ssrc(id);
uint32_t ssrc = channel->get_ssrc();
if (ssrc == 0){
//auto generate SSRC according to the hash code,
//of the string value of the id
ssrc = generate_ssrc(id);
}
rtmpmuxer_map_by_ssrc(muxer, ssrc);
//Generate RTMP push stream address,
std::string app = channel->get_app();
std::string stream = channel->get_stream();
app = srs_string_replace(app, "[app]", "live");
stream = srs_string_replace(stream, "[stream]", id);
std::string url = "rtmp://" + config->output + "/" + app + "/" + stream;
//generate RTMP push stream address,
//if the app and stream in the API are empty,
//RTMP URL is generated using the output template parameter
std::string url = "";
int rtmp_port;
string app = channel->get_app();
string stream = channel->get_stream();
if (true) {
std::string schema, host, vhost, param, _app, _stream;
srs_discovery_tc_url(url, schema, host, vhost, _app, _stream, rtmp_port, param);
url = srs_generate_rtmp_url(host, rtmp_port, "", "", app, stream, "");
string tcUrl, stream_name;
//get template rtmp url configuration
std::string output = config->output;
srs_parse_rtmp_url(output, tcUrl, stream_name);
string _schema, _host, _vhost, _param, _app, _stream;
srs_discovery_tc_url(tcUrl, _schema, _host, _vhost, _app, _stream, rtmp_port, _param);
//if the stream name is not parameterized,
//it needs to be parameterized to ensure that the stream name is different
if (!srs_string_contains(stream_name, "[stream]") &&
!srs_string_contains(stream_name, "[timestamp]") &&
!srs_string_contains(stream_name, "[ssrc]")){
stream_name = stream_name + "_[stream]";
}
if (app.empty()){
app = _app;
}
if (stream.empty())
{
stream = stream_name;
}
url = srs_generate_rtmp_url(_host, rtmp_port, "", "", app, stream, "");
url = srs_string_replace(url, "[app]", "live");
url = srs_string_replace(url, "[stream]", id);
std::stringstream ss;
ss << ssrc;
url = srs_string_replace(url, "[ssrc]", ss.str());
url = srs_path_build_timestamp(url);
}
muxer->set_rtmp_url(url);
srs_trace("gb28181: create new stream channel id:%s rtmp url=%s", id.c_str(), muxer->rtmp_url().c_str());
//update channel app stream value
srs_parse_rtmp_url(url, tcUrl, stream_name);
srs_discovery_tc_url(tcUrl, _schema, _host, _vhost, _app, _stream, rtmp_port, _param);
//generate the value returned to the api response
channel->set_rtp_port(rtp_port);
channel->set_ssrc(ssrc);
//generate the value returned to the api response
channel->set_app(app);
channel->set_stream(stream);
channel->set_rtp_port(rtp_port);
channel->set_rtmp_port(rtmp_port);
channel->set_ip(config->host);
channel->set_ssrc(ssrc);
channel->set_app(_app);
channel->set_stream(stream_name);
channel->set_rtmp_port(rtmp_port);
channel->set_ip(config->host);
std::string play_url = srs_generate_rtmp_url(config->host, rtmp_port, "", "", app, stream_name, "");
channel->set_rtmp_url(play_url);
}
muxer->set_rtmp_url(url);
srs_trace("gb28181: create new stream channel id:%s rtmp url=%s", id.c_str(), url.c_str());
muxer->copy_channel(channel);

View file

@ -299,14 +299,15 @@ public:
int rtp_port_min;
int rtp_port_max;
int rtp_mux_port;
bool auto_create_channel;
//sip config
int sip_port;
std::string sip_serial;
std::string sip_realm;
bool sip_enable;
int sip_ack_timeout;
int sip_keepalive_timeout;
srs_utime_t sip_ack_timeout;
srs_utime_t sip_keepalive_timeout;
bool print_sip_message;
bool sip_auto_play;
bool sip_invite_port_fixed;
@ -323,6 +324,7 @@ private:
std::string port_mode;
std::string app;
std::string stream;
std::string rtmp_url;
std::string ip;
int rtp_port;
@ -348,6 +350,7 @@ public:
uint32_t get_ssrc() const { return ssrc; }
uint32_t get_rtp_peer_port() const { return rtp_peer_port; }
std::string get_rtp_peer_ip() const { return rtp_peer_ip; }
std::string get_rtmp_url() const { return rtmp_url; }
void set_channel_id(const std::string &i) { channel_id = i; }
void set_port_mode(const std::string &p) { port_mode = p; }
@ -359,6 +362,7 @@ public:
void set_ssrc( const int &s) { ssrc = s;}
void set_rtp_peer_ip( const std::string &p) { rtp_peer_ip = p; }
void set_rtp_peer_port( const int &s) { rtp_peer_port = s;}
void set_rtmp_url( const std::string &u) { rtmp_url = u; }
void copy(const SrsGb28181StreamChannel *s);
void dumps(SrsJsonObject* obj);

View file

@ -122,10 +122,10 @@ srs_error_t SrsGb28181SipService::on_udp_sip(string peer_ip, int peer_port,
{
srs_error_t err = srs_success;
if (config->print_sip_message || true)
if (config->print_sip_message)
{
srs_trace("gb28181: request peer_ip=%s, peer_port=%d nbbuf=%d", peer_ip.c_str(), peer_port, nb_buf);
//srs_trace("gb28181: request recv message=%s", buf);
srs_trace("gb28181: request recv message=%s", buf);
}
if (nb_buf < 10) {
@ -208,8 +208,6 @@ srs_error_t SrsGb28181SipService::on_udp_sip(string peer_ip, int peer_port,
SrsGb28181StreamChannel ch;
ch.set_channel_id(session_id);
ch.set_ip(config->host);
ch.set_stream(session_id);
ch.set_app("live");
if (config->sip_invite_port_fixed){
ch.set_port_mode(RTP_PORT_MODE_FIXED);
}else {