mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
添加 hls ts 切片录制完成通知
This commit is contained in:
parent
a024c51536
commit
188e087fc2
@ -53,6 +53,7 @@ const string kOnRtspAuth = HOOK_FIELD"on_rtsp_auth";
|
||||
const string kOnStreamChanged = HOOK_FIELD"on_stream_changed";
|
||||
const string kOnStreamNotFound = HOOK_FIELD"on_stream_not_found";
|
||||
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 kOnStreamNoneReader = HOOK_FIELD"on_stream_none_reader";
|
||||
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()[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()[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()[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";
|
||||
@ -190,6 +192,7 @@ void installWebHook(){
|
||||
GET_CONFIG(string,hook_stream_chaned,Hook::kOnStreamChanged);
|
||||
GET_CONFIG(string,hook_stream_not_found,Hook::kOnStreamNotFound);
|
||||
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_stream_none_reader,Hook::kOnStreamNoneReader);
|
||||
GET_CONFIG(string,hook_http_access,Hook::kOnHttpAccess);
|
||||
@ -361,6 +364,25 @@ void installWebHook(){
|
||||
});
|
||||
#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){
|
||||
if(!hook_enable || hook_shell_login.empty() || sender.get_peer_ip() == "127.0.0.1"){
|
||||
invoker("");
|
||||
|
@ -40,6 +40,7 @@ bool loadIniConfig(const char *ini_path){
|
||||
namespace Broadcast {
|
||||
const string kBroadcastMediaChanged = "kBroadcastMediaChanged";
|
||||
const string kBroadcastRecordMP4 = "kBroadcastRecordMP4";
|
||||
const string kBroadcastRecordTs = "kBroadcastRecoredTs";
|
||||
const string kBroadcastHttpRequest = "kBroadcastHttpRequest";
|
||||
const string kBroadcastHttpAccess = "kBroadcastHttpAccess";
|
||||
const string kBroadcastOnGetRtspRealm = "kBroadcastOnGetRtspRealm";
|
||||
|
@ -60,6 +60,10 @@ extern const string kBroadcastMediaChanged;
|
||||
extern const string kBroadcastRecordMP4;
|
||||
#define BroadcastRecordMP4Args const MP4Info &info
|
||||
|
||||
// 录制 ts 文件后广播
|
||||
extern const string kBroadcastRecordTs;
|
||||
#define BroadcastRecordTsArgs const TsInfo &info
|
||||
|
||||
//收到http api请求广播
|
||||
extern const string kBroadcastHttpRequest;
|
||||
#define BroadcastHttpRequestArgs const Parser &parser,const HttpSession::HttpResponseInvoker &invoker,bool &consumed,SockInfo &sender
|
||||
|
@ -120,6 +120,11 @@ void HlsMaker::flushLastSegment(uint32_t timestamp, bool eof){
|
||||
delOldSegment();
|
||||
makeIndexFile(eof);
|
||||
_last_file_name.clear();
|
||||
|
||||
onFlushLastSegment(seg_dur);
|
||||
}
|
||||
|
||||
void HlsMaker::onFlushLastSegment(uint32_t) {
|
||||
}
|
||||
|
||||
bool HlsMaker::isLive() {
|
||||
|
@ -22,6 +22,20 @@ using namespace toolkit;
|
||||
|
||||
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 {
|
||||
public:
|
||||
/**
|
||||
@ -85,6 +99,12 @@ protected:
|
||||
*/
|
||||
void flushLastSegment(uint32_t timestamp, bool eof = false);
|
||||
|
||||
/**
|
||||
* 上一个 ts 切片写入完成, 可在这里进行通知处理
|
||||
* @param duration 上一个 ts 切片的时长, 单位为毫秒
|
||||
*/
|
||||
virtual void onFlushLastSegment(uint32_t duration);
|
||||
|
||||
private:
|
||||
/**
|
||||
* 生成m3u8文件
|
||||
|
@ -8,7 +8,10 @@
|
||||
* may be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include <ctime>
|
||||
#include <sys/stat.h>
|
||||
#include "HlsMakerImp.h"
|
||||
#include "Thread/WorkThreadPool.h"
|
||||
#include "Util/util.h"
|
||||
#include "Util/uv_errno.h"
|
||||
|
||||
@ -28,6 +31,8 @@ HlsMakerImp::HlsMakerImp(const string &m3u8_file,
|
||||
_file_buf.reset(new char[bufSize], [](char *ptr) {
|
||||
delete[] ptr;
|
||||
});
|
||||
|
||||
_info.strFolder = _path_prefix;
|
||||
}
|
||||
|
||||
HlsMakerImp::~HlsMakerImp() {
|
||||
@ -59,6 +64,12 @@ string HlsMakerImp::onOpenSegment(int index) {
|
||||
}
|
||||
}
|
||||
_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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
_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 {
|
||||
|
@ -54,6 +54,7 @@ protected:
|
||||
void onDelSegment(int index) override;
|
||||
void onWriteSegment(const char *data, int len) override;
|
||||
void onWriteHls(const char *data, int len) override;
|
||||
void onFlushLastSegment(uint32_t duration) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<FILE> makeFile(const string &file,bool setbuf = false);
|
||||
@ -66,6 +67,7 @@ private:
|
||||
std::shared_ptr<FILE> _file;
|
||||
std::shared_ptr<char> _file_buf;
|
||||
HlsMediaSource::Ptr _media_src;
|
||||
TsInfo _info;
|
||||
map<int /*index*/,string/*file_path*/> _segment_file_paths;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user