Commit de33d6a8 by xiongziliang

整理文件录制

parent 2c2e7262
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "Rtsp/RtspSession.h" #include "Rtsp/RtspSession.h"
#include "Http/HttpSession.h" #include "Http/HttpSession.h"
#include "WebHook.h" #include "WebHook.h"
#include "Record/MP4Recorder.h"
using namespace Json; using namespace Json;
using namespace toolkit; using namespace toolkit;
......
...@@ -40,6 +40,8 @@ namespace mediakit{ ...@@ -40,6 +40,8 @@ namespace mediakit{
class MediaSinkInterface : public FrameWriterInterface { class MediaSinkInterface : public FrameWriterInterface {
public: public:
typedef std::shared_ptr<MediaSinkInterface> Ptr;
MediaSinkInterface(){}; MediaSinkInterface(){};
virtual ~MediaSinkInterface(){}; virtual ~MediaSinkInterface(){};
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include "MediaSource.h" #include "MediaSource.h"
#include "MediaFile/MediaReader.h" #include "Record/MP4Reader.h"
#include "Util/util.h" #include "Util/util.h"
#include "Network/sockutil.h" #include "Network/sockutil.h"
#include "Network/TcpSession.h" #include "Network/TcpSession.h"
...@@ -278,7 +278,7 @@ MediaSource::Ptr MediaSource::find( ...@@ -278,7 +278,7 @@ MediaSource::Ptr MediaSource::find(
}); });
if(!ret && bMake){ if(!ret && bMake){
//未查找媒体源,则创建一个 //未查找媒体源,则创建一个
ret = MediaReader::onMakeMediaSource(schema, vhost,app,id); ret = MP4Reader::onMakeMediaSource(schema, vhost,app,id);
} }
return ret; return ret;
} }
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "Rtsp/RtspMediaSourceMuxer.h" #include "Rtsp/RtspMediaSourceMuxer.h"
#include "Rtmp/RtmpMediaSourceMuxer.h" #include "Rtmp/RtmpMediaSourceMuxer.h"
#include "MediaFile/MediaRecorder.h" #include "Record/Recorder.h"
class MultiMediaSourceMuxer : public MediaSink , public std::enable_shared_from_this<MultiMediaSourceMuxer>{ class MultiMediaSourceMuxer : public MediaSink , public std::enable_shared_from_this<MultiMediaSourceMuxer>{
public: public:
...@@ -42,15 +42,19 @@ public: ...@@ -42,15 +42,19 @@ public:
bool bEanbleRtsp = true, bool bEanbleRtsp = true,
bool bEanbleRtmp = true, bool bEanbleRtmp = true,
bool bEanbleHls = true, bool bEanbleHls = true,
bool bEnableMp4 = false bool bEnableMp4 = false){
){
if (bEanbleRtmp) { if (bEanbleRtmp) {
_rtmp = std::make_shared<RtmpMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleMeta>(dur_sec)); _rtmp = std::make_shared<RtmpMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleMeta>(dur_sec));
} }
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));
} }
_record = std::make_shared<MediaRecorder>(vhost,strApp,strId,bEanbleHls,bEnableMp4); if(bEanbleHls){
_hls.reset(Recorder::createHlsRecorder(vhost, strApp, strId));
}
if(bEnableMp4){
_mp4.reset(Recorder::createMP4Recorder(vhost, strApp, strId));
}
} }
virtual ~MultiMediaSourceMuxer(){} virtual ~MultiMediaSourceMuxer(){}
...@@ -64,7 +68,12 @@ public: ...@@ -64,7 +68,12 @@ public:
if(_rtsp){ if(_rtsp){
_rtsp->resetTracks(); _rtsp->resetTracks();
} }
_record->resetTracks(); if(_hls){
_hls->resetTracks();
}
if(_mp4){
_mp4->resetTracks();
}
} }
/** /**
...@@ -106,7 +115,12 @@ protected: ...@@ -106,7 +115,12 @@ protected:
if(_rtsp){ if(_rtsp){
_rtsp->addTrack(track); _rtsp->addTrack(track);
} }
_record->addTrack(track); if(_hls){
_hls->addTrack(track);
}
if(_mp4){
_mp4->addTrack(track);
}
} }
/** /**
...@@ -120,7 +134,12 @@ protected: ...@@ -120,7 +134,12 @@ protected:
if(_rtsp) { if(_rtsp) {
_rtsp->inputFrame(frame); _rtsp->inputFrame(frame);
} }
_record->inputFrame(frame); if(_hls){
_hls->inputFrame(frame);
}
if(_mp4){
_mp4->inputFrame(frame);
}
} }
/** /**
...@@ -139,7 +158,8 @@ protected: ...@@ -139,7 +158,8 @@ protected:
private: private:
RtmpMediaSourceMuxer::Ptr _rtmp; RtmpMediaSourceMuxer::Ptr _rtmp;
RtspMediaSourceMuxer::Ptr _rtsp; RtspMediaSourceMuxer::Ptr _rtsp;
MediaRecorder::Ptr _record; MediaSinkInterface::Ptr _hls;
MediaSinkInterface::Ptr _mp4;
}; };
......
...@@ -32,15 +32,23 @@ ...@@ -32,15 +32,23 @@
namespace mediakit { namespace mediakit {
class HlsRecorder : public HlsMakerImp, public TsMuxer { class HlsRecorder : public TsMuxer {
public: public:
template<typename ...ArgsType> HlsRecorder(const string &m3u8_file, const string &params){
HlsRecorder(ArgsType &&...args):HlsMakerImp(std::forward<ArgsType>(args)...){} GET_CONFIG(uint32_t,hlsNum,Hls::kSegmentNum);
~HlsRecorder(){}; GET_CONFIG(uint32_t,hlsBufSize,Hls::kFileBufSize);
GET_CONFIG(uint32_t,hlsDuration,Hls::kSegmentDuration);
_hls = new HlsMakerImp(m3u8_file,params,hlsBufSize,hlsDuration,hlsNum);
}
~HlsRecorder(){
delete _hls;
}
protected: protected:
void onTs(const void *packet, int bytes,uint32_t timestamp,int flags) override { void onTs(const void *packet, int bytes,uint32_t timestamp,int flags) override {
inputData((char *)packet,bytes,timestamp); _hls->inputData((char *)packet,bytes,timestamp);
}; };
private:
HlsMakerImp *_hls;
}; };
}//namespace mediakit }//namespace mediakit
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include "Extension/AAC.h" #include "Extension/AAC.h"
#include "Extension/H264.h" #include "Extension/H264.h"
#include "Extension/H265.h" #include "Extension/H265.h"
#include "Stamp.h" #include "Common/Stamp.h"
namespace mediakit{ namespace mediakit{
......
...@@ -24,9 +24,10 @@ ...@@ -24,9 +24,10 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include "MediaReader.h" #include "MP4Reader.h"
#include "Common/config.h" #include "Common/config.h"
#include "Util/mini.h" #include "Util/mini.h"
#include "Util/File.h"
#include "Http/HttpSession.h" #include "Http/HttpSession.h"
#include "Extension/AAC.h" #include "Extension/AAC.h"
#include "Extension/H264.h" #include "Extension/H264.h"
...@@ -37,7 +38,7 @@ using namespace toolkit; ...@@ -37,7 +38,7 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
#ifdef ENABLE_MP4V2 #ifdef ENABLE_MP4V2
MediaReader::MediaReader(const string &strVhost,const string &strApp, const string &strId,const string &filePath ) { MP4Reader::MP4Reader(const string &strVhost,const string &strApp, const string &strId,const string &filePath ) {
_poller = WorkThreadPool::Instance().getPoller(); _poller = WorkThreadPool::Instance().getPoller();
auto strFileName = filePath; auto strFileName = filePath;
if(strFileName.empty()){ if(strFileName.empty()){
...@@ -153,7 +154,7 @@ MediaReader::MediaReader(const string &strVhost,const string &strApp, const stri ...@@ -153,7 +154,7 @@ MediaReader::MediaReader(const string &strVhost,const string &strApp, const stri
} }
MediaReader::~MediaReader() { MP4Reader::~MP4Reader() {
if (_hMP4File != MP4_INVALID_FILE_HANDLE) { if (_hMP4File != MP4_INVALID_FILE_HANDLE) {
MP4Close(_hMP4File); MP4Close(_hMP4File);
_hMP4File = MP4_INVALID_FILE_HANDLE; _hMP4File = MP4_INVALID_FILE_HANDLE;
...@@ -161,7 +162,7 @@ MediaReader::~MediaReader() { ...@@ -161,7 +162,7 @@ MediaReader::~MediaReader() {
} }
void MediaReader::startReadMP4() { void MP4Reader::startReadMP4() {
auto strongSelf = shared_from_this(); auto strongSelf = shared_from_this();
GET_CONFIG(uint32_t,sampleMS,Record::kSampleMS); GET_CONFIG(uint32_t,sampleMS,Record::kSampleMS);
...@@ -173,11 +174,11 @@ void MediaReader::startReadMP4() { ...@@ -173,11 +174,11 @@ void MediaReader::startReadMP4() {
readSample(sampleMS, false); readSample(sampleMS, false);
_mediaMuxer->setListener(strongSelf); _mediaMuxer->setListener(strongSelf);
} }
bool MediaReader::seekTo(MediaSource &sender,uint32_t ui32Stamp){ bool MP4Reader::seekTo(MediaSource &sender,uint32_t ui32Stamp){
seek(ui32Stamp); seek(ui32Stamp);
return true; return true;
} }
bool MediaReader::close(MediaSource &sender,bool force){ bool MP4Reader::close(MediaSource &sender,bool force){
if(!_mediaMuxer || (!force && _mediaMuxer->readerCount() != 0)){ if(!_mediaMuxer || (!force && _mediaMuxer->readerCount() != 0)){
return false; return false;
} }
...@@ -186,14 +187,14 @@ bool MediaReader::close(MediaSource &sender,bool force){ ...@@ -186,14 +187,14 @@ bool MediaReader::close(MediaSource &sender,bool force){
return true; return true;
} }
void MediaReader::onNoneReader(MediaSource &sender) { void MP4Reader::onNoneReader(MediaSource &sender) {
if(!_mediaMuxer || _mediaMuxer->readerCount() != 0){ if(!_mediaMuxer || _mediaMuxer->readerCount() != 0){
return; return;
} }
MediaSourceEvent::onNoneReader(sender); MediaSourceEvent::onNoneReader(sender);
} }
bool MediaReader::readSample(int iTimeInc,bool justSeekSyncFrame) { bool MP4Reader::readSample(int iTimeInc,bool justSeekSyncFrame) {
TimeTicker(); TimeTicker();
lock_guard<recursive_mutex> lck(_mtx); lock_guard<recursive_mutex> lck(_mtx);
auto bFlag0 = readVideoSample(iTimeInc,justSeekSyncFrame);//数据没读完 auto bFlag0 = readVideoSample(iTimeInc,justSeekSyncFrame);//数据没读完
...@@ -211,7 +212,7 @@ bool MediaReader::readSample(int iTimeInc,bool justSeekSyncFrame) { ...@@ -211,7 +212,7 @@ bool MediaReader::readSample(int iTimeInc,bool justSeekSyncFrame) {
//3秒延时关闭 //3秒延时关闭
return _alive.elapsedTime() < 3 * 1000; return _alive.elapsedTime() < 3 * 1000;
} }
inline bool MediaReader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) { inline bool MP4Reader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
if (_video_trId != MP4_INVALID_TRACK_ID) { if (_video_trId != MP4_INVALID_TRACK_ID) {
auto iNextSample = getVideoSampleId(iTimeInc); auto iNextSample = getVideoSampleId(iTimeInc);
MP4SampleId iIdx = _video_current; MP4SampleId iIdx = _video_current;
...@@ -245,7 +246,7 @@ inline bool MediaReader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) { ...@@ -245,7 +246,7 @@ inline bool MediaReader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) {
return false; return false;
} }
inline bool MediaReader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) { inline bool MP4Reader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) {
if (_audio_trId != MP4_INVALID_TRACK_ID) { if (_audio_trId != MP4_INVALID_TRACK_ID) {
auto iNextSample = getAudioSampleId(iTimeInc); auto iNextSample = getAudioSampleId(iTimeInc);
for (auto i = _audio_current; i < iNextSample; i++) { for (auto i = _audio_current; i < iNextSample; i++) {
...@@ -267,27 +268,27 @@ inline bool MediaReader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) { ...@@ -267,27 +268,27 @@ inline bool MediaReader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) {
return false; return false;
} }
inline void MediaReader::writeH264(uint8_t *pucData,int iLen,uint32_t dts,uint32_t pts) { inline void MP4Reader::writeH264(uint8_t *pucData,int iLen,uint32_t dts,uint32_t pts) {
_mediaMuxer->inputFrame(std::make_shared<H264FrameNoCacheAble>((char*)pucData,iLen,dts,pts)); _mediaMuxer->inputFrame(std::make_shared<H264FrameNoCacheAble>((char*)pucData,iLen,dts,pts));
} }
inline void MediaReader::writeAAC(uint8_t *pucData,int iLen,uint32_t uiStamp) { inline void MP4Reader::writeAAC(uint8_t *pucData,int iLen,uint32_t uiStamp) {
_mediaMuxer->inputFrame(std::make_shared<AACFrameNoCacheAble>((char*)pucData,iLen,uiStamp)); _mediaMuxer->inputFrame(std::make_shared<AACFrameNoCacheAble>((char*)pucData,iLen,uiStamp));
} }
inline MP4SampleId MediaReader::getVideoSampleId(int iTimeInc ) { inline MP4SampleId MP4Reader::getVideoSampleId(int iTimeInc ) {
MP4SampleId video_current = (double)_video_num_samples * (_iSeekTime + _ticker.elapsedTime() + iTimeInc) / _video_ms; MP4SampleId video_current = (double)_video_num_samples * (_iSeekTime + _ticker.elapsedTime() + iTimeInc) / _video_ms;
video_current = MAX(0,MIN(_video_num_samples, video_current)); video_current = MAX(0,MIN(_video_num_samples, video_current));
return video_current; return video_current;
} }
inline MP4SampleId MediaReader::getAudioSampleId(int iTimeInc) { inline MP4SampleId MP4Reader::getAudioSampleId(int iTimeInc) {
MP4SampleId audio_current = (double)_audio_num_samples * (_iSeekTime + _ticker.elapsedTime() + iTimeInc) / _audio_ms ; MP4SampleId audio_current = (double)_audio_num_samples * (_iSeekTime + _ticker.elapsedTime() + iTimeInc) / _audio_ms ;
audio_current = MAX(0,MIN(_audio_num_samples,audio_current)); audio_current = MAX(0,MIN(_audio_num_samples,audio_current));
return audio_current; return audio_current;
} }
inline void MediaReader::setSeekTime(uint32_t iSeekTime){ inline void MP4Reader::setSeekTime(uint32_t iSeekTime){
_iSeekTime = MAX(0, MIN(iSeekTime,_iDuration)); _iSeekTime = MAX(0, MIN(iSeekTime,_iDuration));
_ticker.resetTime(); _ticker.resetTime();
if (_audio_trId != MP4_INVALID_TRACK_ID) { if (_audio_trId != MP4_INVALID_TRACK_ID) {
...@@ -298,10 +299,10 @@ inline void MediaReader::setSeekTime(uint32_t iSeekTime){ ...@@ -298,10 +299,10 @@ inline void MediaReader::setSeekTime(uint32_t iSeekTime){
} }
} }
inline uint32_t MediaReader::getVideoCurrentTime(){ inline uint32_t MP4Reader::getVideoCurrentTime(){
return (double)_video_current * _video_ms /_video_num_samples; return (double)_video_current * _video_ms /_video_num_samples;
} }
void MediaReader::seek(uint32_t iSeekTime,bool bReStart){ void MP4Reader::seek(uint32_t iSeekTime,bool bReStart){
lock_guard<recursive_mutex> lck(_mtx); lock_guard<recursive_mutex> lck(_mtx);
if(iSeekTime == 0 || _video_trId == MP4_INVALID_TRACK_ID){ if(iSeekTime == 0 || _video_trId == MP4_INVALID_TRACK_ID){
setSeekTime(iSeekTime); setSeekTime(iSeekTime);
...@@ -331,7 +332,7 @@ void MediaReader::seek(uint32_t iSeekTime,bool bReStart){ ...@@ -331,7 +332,7 @@ void MediaReader::seek(uint32_t iSeekTime,bool bReStart){
MediaSource::Ptr MediaReader::onMakeMediaSource(const string &strSchema, MediaSource::Ptr MP4Reader::onMakeMediaSource(const string &strSchema,
const string &strVhost, const string &strVhost,
const string &strApp, const string &strApp,
const string &strId, const string &strId,
...@@ -343,7 +344,7 @@ MediaSource::Ptr MediaReader::onMakeMediaSource(const string &strSchema, ...@@ -343,7 +344,7 @@ MediaSource::Ptr MediaReader::onMakeMediaSource(const string &strSchema,
return nullptr; return nullptr;
} }
try { try {
MediaReader::Ptr pReader(new MediaReader(strVhost,strApp, strId,filePath)); MP4Reader::Ptr pReader(new MP4Reader(strVhost,strApp, strId,filePath));
pReader->startReadMP4(); pReader->startReadMP4();
return MediaSource::find(strSchema,strVhost,strApp, strId, false); return MediaSource::find(strSchema,strVhost,strApp, strId, false);
} catch (std::exception &ex) { } catch (std::exception &ex) {
......
...@@ -37,10 +37,10 @@ using namespace toolkit; ...@@ -37,10 +37,10 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
class MediaReader : public std::enable_shared_from_this<MediaReader> ,public MediaSourceEvent{ class MP4Reader : public std::enable_shared_from_this<MP4Reader> ,public MediaSourceEvent{
public: public:
typedef std::shared_ptr<MediaReader> Ptr; typedef std::shared_ptr<MP4Reader> Ptr;
virtual ~MediaReader(); virtual ~MP4Reader();
/** /**
* 流化一个mp4文件,使之转换成RtspMediaSource和RtmpMediaSource * 流化一个mp4文件,使之转换成RtspMediaSource和RtmpMediaSource
...@@ -49,10 +49,10 @@ public: ...@@ -49,10 +49,10 @@ public:
* @param strId 流id * @param strId 流id
* @param filePath 文件路径,如果为空则根据配置文件和上面参数自动生成,否则使用指定的文件 * @param filePath 文件路径,如果为空则根据配置文件和上面参数自动生成,否则使用指定的文件
*/ */
MediaReader(const string &strVhost,const string &strApp, const string &strId,const string &filePath = ""); MP4Reader(const string &strVhost,const string &strApp, const string &strId,const string &filePath = "");
/** /**
* 开始流化MP4文件,需要指出的是,MediaReader对象一经过调用startReadMP4方法,它的强引用会自持有, * 开始流化MP4文件,需要指出的是,MP4Reader对象一经过调用startReadMP4方法,它的强引用会自持有,
* 意思是在文件流化结束之前或中断之前,MediaReader对象是不会被销毁的(不管有没有被外部对象持有) * 意思是在文件流化结束之前或中断之前,MP4Reader对象是不会被销毁的(不管有没有被外部对象持有)
*/ */
void startReadMP4(); void startReadMP4();
...@@ -64,13 +64,13 @@ public: ...@@ -64,13 +64,13 @@ public:
bool seekTo(MediaSource &sender,uint32_t ui32Stamp) override; bool seekTo(MediaSource &sender,uint32_t ui32Stamp) override;
/** /**
* 关闭MediaReader的流化进程,会触发该对象放弃自持有 * 关闭MP4Reader的流化进程,会触发该对象放弃自持有
* @return * @return
*/ */
bool close(MediaSource &sender,bool force) override; bool close(MediaSource &sender,bool force) override;
/** /**
* 自动生成MediaReader对象然后查找相关的MediaSource对象 * 自动生成MP4Reader对象然后查找相关的MediaSource对象
* @param strSchema 协议名 * @param strSchema 协议名
* @param strVhost 虚拟主机 * @param strVhost 虚拟主机
* @param strApp 应用名 * @param strApp 应用名
......
/* /*
* MIT License * MIT License
* *
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com> * Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
* *
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit). * This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. * SOFTWARE.
*/ */
#include "MediaRecorder.h" #include "Recorder.h"
#include "Common/config.h" #include "Common/config.h"
#include "Http/HttpSession.h" #include "Http/HttpSession.h"
#include "Util/util.h" #include "Util/util.h"
#include "Util/mini.h" #include "Util/mini.h"
#include "Network/sockutil.h" #include "Network/sockutil.h"
#include "HlsMakerImp.h" #include "HlsMakerImp.h"
#include "Player/PlayerBase.h"
#include "Common/MediaSink.h"
#include "MP4Recorder.h"
#include "HlsRecorder.h"
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
MediaRecorder::MediaRecorder(const string &strVhost_tmp, MediaSinkInterface *Recorder::createHlsRecorder(const string &strVhost_tmp, const string &strApp, const string &strId) {
const string &strApp, #if defined(ENABLE_HLS)
const string &strId, GET_CONFIG(bool, enableVhost, General::kEnableVhost);
bool enableHls, GET_CONFIG(string, hlsPath, Hls::kFilePath);
bool enableMp4) {
GET_CONFIG(string,hlsPath,Hls::kFilePath);
GET_CONFIG(uint32_t,hlsBufSize,Hls::kFileBufSize);
GET_CONFIG(uint32_t,hlsDuration,Hls::kSegmentDuration);
GET_CONFIG(uint32_t,hlsNum,Hls::kSegmentNum);
GET_CONFIG(bool,enableVhost,General::kEnableVhost);
string strVhost = strVhost_tmp; string strVhost = strVhost_tmp;
if(trim(strVhost).empty()){ if (trim(strVhost).empty()) {
//如果strVhost为空,则强制为默认虚拟主机 //如果strVhost为空,则强制为默认虚拟主机
strVhost = DEFAULT_VHOST; strVhost = DEFAULT_VHOST;
} }
#if defined(ENABLE_HLS) string m3u8FilePath;
if(enableHls) { string params;
string m3u8FilePath; if (enableVhost) {
string params; m3u8FilePath = strVhost + "/" + strApp + "/" + strId + "/hls.m3u8";
if(enableVhost){ params = string(VHOST_KEY) + "=" + strVhost;
m3u8FilePath = strVhost + "/" + strApp + "/" + strId + "/hls.m3u8"; } else {
params = string(VHOST_KEY) + "=" + strVhost; m3u8FilePath = strApp + "/" + strId + "/hls.m3u8";
}else{
m3u8FilePath = strApp + "/" + strId + "/hls.m3u8";
}
m3u8FilePath = File::absolutePath(m3u8FilePath,hlsPath);
_hlsRecorder.reset(new HlsRecorder(m3u8FilePath,params,hlsBufSize, hlsDuration, hlsNum));
} }
m3u8FilePath = File::absolutePath(m3u8FilePath, hlsPath);
return new HlsRecorder(m3u8FilePath, params);
#else
return nullptr;
#endif //defined(ENABLE_HLS) #endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4RECORD)
GET_CONFIG(string,recordPath,Record::kFilePath);
GET_CONFIG(string,recordAppName,Record::kAppName);
if(enableMp4){
string mp4FilePath;
if(enableVhost){
mp4FilePath = strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/";
} else {
mp4FilePath = recordAppName + "/" + strApp + "/" + strId + "/";
}
mp4FilePath = File::absolutePath(mp4FilePath,recordPath);
_mp4Recorder.reset(new MP4Recorder(mp4FilePath,strVhost,strApp,strId));
}
#endif //defined(ENABLE_MP4RECORD)
}
MediaRecorder::~MediaRecorder() {
} }
void MediaRecorder::inputFrame(const Frame::Ptr &frame) { MediaSinkInterface *Recorder::createMP4Recorder(const string &strVhost_tmp, const string &strApp, const string &strId) {
#if defined(ENABLE_HLS)
if (_hlsRecorder) {
_hlsRecorder->inputFrame(frame);
}
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4RECORD) #if defined(ENABLE_MP4RECORD)
if (_mp4Recorder) { GET_CONFIG(bool, enableVhost, General::kEnableVhost);
_mp4Recorder->inputFrame(frame); GET_CONFIG(string, recordPath, Record::kFilePath);
} GET_CONFIG(string, recordAppName, Record::kAppName);
#endif //defined(ENABLE_MP4RECORD)
}
void MediaRecorder::addTrack(const Track::Ptr &track) { string strVhost = strVhost_tmp;
#if defined(ENABLE_HLS) if (trim(strVhost).empty()) {
if (_hlsRecorder) { //如果strVhost为空,则强制为默认虚拟主机
_hlsRecorder->addTrack(track); strVhost = DEFAULT_VHOST;
} }
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4RECORD) string mp4FilePath;
if (_mp4Recorder) { if (enableVhost) {
_mp4Recorder->addTrack(track); mp4FilePath = strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/";
} else {
mp4FilePath = recordAppName + "/" + strApp + "/" + strId + "/";
} }
mp4FilePath = File::absolutePath(mp4FilePath, recordPath);
return new MP4Recorder(mp4FilePath, strVhost, strApp, strId);
#else
return nullptr;
#endif //defined(ENABLE_MP4RECORD) #endif //defined(ENABLE_MP4RECORD)
} }
void MediaRecorder::resetTracks() {
#if defined(ENABLE_HLS)
if (_hlsRecorder) {
_hlsRecorder->resetTracks();
}
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4RECORD)
if (_mp4Recorder) {
_mp4Recorder->resetTracks();
}
#endif //defined(ENABLE_MP4RECORD)
}
} /* namespace mediakit */ } /* namespace mediakit */
...@@ -24,56 +24,26 @@ ...@@ -24,56 +24,26 @@
* SOFTWARE. * SOFTWARE.
*/ */
#ifndef SRC_MEDIAFILE_MEDIARECORDER_H_ #ifndef SRC_MEDIAFILE_RECORDER_H_
#define SRC_MEDIAFILE_MEDIARECORDER_H_ #define SRC_MEDIAFILE_RECORDER_H_
#include <memory> #include <memory>
#include "Player/PlayerBase.h" #include <string>
#include "Common/MediaSink.h" using namespace std;
#include "MP4Recorder.h"
#include "HlsRecorder.h"
using namespace toolkit;
namespace mediakit { namespace mediakit {
class MediaRecorder : public MediaSinkInterface{ class MediaSinkInterface;
public:
typedef std::shared_ptr<MediaRecorder> Ptr;
MediaRecorder(const string &strVhost,
const string &strApp,
const string &strId,
bool enableHls = true,
bool enableMp4 = false);
virtual ~MediaRecorder();
/**
* 输入frame
* @param frame
*/
void inputFrame(const Frame::Ptr &frame) override;
/** class Recorder{
* 添加track,内部会调用Track的clone方法 public:
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系 static MediaSinkInterface *createHlsRecorder(const string &strVhost, const string &strApp, const string &strId);
* @param track static MediaSinkInterface *createMP4Recorder(const string &strVhost, const string &strApp, const string &strId);
*/
void addTrack(const Track::Ptr &track) override;
/**
* 重置track
*/
void resetTracks() override;
private: private:
#if defined(ENABLE_HLS) Recorder() = delete;
std::shared_ptr<HlsRecorder> _hlsRecorder; ~Recorder() = delete;
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4RECORD)
std::shared_ptr<MP4Recorder> _mp4Recorder;
#endif //defined(ENABLE_MP4RECORD)
}; };
} /* namespace mediakit */ } /* namespace mediakit */
#endif /* SRC_MEDIAFILE_MEDIARECORDER_H_ */ #endif /* SRC_MEDIAFILE_RECORDER_H_ */
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#include "Extension/Track.h" #include "Extension/Track.h"
#include "Util/File.h" #include "Util/File.h"
#include "Common/MediaSink.h" #include "Common/MediaSink.h"
#include "Stamp.h" #include "Common/Stamp.h"
using namespace toolkit; using namespace toolkit;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "Rtmp/Rtmp.h" #include "Rtmp/Rtmp.h"
#include "Rtmp/RtmpMediaSource.h" #include "Rtmp/RtmpMediaSource.h"
#include "Network/Socket.h" #include "Network/Socket.h"
#include "MediaFile/Stamp.h" #include "Common/Stamp.h"
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "Util/util.h" #include "Util/util.h"
#include "Util/TimeTicker.h" #include "Util/TimeTicker.h"
#include "Network/TcpSession.h" #include "Network/TcpSession.h"
#include "MediaFile/Stamp.h" #include "Common/Stamp.h"
using namespace toolkit; using namespace toolkit;
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include "Network/TcpClient.h" #include "Network/TcpClient.h"
#include "RtspSplitter.h" #include "RtspSplitter.h"
#include "RtpReceiver.h" #include "RtpReceiver.h"
#include "MediaFile/Stamp.h" #include "Common/Stamp.h"
using namespace std; using namespace std;
using namespace toolkit; using namespace toolkit;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "RtspSplitter.h" #include "RtspSplitter.h"
#include "RtpReceiver.h" #include "RtpReceiver.h"
#include "RtspToRtmpMediaSource.h" #include "RtspToRtmpMediaSource.h"
#include "Common/Stamp.h"
using namespace std; using namespace std;
using namespace toolkit; using namespace toolkit;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论