diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index 1facb9619d..8c03eae477 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -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) @@ -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) diff --git a/trunk/src/app/srs_app_http_static.cpp b/trunk/src/app/srs_app_http_static.cpp index bbcd8f3dc4..89299c5a6b 100644 --- a/trunk/src/app/srs_app_http_static.cpp +++ b/trunk/src/app/srs_app_http_static.cpp @@ -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); @@ -60,9 +70,9 @@ SrsHlsStream::~SrsHlsStream() { _srs_hybrid->timer5s()->unsubscribe(this); - std::map::iterator it; + std::map::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(); @@ -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). @@ -238,20 +254,31 @@ bool SrsHlsStream::ctx_is_exist(std::string ctx) void SrsHlsStream::alive(std::string ctx, SrsRequest* req) { - std::map::iterator it = map_ctx_info_.find(ctx); + std::map::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) @@ -321,10 +348,10 @@ srs_error_t SrsHlsStream::on_timer(srs_utime_t interval) { srs_error_t err = srs_success; - std::map::iterator it; + std::map::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()) { @@ -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::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) { } diff --git a/trunk/src/app/srs_app_http_static.hpp b/trunk/src/app/srs_app_http_static.hpp index 0ceaf3ff3b..7fd83b67b2 100644 --- a/trunk/src/app/srs_app_http_static.hpp +++ b/trunk/src/app/srs_app_http_static.hpp @@ -13,12 +13,20 @@ 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. @@ -26,7 +34,7 @@ class SrsHlsStream : public ISrsFastTimer { private: // The period of validity of the ctx - std::map map_ctx_info_; + std::map map_ctx_info_; public: SrsHlsStream(); virtual ~SrsHlsStream(); @@ -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); diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index 3d48b023a4..ebdce60d49 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 138 +#define VERSION_REVISION 139 #endif diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp index 2aeab1a5f9..d030f06107 100644 --- a/trunk/src/core/srs_core_version6.hpp +++ b/trunk/src/core/srs_core_version6.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 6 #define VERSION_MINOR 0 -#define VERSION_REVISION 20 +#define VERSION_REVISION 21 #endif