mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-30 16:27:36 +08:00
修改文件录制、hls生成、拉流代理逻辑
This commit is contained in:
parent
ae1b62c78f
commit
5ed2ce40fe
@ -29,10 +29,6 @@
|
||||
#include "Util/onceToken.h"
|
||||
#include "Network/sockutil.h"
|
||||
|
||||
#ifndef UINT64_MAX
|
||||
#define UINT64_MAX 0xFFFFFFFFFFFFFFFF
|
||||
#endif//UINT64_MAX
|
||||
|
||||
using namespace ZL::Network;
|
||||
|
||||
namespace Config {
|
||||
@ -61,20 +57,6 @@ onceToken token([](){
|
||||
},nullptr);
|
||||
} //namespace Broadcast
|
||||
|
||||
//代理失败最大重试次数
|
||||
namespace Proxy {
|
||||
#define PROXY_FIELD "proxy."
|
||||
|
||||
#define PROXY_REPLAY_CNT (UINT64_MAX)
|
||||
const char kReplayCount[] = PROXY_FIELD"replayCount";
|
||||
|
||||
onceToken token([](){
|
||||
mINI::Instance()[kReplayCount] = PROXY_REPLAY_CNT;
|
||||
},nullptr);
|
||||
|
||||
}//namespace Proxy
|
||||
|
||||
|
||||
////////////HTTP配置///////////
|
||||
namespace Http {
|
||||
#define HTTP_FIELD "http."
|
||||
|
@ -104,12 +104,6 @@ extern const char kBroadcastFlowReport[];
|
||||
extern const char kFlowThreshold[];
|
||||
} //namespace Broadcast
|
||||
|
||||
//代理失败最大重试次数
|
||||
namespace Proxy {
|
||||
extern const char kReplayCount[];
|
||||
}//namespace Proxy
|
||||
|
||||
|
||||
////////////HTTP配置///////////
|
||||
namespace Http {
|
||||
extern const char kPort[];
|
||||
|
@ -36,8 +36,13 @@ using namespace ZL::Util;
|
||||
namespace ZL {
|
||||
namespace DEV {
|
||||
|
||||
DevChannel::DevChannel(const char *strVhost,const char *strApp, const char *strId,float fDuration,bool bLiveStream ) :
|
||||
RtspToRtmpMediaSource(strVhost,strApp,strId , bLiveStream) {
|
||||
DevChannel::DevChannel(const char *strVhost,
|
||||
const char *strApp,
|
||||
const char *strId,
|
||||
float fDuration,
|
||||
bool bEanbleHls,
|
||||
bool bEnableMp4 ) :
|
||||
RtspToRtmpMediaSource(strVhost,strApp,strId,bEanbleHls,bEnableMp4) {
|
||||
|
||||
m_strSdp = "v=0\r\n";
|
||||
m_strSdp += "o=- 1383190487994921 1 IN IP4 0.0.0.0\r\n";
|
||||
@ -46,7 +51,7 @@ DevChannel::DevChannel(const char *strVhost,const char *strApp, const char *strI
|
||||
m_strSdp += "c=IN IP4 0.0.0.0\r\n";
|
||||
m_strSdp += "t=0 0\r\n";
|
||||
//直播,时间长度永远
|
||||
if(fDuration <= 0 || bLiveStream){
|
||||
if(fDuration <= 0){
|
||||
m_strSdp += "a=range:npt=0-\r\n";
|
||||
}else{
|
||||
m_strSdp += StrPrinter <<"a=range:npt=0-" << fDuration << "\r\n" << endl;
|
||||
@ -56,9 +61,9 @@ DevChannel::DevChannel(const char *strVhost,const char *strApp, const char *strI
|
||||
DevChannel::~DevChannel() {
|
||||
}
|
||||
|
||||
#ifdef ENABLE_X264
|
||||
void DevChannel::inputYUV(char* apcYuv[3], int aiYuvLen[3], uint32_t uiStamp) {
|
||||
//TimeTicker1(50);
|
||||
#ifdef ENABLE_X264
|
||||
if (!m_pH264Enc) {
|
||||
m_pH264Enc.reset(new H264Encoder());
|
||||
if (!m_pH264Enc->init(m_video->iWidth, m_video->iHeight, m_video->iFrameRate)) {
|
||||
@ -73,13 +78,11 @@ void DevChannel::inputYUV(char* apcYuv[3], int aiYuvLen[3], uint32_t uiStamp) {
|
||||
inputH264((char *) pOut[i].pucData, pOut[i].iLength, uiStamp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ErrorL << "libx264 was not enabled!";
|
||||
#endif //ENABLE_X264
|
||||
}
|
||||
#endif //ENABLE_X264
|
||||
|
||||
void DevChannel::inputPCM(char* pcData, int iDataLen, uint32_t uiStamp) {
|
||||
#ifdef ENABLE_FAAC
|
||||
void DevChannel::inputPCM(char* pcData, int iDataLen, uint32_t uiStamp) {
|
||||
if (!m_pAacEnc) {
|
||||
m_pAacEnc.reset(new AACEncoder());
|
||||
if (!m_pAacEnc->init(m_audio->iSampleRate, m_audio->iChannel, m_audio->iSampleBit)) {
|
||||
@ -94,10 +97,8 @@ void DevChannel::inputPCM(char* pcData, int iDataLen, uint32_t uiStamp) {
|
||||
inputAAC((char *) pucOut, iRet, uiStamp);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ErrorL << "libfaac was not enabled!";
|
||||
#endif //ENABLE_FAAC
|
||||
}
|
||||
#endif //ENABLE_FAAC
|
||||
|
||||
void DevChannel::inputH264(char* pcData, int iDataLen, uint32_t uiStamp) {
|
||||
if (!m_pRtpMaker_h264) {
|
||||
|
@ -69,18 +69,30 @@ public:
|
||||
class DevChannel : public RtspToRtmpMediaSource{
|
||||
public:
|
||||
typedef std::shared_ptr<DevChannel> Ptr;
|
||||
DevChannel(const char *strVhost,const char *strApp, const char *strId,float fDuration = 0,bool bLiveStream = true);
|
||||
//fDuration<=0为直播,否则为点播
|
||||
DevChannel(const char *strVhost,
|
||||
const char *strApp,
|
||||
const char *strId,
|
||||
float fDuration = 0,
|
||||
bool bEanbleHls = true,
|
||||
bool bEnableMp4 = false);
|
||||
virtual ~DevChannel();
|
||||
|
||||
void initVideo(const VideoInfo &info);
|
||||
void initAudio(const AudioInfo &info);
|
||||
|
||||
void inputYUV(char *apcYuv[3], int aiYuvLen[3], uint32_t uiStamp);
|
||||
void inputPCM(char *pcData, int iDataLen, uint32_t uiStamp);
|
||||
|
||||
void inputH264(char *pcData, int iDataLen, uint32_t uiStamp);
|
||||
void inputAAC(char *pcDataWithAdts, int iDataLen, uint32_t uiStamp);
|
||||
void inputAAC(char *pcDataWithoutAdts,int iDataLen, uint32_t uiStamp,char *pcAdtsHeader);
|
||||
|
||||
#ifdef ENABLE_X264
|
||||
void inputYUV(char *apcYuv[3], int aiYuvLen[3], uint32_t uiStamp);
|
||||
#endif //ENABLE_X264
|
||||
|
||||
#ifdef ENABLE_FAAC
|
||||
void inputPCM(char *pcData, int iDataLen, uint32_t uiStamp);
|
||||
#endif //ENABLE_FAAC
|
||||
|
||||
private:
|
||||
inline void makeSDP_264(unsigned char *pucData, int iDataLen);
|
||||
inline void makeSDP_AAC(unsigned char *pucData);
|
||||
|
@ -37,15 +37,20 @@ using namespace ZL::Thread;
|
||||
namespace ZL {
|
||||
namespace DEV {
|
||||
|
||||
const char PlayerProxy::kAliveSecond[] = "alive_second";
|
||||
|
||||
PlayerProxy::PlayerProxy(const char *strVhost,const char *strApp,const char *strSrc){
|
||||
PlayerProxy::PlayerProxy(const char *strVhost,
|
||||
const char *strApp,
|
||||
const char *strSrc,
|
||||
bool bEnableHls,
|
||||
bool bEnableMp4,
|
||||
int iRetryCount){
|
||||
m_strVhost = strVhost;
|
||||
m_strApp = strApp;
|
||||
m_strSrc = strSrc;
|
||||
m_bEnableHls = bEnableHls;
|
||||
m_bEnableMp4 = bEnableMp4;
|
||||
m_iRetryCount = iRetryCount;
|
||||
}
|
||||
void PlayerProxy::play(const char* strUrl) {
|
||||
m_aliveSecond = (*this)[kAliveSecond];
|
||||
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
||||
setOnVideoCB( [weakSelf](const H264Frame &data ) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
@ -57,7 +62,6 @@ void PlayerProxy::play(const char* strUrl) {
|
||||
}else{
|
||||
strongSelf->initMedia();
|
||||
}
|
||||
strongSelf->checkExpired();
|
||||
});
|
||||
setOnAudioCB( [weakSelf](const AdtsFrame &data ) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
@ -69,25 +73,21 @@ void PlayerProxy::play(const char* strUrl) {
|
||||
}else{
|
||||
strongSelf->initMedia();
|
||||
}
|
||||
strongSelf->checkExpired();
|
||||
});
|
||||
|
||||
std::shared_ptr<uint64_t> piFailedCnt(new uint64_t(0)); //连续播放失败次数
|
||||
std::shared_ptr<int> piFailedCnt(new int(0)); //连续播放失败次数
|
||||
string strUrlTmp(strUrl);
|
||||
setOnPlayResult([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
if(!strongSelf) {
|
||||
return;
|
||||
}
|
||||
static uint64_t replayCnt = mINI::Instance()[Config::Proxy::kReplayCount].as<uint64_t>();
|
||||
if(!err) {
|
||||
// 播放成功
|
||||
*piFailedCnt = 0;//连续播放失败次数清0
|
||||
}else if(*piFailedCnt < replayCnt) {
|
||||
}else if(*piFailedCnt < strongSelf->m_iRetryCount || strongSelf->m_iRetryCount < 0) {
|
||||
// 播放失败,延时重试播放
|
||||
strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++);
|
||||
}else{
|
||||
strongSelf->expired();
|
||||
}
|
||||
});
|
||||
setOnShutdown([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) {
|
||||
@ -99,11 +99,8 @@ void PlayerProxy::play(const char* strUrl) {
|
||||
strongSelf->m_pChn.reset();
|
||||
}
|
||||
//播放异常中断,延时重试播放
|
||||
static uint64_t replayCnt = mINI::Instance()[Config::Proxy::kReplayCount].as<uint64_t>();
|
||||
if(*piFailedCnt < replayCnt) {
|
||||
if(*piFailedCnt < strongSelf->m_iRetryCount || strongSelf->m_iRetryCount < 0) {
|
||||
strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++);
|
||||
}else{
|
||||
strongSelf->expired();
|
||||
}
|
||||
});
|
||||
MediaPlayer::play(strUrl);
|
||||
@ -113,10 +110,9 @@ PlayerProxy::~PlayerProxy() {
|
||||
auto iTaskId = reinterpret_cast<uint64_t>(this);
|
||||
AsyncTaskThread::Instance().CancelTask(iTaskId);
|
||||
}
|
||||
void PlayerProxy::rePlay(const string &strUrl,uint64_t iFailedCnt){
|
||||
checkExpired();
|
||||
void PlayerProxy::rePlay(const string &strUrl,int iFailedCnt){
|
||||
auto iTaskId = reinterpret_cast<uint64_t>(this);
|
||||
auto iDelay = MAX((uint64_t)2 * 1000, MIN(iFailedCnt * 3000,(uint64_t)60*1000));
|
||||
auto iDelay = MAX(2 * 1000, MIN(iFailedCnt * 3000,60*1000));
|
||||
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
||||
AsyncTaskThread::Instance().CancelTask(iTaskId);
|
||||
AsyncTaskThread::Instance().DoTaskDelay(iTaskId, iDelay, [weakSelf,strUrl,iFailedCnt]() {
|
||||
@ -134,7 +130,7 @@ void PlayerProxy::initMedia() {
|
||||
if (!isInited()) {
|
||||
return;
|
||||
}
|
||||
m_pChn.reset(new DevChannel(m_strVhost.data(),m_strApp.data(),m_strSrc.data(),getDuration()));
|
||||
m_pChn.reset(new DevChannel(m_strVhost.data(),m_strApp.data(),m_strSrc.data(),getDuration(),m_bEnableHls,m_bEnableMp4));
|
||||
if (containVideo()) {
|
||||
VideoInfo info;
|
||||
info.iFrameRate = getVideoFps();
|
||||
@ -151,18 +147,6 @@ void PlayerProxy::initMedia() {
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerProxy::checkExpired() {
|
||||
if(m_aliveSecond && m_aliveTicker.elapsedTime() > m_aliveSecond * 1000){
|
||||
//到期
|
||||
expired();
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerProxy::expired() {
|
||||
if(onExpired){
|
||||
onExpired();
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace Player */
|
||||
} /* namespace ZL */
|
||||
|
@ -41,28 +41,31 @@ namespace DEV {
|
||||
class PlayerProxy :public MediaPlayer, public std::enable_shared_from_this<PlayerProxy>{
|
||||
public:
|
||||
typedef std::shared_ptr<PlayerProxy> Ptr;
|
||||
//设置代理时间,0为永久,其他为代理秒数
|
||||
//设置方法:proxy[PlayerProxy::kAliveSecond] = 100;
|
||||
static const char kAliveSecond[];
|
||||
|
||||
PlayerProxy(const char *strVhost, const char *strApp, const char *strSrc);
|
||||
//如果iRetryCount<0,则一直重试播放;否则重试iRetryCount次数
|
||||
//默认一直重试
|
||||
PlayerProxy(const char *strVhost,
|
||||
const char *strApp,
|
||||
const char *strSrc,
|
||||
bool bEnableHls = true,
|
||||
bool bEnableMp4 = false,
|
||||
int iRetryCount = -1);
|
||||
|
||||
virtual ~PlayerProxy();
|
||||
|
||||
void play(const char* strUrl) override;
|
||||
void setOnExpired(const function<void()> &cb){
|
||||
onExpired = cb;
|
||||
}
|
||||
private :
|
||||
DevChannel::Ptr m_pChn;
|
||||
Ticker m_aliveTicker;
|
||||
uint32_t m_aliveSecond = 0;
|
||||
function<void()> onExpired;
|
||||
|
||||
private:
|
||||
bool m_bEnableHls;
|
||||
bool m_bEnableMp4;
|
||||
int m_iRetryCount;
|
||||
DevChannel::Ptr m_pChn;
|
||||
string m_strVhost;
|
||||
string m_strApp;
|
||||
string m_strSrc;
|
||||
private:
|
||||
void initMedia();
|
||||
void rePlay(const string &strUrl,uint64_t iFailedCnt);
|
||||
void checkExpired();
|
||||
void expired();
|
||||
void rePlay(const string &strUrl,int iFailedCnt);
|
||||
};
|
||||
|
||||
} /* namespace Player */
|
||||
|
@ -129,7 +129,7 @@ MediaReader::MediaReader(const string &strVhost,const string &strApp, const stri
|
||||
}
|
||||
|
||||
m_iDuration = MAX(m_video_ms,m_audio_ms);
|
||||
m_pChn.reset(new DevChannel(strVhost.data(),strApp.data(),strId.data(),m_iDuration/1000.0,false));
|
||||
m_pChn.reset(new DevChannel(strVhost.data(),strApp.data(),strId.data(),m_iDuration/1000.0,true, false));
|
||||
if (m_audio_trId != MP4_INVALID_TRACK_ID) {
|
||||
AudioInfo info;
|
||||
info.iChannel = m_audio_num_channels;
|
||||
|
@ -37,7 +37,13 @@ using namespace ZL::Network;
|
||||
namespace ZL {
|
||||
namespace MediaFile {
|
||||
|
||||
MediaRecorder::MediaRecorder(const string &strVhost ,const string &strApp,const string &strId,const std::shared_ptr<PlayerBase> &pPlayer) {
|
||||
MediaRecorder::MediaRecorder(const string &strVhost_tmp,
|
||||
const string &strApp,
|
||||
const string &strId,
|
||||
const std::shared_ptr<PlayerBase> &pPlayer,
|
||||
bool enableHls,
|
||||
bool enableMp4) {
|
||||
|
||||
static string hlsPrefix = mINI::Instance()[Config::Hls::kHttpPrefix];
|
||||
static string hlsPrefixDefaultVhost = mINI::Instance()[Config::Hls::kHttpPrefixDefaultVhost];
|
||||
static string hlsPath = mINI::Instance()[Config::Hls::kFilePath];
|
||||
@ -45,31 +51,41 @@ MediaRecorder::MediaRecorder(const string &strVhost ,const string &strApp,const
|
||||
static uint32_t hlsDuration = mINI::Instance()[Config::Hls::kSegmentDuration].as<uint32_t>();
|
||||
static uint32_t hlsNum = mINI::Instance()[Config::Hls::kSegmentNum].as<uint32_t>();
|
||||
|
||||
string hlsPrefixVhost = hlsPrefix;
|
||||
do{
|
||||
//生成hls http前缀
|
||||
if (strVhost.empty() || strVhost == DEFAULT_VHOST) {
|
||||
hlsPrefixVhost = hlsPrefixDefaultVhost;
|
||||
break;
|
||||
}
|
||||
auto pos_start = hlsPrefixVhost.find("${");
|
||||
auto pos_end = hlsPrefixVhost.find("}");
|
||||
if (pos_start != string::npos && pos_end != string::npos && pos_end - pos_start - 2 > 0 ) {
|
||||
auto key = hlsPrefixVhost.substr(pos_start + 2, pos_end - pos_start - 2);
|
||||
trim(key);
|
||||
if (key == VHOST_KEY) {
|
||||
hlsPrefixVhost.replace(pos_start, pos_end - pos_start + 1, strVhost);
|
||||
}
|
||||
}
|
||||
}while(0);
|
||||
m_hlsMaker.reset(new HLSMaker(hlsPath + "/" + strVhost + "/" + strApp + "/" + strId + "/hls.m3u8",
|
||||
hlsPrefixVhost + "/" + strApp + "/" + strId + "/",
|
||||
hlsBufSize,hlsDuration,hlsNum));
|
||||
string strVhost = strVhost_tmp;
|
||||
if(trim(strVhost).empty()){
|
||||
//如果strVhost为空,则强制为默认虚拟主机
|
||||
strVhost = DEFAULT_VHOST;
|
||||
}
|
||||
|
||||
if(enableHls) {
|
||||
string hlsPrefixVhost = hlsPrefix;
|
||||
do {
|
||||
//生成hls http前缀
|
||||
if (strVhost == DEFAULT_VHOST) {
|
||||
hlsPrefixVhost = hlsPrefixDefaultVhost;
|
||||
break;
|
||||
}
|
||||
auto pos_start = hlsPrefixVhost.find("${");
|
||||
auto pos_end = hlsPrefixVhost.find("}");
|
||||
if (pos_start != string::npos && pos_end != string::npos && pos_end - pos_start - 2 > 0) {
|
||||
auto key = hlsPrefixVhost.substr(pos_start + 2, pos_end - pos_start - 2);
|
||||
trim(key);
|
||||
if (key == VHOST_KEY) {
|
||||
hlsPrefixVhost.replace(pos_start, pos_end - pos_start + 1, strVhost);
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
m_hlsMaker.reset(new HLSMaker(hlsPath + "/" + strVhost + "/" + strApp + "/" + strId + "/hls.m3u8",
|
||||
hlsPrefixVhost + "/" + strApp + "/" + strId + "/",
|
||||
hlsBufSize, hlsDuration, hlsNum));
|
||||
}
|
||||
#ifdef ENABLE_MP4V2
|
||||
static string recordPath = mINI::Instance()[Config::Record::kFilePath];
|
||||
static string recordAppName = mINI::Instance()[Config::Record::kAppName];
|
||||
m_mp4Maker.reset(new Mp4Maker(recordPath + "/" + strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/",
|
||||
strVhost,strApp,strId,pPlayer));
|
||||
if(enableMp4){
|
||||
m_mp4Maker.reset(new Mp4Maker(recordPath + "/" + strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/",
|
||||
strVhost,strApp,strId,pPlayer));
|
||||
}
|
||||
#endif //ENABLE_MP4V2
|
||||
}
|
||||
|
||||
@ -77,16 +93,24 @@ MediaRecorder::~MediaRecorder() {
|
||||
}
|
||||
|
||||
void MediaRecorder::inputH264(void* pData, uint32_t ui32Length, uint32_t ui32TimeStamp, int iType) {
|
||||
m_hlsMaker->inputH264(pData, ui32Length, ui32TimeStamp * 90, iType);
|
||||
if(m_hlsMaker){
|
||||
m_hlsMaker->inputH264(pData, ui32Length, ui32TimeStamp * 90, iType);
|
||||
}
|
||||
#ifdef ENABLE_MP4V2
|
||||
m_mp4Maker->inputH264(pData, ui32Length, ui32TimeStamp, iType);
|
||||
if(m_mp4Maker){
|
||||
m_mp4Maker->inputH264(pData, ui32Length, ui32TimeStamp, iType);
|
||||
}
|
||||
#endif //ENABLE_MP4V2
|
||||
}
|
||||
|
||||
void MediaRecorder::inputAAC(void* pData, uint32_t ui32Length, uint32_t ui32TimeStamp) {
|
||||
m_hlsMaker->inputAAC(pData, ui32Length, ui32TimeStamp * 90);
|
||||
if(m_hlsMaker){
|
||||
m_hlsMaker->inputAAC(pData, ui32Length, ui32TimeStamp * 90);
|
||||
}
|
||||
#ifdef ENABLE_MP4V2
|
||||
m_mp4Maker->inputAAC(pData, ui32Length, ui32TimeStamp);
|
||||
if(m_mp4Maker){
|
||||
m_mp4Maker->inputAAC(pData, ui32Length, ui32TimeStamp);
|
||||
}
|
||||
#endif //ENABLE_MP4V2
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,12 @@ namespace MediaFile {
|
||||
class MediaRecorder {
|
||||
public:
|
||||
typedef std::shared_ptr<MediaRecorder> Ptr;
|
||||
MediaRecorder(const string &strVhost,const string &strApp,const string &strId,const std::shared_ptr<PlayerBase> &pPlayer);
|
||||
MediaRecorder(const string &strVhost,
|
||||
const string &strApp,
|
||||
const string &strId,
|
||||
const std::shared_ptr<PlayerBase> &pPlayer,
|
||||
bool m_enableHls = true,
|
||||
bool m_enableMp4 = false);
|
||||
virtual ~MediaRecorder();
|
||||
|
||||
void inputH264( void *pData,
|
||||
|
@ -36,8 +36,12 @@ using namespace ZL::Network;
|
||||
namespace ZL {
|
||||
namespace Rtmp {
|
||||
|
||||
RtmpToRtspMediaSource::RtmpToRtspMediaSource(const string &vhost,const string &app, const string &id) :
|
||||
RtmpMediaSource(vhost,app,id) {
|
||||
RtmpToRtspMediaSource::RtmpToRtspMediaSource(const string &vhost,
|
||||
const string &app,
|
||||
const string &id,
|
||||
bool bEnableHls,
|
||||
bool bEnableMp4) :
|
||||
RtmpMediaSource(vhost,app,id),m_bEnableHls(bEnableHls),m_bEnableMp4(bEnableMp4) {
|
||||
}
|
||||
RtmpToRtspMediaSource::~RtmpToRtspMediaSource() {}
|
||||
|
||||
@ -56,14 +60,18 @@ bool RtmpToRtspMediaSource::unregist() {
|
||||
}
|
||||
|
||||
void RtmpToRtspMediaSource::onGetH264(const H264Frame &frame) {
|
||||
m_pRecorder->inputH264((char *) frame.data.data(), frame.data.size(), frame.timeStamp, frame.type);
|
||||
if(m_pRecorder){
|
||||
m_pRecorder->inputH264((char *) frame.data.data(), frame.data.size(), frame.timeStamp, frame.type);
|
||||
}
|
||||
|
||||
if(m_pRtpMaker_h264){
|
||||
m_pRtpMaker_h264->makeRtp(frame.data.data() + 4, frame.data.size() - 4, frame.timeStamp);
|
||||
}
|
||||
}
|
||||
inline void RtmpToRtspMediaSource::onGetAdts(const AdtsFrame &frame) {
|
||||
m_pRecorder->inputAAC((char *) frame.data, frame.aac_frame_length, frame.timeStamp);
|
||||
if(m_pRecorder){
|
||||
m_pRecorder->inputAAC((char *) frame.data, frame.aac_frame_length, frame.timeStamp);
|
||||
}
|
||||
|
||||
if (m_pRtpMaker_aac) {
|
||||
m_pRtpMaker_aac->makeRtp((char *) frame.data + 7, frame.aac_frame_length - 7, frame.timeStamp);
|
||||
|
@ -56,7 +56,11 @@ class RtmpToRtspMediaSource: public RtmpMediaSource {
|
||||
public:
|
||||
typedef std::shared_ptr<RtmpToRtspMediaSource> Ptr;
|
||||
|
||||
RtmpToRtspMediaSource(const string &vhost,const string &app, const string &id);
|
||||
RtmpToRtspMediaSource(const string &vhost,
|
||||
const string &app,
|
||||
const string &id,
|
||||
bool bEnableHls = true,
|
||||
bool bEnableMp4 = false);
|
||||
virtual ~RtmpToRtspMediaSource();
|
||||
|
||||
bool regist() override;
|
||||
@ -65,7 +69,7 @@ public:
|
||||
void onGetMetaData(const AMFValue &_metadata) override {
|
||||
try {
|
||||
m_pParser.reset(new RtmpParser(_metadata));
|
||||
m_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),m_pParser));
|
||||
m_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),m_pParser,m_bEnableHls,m_bEnableMp4));
|
||||
m_pParser->setOnAudioCB(std::bind(&RtmpToRtspMediaSource::onGetAdts, this, placeholders::_1));
|
||||
m_pParser->setOnVideoCB(std::bind(&RtmpToRtspMediaSource::onGetH264, this, placeholders::_1));
|
||||
} catch (exception &ex) {
|
||||
@ -90,7 +94,8 @@ private:
|
||||
RtpMaker_AAC::Ptr m_pRtpMaker_aac;
|
||||
RtpMaker_H264::Ptr m_pRtpMaker_h264;
|
||||
MediaRecorder::Ptr m_pRecorder;
|
||||
|
||||
bool m_bEnableHls;
|
||||
bool m_bEnableMp4;
|
||||
void onGetH264(const H264Frame &frame);
|
||||
void onGetAdts(const AdtsFrame &frame);
|
||||
void makeSDP();
|
||||
|
@ -38,8 +38,12 @@ namespace ZL {
|
||||
namespace Rtsp {
|
||||
|
||||
|
||||
RtspToRtmpMediaSource::RtspToRtmpMediaSource(const string &vhost,const string &app,const string &id,bool bEnableFile) :
|
||||
RtspMediaSource(vhost,app,id),m_bEnableFile(bEnableFile) {
|
||||
RtspToRtmpMediaSource::RtspToRtmpMediaSource(const string &vhost,
|
||||
const string &app,
|
||||
const string &id,
|
||||
bool bEnableHls,
|
||||
bool bEnableMp4) :
|
||||
RtspMediaSource(vhost,app,id),m_bEnableHls(bEnableHls),m_bEnableMp4(bEnableMp4) {
|
||||
}
|
||||
|
||||
RtspToRtmpMediaSource::~RtspToRtmpMediaSource() {
|
||||
|
@ -41,15 +41,19 @@ namespace Rtsp {
|
||||
class RtspToRtmpMediaSource: public RtspMediaSource {
|
||||
public:
|
||||
typedef std::shared_ptr<RtspToRtmpMediaSource> Ptr;
|
||||
RtspToRtmpMediaSource(const string &vhost,const string &app,const string &id,bool bEnableFile = true);
|
||||
|
||||
RtspToRtmpMediaSource(const string &vhost,
|
||||
const string &app,
|
||||
const string &id,
|
||||
bool bEnableHls = true,
|
||||
bool bEnableMp4 = true);
|
||||
|
||||
virtual ~RtspToRtmpMediaSource();
|
||||
|
||||
virtual void onGetSDP(const string& strSdp) override{
|
||||
try {
|
||||
m_pParser.reset(new RtpParser(strSdp));
|
||||
if(m_bEnableFile){
|
||||
m_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),m_pParser));
|
||||
}
|
||||
m_pRecorder.reset(new MediaRecorder(getVhost(),getApp(),getId(),m_pParser,m_bEnableHls,m_bEnableMp4));
|
||||
m_pParser->setOnAudioCB( std::bind(&RtspToRtmpMediaSource::onGetAdts, this, placeholders::_1));
|
||||
m_pParser->setOnVideoCB( std::bind(&RtspToRtmpMediaSource::onGetH264, this, placeholders::_1));
|
||||
makeMetaData();
|
||||
@ -92,8 +96,9 @@ private:
|
||||
RtmpMediaSource::Ptr m_pRtmpSrc;
|
||||
uint8_t m_ui8AudioFlags = 0;
|
||||
MediaRecorder::Ptr m_pRecorder;
|
||||
bool m_bEnableFile = true;
|
||||
void onGetH264(const H264Frame &frame);
|
||||
bool m_bEnableHls;
|
||||
bool m_bEnableMp4;
|
||||
void onGetH264(const H264Frame &frame);
|
||||
void onGetAdts(const AdtsFrame &frame);
|
||||
void makeVideoConfigPkt();
|
||||
void makeAudioConfigPkt();
|
||||
|
@ -112,16 +112,16 @@ static onceToken s_token([](){
|
||||
NoticeCenter::Instance().addListener(nullptr,Config::Broadcast::kBroadcastRtmpPublish,[](BroadcastRtmpPublishArgs){
|
||||
InfoL << args.m_vhost << " " << args.m_app << " " << args.m_streamid << " " << args.m_param_strs ;
|
||||
EventPoller::Instance().async([invoker](){
|
||||
//invoker(true,"");//鉴权成功
|
||||
invoker(false,"this is auth failed message");//鉴权失败
|
||||
//invoker("");//鉴权成功
|
||||
invoker("this is auth failed message");//鉴权失败
|
||||
});
|
||||
});
|
||||
|
||||
NoticeCenter::Instance().addListener(nullptr,Config::Broadcast::kBroadcastMediaPlayed,[](BroadcastMediaPlayedArgs){
|
||||
InfoL << args.m_schema << " " << args.m_vhost << " " << args.m_app << " " << args.m_streamid << " " << args.m_param_strs ;
|
||||
EventPoller::Instance().async([invoker](){
|
||||
//invoker(true,"");//鉴权成功
|
||||
invoker(false,"this is auth failed message");//鉴权失败
|
||||
//invoker("");//鉴权成功
|
||||
invoker("this is auth failed message");//鉴权失败
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user