mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
add rtc http request and response, exchange sdp.
This commit is contained in:
parent
3ce5f6ce6a
commit
bc22ebe949
11 changed files with 488 additions and 2 deletions
2
trunk/configure
vendored
2
trunk/configure
vendored
|
@ -254,7 +254,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
"srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge"
|
||||
"srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static"
|
||||
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
|
||||
"srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"
|
||||
"srs_app_mpegts_udp" "srs_app_rtc_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_hybrid")
|
||||
|
|
90
trunk/research/players/srs_rtc_player.html
Normal file
90
trunk/research/players/srs_rtc_player.html
Normal file
|
@ -0,0 +1,90 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh-cmn-Hans">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
rtc_media_player: <br>
|
||||
<video id = "rtc_media_player" autoplay></video>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
|
||||
var PeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
|
||||
var SessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
|
||||
|
||||
var url = "http://hw.com:1985/api/v1/sdp/";
|
||||
|
||||
var method = "POST";
|
||||
var shouldBeAsync = true;
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
|
||||
request.open(method, url, shouldBeAsync);
|
||||
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
||||
|
||||
var pc = new PeerConnection(null);
|
||||
|
||||
var constraints = {
|
||||
mandatory: {
|
||||
OfferToReceiveAudio: true,
|
||||
OfferToReceiveVideo: true
|
||||
}
|
||||
};
|
||||
|
||||
var sendViewerOfferFn = function(desc) {
|
||||
console.log('sendViewerOfferFn:', desc);
|
||||
|
||||
pc.setLocalDescription(desc);
|
||||
|
||||
var sdp_json = {"sdp":desc.sdp, "app":"webrtc", "stream":"test"};
|
||||
request.send(JSON.stringify(sdp_json));
|
||||
};
|
||||
|
||||
pc.createOffer(sendViewerOfferFn,
|
||||
function(error) {
|
||||
console.log('sendViewerOfferFn error:' + error);
|
||||
},
|
||||
constraints
|
||||
);
|
||||
|
||||
pc.onaddstream = function(event) {
|
||||
console.log('onaddstream');
|
||||
document.getElementById('rtc_media_player').srcObject = event.stream;
|
||||
rtc_media_player.load();
|
||||
};
|
||||
|
||||
pc.onicecandidate = function(event) {
|
||||
console.log('onicecandidate');
|
||||
};
|
||||
|
||||
pc.onconnectionstatechange = function(event) {
|
||||
console.log('onconnectionstatechange');
|
||||
};
|
||||
|
||||
pc.onicegatheringstatechange = function(event) {
|
||||
console.log('onicegatheringstatechange');
|
||||
};
|
||||
|
||||
pc.onsignalingstatechange = function(event) {
|
||||
console.log('onsignalingstatechange');
|
||||
};
|
||||
|
||||
request.onerror = function(event) {
|
||||
console.log('http error');
|
||||
};
|
||||
|
||||
request.onload = function () {
|
||||
console.log('onload,' , request.responseText);
|
||||
var json = JSON.parse(request.responseText);
|
||||
console.log('onmessage viewerResponse:', json.sdp);
|
||||
|
||||
pc.setRemoteDescription(new SessionDescription({type:'answer', sdp:json.sdp}));
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -3486,7 +3486,7 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
&& n != "srs_log_tank" && n != "srs_log_level" && n != "srs_log_file"
|
||||
&& 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 != "srt_server"
|
||||
&& n != "http_server" && n != "stream_caster" && n != "rtc" && n != "srt_server"
|
||||
&& n != "utc_time" && n != "work_dir" && n != "asprocess"
|
||||
&& n != "ff_log_level" && n != "grace_final_wait" && n != "force_grace_quit"
|
||||
&& n != "grace_start_wait"
|
||||
|
@ -4216,6 +4216,45 @@ int SrsConfig::get_stream_caster_rtp_port_max(SrsConfDirective* conf)
|
|||
return ::atoi(conf->arg0().c_str());
|
||||
}
|
||||
|
||||
int SrsConfig::get_rtc_enabled()
|
||||
{
|
||||
SrsConfDirective* conf = root->get("rtc");
|
||||
return get_rtc_enabled(conf);
|
||||
}
|
||||
|
||||
bool SrsConfig::get_rtc_enabled(SrsConfDirective* conf)
|
||||
{
|
||||
static bool DEFAULT = false;
|
||||
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("enabled");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
int SrsConfig::get_rtc_listen()
|
||||
{
|
||||
static int DEFAULT = 9527;
|
||||
|
||||
SrsConfDirective* conf = root->get("rtc");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("listen");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return ::atoi(conf->arg0().c_str());
|
||||
}
|
||||
|
||||
SrsConfDirective* SrsConfig::get_vhost(string vhost, bool try_default_vhost)
|
||||
{
|
||||
srs_assert(root);
|
||||
|
|
|
@ -490,6 +490,13 @@ public:
|
|||
virtual int get_stream_caster_rtp_port_min(SrsConfDirective* conf);
|
||||
// Get the max udp port for rtp of stream caster rtsp.
|
||||
virtual int get_stream_caster_rtp_port_max(SrsConfDirective* conf);
|
||||
|
||||
// rtc section
|
||||
public:
|
||||
virtual int get_rtc_enabled();
|
||||
virtual bool get_rtc_enabled(SrsConfDirective* conf);
|
||||
virtual int get_rtc_listen();
|
||||
|
||||
// vhost specified section
|
||||
public:
|
||||
// Get the vhost directive by vhost name.
|
||||
|
|
|
@ -47,6 +47,73 @@ using namespace std;
|
|||
#include <srs_protocol_utility.hpp>
|
||||
#include <srs_app_coworkers.hpp>
|
||||
|
||||
string test_sdp =
|
||||
"v=0\\r\\n"
|
||||
"o=- 0 0 IN IP4 127.0.0.1\\r\\n"
|
||||
"s=-\\r\\n"
|
||||
"t=0 0\\r\\n"
|
||||
"a=ice-lite\\r\\n"
|
||||
"a=group:BUNDLE 0 1\\r\\n"
|
||||
"a=msid-semantic: WMS 6VrfBKXrwK\\r\\n"
|
||||
"m=audio 9 UDP/TLS/RTP/SAVPF 111\\r\\n"
|
||||
"c=IN IP4 0.0.0.0\\r\\n"
|
||||
"a=candidate:10 1 udp 2115783679 192.168.170.129 9527 typ host generation 0\\r\\n"
|
||||
"a=rtcp:9 IN IP4 0.0.0.0\\r\\n"
|
||||
"a=ice-ufrag:xiaozhihongjohn\\r\\n"
|
||||
"a=ice-pwd:simple_rtmp_server__john\\r\\n"
|
||||
"a=ice-options:trickle\\r\\n"
|
||||
"a=fingerprint:sha-256 76:E8:6A:6D:48:F0:86:58:30:2E:69:56:0F:C6:A1:B8:69:98:5D:73:45:93:37:8E:C4:2B:C7:97:04:18:E4:24\\r\\n"
|
||||
"a=sendrecv\\r\\n"
|
||||
"a=mid:0\\r\\n"
|
||||
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\\r\\n"
|
||||
"a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\\r\\n"
|
||||
"a=rtcp-mux\\r\\n"
|
||||
"a=rtpmap:111 opus/48000/2\\r\\n"
|
||||
"a=fmtp:111 minptime=10;useinbandfec=1\\r\\n"
|
||||
"a=maxptime:60\\r\\n"
|
||||
"a=ssrc:3233846890 cname:o/i14u9pJrxRKAsu\\r\\n"
|
||||
"a=ssrc:3233846890 msid:6VrfBKXrwK a0\\r\\n"
|
||||
"a=ssrc:3233846890 mslabel:6VrfBKXrwK\\r\\n"
|
||||
"a=ssrc:3233846890 label:6VrfBKXrwKa0\\r\\n"
|
||||
"m=video 9 UDP/TLS/RTP/SAVPF 96 98 102\\r\\n"
|
||||
"c=IN IP4 0.0.0.0\\r\\n"
|
||||
"a=candidate:10 1 udp 2115783679 192.168.170.129 9527 typ host generation 0\\r\\n"
|
||||
"a=rtcp:9 IN IP4 0.0.0.0\\r\\n"
|
||||
"b=as:2000000\\r\\n"
|
||||
"a=ice-ufrag:xiaozhihongjohn\\r\\n"
|
||||
"a=ice-pwd:simple_rtmp_server__john\\r\\n"
|
||||
"a=ice-options:trickle\\r\\n"
|
||||
"a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\\r\\n"
|
||||
"a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\\r\\n"
|
||||
"a=extmap:4 urn:3gpp:video-orientation\\r\\n"
|
||||
"a=fingerprint:sha-256 76:E8:6A:6D:48:F0:86:58:30:2E:69:56:0F:C6:A1:B8:69:98:5D:73:45:93:37:8E:C4:2B:C7:97:04:18:E4:24\\r\\n"
|
||||
"a=sendrecv\\r\\n"
|
||||
"a=mid:1\\r\\n"
|
||||
"a=rtcp-mux\\r\\n"
|
||||
"a=rtpmap:96 VP8/90000\\r\\n"
|
||||
"a=rtcp-fb:96 ccm fir\\r\\n"
|
||||
"a=rtcp-fb:96 nack\\r\\n"
|
||||
"a=rtcp-fb:96 nack pli\\r\\n"
|
||||
"a=rtcp-fb:96 goog-remb\\r\\n"
|
||||
"a=rtcp-fb:96 transport-cc\\r\\n"
|
||||
"a=rtpmap:98 VP9/90000\\r\\n"
|
||||
"a=rtcp-fb:98 ccm fir\\r\\n"
|
||||
"a=rtcp-fb:98 nack\\r\\n"
|
||||
"a=rtcp-fb:98 nack pli\\r\\n"
|
||||
"a=rtcp-fb:98 goog-remb\\r\\n"
|
||||
"a=rtcp-fb:98 transport-cc\\r\\n"
|
||||
"a=rtpmap:102 H264/90000\\r\\n"
|
||||
"a=rtcp-fb:102 goog-remb\\r\\n"
|
||||
"a=rtcp-fb:102 transport-cc\\r\\n"
|
||||
"a=rtcp-fb:102 ccm fir \\r\\n"
|
||||
"a=rtcp-fb:102 nack\\r\\n"
|
||||
"a=rtcp-fb:102 nack pli \\r\\n"
|
||||
"a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\\r\\n"
|
||||
"a=ssrc:3233846889 cname:o/i14u9pJrxRKAsu\\r\\n"
|
||||
"a=ssrc:3233846889 msid:6VrfBKXrwK v0\\r\\n"
|
||||
"a=ssrc:3233846889 mslabel:6VrfBKXrwK\\r\\n"
|
||||
"a=ssrc:3233846889 label:6VrfBKXrwKv0\\r\\n";
|
||||
|
||||
srs_error_t srs_api_response_jsonp(ISrsHttpResponseWriter* w, string callback, string data)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
@ -780,6 +847,44 @@ srs_error_t SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
|
|||
return srs_api_response(w, r, obj->dumps());
|
||||
}
|
||||
|
||||
SrsGoApiSdp::SrsGoApiSdp()
|
||||
{
|
||||
}
|
||||
|
||||
SrsGoApiSdp::~SrsGoApiSdp()
|
||||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsGoApiSdp::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
SrsStatistic* stat = SrsStatistic::instance();
|
||||
|
||||
// path: {pattern}{stream_id}
|
||||
// e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100
|
||||
int sid = r->parse_rest_id(entry->pattern);
|
||||
|
||||
SrsStatisticStream* stream = NULL;
|
||||
if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) {
|
||||
return srs_api_response_code(w, r, ERROR_RTMP_STREAM_NOT_FOUND);
|
||||
}
|
||||
|
||||
SrsJsonObject* obj = SrsJsonAny::object();
|
||||
SrsAutoFree(SrsJsonObject, obj);
|
||||
|
||||
obj->set("code", SrsJsonAny::integer(ERROR_SUCCESS));
|
||||
obj->set("server", SrsJsonAny::integer(stat->server_id()));
|
||||
|
||||
if (r->is_http_post()) {
|
||||
obj->set("sdp", SrsJsonAny::str(test_sdp.c_str()));
|
||||
} else {
|
||||
return srs_go_http_error(w, SRS_CONSTS_HTTP_MethodNotAllowed);
|
||||
}
|
||||
|
||||
return srs_api_response(w, r, obj->dumps());
|
||||
}
|
||||
|
||||
SrsGoApiClients::SrsGoApiClients()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -164,6 +164,15 @@ public:
|
|||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
};
|
||||
|
||||
class SrsGoApiSdp : public ISrsHttpHandler
|
||||
{
|
||||
public:
|
||||
SrsGoApiSdp();
|
||||
virtual ~SrsGoApiSdp();
|
||||
public:
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
};
|
||||
|
||||
class SrsGoApiClients : public ISrsHttpHandler
|
||||
{
|
||||
public:
|
||||
|
|
89
trunk/src/app/srs_app_rtc_udp.cpp
Normal file
89
trunk/src/app/srs_app_rtc_udp.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* 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 <srs_app_rtc_udp.hpp>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
using namespace std;
|
||||
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_kernel_log.hpp>
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_kernel_ts.hpp>
|
||||
#include <srs_kernel_buffer.hpp>
|
||||
#include <srs_kernel_ts.hpp>
|
||||
#include <srs_kernel_stream.hpp>
|
||||
#include <srs_kernel_file.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_rtmp_stack.hpp>
|
||||
#include <srs_app_st.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
#include <srs_protocol_amf0.hpp>
|
||||
#include <srs_raw_avc.hpp>
|
||||
#include <srs_app_pithy_print.hpp>
|
||||
#include <srs_app_rtmp_conn.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
|
||||
SrsRtcOverUdp::SrsRtcOverUdp()
|
||||
{
|
||||
}
|
||||
|
||||
SrsRtcOverUdp::~SrsRtcOverUdp()
|
||||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcOverUdp::on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf)
|
||||
{
|
||||
char address_string[64];
|
||||
char port_string[16];
|
||||
if(getnameinfo(from, fromlen,
|
||||
(char*)&address_string, sizeof(address_string),
|
||||
(char*)&port_string, sizeof(port_string),
|
||||
NI_NUMERICHOST|NI_NUMERICSERV)) {
|
||||
return srs_error_new(ERROR_SYSTEM_IP_INVALID, "bad address");
|
||||
}
|
||||
std::string peer_ip = std::string(address_string);
|
||||
int peer_port = atoi(port_string);
|
||||
|
||||
srs_error_t err = on_udp_bytes(peer_ip, peer_port, buf, nb_buf);
|
||||
if (err != srs_success) {
|
||||
return srs_error_wrap(err, "process udp");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
srs_trace("recv rtc udp packet from %s:%d, nb_buf=%d", host.c_str(), port, nb_buf);
|
||||
|
||||
return err;
|
||||
}
|
52
trunk/src/app/srs_app_rtc_udp.hpp
Normal file
52
trunk/src/app/srs_app_rtc_udp.hpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* 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_RTC_UDP_HPP
|
||||
#define SRS_APP_RTC_UDP_HPP
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
struct sockaddr;
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <srs_app_st.hpp>
|
||||
#include <srs_kernel_ts.hpp>
|
||||
#include <srs_app_listener.hpp>
|
||||
|
||||
// The rtc over udp stream receiver
|
||||
class SrsRtcOverUdp : virtual public ISrsUdpHandler
|
||||
{
|
||||
private:
|
||||
public:
|
||||
SrsRtcOverUdp();
|
||||
virtual ~SrsRtcOverUdp();
|
||||
// Interface ISrsUdpHandler
|
||||
public:
|
||||
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
private:
|
||||
virtual srs_error_t on_udp_bytes(std::string host, int port, char* buf, int nb_buf);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -44,6 +44,7 @@ using namespace std;
|
|||
#include <srs_app_utility.hpp>
|
||||
#include <srs_app_heartbeat.hpp>
|
||||
#include <srs_app_mpegts_udp.hpp>
|
||||
#include <srs_app_rtc_udp.hpp>
|
||||
#include <srs_app_rtsp.hpp>
|
||||
#include <srs_app_statistic.hpp>
|
||||
#include <srs_app_caster_flv.hpp>
|
||||
|
@ -108,6 +109,8 @@ std::string srs_listener_type2string(SrsListenerType type)
|
|||
return "RTSP";
|
||||
case SrsListenerFlv:
|
||||
return "HTTP-FLV";
|
||||
case SrsListenerRtcOverUdp:
|
||||
return "RTC over UDP";
|
||||
default:
|
||||
return "UNKONWN";
|
||||
}
|
||||
|
@ -335,6 +338,45 @@ SrsUdpCasterListener::~SrsUdpCasterListener()
|
|||
srs_freep(caster);
|
||||
}
|
||||
|
||||
SrsRtcListener::SrsRtcListener(SrsServer* svr, SrsListenerType t) : SrsListener(svr, t)
|
||||
{
|
||||
srs_assert(type == SrsListenerRtcOverUdp);
|
||||
rtc = new SrsRtcOverUdp();
|
||||
}
|
||||
|
||||
SrsRtcListener::~SrsRtcListener()
|
||||
{
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcListener::listen(std::string i, int p)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// the caller already ensure the type is ok,
|
||||
// we just assert here for unknown stream caster.
|
||||
srs_assert(type == SrsListenerRtcOverUdp);
|
||||
|
||||
ip = i;
|
||||
port = p;
|
||||
|
||||
srs_freep(listener);
|
||||
listener = new SrsUdpListener(rtc, ip, port);
|
||||
|
||||
if ((err = listener->listen()) != srs_success) {
|
||||
return srs_error_wrap(err, "listen %s:%d", ip.c_str(), port);
|
||||
}
|
||||
|
||||
// notify the handler the fd changed.
|
||||
if ((err = rtc->on_stfd_change(listener->stfd())) != srs_success) {
|
||||
return srs_error_wrap(err, "notify fd change failed");
|
||||
}
|
||||
|
||||
string v = srs_listener_type2string(type);
|
||||
srs_trace("%s listen at udp://%s:%d, fd=%d", v.c_str(), ip.c_str(), port, listener->fd());
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsSignalManager* SrsSignalManager::instance = NULL;
|
||||
|
||||
SrsSignalManager::SrsSignalManager(SrsServer* s)
|
||||
|
@ -729,6 +771,10 @@ srs_error_t SrsServer::listen()
|
|||
return srs_error_wrap(err, "stream caster listen");
|
||||
}
|
||||
|
||||
if ((err = listen_rtc()) != srs_success) {
|
||||
return srs_error_wrap(err, "rtc listen");
|
||||
}
|
||||
|
||||
if ((err = conn_manager->start()) != srs_success) {
|
||||
return srs_error_wrap(err, "connection manager");
|
||||
}
|
||||
|
@ -790,6 +836,9 @@ srs_error_t SrsServer::http_handle()
|
|||
if ((err = http_api_mux->handle("/api/v1/streams/", new SrsGoApiStreams())) != srs_success) {
|
||||
return srs_error_wrap(err, "handle streams");
|
||||
}
|
||||
if ((err = http_api_mux->handle("/api/v1/sdp/", new SrsGoApiSdp())) != srs_success) {
|
||||
return srs_error_wrap(err, "handle sdp");
|
||||
}
|
||||
if ((err = http_api_mux->handle("/api/v1/clients/", new SrsGoApiClients())) != srs_success) {
|
||||
return srs_error_wrap(err, "handle clients");
|
||||
}
|
||||
|
@ -1188,6 +1237,35 @@ srs_error_t SrsServer::listen_stream_caster()
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsServer::listen_rtc()
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
close_listeners(SrsListenerRtcOverUdp);
|
||||
|
||||
if (!_srs_config->get_rtc_enabled()) {
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsListener* listener = NULL;
|
||||
|
||||
listener = new SrsRtcListener(this, SrsListenerRtcOverUdp);
|
||||
srs_assert(listener != NULL);
|
||||
|
||||
listeners.push_back(listener);
|
||||
|
||||
int port = _srs_config->get_rtc_listen();
|
||||
if (port <= 0) {
|
||||
return srs_error_new(ERROR_RTC_PORT, "invalid port=%d", port);
|
||||
}
|
||||
|
||||
if ((err = listener->listen(srs_any_address_for_listener(), port)) != srs_success) {
|
||||
return srs_error_wrap(err, "listen at %d", port);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void SrsServer::close_listeners(SrsListenerType type)
|
||||
{
|
||||
std::vector<SrsListener*>::iterator it;
|
||||
|
|
|
@ -68,6 +68,8 @@ enum SrsListenerType
|
|||
SrsListenerRtsp = 4,
|
||||
// TCP stream, FLV stream over HTTP.
|
||||
SrsListenerFlv = 5,
|
||||
// UDP sream, rtp over udp
|
||||
SrsListenerRtcOverUdp = 6,
|
||||
};
|
||||
|
||||
// A common tcp listener, for RTMP/HTTP server.
|
||||
|
@ -155,6 +157,19 @@ public:
|
|||
virtual ~SrsUdpCasterListener();
|
||||
};
|
||||
|
||||
// A UDP listener, for udp stream caster server.
|
||||
class SrsRtcListener : public SrsListener
|
||||
{
|
||||
protected:
|
||||
SrsUdpListener* listener;
|
||||
ISrsUdpHandler* rtc;
|
||||
public:
|
||||
SrsRtcListener(SrsServer* svr, SrsListenerType t);
|
||||
virtual ~SrsRtcListener();
|
||||
public:
|
||||
virtual srs_error_t listen(std::string i, int p);
|
||||
};
|
||||
|
||||
// Convert signal to io,
|
||||
// @see: st-1.9/docs/notes.html
|
||||
class SrsSignalManager : public ISrsCoroutineHandler
|
||||
|
@ -284,6 +299,7 @@ private:
|
|||
virtual srs_error_t listen_http_api();
|
||||
virtual srs_error_t listen_http_stream();
|
||||
virtual srs_error_t listen_stream_caster();
|
||||
virtual srs_error_t listen_rtc();
|
||||
// Close the listeners for specified type,
|
||||
// Remove the listen object from manager.
|
||||
virtual void close_listeners(SrsListenerType type);
|
||||
|
|
|
@ -321,6 +321,7 @@
|
|||
#define ERROR_HTTP_302_INVALID 4038
|
||||
#define ERROR_BASE64_DECODE 4039
|
||||
#define ERROR_HTTP_STREAM_EOF 4040
|
||||
#define ERROR_RTC_PORT 4041
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// HTTP API error.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue