解决hls中断恢复时播放器计数不准确的问题

This commit is contained in:
xiongziliang 2019-12-29 17:55:02 +08:00
parent 7e1e367844
commit 0063571f3a
3 changed files with 43 additions and 26 deletions

View File

@ -258,13 +258,13 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
auto lck = cookie->getLock(); auto lck = cookie->getLock();
auto accessErr = (*cookie)[kAccessErrKey].get<string>(); auto accessErr = (*cookie)[kAccessErrKey].get<string>();
auto cookiePath = (*cookie)[kCookiePathKey].get<string>(); auto cookiePath = (*cookie)[kCookiePathKey].get<string>();
auto is_hls = (*cookie)[kAccessHls].get<bool>(); auto cookie_is_hls = (*cookie)[kAccessHls].get<bool>();
if (path.find(cookiePath) == 0) { if (path.find(cookiePath) == 0) {
//上次cookie是限定本目录 //上次cookie是限定本目录
if (accessErr.empty()) { if (accessErr.empty()) {
//上次鉴权成功 //上次鉴权成功
if(is_hls){ if(cookie_is_hls){
//如果播放的是hls那么刷新hls的cookie //如果播放的是hls那么刷新hls的cookie(获取ts文件也会刷新)
cookie->updateTime(); cookie->updateTime();
cookie_from_header = false; cookie_from_header = false;
} }
@ -284,8 +284,8 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
bool is_hls = mediaInfo._schema == HLS_SCHEMA; bool is_hls = mediaInfo._schema == HLS_SCHEMA;
//该用户从来未获取过cookie这个时候我们广播是否允许该用户访问该http目录 //该用户从来未获取过cookie这个时候我们广播是否允许该用户访问该http目录
HttpSession::HttpAccessPathInvoker accessPathInvoker = [callback, uid, path, is_dir, is_hls, mediaInfo] HttpSession::HttpAccessPathInvoker accessPathInvoker = [callback, uid, path, is_dir, is_hls, mediaInfo]
(const string &errMsg, const string &cookie_path_in, int cookieLifeSecond) { (const string &errMsg, const string &cookie_path_in, int cookieLifeSecond) {
HttpServerCookie::Ptr cookie; HttpServerCookie::Ptr cookie;
if (cookieLifeSecond) { if (cookieLifeSecond) {
//本次鉴权设置了有效期我们把鉴权结果缓存在cookie中 //本次鉴权设置了有效期我们把鉴权结果缓存在cookie中
@ -388,13 +388,13 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
return; return;
} }
auto response_file = [](const HttpServerCookie::Ptr &cookie, const HttpFileManager::invoker &cb, const string &strFile, const Parser &parser) { auto response_file = [file_exist](const HttpServerCookie::Ptr &cookie, const HttpFileManager::invoker &cb, const string &strFile, const Parser &parser) {
StrCaseMap httpHeader; StrCaseMap httpHeader;
if (cookie) { if (cookie) {
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>()); httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
} }
HttpSession::HttpResponseInvoker invoker = [&](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) { HttpSession::HttpResponseInvoker invoker = [&](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
if (cookie) { if (cookie && file_exist) {
cookie->getLock(); cookie->getLock();
auto is_hls = (*cookie)[kAccessHls].get<bool>(); auto is_hls = (*cookie)[kAccessHls].get<bool>();
if (is_hls) { if (is_hls) {

View File

@ -30,22 +30,29 @@ namespace mediakit{
HlsCookieData::HlsCookieData(const MediaInfo &info) { HlsCookieData::HlsCookieData(const MediaInfo &info) {
_info = info; _info = info;
_added = std::make_shared<bool>(false);
addReaderCount(); addReaderCount();
} }
void HlsCookieData::addReaderCount(){ void HlsCookieData::addReaderCount(){
if(!_added){ if(!*_added){
auto src = dynamic_pointer_cast<HlsMediaSource>(MediaSource::find(HLS_SCHEMA,_info._vhost,_info._app,_info._streamid)); auto src = dynamic_pointer_cast<HlsMediaSource>(MediaSource::find(HLS_SCHEMA,_info._vhost,_info._app,_info._streamid));
if(src){ if(src){
src->modifyReaderCount(true); src->modifyReaderCount(true);
_added = true; *_added = true;
_src = src; _src = src;
_ring_reader = src->getRing()->attach(EventPollerPool::Instance().getPoller());
auto added = _added;
_ring_reader->setDetachCB([added](){
//HlsMediaSource已经销毁
*added = false;
});
} }
} }
} }
HlsCookieData::~HlsCookieData() { HlsCookieData::~HlsCookieData() {
if (_added) { if (*_added) {
auto src = _src.lock(); auto src = _src.lock();
if (src) { if (src) {
src->modifyReaderCount(false); src->modifyReaderCount(false);

View File

@ -31,32 +31,25 @@
#include "Common/MediaSource.h" #include "Common/MediaSource.h"
namespace mediakit{ namespace mediakit{
class HlsMediaSource;
class HlsCookieData{
public:
HlsCookieData(const MediaInfo &info);
~HlsCookieData();
void addByteUsage(uint64_t bytes);
private:
void addReaderCount();
private:
uint64_t _bytes = 0;
MediaInfo _info;
bool _added = false;
weak_ptr<HlsMediaSource> _src;
Ticker _ticker;
};
class HlsMediaSource : public MediaSource { class HlsMediaSource : public MediaSource {
public: public:
friend class HlsCookieData; friend class HlsCookieData;
typedef RingBuffer<string> RingType;
typedef std::shared_ptr<HlsMediaSource> Ptr; typedef std::shared_ptr<HlsMediaSource> Ptr;
HlsMediaSource(const string &vhost, const string &app, const string &stream_id) : MediaSource(HLS_SCHEMA, vhost, app, stream_id){ HlsMediaSource(const string &vhost, const string &app, const string &stream_id) : MediaSource(HLS_SCHEMA, vhost, app, stream_id){
_readerCount = 0; _readerCount = 0;
_ring = std::make_shared<RingType>();
} }
virtual ~HlsMediaSource() = default; virtual ~HlsMediaSource() = default;
/**
*
*/
const RingType::Ptr &getRing() const {
return _ring;
}
/** /**
* *
* @return * @return
@ -93,6 +86,23 @@ private:
private: private:
atomic_int _readerCount; atomic_int _readerCount;
bool _registed = false; bool _registed = false;
RingType::Ptr _ring;
};
class HlsCookieData{
public:
HlsCookieData(const MediaInfo &info);
~HlsCookieData();
void addByteUsage(uint64_t bytes);
private:
void addReaderCount();
private:
uint64_t _bytes = 0;
MediaInfo _info;
std::shared_ptr<bool> _added;
weak_ptr<HlsMediaSource> _src;
Ticker _ticker;
HlsMediaSource::RingType::RingReader::Ptr _ring_reader;
}; };