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