整理文件录制

This commit is contained in:
xiongziliang 2019-12-04 10:45:38 +08:00
parent 2c2e7262d6
commit de33d6a847
26 changed files with 187 additions and 222 deletions

View File

@ -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;

View File

@ -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(){};

View File

@ -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(
}); });
if(!ret && bMake){ if(!ret && bMake){
//未查找媒体源,则创建一个 //未查找媒体源,则创建一个
ret = MediaReader::onMakeMediaSource(schema, vhost,app,id); ret = MP4Reader::onMakeMediaSource(schema, vhost,app,id);
} }
return ret; return ret;
} }

View File

@ -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:
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:
if(_rtsp){ if(_rtsp){
_rtsp->resetTracks(); _rtsp->resetTracks();
} }
_record->resetTracks(); if(_hls){
_hls->resetTracks();
}
if(_mp4){
_mp4->resetTracks();
}
} }
/** /**
@ -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:
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:
private: private:
RtmpMediaSourceMuxer::Ptr _rtmp; RtmpMediaSourceMuxer::Ptr _rtmp;
RtspMediaSourceMuxer::Ptr _rtsp; RtspMediaSourceMuxer::Ptr _rtsp;
MediaRecorder::Ptr _record; MediaSinkInterface::Ptr _hls;
MediaSinkInterface::Ptr _mp4;
}; };

View File

@ -1,133 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* 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
* SOFTWARE.
*/
#include "MediaRecorder.h"
#include "Common/config.h"
#include "Http/HttpSession.h"
#include "Util/util.h"
#include "Util/mini.h"
#include "Network/sockutil.h"
#include "HlsMakerImp.h"
using namespace toolkit;
namespace mediakit {
MediaRecorder::MediaRecorder(const string &strVhost_tmp,
const string &strApp,
const string &strId,
bool enableHls,
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;
if(trim(strVhost).empty()){
//如果strVhost为空则强制为默认虚拟主机
strVhost = DEFAULT_VHOST;
}
#if defined(ENABLE_HLS)
if(enableHls) {
string m3u8FilePath;
string params;
if(enableVhost){
m3u8FilePath = strVhost + "/" + strApp + "/" + strId + "/hls.m3u8";
params = string(VHOST_KEY) + "=" + strVhost;
}else{
m3u8FilePath = strApp + "/" + strId + "/hls.m3u8";
}
m3u8FilePath = File::absolutePath(m3u8FilePath,hlsPath);
_hlsRecorder.reset(new HlsRecorder(m3u8FilePath,params,hlsBufSize, hlsDuration, hlsNum));
}
#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) {
#if defined(ENABLE_HLS)
if (_hlsRecorder) {
_hlsRecorder->inputFrame(frame);
}
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4RECORD)
if (_mp4Recorder) {
_mp4Recorder->inputFrame(frame);
}
#endif //defined(ENABLE_MP4RECORD)
}
void MediaRecorder::addTrack(const Track::Ptr &track) {
#if defined(ENABLE_HLS)
if (_hlsRecorder) {
_hlsRecorder->addTrack(track);
}
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4RECORD)
if (_mp4Recorder) {
_mp4Recorder->addTrack(track);
}
#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 */

View File

@ -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

View File

@ -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{

View File

@ -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;
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
} }
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() {
} }
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() {
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){
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) {
//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) {
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) {
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){
} }
} }
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){
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,
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) {

View File

@ -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:
* @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:
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

95
src/Record/Recorder.cpp Normal file
View File

@ -0,0 +1,95 @@
/*
* MIT License
*
* Copyright (c) 2016-2019 xiongziliang <771730766@qq.com>
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* 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
* SOFTWARE.
*/
#include "Recorder.h"
#include "Common/config.h"
#include "Http/HttpSession.h"
#include "Util/util.h"
#include "Util/mini.h"
#include "Network/sockutil.h"
#include "HlsMakerImp.h"
#include "Player/PlayerBase.h"
#include "Common/MediaSink.h"
#include "MP4Recorder.h"
#include "HlsRecorder.h"
using namespace toolkit;
namespace mediakit {
MediaSinkInterface *Recorder::createHlsRecorder(const string &strVhost_tmp, const string &strApp, const string &strId) {
#if defined(ENABLE_HLS)
GET_CONFIG(bool, enableVhost, General::kEnableVhost);
GET_CONFIG(string, hlsPath, Hls::kFilePath);
string strVhost = strVhost_tmp;
if (trim(strVhost).empty()) {
//如果strVhost为空则强制为默认虚拟主机
strVhost = DEFAULT_VHOST;
}
string m3u8FilePath;
string params;
if (enableVhost) {
m3u8FilePath = strVhost + "/" + strApp + "/" + strId + "/hls.m3u8";
params = string(VHOST_KEY) + "=" + strVhost;
} else {
m3u8FilePath = strApp + "/" + strId + "/hls.m3u8";
}
m3u8FilePath = File::absolutePath(m3u8FilePath, hlsPath);
return new HlsRecorder(m3u8FilePath, params);
#else
return nullptr;
#endif //defined(ENABLE_HLS)
}
MediaSinkInterface *Recorder::createMP4Recorder(const string &strVhost_tmp, const string &strApp, const string &strId) {
#if defined(ENABLE_MP4RECORD)
GET_CONFIG(bool, enableVhost, General::kEnableVhost);
GET_CONFIG(string, recordPath, Record::kFilePath);
GET_CONFIG(string, recordAppName, Record::kAppName);
string strVhost = strVhost_tmp;
if (trim(strVhost).empty()) {
//如果strVhost为空则强制为默认虚拟主机
strVhost = DEFAULT_VHOST;
}
string mp4FilePath;
if (enableVhost) {
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)
}
} /* namespace mediakit */

View File

@ -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;
class Recorder{
public: public:
typedef std::shared_ptr<MediaRecorder> Ptr; static MediaSinkInterface *createHlsRecorder(const string &strVhost, const string &strApp, const string &strId);
MediaRecorder(const string &strVhost, static MediaSinkInterface *createMP4Recorder(const string &strVhost, const string &strApp, const string &strId);
const string &strApp,
const string &strId,
bool enableHls = true,
bool enableMp4 = false);
virtual ~MediaRecorder();
/**
* frame
* @param frame
*/
void inputFrame(const Frame::Ptr &frame) override;
/**
* trackTrack的clone方法
* sps pps这些信息 Delegate相关关系
* @param track
*/
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_ */

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;