From 6348e64cdf52abe94e3573d04d7275fd49361ed6 Mon Sep 17 00:00:00 2001 From: PioLing <964472638@qq.com> Date: Thu, 12 Oct 2023 11:05:41 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A1=AE=E4=BF=9Dhls=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E5=99=A8=E6=8C=81=E7=BB=AD=E6=92=AD=E6=94=BE=20(#2896)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在hls注销后,hls cookie会继续存活60秒,在此期间,如果hls流重新注册,将导致无法继续播放; 通过此修改,在hls注销后每3秒查询一次MediaSource,可以在性能和功能间保持平衡。 --- src/Http/HttpCookieManager.cpp | 5 ++--- src/Http/HttpCookieManager.h | 8 ++++---- src/Http/HttpFileManager.cpp | 25 +++++++++++++++++-------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/Http/HttpCookieManager.cpp b/src/Http/HttpCookieManager.cpp index b846a3b9..e829423d 100644 --- a/src/Http/HttpCookieManager.cpp +++ b/src/Http/HttpCookieManager.cpp @@ -61,7 +61,7 @@ bool HttpServerCookie::isExpired() { return _ticker.elapsedTime() > _max_elapsed * 1000; } -void HttpServerCookie::setAttach(std::shared_ptr attach) { +void HttpServerCookie::setAttach(toolkit::Any attach) { _attach = std::move(attach); } @@ -114,8 +114,7 @@ void HttpCookieManager::onManager() { } } -HttpServerCookie::Ptr HttpCookieManager::addCookie(const string &cookie_name, const string &uid_in, - uint64_t max_elapsed, std::shared_ptr attach, int max_client) { +HttpServerCookie::Ptr HttpCookieManager::addCookie(const string &cookie_name, const string &uid_in, uint64_t max_elapsed, toolkit::Any attach, int max_client) { lock_guard lck(_mtx_cookie); auto cookie = _generator.obtain(); auto uid = uid_in.empty() ? cookie : uid_in; diff --git a/src/Http/HttpCookieManager.h b/src/Http/HttpCookieManager.h index e55c2086..53775b79 100644 --- a/src/Http/HttpCookieManager.h +++ b/src/Http/HttpCookieManager.h @@ -85,14 +85,14 @@ public: /** * 设置附加数据 */ - void setAttach(std::shared_ptr attach); + void setAttach(toolkit::Any attach); /* * 获取附加数据 */ template T& getAttach() { - return *static_cast(_attach.get()); + return _attach.get(); } private: @@ -104,7 +104,7 @@ private: std::string _cookie_uuid; uint64_t _max_elapsed; toolkit::Ticker _ticker; - std::shared_ptr _attach; + toolkit::Any _attach; std::weak_ptr _manager; }; @@ -163,7 +163,7 @@ public: */ HttpServerCookie::Ptr addCookie( const std::string &cookie_name, const std::string &uid, uint64_t max_elapsed = COOKIE_DEFAULT_LIFE, - std::shared_ptr attach = nullptr, + toolkit::Any = toolkit::Any{}, int max_client = 1); /** diff --git a/src/Http/HttpFileManager.cpp b/src/Http/HttpFileManager.cpp index c8996d1c..1eaa9ec1 100644 --- a/src/Http/HttpFileManager.cpp +++ b/src/Http/HttpFileManager.cpp @@ -31,13 +31,16 @@ namespace mediakit { // 每次访问一次该cookie,那么将重新刷新cookie有效期 // 假如播放器在60秒内都未访问该cookie,那么将重新触发hls播放鉴权 static int kHlsCookieSecond = 60; +static int kFindSrcIntervalSecond = 3; static const string kCookieName = "ZL_COOKIE"; static const string kHlsSuffix = "/hls.m3u8"; static const string kHlsFMP4Suffix = "/hls.fmp4.m3u8"; struct HttpCookieAttachment { - //是否已经查找到过MediaSource + // 是否已经查找到过MediaSource bool _find_src = false; + // 查找MediaSource计时 + Ticker _find_src_ticker; //cookie生效作用域,本cookie只对该目录下的文件生效 string _path; //上次鉴权失败信息,为空则上次鉴权成功 @@ -414,7 +417,9 @@ static void canAccessPath(Session &sender, const Parser &parser, const MediaInfo // hls相关信息 attach->_hls_data = std::make_shared(media_info, info); } - callback(err_msg, HttpCookieManager::Instance().addCookie(kCookieName, uid, life_second, attach)); + toolkit::Any any; + any.set(std::move(attach)); + callback(err_msg, HttpCookieManager::Instance().addCookie(kCookieName, uid, life_second, std::move(any))); } else { callback(err_msg, nullptr); } @@ -532,14 +537,15 @@ static void accessFile(Session &sender, const Parser &parser, const MediaInfo &m return; } - auto src = cookie->getAttach()._hls_data->getMediaSource(); + auto &attach = cookie->getAttach(); + auto src = attach._hls_data->getMediaSource(); if (src) { - //直接从内存获取m3u8索引文件(而不是从文件系统) + // 直接从内存获取m3u8索引文件(而不是从文件系统) response_file(cookie, cb, file_path, parser, src->getIndexFile()); return; } - if (cookie->getAttach()._find_src) { - //查找过MediaSource,但是流已经注销了,不用再查找 + if (attach._find_src && attach._find_src_ticker.elapsedTime() < kFindSrcIntervalSecond * 1000) { + // 最近已经查找过MediaSource了,为了防止频繁查找导致占用全局互斥锁的问题,我们尝试直接从磁盘返回hls索引文件 response_file(cookie, cb, file_path, parser); return; } @@ -555,11 +561,14 @@ static void accessFile(Session &sender, const Parser &parser, const MediaInfo &m auto &attach = cookie->getAttach(); attach._hls_data->setMediaSource(hls); - //添加HlsMediaSource的观看人数(HLS是按需生成的,这样可以触发HLS文件的生成) + // 添加HlsMediaSource的观看人数(HLS是按需生成的,这样可以触发HLS文件的生成) attach._hls_data->addByteUsage(0); - //标记找到MediaSource + // 标记找到MediaSource attach._find_src = true; + // 重置查找MediaSource计时 + attach._find_src_ticker.resetTime(); + // m3u8文件可能不存在, 等待m3u8索引文件按需生成 hls->getIndexFile([response_file, file_path, cookie, cb, parser](const string &file) { response_file(cookie, cb, file_path, parser, file);