添加 hls ts 切片录制完成通知

This commit is contained in:
wxf 2020-09-13 14:08:05 +08:00
parent a024c51536
commit 188e087fc2
7 changed files with 79 additions and 0 deletions

View File

@ -53,6 +53,7 @@ const string kOnRtspAuth = HOOK_FIELD"on_rtsp_auth";
const string kOnStreamChanged = HOOK_FIELD"on_stream_changed"; const string kOnStreamChanged = HOOK_FIELD"on_stream_changed";
const string kOnStreamNotFound = HOOK_FIELD"on_stream_not_found"; const string kOnStreamNotFound = HOOK_FIELD"on_stream_not_found";
const string kOnRecordMp4 = HOOK_FIELD"on_record_mp4"; const string kOnRecordMp4 = HOOK_FIELD"on_record_mp4";
const string kOnRecordTs = HOOK_FIELD"on_record_ts";
const string kOnShellLogin = HOOK_FIELD"on_shell_login"; const string kOnShellLogin = HOOK_FIELD"on_shell_login";
const string kOnStreamNoneReader = HOOK_FIELD"on_stream_none_reader"; const string kOnStreamNoneReader = HOOK_FIELD"on_stream_none_reader";
const string kOnHttpAccess = HOOK_FIELD"on_http_access"; const string kOnHttpAccess = HOOK_FIELD"on_http_access";
@ -70,6 +71,7 @@ onceToken token([](){
mINI::Instance()[kOnStreamChanged] = "https://127.0.0.1/index/hook/on_stream_changed"; mINI::Instance()[kOnStreamChanged] = "https://127.0.0.1/index/hook/on_stream_changed";
mINI::Instance()[kOnStreamNotFound] = "https://127.0.0.1/index/hook/on_stream_not_found"; mINI::Instance()[kOnStreamNotFound] = "https://127.0.0.1/index/hook/on_stream_not_found";
mINI::Instance()[kOnRecordMp4] = "https://127.0.0.1/index/hook/on_record_mp4"; mINI::Instance()[kOnRecordMp4] = "https://127.0.0.1/index/hook/on_record_mp4";
mINI::Instance()[kOnRecordTs] = "https://127.0.0.1/index/hook/on_record_ts";
mINI::Instance()[kOnShellLogin] = "https://127.0.0.1/index/hook/on_shell_login"; mINI::Instance()[kOnShellLogin] = "https://127.0.0.1/index/hook/on_shell_login";
mINI::Instance()[kOnStreamNoneReader] = "https://127.0.0.1/index/hook/on_stream_none_reader"; mINI::Instance()[kOnStreamNoneReader] = "https://127.0.0.1/index/hook/on_stream_none_reader";
mINI::Instance()[kOnHttpAccess] = "https://127.0.0.1/index/hook/on_http_access"; mINI::Instance()[kOnHttpAccess] = "https://127.0.0.1/index/hook/on_http_access";
@ -190,6 +192,7 @@ void installWebHook(){
GET_CONFIG(string,hook_stream_chaned,Hook::kOnStreamChanged); GET_CONFIG(string,hook_stream_chaned,Hook::kOnStreamChanged);
GET_CONFIG(string,hook_stream_not_found,Hook::kOnStreamNotFound); GET_CONFIG(string,hook_stream_not_found,Hook::kOnStreamNotFound);
GET_CONFIG(string,hook_record_mp4,Hook::kOnRecordMp4); GET_CONFIG(string,hook_record_mp4,Hook::kOnRecordMp4);
GET_CONFIG(string,hook_record_ts,Hook::kOnRecordTs);
GET_CONFIG(string,hook_shell_login,Hook::kOnShellLogin); GET_CONFIG(string,hook_shell_login,Hook::kOnShellLogin);
GET_CONFIG(string,hook_stream_none_reader,Hook::kOnStreamNoneReader); GET_CONFIG(string,hook_stream_none_reader,Hook::kOnStreamNoneReader);
GET_CONFIG(string,hook_http_access,Hook::kOnHttpAccess); GET_CONFIG(string,hook_http_access,Hook::kOnHttpAccess);
@ -361,6 +364,25 @@ void installWebHook(){
}); });
#endif //ENABLE_MP4 #endif //ENABLE_MP4
NoticeCenter::Instance().addListener(nullptr, Broadcast::kBroadcastRecordTs, [](BroadcastRecordTsArgs) {
if (!hook_enable || hook_record_ts.empty()) {
return;
}
ArgsType body;
body["start_time"] = (Json::UInt64)info.ui64StartedTime;
body["time_len"] = (Json::UInt64)info.ui64TimeLen;
body["file_size"] = (Json::UInt64)info.ui64FileSize;
body["file_path"] = info.strFilePath;
body["file_name"] = info.strFileName;
body["folder"] = info.strFolder;
body["url"] = info.strUrl;
body["app"] = info.strAppName;
body["stream"] = info.strStreamId;
body["vhost"] = info.strVhost;
// 执行 hook
do_http_hook(hook_record_ts, body, nullptr);
});
NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastShellLogin,[](BroadcastShellLoginArgs){ NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastShellLogin,[](BroadcastShellLoginArgs){
if(!hook_enable || hook_shell_login.empty() || sender.get_peer_ip() == "127.0.0.1"){ if(!hook_enable || hook_shell_login.empty() || sender.get_peer_ip() == "127.0.0.1"){
invoker(""); invoker("");

View File

@ -40,6 +40,7 @@ bool loadIniConfig(const char *ini_path){
namespace Broadcast { namespace Broadcast {
const string kBroadcastMediaChanged = "kBroadcastMediaChanged"; const string kBroadcastMediaChanged = "kBroadcastMediaChanged";
const string kBroadcastRecordMP4 = "kBroadcastRecordMP4"; const string kBroadcastRecordMP4 = "kBroadcastRecordMP4";
const string kBroadcastRecordTs = "kBroadcastRecoredTs";
const string kBroadcastHttpRequest = "kBroadcastHttpRequest"; const string kBroadcastHttpRequest = "kBroadcastHttpRequest";
const string kBroadcastHttpAccess = "kBroadcastHttpAccess"; const string kBroadcastHttpAccess = "kBroadcastHttpAccess";
const string kBroadcastOnGetRtspRealm = "kBroadcastOnGetRtspRealm"; const string kBroadcastOnGetRtspRealm = "kBroadcastOnGetRtspRealm";

View File

@ -60,6 +60,10 @@ extern const string kBroadcastMediaChanged;
extern const string kBroadcastRecordMP4; extern const string kBroadcastRecordMP4;
#define BroadcastRecordMP4Args const MP4Info &info #define BroadcastRecordMP4Args const MP4Info &info
// 录制 ts 文件后广播
extern const string kBroadcastRecordTs;
#define BroadcastRecordTsArgs const TsInfo &info
//收到http api请求广播 //收到http api请求广播
extern const string kBroadcastHttpRequest; extern const string kBroadcastHttpRequest;
#define BroadcastHttpRequestArgs const Parser &parser,const HttpSession::HttpResponseInvoker &invoker,bool &consumed,SockInfo &sender #define BroadcastHttpRequestArgs const Parser &parser,const HttpSession::HttpResponseInvoker &invoker,bool &consumed,SockInfo &sender

View File

@ -120,6 +120,11 @@ void HlsMaker::flushLastSegment(uint32_t timestamp, bool eof){
delOldSegment(); delOldSegment();
makeIndexFile(eof); makeIndexFile(eof);
_last_file_name.clear(); _last_file_name.clear();
onFlushLastSegment(seg_dur);
}
void HlsMaker::onFlushLastSegment(uint32_t) {
} }
bool HlsMaker::isLive() { bool HlsMaker::isLive() {

View File

@ -22,6 +22,20 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
class TsInfo {
public:
time_t ui64StartedTime; // GMT 标准时间,单位秒
time_t ui64TimeLen; // 录像长度,单位毫秒
off_t ui64FileSize; // 文件大小,单位 BYTE
string strFilePath; // 文件路径
string strFileName; // 文件名称
string strFolder; // 文件夹路径
string strUrl; // 播放路径
string strAppName; // 应用名称
string strStreamId; // 流 ID
string strVhost; // vhost
};
class HlsMaker { class HlsMaker {
public: public:
/** /**
@ -85,6 +99,12 @@ protected:
*/ */
void flushLastSegment(uint32_t timestamp, bool eof = false); void flushLastSegment(uint32_t timestamp, bool eof = false);
/**
* ts ,
* @param duration ts ,
*/
virtual void onFlushLastSegment(uint32_t duration);
private: private:
/** /**
* m3u8文件 * m3u8文件

View File

@ -8,7 +8,10 @@
* may be found in the AUTHORS file in the root of the source tree. * may be found in the AUTHORS file in the root of the source tree.
*/ */
#include <ctime>
#include <sys/stat.h>
#include "HlsMakerImp.h" #include "HlsMakerImp.h"
#include "Thread/WorkThreadPool.h"
#include "Util/util.h" #include "Util/util.h"
#include "Util/uv_errno.h" #include "Util/uv_errno.h"
@ -28,6 +31,8 @@ HlsMakerImp::HlsMakerImp(const string &m3u8_file,
_file_buf.reset(new char[bufSize], [](char *ptr) { _file_buf.reset(new char[bufSize], [](char *ptr) {
delete[] ptr; delete[] ptr;
}); });
_info.strFolder = _path_prefix;
} }
HlsMakerImp::~HlsMakerImp() { HlsMakerImp::~HlsMakerImp() {
@ -59,6 +64,12 @@ string HlsMakerImp::onOpenSegment(int index) {
} }
} }
_file = makeFile(segment_path, true); _file = makeFile(segment_path, true);
_info.ui64StartedTime = ::time(NULL);
_info.strFileName = segment_name;
_info.strFilePath = segment_path;
_info.strUrl = _info.strAppName + "/" + _info.strStreamId + "/" + segment_name;
if (!_file) { if (!_file) {
WarnL << "create file failed," << segment_path << " " << get_uv_errmsg(); WarnL << "create file failed," << segment_path << " " << get_uv_errmsg();
} }
@ -97,6 +108,17 @@ void HlsMakerImp::onWriteHls(const char *data, int len) {
//DebugL << "\r\n" << string(data,len); //DebugL << "\r\n" << string(data,len);
} }
void HlsMakerImp::onFlushLastSegment(uint32_t duration) {
auto info = _info;
info.ui64TimeLen = duration;
WorkThreadPool::Instance().getExecutor()->async([info]() {
struct stat fileData;
stat(info.strFilePath.data(), &fileData);
const_cast<TsInfo&>(info).ui64FileSize = fileData.st_size;
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastRecordTs, info);
});
}
std::shared_ptr<FILE> HlsMakerImp::makeFile(const string &file, bool setbuf) { std::shared_ptr<FILE> HlsMakerImp::makeFile(const string &file, bool setbuf) {
auto file_buf = _file_buf; auto file_buf = _file_buf;
@ -113,6 +135,9 @@ std::shared_ptr<FILE> HlsMakerImp::makeFile(const string &file, bool setbuf) {
void HlsMakerImp::setMediaSource(const string &vhost, const string &app, const string &stream_id) { void HlsMakerImp::setMediaSource(const string &vhost, const string &app, const string &stream_id) {
_media_src = std::make_shared<HlsMediaSource>(vhost, app, stream_id); _media_src = std::make_shared<HlsMediaSource>(vhost, app, stream_id);
_info.strAppName = app;
_info.strStreamId = stream_id;
_info.strVhost = vhost;
} }
HlsMediaSource::Ptr HlsMakerImp::getMediaSource() const { HlsMediaSource::Ptr HlsMakerImp::getMediaSource() const {

View File

@ -54,6 +54,7 @@ protected:
void onDelSegment(int index) override; void onDelSegment(int index) override;
void onWriteSegment(const char *data, int len) override; void onWriteSegment(const char *data, int len) override;
void onWriteHls(const char *data, int len) override; void onWriteHls(const char *data, int len) override;
void onFlushLastSegment(uint32_t duration) override;
private: private:
std::shared_ptr<FILE> makeFile(const string &file,bool setbuf = false); std::shared_ptr<FILE> makeFile(const string &file,bool setbuf = false);
@ -66,6 +67,7 @@ private:
std::shared_ptr<FILE> _file; std::shared_ptr<FILE> _file;
std::shared_ptr<char> _file_buf; std::shared_ptr<char> _file_buf;
HlsMediaSource::Ptr _media_src; HlsMediaSource::Ptr _media_src;
TsInfo _info;
map<int /*index*/,string/*file_path*/> _segment_file_paths; map<int /*index*/,string/*file_path*/> _segment_file_paths;
}; };