From de33d6a8474de3b5ad21e0b44d6f443752d79786 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Wed, 4 Dec 2019 10:45:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E6=96=87=E4=BB=B6=E5=BD=95?= =?UTF-8?q?=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/WebHook.cpp | 1 + src/Common/MediaSink.h | 2 + src/Common/MediaSource.cpp | 4 +- src/Common/MultiMediaSourceMuxer.h | 36 +++-- src/{MediaFile => Common}/Stamp.cpp | 0 src/{MediaFile => Common}/Stamp.h | 0 src/MediaFile/MediaRecorder.cpp | 133 ------------------ src/{MediaFile => Record}/HlsMaker.cpp | 0 src/{MediaFile => Record}/HlsMaker.h | 0 src/{MediaFile => Record}/HlsMakerImp.cpp | 0 src/{MediaFile => Record}/HlsMakerImp.h | 0 src/{MediaFile => Record}/HlsRecorder.h | 18 ++- src/{MediaFile => Record}/MP4Muxer.cpp | 0 src/{MediaFile => Record}/MP4Muxer.h | 2 +- .../MediaReader.cpp => Record/MP4Reader.cpp} | 39 ++--- .../MediaReader.h => Record/MP4Reader.h} | 16 +-- src/{MediaFile => Record}/MP4Recorder.cpp | 0 src/{MediaFile => Record}/MP4Recorder.h | 0 src/Record/Recorder.cpp | 95 +++++++++++++ .../MediaRecorder.h => Record/Recorder.h} | 54 ++----- src/{MediaFile => Record}/TsMuxer.cpp | 0 src/{MediaFile => Record}/TsMuxer.h | 2 +- src/Rtmp/FlvMuxer.h | 2 +- src/Rtmp/RtmpSession.h | 2 +- src/Rtsp/RtspPlayer.h | 2 +- src/Rtsp/RtspSession.h | 1 + 26 files changed, 187 insertions(+), 222 deletions(-) rename src/{MediaFile => Common}/Stamp.cpp (100%) rename src/{MediaFile => Common}/Stamp.h (100%) delete mode 100644 src/MediaFile/MediaRecorder.cpp rename src/{MediaFile => Record}/HlsMaker.cpp (100%) rename src/{MediaFile => Record}/HlsMaker.h (100%) rename src/{MediaFile => Record}/HlsMakerImp.cpp (100%) rename src/{MediaFile => Record}/HlsMakerImp.h (100%) rename src/{MediaFile => Record}/HlsRecorder.h (75%) rename src/{MediaFile => Record}/MP4Muxer.cpp (100%) rename src/{MediaFile => Record}/MP4Muxer.h (99%) rename src/{MediaFile/MediaReader.cpp => Record/MP4Reader.cpp} (90%) rename src/{MediaFile/MediaReader.h => Record/MP4Reader.h} (86%) rename src/{MediaFile => Record}/MP4Recorder.cpp (100%) rename src/{MediaFile => Record}/MP4Recorder.h (100%) create mode 100644 src/Record/Recorder.cpp rename src/{MediaFile/MediaRecorder.h => Record/Recorder.h} (53%) rename src/{MediaFile => Record}/TsMuxer.cpp (100%) rename src/{MediaFile => Record}/TsMuxer.h (98%) diff --git a/server/WebHook.cpp b/server/WebHook.cpp index e251f24b..b6283025 100644 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -39,6 +39,7 @@ #include "Rtsp/RtspSession.h" #include "Http/HttpSession.h" #include "WebHook.h" +#include "Record/MP4Recorder.h" using namespace Json; using namespace toolkit; diff --git a/src/Common/MediaSink.h b/src/Common/MediaSink.h index 0f7fc92a..64317385 100644 --- a/src/Common/MediaSink.h +++ b/src/Common/MediaSink.h @@ -40,6 +40,8 @@ namespace mediakit{ class MediaSinkInterface : public FrameWriterInterface { public: + typedef std::shared_ptr Ptr; + MediaSinkInterface(){}; virtual ~MediaSinkInterface(){}; diff --git a/src/Common/MediaSource.cpp b/src/Common/MediaSource.cpp index 96b63332..d489a217 100644 --- a/src/Common/MediaSource.cpp +++ b/src/Common/MediaSource.cpp @@ -26,7 +26,7 @@ #include "MediaSource.h" -#include "MediaFile/MediaReader.h" +#include "Record/MP4Reader.h" #include "Util/util.h" #include "Network/sockutil.h" #include "Network/TcpSession.h" @@ -278,7 +278,7 @@ MediaSource::Ptr MediaSource::find( }); if(!ret && bMake){ //未查找媒体源,则创建一个 - ret = MediaReader::onMakeMediaSource(schema, vhost,app,id); + ret = MP4Reader::onMakeMediaSource(schema, vhost,app,id); } return ret; } diff --git a/src/Common/MultiMediaSourceMuxer.h b/src/Common/MultiMediaSourceMuxer.h index cbe6e75c..431f609c 100644 --- a/src/Common/MultiMediaSourceMuxer.h +++ b/src/Common/MultiMediaSourceMuxer.h @@ -29,7 +29,7 @@ #include "Rtsp/RtspMediaSourceMuxer.h" #include "Rtmp/RtmpMediaSourceMuxer.h" -#include "MediaFile/MediaRecorder.h" +#include "Record/Recorder.h" class MultiMediaSourceMuxer : public MediaSink , public std::enable_shared_from_this{ public: @@ -42,15 +42,19 @@ public: bool bEanbleRtsp = true, bool bEanbleRtmp = true, bool bEanbleHls = true, - bool bEnableMp4 = false - ){ + bool bEnableMp4 = false){ if (bEanbleRtmp) { _rtmp = std::make_shared(vhost, strApp, strId, std::make_shared(dur_sec)); } if (bEanbleRtsp) { _rtsp = std::make_shared(vhost, strApp, strId, std::make_shared(dur_sec)); } - _record = std::make_shared(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(){} @@ -64,7 +68,12 @@ public: if(_rtsp){ _rtsp->resetTracks(); } - _record->resetTracks(); + if(_hls){ + _hls->resetTracks(); + } + if(_mp4){ + _mp4->resetTracks(); + } } /** @@ -106,7 +115,12 @@ protected: if(_rtsp){ _rtsp->addTrack(track); } - _record->addTrack(track); + if(_hls){ + _hls->addTrack(track); + } + if(_mp4){ + _mp4->addTrack(track); + } } /** @@ -120,7 +134,12 @@ protected: if(_rtsp) { _rtsp->inputFrame(frame); } - _record->inputFrame(frame); + if(_hls){ + _hls->inputFrame(frame); + } + if(_mp4){ + _mp4->inputFrame(frame); + } } /** @@ -139,7 +158,8 @@ protected: private: RtmpMediaSourceMuxer::Ptr _rtmp; RtspMediaSourceMuxer::Ptr _rtsp; - MediaRecorder::Ptr _record; + MediaSinkInterface::Ptr _hls; + MediaSinkInterface::Ptr _mp4; }; diff --git a/src/MediaFile/Stamp.cpp b/src/Common/Stamp.cpp similarity index 100% rename from src/MediaFile/Stamp.cpp rename to src/Common/Stamp.cpp diff --git a/src/MediaFile/Stamp.h b/src/Common/Stamp.h similarity index 100% rename from src/MediaFile/Stamp.h rename to src/Common/Stamp.h diff --git a/src/MediaFile/MediaRecorder.cpp b/src/MediaFile/MediaRecorder.cpp deleted file mode 100644 index e422b6e5..00000000 --- a/src/MediaFile/MediaRecorder.cpp +++ /dev/null @@ -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 */ diff --git a/src/MediaFile/HlsMaker.cpp b/src/Record/HlsMaker.cpp similarity index 100% rename from src/MediaFile/HlsMaker.cpp rename to src/Record/HlsMaker.cpp diff --git a/src/MediaFile/HlsMaker.h b/src/Record/HlsMaker.h similarity index 100% rename from src/MediaFile/HlsMaker.h rename to src/Record/HlsMaker.h diff --git a/src/MediaFile/HlsMakerImp.cpp b/src/Record/HlsMakerImp.cpp similarity index 100% rename from src/MediaFile/HlsMakerImp.cpp rename to src/Record/HlsMakerImp.cpp diff --git a/src/MediaFile/HlsMakerImp.h b/src/Record/HlsMakerImp.h similarity index 100% rename from src/MediaFile/HlsMakerImp.h rename to src/Record/HlsMakerImp.h diff --git a/src/MediaFile/HlsRecorder.h b/src/Record/HlsRecorder.h similarity index 75% rename from src/MediaFile/HlsRecorder.h rename to src/Record/HlsRecorder.h index ca20c5f0..c0def9bb 100644 --- a/src/MediaFile/HlsRecorder.h +++ b/src/Record/HlsRecorder.h @@ -32,15 +32,23 @@ namespace mediakit { -class HlsRecorder : public HlsMakerImp, public TsMuxer { +class HlsRecorder : public TsMuxer { public: - template - HlsRecorder(ArgsType &&...args):HlsMakerImp(std::forward(args)...){} - ~HlsRecorder(){}; + HlsRecorder(const string &m3u8_file, const string ¶ms){ + GET_CONFIG(uint32_t,hlsNum,Hls::kSegmentNum); + 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: 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 diff --git a/src/MediaFile/MP4Muxer.cpp b/src/Record/MP4Muxer.cpp similarity index 100% rename from src/MediaFile/MP4Muxer.cpp rename to src/Record/MP4Muxer.cpp diff --git a/src/MediaFile/MP4Muxer.h b/src/Record/MP4Muxer.h similarity index 99% rename from src/MediaFile/MP4Muxer.h rename to src/Record/MP4Muxer.h index 1532d87e..401431d2 100644 --- a/src/MediaFile/MP4Muxer.h +++ b/src/Record/MP4Muxer.h @@ -39,7 +39,7 @@ #include "Extension/AAC.h" #include "Extension/H264.h" #include "Extension/H265.h" -#include "Stamp.h" +#include "Common/Stamp.h" namespace mediakit{ diff --git a/src/MediaFile/MediaReader.cpp b/src/Record/MP4Reader.cpp similarity index 90% rename from src/MediaFile/MediaReader.cpp rename to src/Record/MP4Reader.cpp index eae430bd..74521fd3 100644 --- a/src/MediaFile/MediaReader.cpp +++ b/src/Record/MP4Reader.cpp @@ -24,9 +24,10 @@ * SOFTWARE. */ -#include "MediaReader.h" +#include "MP4Reader.h" #include "Common/config.h" #include "Util/mini.h" +#include "Util/File.h" #include "Http/HttpSession.h" #include "Extension/AAC.h" #include "Extension/H264.h" @@ -37,7 +38,7 @@ using namespace toolkit; namespace mediakit { #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(); auto strFileName = filePath; 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) { MP4Close(_hMP4File); _hMP4File = MP4_INVALID_FILE_HANDLE; @@ -161,7 +162,7 @@ MediaReader::~MediaReader() { } -void MediaReader::startReadMP4() { +void MP4Reader::startReadMP4() { auto strongSelf = shared_from_this(); GET_CONFIG(uint32_t,sampleMS,Record::kSampleMS); @@ -173,11 +174,11 @@ void MediaReader::startReadMP4() { readSample(sampleMS, false); _mediaMuxer->setListener(strongSelf); } - bool MediaReader::seekTo(MediaSource &sender,uint32_t ui32Stamp){ + bool MP4Reader::seekTo(MediaSource &sender,uint32_t ui32Stamp){ seek(ui32Stamp); return true; } -bool MediaReader::close(MediaSource &sender,bool force){ +bool MP4Reader::close(MediaSource &sender,bool force){ if(!_mediaMuxer || (!force && _mediaMuxer->readerCount() != 0)){ return false; } @@ -186,14 +187,14 @@ bool MediaReader::close(MediaSource &sender,bool force){ return true; } -void MediaReader::onNoneReader(MediaSource &sender) { +void MP4Reader::onNoneReader(MediaSource &sender) { if(!_mediaMuxer || _mediaMuxer->readerCount() != 0){ return; } MediaSourceEvent::onNoneReader(sender); } -bool MediaReader::readSample(int iTimeInc,bool justSeekSyncFrame) { +bool MP4Reader::readSample(int iTimeInc,bool justSeekSyncFrame) { TimeTicker(); lock_guard lck(_mtx); auto bFlag0 = readVideoSample(iTimeInc,justSeekSyncFrame);//数据没读完 @@ -211,7 +212,7 @@ bool MediaReader::readSample(int iTimeInc,bool justSeekSyncFrame) { //3秒延时关闭 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) { auto iNextSample = getVideoSampleId(iTimeInc); MP4SampleId iIdx = _video_current; @@ -245,7 +246,7 @@ inline bool MediaReader::readVideoSample(int iTimeInc,bool justSeekSyncFrame) { 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) { auto iNextSample = getAudioSampleId(iTimeInc); for (auto i = _audio_current; i < iNextSample; i++) { @@ -267,27 +268,27 @@ inline bool MediaReader::readAudioSample(int iTimeInc,bool justSeekSyncFrame) { 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((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((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; video_current = MAX(0,MIN(_video_num_samples, 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 ; audio_current = MAX(0,MIN(_audio_num_samples,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)); _ticker.resetTime(); 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; } -void MediaReader::seek(uint32_t iSeekTime,bool bReStart){ +void MP4Reader::seek(uint32_t iSeekTime,bool bReStart){ lock_guard lck(_mtx); if(iSeekTime == 0 || _video_trId == MP4_INVALID_TRACK_ID){ 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 &strApp, const string &strId, @@ -343,7 +344,7 @@ MediaSource::Ptr MediaReader::onMakeMediaSource(const string &strSchema, return nullptr; } try { - MediaReader::Ptr pReader(new MediaReader(strVhost,strApp, strId,filePath)); + MP4Reader::Ptr pReader(new MP4Reader(strVhost,strApp, strId,filePath)); pReader->startReadMP4(); return MediaSource::find(strSchema,strVhost,strApp, strId, false); } catch (std::exception &ex) { diff --git a/src/MediaFile/MediaReader.h b/src/Record/MP4Reader.h similarity index 86% rename from src/MediaFile/MediaReader.h rename to src/Record/MP4Reader.h index a2917367..576d0ed2 100644 --- a/src/MediaFile/MediaReader.h +++ b/src/Record/MP4Reader.h @@ -37,10 +37,10 @@ using namespace toolkit; namespace mediakit { -class MediaReader : public std::enable_shared_from_this ,public MediaSourceEvent{ +class MP4Reader : public std::enable_shared_from_this ,public MediaSourceEvent{ public: - typedef std::shared_ptr Ptr; - virtual ~MediaReader(); + typedef std::shared_ptr Ptr; + virtual ~MP4Reader(); /** * 流化一个mp4文件,使之转换成RtspMediaSource和RtmpMediaSource @@ -49,10 +49,10 @@ public: * @param strId 流id * @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方法,它的强引用会自持有, - * 意思是在文件流化结束之前或中断之前,MediaReader对象是不会被销毁的(不管有没有被外部对象持有) + * 开始流化MP4文件,需要指出的是,MP4Reader对象一经过调用startReadMP4方法,它的强引用会自持有, + * 意思是在文件流化结束之前或中断之前,MP4Reader对象是不会被销毁的(不管有没有被外部对象持有) */ void startReadMP4(); @@ -64,13 +64,13 @@ public: bool seekTo(MediaSource &sender,uint32_t ui32Stamp) override; /** - * 关闭MediaReader的流化进程,会触发该对象放弃自持有 + * 关闭MP4Reader的流化进程,会触发该对象放弃自持有 * @return */ bool close(MediaSource &sender,bool force) override; /** - * 自动生成MediaReader对象然后查找相关的MediaSource对象 + * 自动生成MP4Reader对象然后查找相关的MediaSource对象 * @param strSchema 协议名 * @param strVhost 虚拟主机 * @param strApp 应用名 diff --git a/src/MediaFile/MP4Recorder.cpp b/src/Record/MP4Recorder.cpp similarity index 100% rename from src/MediaFile/MP4Recorder.cpp rename to src/Record/MP4Recorder.cpp diff --git a/src/MediaFile/MP4Recorder.h b/src/Record/MP4Recorder.h similarity index 100% rename from src/MediaFile/MP4Recorder.h rename to src/Record/MP4Recorder.h diff --git a/src/Record/Recorder.cpp b/src/Record/Recorder.cpp new file mode 100644 index 00000000..cc73324c --- /dev/null +++ b/src/Record/Recorder.cpp @@ -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 */ diff --git a/src/MediaFile/MediaRecorder.h b/src/Record/Recorder.h similarity index 53% rename from src/MediaFile/MediaRecorder.h rename to src/Record/Recorder.h index fbfba1e7..63fdc147 100644 --- a/src/MediaFile/MediaRecorder.h +++ b/src/Record/Recorder.h @@ -24,56 +24,26 @@ * SOFTWARE. */ -#ifndef SRC_MEDIAFILE_MEDIARECORDER_H_ -#define SRC_MEDIAFILE_MEDIARECORDER_H_ +#ifndef SRC_MEDIAFILE_RECORDER_H_ +#define SRC_MEDIAFILE_RECORDER_H_ #include -#include "Player/PlayerBase.h" -#include "Common/MediaSink.h" -#include "MP4Recorder.h" -#include "HlsRecorder.h" - -using namespace toolkit; +#include +using namespace std; namespace mediakit { -class MediaRecorder : public MediaSinkInterface{ +class MediaSinkInterface; + +class Recorder{ public: - typedef std::shared_ptr 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; - - /** - * 添加track,内部会调用Track的clone方法 - * 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系 - * @param track - */ - void addTrack(const Track::Ptr &track) override; - - /** - * 重置track - */ - void resetTracks() override; + static MediaSinkInterface *createHlsRecorder(const string &strVhost, const string &strApp, const string &strId); + static MediaSinkInterface *createMP4Recorder(const string &strVhost, const string &strApp, const string &strId); private: -#if defined(ENABLE_HLS) - std::shared_ptr _hlsRecorder; -#endif //defined(ENABLE_HLS) - -#if defined(ENABLE_MP4RECORD) - std::shared_ptr _mp4Recorder; -#endif //defined(ENABLE_MP4RECORD) + Recorder() = delete; + ~Recorder() = delete; }; } /* namespace mediakit */ -#endif /* SRC_MEDIAFILE_MEDIARECORDER_H_ */ +#endif /* SRC_MEDIAFILE_RECORDER_H_ */ diff --git a/src/MediaFile/TsMuxer.cpp b/src/Record/TsMuxer.cpp similarity index 100% rename from src/MediaFile/TsMuxer.cpp rename to src/Record/TsMuxer.cpp diff --git a/src/MediaFile/TsMuxer.h b/src/Record/TsMuxer.h similarity index 98% rename from src/MediaFile/TsMuxer.h rename to src/Record/TsMuxer.h index 3bd4509c..26b262cc 100644 --- a/src/MediaFile/TsMuxer.h +++ b/src/Record/TsMuxer.h @@ -32,7 +32,7 @@ #include "Extension/Track.h" #include "Util/File.h" #include "Common/MediaSink.h" -#include "Stamp.h" +#include "Common/Stamp.h" using namespace toolkit; diff --git a/src/Rtmp/FlvMuxer.h b/src/Rtmp/FlvMuxer.h index 7f48d3fd..a01d6250 100644 --- a/src/Rtmp/FlvMuxer.h +++ b/src/Rtmp/FlvMuxer.h @@ -30,7 +30,7 @@ #include "Rtmp/Rtmp.h" #include "Rtmp/RtmpMediaSource.h" #include "Network/Socket.h" -#include "MediaFile/Stamp.h" +#include "Common/Stamp.h" using namespace toolkit; namespace mediakit { diff --git a/src/Rtmp/RtmpSession.h b/src/Rtmp/RtmpSession.h index a891b49b..9eac1e35 100644 --- a/src/Rtmp/RtmpSession.h +++ b/src/Rtmp/RtmpSession.h @@ -37,7 +37,7 @@ #include "Util/util.h" #include "Util/TimeTicker.h" #include "Network/TcpSession.h" -#include "MediaFile/Stamp.h" +#include "Common/Stamp.h" using namespace toolkit; diff --git a/src/Rtsp/RtspPlayer.h b/src/Rtsp/RtspPlayer.h index ee7afba0..8247dc9d 100644 --- a/src/Rtsp/RtspPlayer.h +++ b/src/Rtsp/RtspPlayer.h @@ -40,7 +40,7 @@ #include "Network/TcpClient.h" #include "RtspSplitter.h" #include "RtpReceiver.h" -#include "MediaFile/Stamp.h" +#include "Common/Stamp.h" using namespace std; using namespace toolkit; diff --git a/src/Rtsp/RtspSession.h b/src/Rtsp/RtspSession.h index 33637666..6ffa550a 100644 --- a/src/Rtsp/RtspSession.h +++ b/src/Rtsp/RtspSession.h @@ -41,6 +41,7 @@ #include "RtspSplitter.h" #include "RtpReceiver.h" #include "RtspToRtmpMediaSource.h" +#include "Common/Stamp.h" using namespace std; using namespace toolkit;