mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-14 12:05:58 +08:00
修改文件录制、hls生成、拉流代理逻辑
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user