Commit b3fcb4c0 by xiongziliang

重写mp4录制驱动机制

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