mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-21 01:13:37 +08:00
整理文件录制
This commit is contained in:
parent
2c2e7262d6
commit
de33d6a847
@ -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;
|
||||
|
@ -40,6 +40,8 @@ namespace mediakit{
|
||||
|
||||
class MediaSinkInterface : public FrameWriterInterface {
|
||||
public:
|
||||
typedef std::shared_ptr<MediaSinkInterface> Ptr;
|
||||
|
||||
MediaSinkInterface(){};
|
||||
virtual ~MediaSinkInterface(){};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<MultiMediaSourceMuxer>{
|
||||
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<RtmpMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleMeta>(dur_sec));
|
||||
}
|
||||
if (bEanbleRtsp) {
|
||||
_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(){}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 */
|
@ -32,15 +32,23 @@
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
class HlsRecorder : public HlsMakerImp, public TsMuxer {
|
||||
class HlsRecorder : public TsMuxer {
|
||||
public:
|
||||
template<typename ...ArgsType>
|
||||
HlsRecorder(ArgsType &&...args):HlsMakerImp(std::forward<ArgsType>(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
|
@ -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{
|
||||
|
@ -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<recursive_mutex> 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<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));
|
||||
}
|
||||
|
||||
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<recursive_mutex> 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) {
|
@ -37,10 +37,10 @@ using namespace toolkit;
|
||||
|
||||
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:
|
||||
typedef std::shared_ptr<MediaReader> Ptr;
|
||||
virtual ~MediaReader();
|
||||
typedef std::shared_ptr<MP4Reader> 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 应用名
|
95
src/Record/Recorder.cpp
Normal file
95
src/Record/Recorder.cpp
Normal 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 */
|
@ -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 <memory>
|
||||
#include "Player/PlayerBase.h"
|
||||
#include "Common/MediaSink.h"
|
||||
#include "MP4Recorder.h"
|
||||
#include "HlsRecorder.h"
|
||||
|
||||
using namespace toolkit;
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
class MediaRecorder : public MediaSinkInterface{
|
||||
class MediaSinkInterface;
|
||||
|
||||
class Recorder{
|
||||
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;
|
||||
|
||||
/**
|
||||
* 添加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> _hlsRecorder;
|
||||
#endif //defined(ENABLE_HLS)
|
||||
|
||||
#if defined(ENABLE_MP4RECORD)
|
||||
std::shared_ptr<MP4Recorder> _mp4Recorder;
|
||||
#endif //defined(ENABLE_MP4RECORD)
|
||||
Recorder() = delete;
|
||||
~Recorder() = delete;
|
||||
};
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
||||
#endif /* SRC_MEDIAFILE_MEDIARECORDER_H_ */
|
||||
#endif /* SRC_MEDIAFILE_RECORDER_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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "RtspSplitter.h"
|
||||
#include "RtpReceiver.h"
|
||||
#include "RtspToRtmpMediaSource.h"
|
||||
#include "Common/Stamp.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
|
Loading…
Reference in New Issue
Block a user