Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HLS: support kick-off hls client #3371

Merged
merged 6 commits into from
Jan 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions trunk/doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The changelog for SRS.

## SRS 6.0 Changelog

* v6.0, 2023-01-29, Merge [#3371](https://github.com/ossrs/srs/pull/3371): HLS: support kick-off hls client. v6.0.21 (#3371)
* v6.0, 2023-01-19, Merge [#3366](https://github.com/ossrs/srs/pull/3366): H265: Support HEVC over SRT. v6.0.20 (#465) (#3366)
* v6.0, 2023-01-19, Merge [#3318](https://github.com/ossrs/srs/pull/3318): RTC: fix rtc publisher pli cid. v6.0.19 (#3318)
* v6.0, 2023-01-18, Merge [#3382](https://github.com/ossrs/srs/pull/3382): Rewrite research/api-server code by Go, remove Python. v6.0.18 (#3382)
Expand All @@ -34,6 +35,7 @@ The changelog for SRS.

## SRS 5.0 Changelog

* v5.0, 2023-01-29, Merge [#3371](https://github.com/ossrs/srs/pull/3371): HLS: support kick-off hls client. v5.0.139 (#3371)
* v5.0, 2023-01-19, Merge [#3318](https://github.com/ossrs/srs/pull/3318): RTC: fix rtc publisher pli cid. v5.0.138 (#3318)
* v5.0, 2023-01-18, Merge [#3382](https://github.com/ossrs/srs/pull/3382): Rewrite research/api-server code by Go, remove Python. v5.0.137 (#3382)
* v5.0, 2023-01-18, Merge [#3386](https://github.com/ossrs/srs/pull/3386): SRT: fix crash when srt_to_rtmp off. v5.0.136 (#3386)
Expand Down
63 changes: 49 additions & 14 deletions trunk/src/app/srs_app_http_static.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,26 @@ using namespace std;

#define SRS_CONTEXT_IN_HLS "hls_ctx"

SrsM3u8CtxInfo::SrsM3u8CtxInfo()
SrsHlsVirtualConn::SrsHlsVirtualConn()
{
req = NULL;
interrupt = false;
}

SrsM3u8CtxInfo::~SrsM3u8CtxInfo()
SrsHlsVirtualConn::~SrsHlsVirtualConn()
{
srs_freep(req);
}

void SrsHlsVirtualConn::expire()
{
interrupt = true;

// remove statistic quickly
SrsStatistic* stat = SrsStatistic::instance();
stat->on_disconnect(ctx, srs_success);
}

SrsHlsStream::SrsHlsStream()
{
_srs_hybrid->timer5s()->subscribe(this);
Expand All @@ -60,9 +70,9 @@ SrsHlsStream::~SrsHlsStream()
{
_srs_hybrid->timer5s()->unsubscribe(this);

std::map<std::string, SrsM3u8CtxInfo*>::iterator it;
std::map<std::string, SrsHlsVirtualConn*>::iterator it;
for (it = map_ctx_info_.begin(); it != map_ctx_info_.end(); ++it) {
SrsM3u8CtxInfo* info = it->second;
SrsHlsVirtualConn* info = it->second;
srs_freep(info);
}
map_ctx_info_.clear();
Expand Down Expand Up @@ -94,6 +104,12 @@ srs_error_t SrsHlsStream::serve_m3u8_ctx(ISrsHttpResponseWriter* w, ISrsHttpMess
*served = false;
return srs_success;
}

if (is_interrupt(ctx)) {
srs_warn("Reject: HLS stream is EOF, ctx=%s", ctx.c_str());
return srs_go_http_error(w, SRS_CONSTS_HTTP_NotFound, srs_fmt("HLS stream %s is EOF", ctx.c_str()));
}

err = serve_exists_session(w, r, factory, fullpath);
} else {
// Create a m3u8 in memory, contains the session id(ctx).
Expand Down Expand Up @@ -238,20 +254,31 @@ bool SrsHlsStream::ctx_is_exist(std::string ctx)

void SrsHlsStream::alive(std::string ctx, SrsRequest* req)
{
std::map<std::string, SrsM3u8CtxInfo*>::iterator it = map_ctx_info_.find(ctx);
std::map<std::string, SrsHlsVirtualConn*>::iterator it = map_ctx_info_.find(ctx);

// Create new context.
if (it == map_ctx_info_.end()) {
SrsM3u8CtxInfo *info = new SrsM3u8CtxInfo();
info->req = req->copy();
info->request_time = srs_get_system_time();
map_ctx_info_.insert(make_pair(ctx, info));
SrsHlsVirtualConn* conn = new SrsHlsVirtualConn();
conn->req = req->copy();
conn->ctx = ctx;
conn->request_time = srs_get_system_time();
map_ctx_info_.insert(make_pair(ctx, conn));

// Update the conn of stat client, which is used for receiving the event of kickoff.
SrsStatistic* stat = SrsStatistic::instance();
SrsStatisticClient* client = stat->find_client(ctx);
if (client) {
client->conn = conn;
}

return;
}

// Update alive time of context.
SrsM3u8CtxInfo* info = it->second;
info->request_time = srs_get_system_time();
// Update alive time of context for virtual connection.
SrsHlsVirtualConn* conn = it->second;
if (!conn->interrupt) {
conn->request_time = srs_get_system_time();
}
}

srs_error_t SrsHlsStream::http_hooks_on_play(SrsRequest* req)
Expand Down Expand Up @@ -321,10 +348,10 @@ srs_error_t SrsHlsStream::on_timer(srs_utime_t interval)
{
srs_error_t err = srs_success;

std::map<std::string, SrsM3u8CtxInfo*>::iterator it;
std::map<std::string, SrsHlsVirtualConn*>::iterator it;
for (it = map_ctx_info_.begin(); it != map_ctx_info_.end(); ++it) {
string ctx = it->first;
SrsM3u8CtxInfo* info = it->second;
SrsHlsVirtualConn* info = it->second;

srs_utime_t hls_window = _srs_config->get_hls_window(info->req->vhost);
if (info->request_time + (2 * hls_window) < srs_get_system_time()) {
Expand All @@ -347,6 +374,14 @@ srs_error_t SrsHlsStream::on_timer(srs_utime_t interval)
return err;
}

bool SrsHlsStream::is_interrupt(std::string id) {
std::map<std::string, SrsHlsVirtualConn*>::iterator it = map_ctx_info_.find(id);
if (it != map_ctx_info_.end()) {
return it->second->interrupt;
}
return false;
}

SrsVodStream::SrsVodStream(string root_dir) : SrsHttpFileServer(root_dir)
{
}
Expand Down
17 changes: 13 additions & 4 deletions trunk/src/app/srs_app_http_static.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,28 @@

class ISrsFileReaderFactory;

struct SrsM3u8CtxInfo
// HLS virtual connection, build on query string ctx of hls stream.
class SrsHlsVirtualConn: public ISrsExpire
{
public:
srs_utime_t request_time;
SrsRequest* req;
SrsM3u8CtxInfo();
virtual ~SrsM3u8CtxInfo();
std::string ctx;
bool interrupt;
public:
SrsHlsVirtualConn();
virtual ~SrsHlsVirtualConn();
// Interface ISrsExpire.
public:
virtual void expire();
};

// Server HLS streaming.
class SrsHlsStream : public ISrsFastTimer
{
private:
// The period of validity of the ctx
std::map<std::string, SrsM3u8CtxInfo*> map_ctx_info_;
std::map<std::string, SrsHlsVirtualConn*> map_ctx_info_;
public:
SrsHlsStream();
virtual ~SrsHlsStream();
Expand All @@ -40,6 +48,7 @@ class SrsHlsStream : public ISrsFastTimer
void alive(std::string ctx, SrsRequest* req);
srs_error_t http_hooks_on_play(SrsRequest* req);
void http_hooks_on_stop(SrsRequest* req);
bool is_interrupt(std::string id);
// interface ISrsFastTimer
private:
srs_error_t on_timer(srs_utime_t interval);
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version5.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 138
#define VERSION_REVISION 139

#endif
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

#define VERSION_MAJOR 6
#define VERSION_MINOR 0
#define VERSION_REVISION 20
#define VERSION_REVISION 21

#endif