2021-05-31 05:42:20 +00:00
|
|
|
//
|
2023-01-01 00:45:39 +00:00
|
|
|
// Copyright (c) 2013-2023 The SRS Authors
|
2021-05-31 05:42:20 +00:00
|
|
|
//
|
2022-01-13 10:40:17 +00:00
|
|
|
// SPDX-License-Identifier: MIT or MulanPSL-2.0
|
2021-05-31 05:42:20 +00:00
|
|
|
//
|
2017-03-26 05:40:39 +00:00
|
|
|
|
2022-06-09 11:59:51 +00:00
|
|
|
#include <srs_protocol_rtmp_conn.hpp>
|
2017-03-26 05:40:39 +00:00
|
|
|
|
2017-05-30 01:05:02 +00:00
|
|
|
#include <unistd.h>
|
2017-03-26 05:40:39 +00:00
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
#include <srs_protocol_kbps.hpp>
|
2022-06-09 12:11:52 +00:00
|
|
|
#include <srs_protocol_rtmp_stack.hpp>
|
2022-06-09 11:59:51 +00:00
|
|
|
#include <srs_protocol_st.hpp>
|
2017-03-26 05:40:39 +00:00
|
|
|
#include <srs_protocol_amf0.hpp>
|
|
|
|
#include <srs_protocol_utility.hpp>
|
2022-06-09 11:59:51 +00:00
|
|
|
#include <srs_protocol_utility.hpp>
|
2017-03-26 05:40:39 +00:00
|
|
|
|
2020-01-08 06:24:41 +00:00
|
|
|
SrsBasicRtmpClient::SrsBasicRtmpClient(string r, srs_utime_t ctm, srs_utime_t stm)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
2022-08-30 05:41:27 +00:00
|
|
|
kbps = new SrsNetworkKbps();
|
|
|
|
|
2020-01-08 06:24:41 +00:00
|
|
|
url = r;
|
2017-03-26 05:40:39 +00:00
|
|
|
connect_timeout = ctm;
|
|
|
|
stream_timeout = stm;
|
|
|
|
|
|
|
|
req = new SrsRequest();
|
|
|
|
srs_parse_rtmp_url(url, req->tcUrl, req->stream);
|
2018-02-13 00:52:57 +00:00
|
|
|
srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->stream, req->port, req->param);
|
2017-03-26 05:40:39 +00:00
|
|
|
|
|
|
|
transport = NULL;
|
|
|
|
client = NULL;
|
|
|
|
|
|
|
|
stream_id = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SrsBasicRtmpClient::~SrsBasicRtmpClient()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
srs_freep(kbps);
|
2020-06-28 08:58:14 +00:00
|
|
|
srs_freep(req);
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2022-08-24 03:04:39 +00:00
|
|
|
SrsAmf0Object* SrsBasicRtmpClient::extra_args()
|
|
|
|
{
|
|
|
|
if (req->args == NULL) {
|
|
|
|
req->args = SrsAmf0Any::object();
|
|
|
|
}
|
|
|
|
return req->args;
|
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::connect()
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
2017-09-22 11:54:50 +00:00
|
|
|
srs_error_t err = srs_success;
|
2017-03-26 05:40:39 +00:00
|
|
|
|
|
|
|
close();
|
|
|
|
|
2019-04-22 00:03:12 +00:00
|
|
|
transport = new SrsTcpClient(req->host, req->port, srs_utime_t(connect_timeout));
|
2017-03-26 05:40:39 +00:00
|
|
|
client = new SrsRtmpClient(transport);
|
|
|
|
kbps->set_io(transport, transport);
|
2022-08-30 05:41:27 +00:00
|
|
|
|
2017-09-22 11:54:50 +00:00
|
|
|
if ((err = transport->connect()) != srs_success) {
|
2017-03-26 05:40:39 +00:00
|
|
|
close();
|
2018-01-01 03:41:15 +00:00
|
|
|
return srs_error_wrap(err, "connect");
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2019-04-22 00:03:12 +00:00
|
|
|
client->set_recv_timeout(stream_timeout);
|
|
|
|
client->set_send_timeout(stream_timeout);
|
2017-03-26 05:40:39 +00:00
|
|
|
|
|
|
|
// connect to vhost/app
|
2018-01-01 03:41:15 +00:00
|
|
|
if ((err = client->handshake()) != srs_success) {
|
|
|
|
return srs_error_wrap(err, "handshake");
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
2018-01-01 03:41:15 +00:00
|
|
|
if ((err = connect_app()) != srs_success) {
|
|
|
|
return srs_error_wrap(err, "connect app");
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
2018-01-01 03:41:15 +00:00
|
|
|
if ((err = client->create_stream(stream_id)) != srs_success) {
|
|
|
|
return srs_error_wrap(err, "create stream_id=%d", stream_id);
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
return err;
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SrsBasicRtmpClient::close()
|
|
|
|
{
|
|
|
|
kbps->set_io(NULL, NULL);
|
|
|
|
srs_freep(client);
|
|
|
|
srs_freep(transport);
|
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::connect_app()
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
return do_connect_app(srs_get_public_internet_address(), false);
|
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t err = srs_success;
|
2017-03-26 05:40:39 +00:00
|
|
|
|
|
|
|
// notify server the edge identity,
|
2022-08-24 03:04:39 +00:00
|
|
|
SrsAmf0Object* data = extra_args();
|
2017-03-26 05:40:39 +00:00
|
|
|
data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY));
|
|
|
|
data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
|
|
|
|
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));
|
|
|
|
// for edge to directly get the id of client.
|
|
|
|
data->set("srs_pid", SrsAmf0Any::number(getpid()));
|
2020-06-18 03:45:43 +00:00
|
|
|
data->set("srs_id", SrsAmf0Any::str(_srs_context->get_id().c_str()));
|
2017-03-26 05:40:39 +00:00
|
|
|
|
|
|
|
// local ip of edge
|
|
|
|
data->set("srs_server_ip", SrsAmf0Any::str(local_ip.c_str()));
|
|
|
|
|
|
|
|
// generate the tcUrl
|
|
|
|
std::string param = "";
|
|
|
|
std::string target_vhost = req->vhost;
|
2022-08-30 11:35:14 +00:00
|
|
|
std::string tc_url = srs_generate_tc_url("rtmp", req->host, req->vhost, req->app, req->port);
|
2017-03-26 05:40:39 +00:00
|
|
|
|
|
|
|
// replace the tcUrl in request,
|
|
|
|
// which will replace the tc_url in client.connect_app().
|
|
|
|
req->tcUrl = tc_url;
|
|
|
|
|
|
|
|
// upnode server identity will show in the connect_app of client.
|
|
|
|
// the debug_srs_upnode is config in vhost and default to true.
|
2019-11-30 09:31:27 +00:00
|
|
|
SrsServerInfo si;
|
|
|
|
if ((err = client->connect_app(req->app, tc_url, req, debug, &si)) != srs_success) {
|
2018-01-01 03:41:15 +00:00
|
|
|
return srs_error_wrap(err, "connect app tcUrl=%s, debug=%d", tc_url.c_str(), debug);
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
return err;
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2020-12-27 04:55:27 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::publish(int chunk_size, bool with_vhost, std::string* pstream)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t err = srs_success;
|
2017-03-26 05:40:39 +00:00
|
|
|
|
2018-08-01 23:14:06 +00:00
|
|
|
// Pass params in stream, @see https://github.com/ossrs/srs/issues/1031#issuecomment-409745733
|
2020-12-26 14:11:23 +00:00
|
|
|
string stream = srs_generate_stream_with_query(req->host, req->vhost, req->stream, req->param, with_vhost);
|
2020-12-27 04:55:27 +00:00
|
|
|
|
|
|
|
// Return the generated stream.
|
|
|
|
if (pstream) {
|
|
|
|
*pstream = stream;
|
|
|
|
}
|
2018-08-01 23:14:06 +00:00
|
|
|
|
2017-03-26 05:40:39 +00:00
|
|
|
// publish.
|
2018-08-02 01:17:49 +00:00
|
|
|
if ((err = client->publish(stream, stream_id, chunk_size)) != srs_success) {
|
2018-08-01 23:14:06 +00:00
|
|
|
return srs_error_wrap(err, "publish failed, stream=%s, stream_id=%d", stream.c_str(), stream_id);
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
return err;
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2020-12-27 04:55:27 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::play(int chunk_size, bool with_vhost, std::string* pstream)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t err = srs_success;
|
2017-03-26 05:40:39 +00:00
|
|
|
|
2018-08-01 23:14:06 +00:00
|
|
|
// Pass params in stream, @see https://github.com/ossrs/srs/issues/1031#issuecomment-409745733
|
2020-12-26 14:11:23 +00:00
|
|
|
string stream = srs_generate_stream_with_query(req->host, req->vhost, req->stream, req->param, with_vhost);
|
2020-12-27 04:55:27 +00:00
|
|
|
|
|
|
|
// Return the generated stream.
|
|
|
|
if (pstream) {
|
|
|
|
*pstream = stream;
|
|
|
|
}
|
2018-08-01 23:14:06 +00:00
|
|
|
|
2018-08-02 01:17:49 +00:00
|
|
|
if ((err = client->play(stream, stream_id, chunk_size)) != srs_success) {
|
2018-08-01 23:14:06 +00:00
|
|
|
return srs_error_wrap(err, "connect with server failed, stream=%s, stream_id=%d", stream.c_str(), stream_id);
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
return err;
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2022-08-30 05:41:27 +00:00
|
|
|
void SrsBasicRtmpClient::kbps_sample(const char* label, srs_utime_t age)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
kbps->sample();
|
2022-08-30 05:41:27 +00:00
|
|
|
|
2017-03-26 05:40:39 +00:00
|
|
|
int sr = kbps->get_send_kbps();
|
|
|
|
int sr30s = kbps->get_send_kbps_30s();
|
|
|
|
int sr5m = kbps->get_send_kbps_5m();
|
|
|
|
int rr = kbps->get_recv_kbps();
|
|
|
|
int rr30s = kbps->get_recv_kbps_30s();
|
|
|
|
int rr5m = kbps->get_recv_kbps_5m();
|
2022-08-30 05:41:27 +00:00
|
|
|
|
|
|
|
srs_trace("<- %s time=%" PRId64 ", okbps=%d,%d,%d, ikbps=%d,%d,%d", label, srsu2ms(age), sr, sr30s, sr5m, rr, rr30s, rr5m);
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
2022-08-30 05:41:27 +00:00
|
|
|
void SrsBasicRtmpClient::kbps_sample(const char* label, srs_utime_t age, int msgs)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
kbps->sample();
|
2022-08-30 05:41:27 +00:00
|
|
|
|
2017-03-26 05:40:39 +00:00
|
|
|
int sr = kbps->get_send_kbps();
|
|
|
|
int sr30s = kbps->get_send_kbps_30s();
|
|
|
|
int sr5m = kbps->get_send_kbps_5m();
|
|
|
|
int rr = kbps->get_recv_kbps();
|
|
|
|
int rr30s = kbps->get_recv_kbps_30s();
|
|
|
|
int rr5m = kbps->get_recv_kbps_5m();
|
2022-08-30 05:41:27 +00:00
|
|
|
|
|
|
|
srs_trace("<- %s time=%" PRId64 ", msgs=%d, okbps=%d,%d,%d, ikbps=%d,%d,%d", label, srsu2ms(age), msgs, sr, sr30s, sr5m, rr, rr30s, rr5m);
|
2017-03-26 05:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int SrsBasicRtmpClient::sid()
|
|
|
|
{
|
|
|
|
return stream_id;
|
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::recv_message(SrsCommonMessage** pmsg)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
return client->recv_message(pmsg);
|
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::decode_message(SrsCommonMessage* msg, SrsPacket** ppacket)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
return client->decode_message(msg, ppacket);
|
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
return client->send_and_free_messages(msgs, nb_msgs, stream_id);
|
|
|
|
}
|
|
|
|
|
2018-01-01 03:41:15 +00:00
|
|
|
srs_error_t SrsBasicRtmpClient::send_and_free_message(SrsSharedPtrMessage* msg)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
return client->send_and_free_message(msg, stream_id);
|
|
|
|
}
|
|
|
|
|
2019-04-17 00:31:53 +00:00
|
|
|
void SrsBasicRtmpClient::set_recv_timeout(srs_utime_t timeout)
|
2017-03-26 05:40:39 +00:00
|
|
|
{
|
|
|
|
transport->set_recv_timeout(timeout);
|
|
|
|
}
|
|
|
|
|