diff --git a/src/Device/PlayerProxy.cpp b/src/Device/PlayerProxy.cpp index 3a37b56f..79330273 100644 --- a/src/Device/PlayerProxy.cpp +++ b/src/Device/PlayerProxy.cpp @@ -18,21 +18,16 @@ using namespace ZL::Thread; namespace ZL { namespace DEV { +const char PlayerProxy::kAliveSecond[] = "alive_second"; + PlayerProxy::PlayerProxy(const char *strApp,const char *strSrc){ m_strApp = strApp; m_strSrc = strSrc; } - -void PlayerProxy::play(const char* strUrl, const char *strUser, - const char *strPwd, PlayerBase::eRtpType eType, uint32_t iSecond) { - m_aliveSecond = iSecond; - string strUrlTmp(strUrl); - string strUserTmp(strUser); - string strPwdTmp(strPwd); - - m_pPlayer.reset(new MediaPlayer()); +void PlayerProxy::play(const char* strUrl) { + m_aliveSecond = (*this)[kAliveSecond]; weak_ptr weakSelf = shared_from_this(); - m_pPlayer->setOnVideoCB( [weakSelf,strUrlTmp](const H264Frame &data ) { + setOnVideoCB( [weakSelf](const H264Frame &data ) { auto strongSelf = weakSelf.lock(); if(!strongSelf){ return; @@ -44,7 +39,7 @@ void PlayerProxy::play(const char* strUrl, const char *strUser, } strongSelf->checkExpired(); }); - m_pPlayer->setOnAudioCB( [weakSelf,strUrlTmp](const AdtsFrame &data ) { + setOnAudioCB( [weakSelf](const AdtsFrame &data ) { auto strongSelf = weakSelf.lock(); if(!strongSelf){ return; @@ -58,7 +53,8 @@ void PlayerProxy::play(const char* strUrl, const char *strUser, }); std::shared_ptr piFailedCnt(new uint64_t(0)); //连续播放失败次数 - m_pPlayer->setOnPlayResult([weakSelf,strUrlTmp,strUserTmp,strPwdTmp,eType,piFailedCnt](const SockException &err) { + string strUrlTmp(strUrl); + setOnPlayResult([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) { auto strongSelf = weakSelf.lock(); if(!strongSelf) { return; @@ -69,13 +65,12 @@ void PlayerProxy::play(const char* strUrl, const char *strUser, *piFailedCnt = 0;//连续播放失败次数清0 }else if(*piFailedCnt < replayCnt) { // 播放失败,延时重试播放 - strongSelf->rePlay(strUrlTmp, strUserTmp, strPwdTmp, eType,(*piFailedCnt)++); + strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++); }else{ strongSelf->expired(); } }); - weak_ptr weakPtr= m_pPlayer; - m_pPlayer->setOnShutdown([weakSelf,weakPtr,strUrlTmp,strUserTmp,strPwdTmp,eType,piFailedCnt](const SockException &err) { + setOnShutdown([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) { auto strongSelf = weakSelf.lock(); if(!strongSelf) { return; @@ -86,52 +81,52 @@ void PlayerProxy::play(const char* strUrl, const char *strUser, //播放异常中断,延时重试播放 static uint64_t replayCnt = mINI::Instance()[Config::Proxy::kReplayCount].as(); if(*piFailedCnt < replayCnt) { - strongSelf->rePlay(strUrlTmp, strUserTmp, strPwdTmp, eType,(*piFailedCnt)++); + strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++); }else{ strongSelf->expired(); } }); - m_pPlayer->play(strUrl, strUser, strPwd, eType); + MediaPlayer::play(strUrl); } PlayerProxy::~PlayerProxy() { auto iTaskId = reinterpret_cast(this); AsyncTaskThread::Instance().CancelTask(iTaskId); } -void PlayerProxy::rePlay(const string &strUrl, const string &strUser, const string &strPwd, PlayerBase::eRtpType eType, uint64_t iFailedCnt){ +void PlayerProxy::rePlay(const string &strUrl,uint64_t iFailedCnt){ checkExpired(); auto iTaskId = reinterpret_cast(this); auto iDelay = MAX((uint64_t)2 * 1000, MIN(iFailedCnt * 3000,(uint64_t)60*1000)); - weak_ptr weakPtr = m_pPlayer; + weak_ptr weakSelf = shared_from_this(); AsyncTaskThread::Instance().CancelTask(iTaskId); - AsyncTaskThread::Instance().DoTaskDelay(iTaskId, iDelay, [weakPtr,strUrl,strUser,strPwd,eType,iFailedCnt]() { + AsyncTaskThread::Instance().DoTaskDelay(iTaskId, iDelay, [weakSelf,strUrl,iFailedCnt]() { //播放失败次数越多,则延时越长 - auto strongPlayer = weakPtr.lock(); + auto strongPlayer = weakSelf.lock(); if(!strongPlayer) { return false; } WarnL << "重试播放[" << iFailedCnt << "]:" << strUrl; - strongPlayer->play(strUrl.data(), strUser.data(), strPwd.data(), eType); + strongPlayer->MediaPlayer::play(strUrl.data()); return false; }); } void PlayerProxy::initMedia() { - if (!m_pPlayer->isInited()) { + if (!isInited()) { return; } - m_pChn.reset(new DevChannel(m_strApp.data(),m_strSrc.data(),m_pPlayer->getDuration())); - if (m_pPlayer->containVideo()) { + m_pChn.reset(new DevChannel(m_strApp.data(),m_strSrc.data(),getDuration())); + if (containVideo()) { VideoInfo info; - info.iFrameRate = m_pPlayer->getVideoFps(); - info.iWidth = m_pPlayer->getVideoWidth(); - info.iHeight = m_pPlayer->getVideoHeight(); + info.iFrameRate = getVideoFps(); + info.iWidth = getVideoWidth(); + info.iHeight = getVideoHeight(); m_pChn->initVideo(info); } - if (m_pPlayer->containAudio()) { + if (containAudio()) { AudioInfo info; - info.iSampleRate = m_pPlayer->getAudioSampleRate(); - info.iChannel = m_pPlayer->getAudioChannel(); - info.iSampleBit = m_pPlayer->getAudioSampleBit(); + info.iSampleRate = getAudioSampleRate(); + info.iChannel = getAudioChannel(); + info.iSampleBit = getAudioSampleBit(); m_pChn->initAudio(info); } } diff --git a/src/Device/PlayerProxy.h b/src/Device/PlayerProxy.h index 7a29b3b0..a05b3faa 100644 --- a/src/Device/PlayerProxy.h +++ b/src/Device/PlayerProxy.h @@ -19,17 +19,20 @@ using namespace ZL::Player; namespace ZL { namespace DEV { -class PlayerProxy : public std::enable_shared_from_this{ +class PlayerProxy :public MediaPlayer, public std::enable_shared_from_this{ public: typedef std::shared_ptr Ptr; + //设置代理时间,0为永久,其他为代理秒数 + //设置方法:proxy[PlayerProxy::kAliveSecond] = 100; + static const char kAliveSecond[]; + PlayerProxy(const char *strApp, const char *strSrc); - void play(const char* strUrl, const char *strUser = "", const char *strPwd = "",PlayerBase::eRtpType eType = PlayerBase::RTP_TCP,uint32_t iSecond = 0); virtual ~PlayerProxy(); + void play(const char* strUrl) override; void setOnExpired(const function &cb){ onExpired = cb; } private : - MediaPlayer::Ptr m_pPlayer; DevChannel::Ptr m_pChn; Ticker m_aliveTicker; uint32_t m_aliveSecond = 0; @@ -37,7 +40,7 @@ private : string m_strApp; string m_strSrc; void initMedia(); - void rePlay(const string &strUrl, const string &strUser, const string &strPwd, PlayerBase::eRtpType eType,uint64_t iFailedCnt); + void rePlay(const string &strUrl,uint64_t iFailedCnt); void checkExpired(); void expired(); }; diff --git a/src/Player/MediaPlayer.cpp b/src/Player/MediaPlayer.cpp index 443c00da..6361f5a1 100644 --- a/src/Player/MediaPlayer.cpp +++ b/src/Player/MediaPlayer.cpp @@ -22,8 +22,7 @@ MediaPlayer::MediaPlayer() { MediaPlayer::~MediaPlayer() { teardown(); } - -void MediaPlayer::play(const char* strUrl, const char* strUser, const char* strPwd, eRtpType eType) { +void MediaPlayer::play(const char* strUrl) { string strPrefix = FindField(strUrl, NULL, "://"); if ((strcasecmp(m_strPrefix.data(),strPrefix.data()) != 0) || strPrefix.empty()) { //协议切换 @@ -34,9 +33,11 @@ void MediaPlayer::play(const char* strUrl, const char* strUser, const char* strP m_parser->setOnAudioCB(m_onGetAudioCB); } m_parser->setOnPlayResult(m_playResultCB); - m_parser->play(strUrl, strUser, strPwd, eType); + m_parser->mINI::operator=(*this); + m_parser->play(strUrl); } + void MediaPlayer::pause(bool bPause) { if (m_parser) { m_parser->pause(bPause); diff --git a/src/Player/MediaPlayer.h b/src/Player/MediaPlayer.h index 4039ccc9..657dafa0 100644 --- a/src/Player/MediaPlayer.h +++ b/src/Player/MediaPlayer.h @@ -12,8 +12,12 @@ #include #include "Player.h" #include "PlayerBase.h" +#include "Rtsp/RtspPlayer.h" +#include "Rtmp/RtmpPlayer.h" using namespace std; +using namespace ZL::Rtsp; +using namespace ZL::Rtmp; namespace ZL { namespace Player { @@ -24,8 +28,7 @@ public: MediaPlayer(); virtual ~MediaPlayer(); - - void play(const char* strUrl, const char *strUser = "", const char *strPwd = "", eRtpType eType = RTP_TCP) override; + void play(const char* strUrl) override; void pause(bool bPause) override; void teardown() override; private: diff --git a/src/Player/PlayerBase.h b/src/Player/PlayerBase.h index 9aa8f316..f68cfd0e 100644 --- a/src/Player/PlayerBase.h +++ b/src/Player/PlayerBase.h @@ -8,19 +8,22 @@ #ifndef SRC_PLAYER_PLAYERBASE_H_ #define SRC_PLAYER_PLAYERBASE_H_ +#include #include #include #include #include "Player.h" #include "Network/Socket.h" +#include "Util/mini.h" using namespace std; +using namespace ZL::Util; using namespace ZL::Network; namespace ZL { namespace Player { -class PlayerBase{ +class PlayerBase : public mINI{ public: typedef std::shared_ptr Ptr; typedef enum { @@ -32,8 +35,7 @@ public: PlayerBase(){}; virtual ~PlayerBase(){}; - - virtual void play(const char* strUrl, const char *strUser = "", const char *strPwd = "", eRtpType eType = RTP_TCP) {}; + virtual void play(const char* strUrl) {}; virtual void pause(bool bPause) {}; virtual void teardown() {}; diff --git a/src/Rtmp/RtmpPlayer.cpp b/src/Rtmp/RtmpPlayer.cpp index 5566c1d1..c4fa7e61 100644 --- a/src/Rtmp/RtmpPlayer.cpp +++ b/src/Rtmp/RtmpPlayer.cpp @@ -52,12 +52,12 @@ void RtmpPlayer::teardown() { m_fSeekTo = 0; CLEAR_ARR(m_adFistStamp); CLEAR_ARR(m_adNowStamp); - clear(); + reset(); shutdown(); } } -void RtmpPlayer::play(const char* strUrl, const char * , const char *, eRtpType) { +void RtmpPlayer::play(const char* strUrl) { teardown(); string strHost = FindField(strUrl, "://", "/"); m_strApp = FindField(strUrl, (strHost + "/").data(), "/"); diff --git a/src/Rtmp/RtmpPlayer.h b/src/Rtmp/RtmpPlayer.h index bed5a590..7012991b 100644 --- a/src/Rtmp/RtmpPlayer.h +++ b/src/Rtmp/RtmpPlayer.h @@ -36,8 +36,7 @@ public: RtmpPlayer(); virtual ~RtmpPlayer(); - void play(const char* strUrl, const char *strUser, const char *strPwd, - eRtpType eType) override; + void play(const char* strUrl) override; void pause(bool bPause) override; void teardown() override; protected: diff --git a/src/Rtmp/RtmpProtocol.cpp b/src/Rtmp/RtmpProtocol.cpp index 8fbda69f..a85a4a1d 100644 --- a/src/Rtmp/RtmpProtocol.cpp +++ b/src/Rtmp/RtmpProtocol.cpp @@ -48,9 +48,9 @@ RtmpProtocol::RtmpProtocol() { }; } RtmpProtocol::~RtmpProtocol() { - clear(); + reset(); } -void RtmpProtocol::clear() { +void RtmpProtocol::reset() { ////////////ChunkSize//////////// m_iChunkLenIn = DEFAULT_CHUNK_LEN; m_iChunkLenOut = DEFAULT_CHUNK_LEN; diff --git a/src/Rtmp/RtmpProtocol.h b/src/Rtmp/RtmpProtocol.h index e33da1e8..d995e442 100644 --- a/src/Rtmp/RtmpProtocol.h +++ b/src/Rtmp/RtmpProtocol.h @@ -33,7 +33,7 @@ public: //作为客户端发送c0c1,等待s0s1s2并且回调 void startClientSession(const function &cb); void onParseRtmp(const char *pcRawData,int iSize); - void clear(); + void reset(); protected: virtual void onSendRawData(const char *pcRawData,int iSize) = 0; virtual void onRtmpChunk(RtmpPacket &chunkData) = 0; diff --git a/src/Rtmp/RtmpPusher.cpp b/src/Rtmp/RtmpPusher.cpp index dc63bebf..9146e028 100644 --- a/src/Rtmp/RtmpPusher.cpp +++ b/src/Rtmp/RtmpPusher.cpp @@ -50,7 +50,7 @@ void RtmpPusher::teardown() { m_dqOnStatusCB.clear(); } m_pPublishTimer.reset(); - clear(); + reset(); shutdown(); } } diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index 359a1d72..19738d79 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -22,6 +22,8 @@ namespace Rtsp { _onRecvRTP(it->second, trackidx); \ m_amapRtpSort[trackidx].erase(it); +const char RtspPlayer::kRtpType[] = "rtp_type"; + RtspPlayer::RtspPlayer(void){ } RtspPlayer::~RtspPlayer(void) { @@ -67,13 +69,34 @@ void RtspPlayer::teardown(){ shutdown(); } } + +void RtspPlayer::play(const char* strUrl){ + auto userAndPwd = FindField(strUrl,"://","@"); + eRtpType eType = (eRtpType)(int)(*this)[kRtpType]; + if(userAndPwd.empty()){ + play(strUrl,nullptr,nullptr,eType); + return; + } + auto suffix = FindField(strUrl,"@",nullptr); + auto url = StrPrinter << "rtsp://" << suffix << endl; + if(userAndPwd.find(":") == string::npos){ + play(url.data(),userAndPwd.data(),nullptr,eType); + return; + } + auto user = FindField(userAndPwd.data(),nullptr,":"); + auto pwd = FindField(userAndPwd.data(),":",nullptr); + play(url.data(),user.data(),pwd.data(),eType); +} //播放,指定是否走rtp over tcp void RtspPlayer::play(const char* strUrl, const char *strUser, const char *strPwd, eRtpType eType ) { - InfoL < Ptr; + //设置rtp传输类型,可选项有0(tcp,默认)、1(udp)、2(组播) + //设置方法:player[RtspPlayer::kRtpType] = 0/1/2; + static const char kRtpType[]; + RtspPlayer(); virtual ~RtspPlayer(void); - void play(const char* strUrl, const char *strUser, const char *strPwd, eRtpType eType) override; + void play(const char* strUrl) override; void pause(bool bPause) override; void teardown() override; float getRtpLossRate(int iTrackId) const override; @@ -84,6 +88,7 @@ private: onPlayResult(ex); } + void play(const char* strUrl, const char *strUser, const char *strPwd, eRtpType eType); void onConnect(const SockException &err) override; void onRecv(const Socket::Buffer::Ptr &pBuf) override; void onErr(const SockException &ex) override; diff --git a/tests/test_benchmark.cpp b/tests/test_benchmark.cpp index 53e2d52a..891c96ce 100644 --- a/tests/test_benchmark.cpp +++ b/tests/test_benchmark.cpp @@ -52,7 +52,8 @@ int main(int argc, char *argv[]){ player->setOnShutdown([&](const SockException &ex){ --alivePlayerCnt; }); - player->play(argv[3], "", "", (PlayerBase::eRtpType)atoi(argv[4])); + (*player)[RtspPlayer::kRtpType] = atoi(argv[4]); + player->play(argv[3]); playerList.push_back(player); return playerCnt--; }); diff --git a/tests/test_player.cpp b/tests/test_player.cpp index 173a2190..cbfa51fe 100644 --- a/tests/test_player.cpp +++ b/tests/test_player.cpp @@ -5,8 +5,8 @@ #include #include "Poller/EventPoller.h" #include "Rtsp/UDPServer.h" +#include "Player/MediaPlayer.h" #include "Util/onceToken.h" -#include "Device/PlayerProxy.h" #include "H264Decoder.h" #include "YuvDisplayer.h" #include "Network/sockutil.h" @@ -18,7 +18,7 @@ using namespace ZL::Util; using namespace ZL::Thread; using namespace ZL::Network; using namespace ZL::Rtsp; -using namespace ZL::DEV; +using namespace ZL::Player; void programExit(int arg) { EventPoller::Instance().shutdown(); @@ -30,9 +30,9 @@ int main(int argc, char *argv[]){ //Logger::Instance().setWriter(std::make_shared()); signal(SIGINT, programExit); - if(argc != 5){ - FatalL << "\r\n测试方法:./test_player rtxp_url rtsp_user rtsp_pwd rtp_type\r\n" - << "例如:./test_player rtsp://127.0.0.1/live/0 admin 123456 0\r\n" + if(argc != 3){ + FatalL << "\r\n测试方法:./test_player rtxp_url rtp_type\r\n" + << "例如:./test_player rtsp://admin:123456@127.0.0.1/live/0 0\r\n" <setOnShutdown([](const SockException &ex) { ErrorL << "OnShutdown:" << ex.what(); }); - - //DebugL << argv[1] << " " << argv[2] << " " << argv[3] << " " << argv[4] << endl; - player->play(argv[1],argv[2],argv[3],(PlayerBase::eRtpType)atoi(argv[4])); + (*player)[RtspPlayer::kRtpType] = atoi(argv[2]); + player->play(argv[1]); H264Decoder decoder; YuvDisplayer displayer; diff --git a/tests/test_server.cpp b/tests/test_server.cpp index fa66aca2..47191833 100644 --- a/tests/test_server.cpp +++ b/tests/test_server.cpp @@ -49,7 +49,7 @@ int main(int argc,char *argv[]){ //support rtmp and rtsp url //just support H264+AAC auto urlList = {"rtmp://live.hkstv.hk.lxdns.com/live/hks", - "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov"}; + "rtsp://admin:jzan123456@192.168.0.122/"}; map proxyMap; int i=0; for(auto url : urlList){ @@ -63,6 +63,7 @@ int main(int argc,char *argv[]){ //rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4 //rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4 PlayerProxy::Ptr player(new PlayerProxy("live",to_string(i++).data())); + (*player)[PlayerProxy::kAliveSecond] = 10;//录制10秒 player->play(url); proxyMap.emplace(string(url),player); }