Commit b3fcb4c0 by xiongziliang

重写mp4录制驱动机制

parent d5a81d71
...@@ -80,6 +80,19 @@ vector<Track::Ptr> MediaSource::getTracks(bool trackReady) const { ...@@ -80,6 +80,19 @@ vector<Track::Ptr> MediaSource::getTracks(bool trackReady) const {
void MediaSource::setTrackSource(const std::weak_ptr<TrackSource> &track_src) { void MediaSource::setTrackSource(const std::weak_ptr<TrackSource> &track_src) {
_track_source = track_src; _track_source = track_src;
weak_ptr<MediaSource> weakPtr = shared_from_this();
EventPollerPool::Instance().getPoller()->async([weakPtr,this](){
auto strongPtr = weakPtr.lock();
if (!strongPtr) {
return;
}
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaResetTracks,
_strSchema,
_strVhost,
_strApp,
_strId,
*this);
},false);
} }
void MediaSource::setListener(const std::weak_ptr<MediaSourceEvent> &listener){ void MediaSource::setListener(const std::weak_ptr<MediaSourceEvent> &listener){
...@@ -293,6 +306,12 @@ void MediaSource::regist() { ...@@ -293,6 +306,12 @@ void MediaSource::regist() {
g_mapMediaSrc[_strSchema][_strVhost][_strApp][_strId] = shared_from_this(); g_mapMediaSrc[_strSchema][_strVhost][_strApp][_strId] = shared_from_this();
} }
InfoL << _strSchema << " " << _strVhost << " " << _strApp << " " << _strId; InfoL << _strSchema << " " << _strVhost << " " << _strApp << " " << _strId;
weak_ptr<MediaSource> weakPtr = shared_from_this();
EventPollerPool::Instance().getPoller()->async([weakPtr,this](){
auto strongPtr = weakPtr.lock();
if (!strongPtr) {
return;
}
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaChanged, NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaChanged,
true, true,
_strSchema, _strSchema,
...@@ -300,6 +319,7 @@ void MediaSource::regist() { ...@@ -300,6 +319,7 @@ void MediaSource::regist() {
_strApp, _strApp,
_strId, _strId,
*this); *this);
},false);
} }
bool MediaSource::unregist() { bool MediaSource::unregist() {
//反注册该源 //反注册该源
...@@ -328,6 +348,21 @@ void MediaSource::unregisted(){ ...@@ -328,6 +348,21 @@ void MediaSource::unregisted(){
_strApp, _strApp,
_strId, _strId,
*this); *this);
weak_ptr<MediaSource> weakPtr = shared_from_this();
EventPollerPool::Instance().getPoller()->async([weakPtr,this](){
auto strongPtr = weakPtr.lock();
if (!strongPtr) {
return;
}
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaChanged,
true,
_strSchema,
_strVhost,
_strApp,
_strId,
*this);
},false);
} }
......
...@@ -49,14 +49,32 @@ public: ...@@ -49,14 +49,32 @@ public:
if (bEanbleRtsp) { if (bEanbleRtsp) {
_rtsp = std::make_shared<RtspMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleSdp>(dur_sec)); _rtsp = std::make_shared<RtspMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleSdp>(dur_sec));
} }
_recordFunc = [bEanbleHls,bEnableMp4,vhost, strApp, strId](bool start){
if(bEanbleHls){ if(bEanbleHls){
_hls.reset(Recorder::createHlsRecorder(vhost, strApp, strId)); if(start){
Recorder::startRecord(Recorder::type_hls,vhost, strApp, strId, true, false);
}else{
Recorder::stopRecord(Recorder::type_hls,vhost, strApp, strId);
}
} }
if(bEnableMp4){ if(bEnableMp4){
_mp4.reset(Recorder::createMP4Recorder(vhost, strApp, strId)); if(start){
Recorder::startRecord(Recorder::type_mp4,vhost, strApp, strId, true, false);
}else{
Recorder::stopRecord(Recorder::type_mp4,vhost, strApp, strId);
}
}
};
_recordFunc(true);
}
virtual ~MultiMediaSourceMuxer(){
if(_recordFunc){
_recordFunc(false);
} }
} }
virtual ~MultiMediaSourceMuxer(){}
/** /**
* 重置音视频媒体 * 重置音视频媒体
...@@ -68,12 +86,6 @@ public: ...@@ -68,12 +86,6 @@ public:
if(_rtsp){ if(_rtsp){
_rtsp->resetTracks(); _rtsp->resetTracks();
} }
if(_hls){
_hls->resetTracks();
}
if(_mp4){
_mp4->resetTracks();
}
} }
/** /**
...@@ -115,12 +127,6 @@ protected: ...@@ -115,12 +127,6 @@ protected:
if(_rtsp){ if(_rtsp){
_rtsp->addTrack(track); _rtsp->addTrack(track);
} }
if(_hls){
_hls->addTrack(track);
}
if(_mp4){
_mp4->addTrack(track);
}
} }
/** /**
...@@ -134,12 +140,6 @@ protected: ...@@ -134,12 +140,6 @@ protected:
if(_rtsp) { if(_rtsp) {
_rtsp->inputFrame(frame); _rtsp->inputFrame(frame);
} }
if(_hls){
_hls->inputFrame(frame);
}
if(_mp4){
_mp4->inputFrame(frame);
}
} }
/** /**
...@@ -158,8 +158,7 @@ protected: ...@@ -158,8 +158,7 @@ protected:
private: private:
RtmpMediaSourceMuxer::Ptr _rtmp; RtmpMediaSourceMuxer::Ptr _rtmp;
RtspMediaSourceMuxer::Ptr _rtsp; RtspMediaSourceMuxer::Ptr _rtsp;
MediaSinkInterface::Ptr _hls; function<void(bool)> _recordFunc;
MediaSinkInterface::Ptr _mp4;
}; };
......
...@@ -55,6 +55,7 @@ bool loadIniConfig(const char *ini_path){ ...@@ -55,6 +55,7 @@ bool loadIniConfig(const char *ini_path){
////////////广播名称/////////// ////////////广播名称///////////
namespace Broadcast { namespace Broadcast {
const string kBroadcastMediaChanged = "kBroadcastMediaChanged"; const string kBroadcastMediaChanged = "kBroadcastMediaChanged";
const string kBroadcastMediaResetTracks = "kBroadcastMediaResetTracks";
const string kBroadcastRecordMP4 = "kBroadcastRecordMP4"; const string kBroadcastRecordMP4 = "kBroadcastRecordMP4";
const string kBroadcastHttpRequest = "kBroadcastHttpRequest"; const string kBroadcastHttpRequest = "kBroadcastHttpRequest";
const string kBroadcastHttpAccess = "kBroadcastHttpAccess"; const string kBroadcastHttpAccess = "kBroadcastHttpAccess";
......
...@@ -71,9 +71,13 @@ namespace Broadcast { ...@@ -71,9 +71,13 @@ namespace Broadcast {
extern const string kBroadcastMediaChanged; extern const string kBroadcastMediaChanged;
#define BroadcastMediaChangedArgs const bool &bRegist, const string &schema,const string &vhost,const string &app,const string &stream,MediaSource &sender #define BroadcastMediaChangedArgs const bool &bRegist, const string &schema,const string &vhost,const string &app,const string &stream,MediaSource &sender
//MediaSource重置Track事件
extern const string kBroadcastMediaResetTracks;
#define BroadcastMediaResetTracksArgs const string &schema,const string &vhost,const string &app,const string &stream,MediaSource &sender
//录制mp4文件成功后广播 //录制mp4文件成功后广播
extern const string kBroadcastRecordMP4; extern const string kBroadcastRecordMP4;
#define BroadcastRecordMP4Args const Mp4Info &info #define BroadcastRecordMP4Args const MP4Info &info
//收到http api请求广播 //收到http api请求广播
extern const string kBroadcastHttpRequest; extern const string kBroadcastHttpRequest;
......
...@@ -107,7 +107,7 @@ void MP4Recorder::asyncClose() { ...@@ -107,7 +107,7 @@ void MP4Recorder::asyncClose() {
auto info = _info; auto info = _info;
WorkThreadPool::Instance().getExecutor()->async([muxer,strFileTmp,strFile,info]() { WorkThreadPool::Instance().getExecutor()->async([muxer,strFileTmp,strFile,info]() {
//获取文件录制时间,放在关闭mp4之前是为了忽略关闭mp4执行时间 //获取文件录制时间,放在关闭mp4之前是为了忽略关闭mp4执行时间
const_cast<Mp4Info&>(info).ui64TimeLen = ::time(NULL) - info.ui64StartedTime; const_cast<MP4Info&>(info).ui64TimeLen = ::time(NULL) - info.ui64StartedTime;
//关闭mp4非常耗时,所以要放在后台线程执行 //关闭mp4非常耗时,所以要放在后台线程执行
const_cast<MP4MuxerFile::Ptr &>(muxer).reset(); const_cast<MP4MuxerFile::Ptr &>(muxer).reset();
//临时文件名改成正式文件名,防止mp4未完成时被访问 //临时文件名改成正式文件名,防止mp4未完成时被访问
...@@ -115,7 +115,7 @@ void MP4Recorder::asyncClose() { ...@@ -115,7 +115,7 @@ void MP4Recorder::asyncClose() {
//获取文件大小 //获取文件大小
struct stat fileData; struct stat fileData;
stat(strFile.data(), &fileData); stat(strFile.data(), &fileData);
const_cast<Mp4Info&>(info).ui64FileSize = fileData.st_size; const_cast<MP4Info&>(info).ui64FileSize = fileData.st_size;
/////record 业务逻辑////// /////record 业务逻辑//////
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastRecordMP4,info); NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastRecordMP4,info);
}); });
......
...@@ -42,7 +42,7 @@ using namespace toolkit; ...@@ -42,7 +42,7 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
class Mp4Info { class MP4Info {
public: public:
time_t ui64StartedTime; //GMT标准时间,单位秒 time_t ui64StartedTime; //GMT标准时间,单位秒
time_t ui64TimeLen;//录像长度,单位秒 time_t ui64TimeLen;//录像长度,单位秒
...@@ -55,11 +55,13 @@ public: ...@@ -55,11 +55,13 @@ public:
string strStreamId;//流ID string strStreamId;//流ID
string strVhost;//vhost string strVhost;//vhost
}; };
class MP4Recorder : public MediaSinkInterface{ class MP4Recorder : public MediaSinkInterface{
public: public:
typedef std::shared_ptr<MP4Recorder> Ptr; typedef std::shared_ptr<MP4Recorder> Ptr;
MP4Recorder(const string &strPath, MP4Recorder(const string &strPath,
const string &strVhost , const string &strVhost,
const string &strApp, const string &strApp,
const string &strStreamId); const string &strStreamId);
virtual ~MP4Recorder(); virtual ~MP4Recorder();
...@@ -87,7 +89,7 @@ private: ...@@ -87,7 +89,7 @@ private:
string _strFile; string _strFile;
string _strFileTmp; string _strFileTmp;
Ticker _createFileTicker; Ticker _createFileTicker;
Mp4Info _info; MP4Info _info;
bool _haveVideo = false; bool _haveVideo = false;
MP4MuxerFile::Ptr _muxer; MP4MuxerFile::Ptr _muxer;
list<Track::Ptr> _tracks; list<Track::Ptr> _tracks;
......
...@@ -37,8 +37,25 @@ class MediaSinkInterface; ...@@ -37,8 +37,25 @@ class MediaSinkInterface;
class Recorder{ class Recorder{
public: public:
static MediaSinkInterface *createHlsRecorder(const string &strVhost, const string &strApp, const string &strId); typedef enum {
static MediaSinkInterface *createMP4Recorder(const string &strVhost, const string &strApp, const string &strId); // 未录制
status_not_record = 0,
// 等待MediaSource注册,注册成功后立即开始录制
status_wait_record = 1,
// MediaSource已注册,并且正在录制
status_recording = 2,
} status;
typedef enum {
// 录制hls
type_hls = 0,
// 录制MP4
type_mp4 = 1
} type;
static status getRecordStatus(type type, const string &vhost, const string &app, const string &stream_id);
static int startRecord(type type, const string &vhost, const string &app, const string &stream_id,bool waitForRecord, bool continueRecord);
static void stopRecord(type type, const string &vhost, const string &app, const string &stream_id);
private: private:
Recorder() = delete; Recorder() = delete;
~Recorder() = delete; ~Recorder() = delete;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论