mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-21 07:53:48 +08:00
开始修改播放器
This commit is contained in:
@@ -93,8 +93,7 @@ public:
|
||||
typedef std::shared_ptr<FrameRing> Ptr;
|
||||
|
||||
FrameRing(){
|
||||
//禁用缓存
|
||||
_frameRing = std::make_shared<RingType>(1);
|
||||
_frameRing = std::make_shared<RingType>();
|
||||
}
|
||||
virtual ~FrameRing(){}
|
||||
|
||||
|
||||
@@ -48,8 +48,9 @@ void MediaPlayer::play(const char* strUrl) {
|
||||
m_strPrefix = strPrefix;
|
||||
m_parser = PlayerBase::createPlayer(strUrl);
|
||||
m_parser->setOnShutdown(m_shutdownCB);
|
||||
m_parser->setOnVideoCB(m_onGetVideoCB);
|
||||
m_parser->setOnAudioCB(m_onGetAudioCB);
|
||||
//todo(xzl) 修复此处
|
||||
// m_parser->setOnVideoCB(m_onGetVideoCB);
|
||||
// m_parser->setOnAudioCB(m_onGetAudioCB);
|
||||
}
|
||||
m_parser->setOnPlayResult(m_playResultCB);
|
||||
m_parser->mINI::operator=(*this);
|
||||
|
||||
@@ -47,23 +47,7 @@ using namespace ZL::Network;
|
||||
namespace ZL {
|
||||
namespace Player {
|
||||
|
||||
class MediaFormat {
|
||||
public:
|
||||
virtual ~MediaFormat(){};
|
||||
virtual int getVideoHeight() const { return 0; };
|
||||
virtual int getVideoWidth() const { return 0; };
|
||||
virtual float getVideoFps() const { return 0; };
|
||||
|
||||
virtual int getAudioSampleRate() const { return 0; };
|
||||
virtual int getAudioSampleBit() const { return 0; };
|
||||
virtual int getAudioChannel() const { return 0; };
|
||||
|
||||
virtual const string& getPps() const { static string null;return null; };
|
||||
virtual const string& getSps() const { static string null;return null; };
|
||||
virtual const string& getAudioCfg() const { static string null;return null; };
|
||||
};
|
||||
|
||||
class PlayerBase : public MediaFormat,public mINI{
|
||||
class PlayerBase : public mINI{
|
||||
public:
|
||||
typedef std::shared_ptr<PlayerBase> Ptr;
|
||||
typedef enum {
|
||||
@@ -85,34 +69,29 @@ public:
|
||||
//rtsp认证用用户密码是否为md5
|
||||
static const char kRtspPwdIsMD5[];
|
||||
|
||||
PlayerBase(){};
|
||||
virtual ~PlayerBase(){};
|
||||
virtual void play(const char* strUrl) {};
|
||||
virtual void pause(bool bPause) {};
|
||||
virtual void teardown() {};
|
||||
PlayerBase(){}
|
||||
virtual ~PlayerBase(){}
|
||||
virtual void play(const char* strUrl) {}
|
||||
virtual void pause(bool bPause) {}
|
||||
virtual void teardown() {}
|
||||
|
||||
virtual void setOnShutdown( const function<void(const SockException &)> &cb) {};
|
||||
virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {};
|
||||
virtual void setOnVideoCB( const function<void(const H264Frame &frame)> &cb) {};
|
||||
virtual void setOnAudioCB( const function<void(const AACFrame &frame)> &cb) {};
|
||||
|
||||
virtual float getProgress() const { return 0;};
|
||||
virtual void seekTo(float fProgress) {};
|
||||
virtual void setMediaSouce(const MediaSource::Ptr & src) {};
|
||||
virtual void setOnShutdown( const function<void(const SockException &)> &cb) {}
|
||||
virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {}
|
||||
|
||||
virtual bool isInited() const { return true; };
|
||||
virtual float getProgress() const { return 0;}
|
||||
virtual void seekTo(float fProgress) {}
|
||||
virtual void setMediaSouce(const MediaSource::Ptr & src) {}
|
||||
|
||||
virtual bool isInited() const { return true; }
|
||||
//TrackVideo = 0, TrackAudio = 1
|
||||
virtual float getRtpLossRate(int trackType) const {return 0; };
|
||||
virtual float getDuration() const { return 0;};
|
||||
virtual float getRtpLossRate(int trackType) const {return 0; }
|
||||
virtual float getDuration() const { return 0;}
|
||||
|
||||
virtual bool containAudio() const { return false; };
|
||||
virtual bool containVideo() const { return false; };
|
||||
|
||||
virtual int getTrackCount() const { return 0;};
|
||||
virtual Track::Ptr getTrack(int index) const {return nullptr;};
|
||||
virtual int getTrackCount() const { return 0;}
|
||||
virtual Track::Ptr getTrack(int index) const {return nullptr;}
|
||||
protected:
|
||||
virtual void onShutdown(const SockException &ex) {};
|
||||
virtual void onPlayResult(const SockException &ex) {};
|
||||
virtual void onShutdown(const SockException &ex) {}
|
||||
virtual void onPlayResult(const SockException &ex) {}
|
||||
};
|
||||
|
||||
template<typename Parent,typename Parser>
|
||||
@@ -120,8 +99,8 @@ class PlayerImp : public Parent
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<PlayerImp> Ptr;
|
||||
PlayerImp(){};
|
||||
virtual ~PlayerImp(){};
|
||||
PlayerImp(){}
|
||||
virtual ~PlayerImp(){}
|
||||
void setOnShutdown(const function<void(const SockException &)> &cb) override {
|
||||
if (m_parser) {
|
||||
m_parser->setOnShutdown(cb);
|
||||
@@ -134,92 +113,7 @@ public:
|
||||
}
|
||||
m_playResultCB = cb;
|
||||
}
|
||||
void setOnVideoCB(const function<void(const H264Frame &frame)> &cb) override{
|
||||
if (m_parser) {
|
||||
m_parser->setOnVideoCB(cb);
|
||||
}
|
||||
m_onGetVideoCB = cb;
|
||||
}
|
||||
void setOnAudioCB(const function<void(const AACFrame &frame)> &cb) override{
|
||||
if (m_parser) {
|
||||
m_parser->setOnAudioCB(cb);
|
||||
}
|
||||
m_onGetAudioCB = cb;
|
||||
}
|
||||
int getVideoHeight() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getVideoHeight();
|
||||
}
|
||||
return PlayerBase::getVideoHeight();
|
||||
}
|
||||
|
||||
int getVideoWidth() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getVideoWidth();
|
||||
}
|
||||
return PlayerBase::getVideoWidth();
|
||||
}
|
||||
|
||||
float getVideoFps() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getVideoFps();
|
||||
}
|
||||
return PlayerBase::getVideoFps();
|
||||
}
|
||||
|
||||
int getAudioSampleRate() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getAudioSampleRate();
|
||||
}
|
||||
return PlayerBase::getAudioSampleRate();
|
||||
}
|
||||
|
||||
int getAudioSampleBit() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getAudioSampleBit();
|
||||
}
|
||||
return PlayerBase::getAudioSampleBit();
|
||||
}
|
||||
|
||||
int getAudioChannel() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getAudioChannel();
|
||||
}
|
||||
return PlayerBase::getAudioChannel();
|
||||
}
|
||||
|
||||
const string& getPps() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getPps();
|
||||
}
|
||||
return PlayerBase::getPps();
|
||||
}
|
||||
|
||||
const string& getSps() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getSps();
|
||||
}
|
||||
return PlayerBase::getSps();
|
||||
}
|
||||
|
||||
const string& getAudioCfg() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getAudioCfg();
|
||||
}
|
||||
return PlayerBase::getAudioCfg();
|
||||
}
|
||||
bool containAudio() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->containAudio();
|
||||
}
|
||||
return PlayerBase::containAudio();
|
||||
}
|
||||
bool containVideo() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->containVideo();
|
||||
}
|
||||
return PlayerBase::containVideo();
|
||||
}
|
||||
bool isInited() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->isInited();
|
||||
@@ -237,21 +131,33 @@ public:
|
||||
return m_parser->getProgress();
|
||||
}
|
||||
return PlayerBase::getProgress();
|
||||
};
|
||||
}
|
||||
void seekTo(float fProgress) override{
|
||||
if (m_parser) {
|
||||
return m_parser->seekTo(fProgress);
|
||||
}
|
||||
return PlayerBase::seekTo(fProgress);
|
||||
};
|
||||
}
|
||||
|
||||
void setMediaSouce(const MediaSource::Ptr & src) override {
|
||||
if (m_parser) {
|
||||
return m_parser->setMediaSouce(src);
|
||||
}
|
||||
m_pMediaSrc = src;
|
||||
};
|
||||
}
|
||||
|
||||
virtual int getTrackCount() const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getTrackCount();
|
||||
}
|
||||
return PlayerBase::getTrackCount();
|
||||
}
|
||||
virtual Track::Ptr getTrack(int index) const override{
|
||||
if (m_parser) {
|
||||
return m_parser->getTrack(index);
|
||||
}
|
||||
return PlayerBase::getTrack(index);
|
||||
}
|
||||
protected:
|
||||
void onShutdown(const SockException &ex) override {
|
||||
if (m_shutdownCB) {
|
||||
@@ -268,11 +174,9 @@ protected:
|
||||
function<void(const SockException &ex)> m_shutdownCB;
|
||||
function<void(const SockException &ex)> m_playResultCB;
|
||||
std::shared_ptr<Parser> m_parser;
|
||||
function<void(const H264Frame &frame)> m_onGetVideoCB;
|
||||
function<void(const AACFrame &frame)> m_onGetAudioCB;
|
||||
MediaSource::Ptr m_pMediaSrc;
|
||||
|
||||
};
|
||||
|
||||
} /* namespace Player */
|
||||
} /* namespace ZL */
|
||||
|
||||
|
||||
@@ -3,3 +3,51 @@
|
||||
//
|
||||
|
||||
#include "Track.h"
|
||||
#include "Util/util.h"
|
||||
#include "Util/base64.h"
|
||||
|
||||
using namespace ZL::Util;
|
||||
|
||||
Track::Ptr Track::getTrackBySdp(const string &sdp) {
|
||||
if (strcasestr(sdp.data(), "mpeg4-generic") != nullptr) {
|
||||
string aac_cfg_str = FindField(sdp.c_str(), "config=", "\r\n");
|
||||
if (aac_cfg_str.size() != 4) {
|
||||
aac_cfg_str = FindField(sdp.c_str(), "config=", ";");
|
||||
}
|
||||
if (aac_cfg_str.size() != 4) {
|
||||
return nullptr;
|
||||
}
|
||||
string aac_cfg;
|
||||
|
||||
unsigned int cfg1;
|
||||
sscanf(aac_cfg_str.substr(0, 2).c_str(), "%02X", &cfg1);
|
||||
cfg1 &= 0x00FF;
|
||||
aac_cfg.push_back(cfg1);
|
||||
|
||||
unsigned int cfg2;
|
||||
sscanf(aac_cfg_str.substr(2, 2).c_str(), "%02X", &cfg2);
|
||||
cfg2 &= 0x00FF;
|
||||
aac_cfg.push_back(cfg2);
|
||||
|
||||
return std::make_shared<AACTrack>(aac_cfg);
|
||||
}
|
||||
|
||||
if (strcasestr(sdp.data(), "h264") != nullptr) {
|
||||
string sps_pps = FindField(sdp.c_str(), "sprop-parameter-sets=", "\r\n");
|
||||
if(sps_pps.empty()){
|
||||
return std::make_shared<H264Track>();
|
||||
}
|
||||
string base64_SPS = FindField(sps_pps.c_str(), NULL, ",");
|
||||
string base64_PPS = FindField(sps_pps.c_str(), ",", NULL);
|
||||
if(base64_PPS.back() == ';'){
|
||||
base64_PPS.pop_back();
|
||||
}
|
||||
|
||||
auto sps = decodeBase64(base64_SPS);
|
||||
auto pps = decodeBase64(base64_PPS);
|
||||
return std::make_shared<H264Track>(sps,pps,0,0);
|
||||
}
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ public:
|
||||
typedef std::shared_ptr<Track> Ptr;
|
||||
Track(){}
|
||||
virtual ~Track(){}
|
||||
|
||||
static Ptr getTrackBySdp(const string &sdp);
|
||||
};
|
||||
|
||||
class VideoTrack : public Track {
|
||||
@@ -71,6 +73,11 @@ public:
|
||||
class H264Track : public VideoTrack{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 不指定sps pps构造h264类型的媒体
|
||||
* 在随后的inputFrame中获取sps pps
|
||||
*/
|
||||
H264Track(){}
|
||||
/**
|
||||
* 构造h264类型的媒体
|
||||
* @param sps sps帧数据
|
||||
@@ -98,7 +105,6 @@ public:
|
||||
parseSps(_sps);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回不带0x00 00 00 01头的sps
|
||||
* @return
|
||||
@@ -142,6 +148,68 @@ public:
|
||||
float getVideoFps() const override{
|
||||
return _fps;
|
||||
}
|
||||
|
||||
TrackType getTrackType() const override {
|
||||
if(_sps.empty() || _pps.empty()){
|
||||
return TrackInvalid;
|
||||
}
|
||||
return TrackAudio;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 输入数据帧,并获取sps pps
|
||||
* @param frame 数据帧
|
||||
* @param key_pos 是否为关键帧
|
||||
*/
|
||||
void inputFrame(const Frame::Ptr &frame,bool key_pos) override{
|
||||
int type = (*((uint8_t *)frame->data() + frame->prefixSize())) & 0x1F;
|
||||
switch (type){
|
||||
case 7:{
|
||||
//sps
|
||||
bool flag = _sps.empty();
|
||||
_sps = string(frame->data() + frame->prefixSize(),frame->size() - frame->prefixSize());
|
||||
if(flag && _width == 0){
|
||||
parseSps(_sps);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:{
|
||||
//pps
|
||||
_pps = string(frame->data() + frame->prefixSize(),frame->size() - frame->prefixSize());
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:{
|
||||
//I
|
||||
if(!_sps.empty()){
|
||||
H264Frame::Ptr insertFrame = std::make_shared<H264Frame>();
|
||||
insertFrame->timeStamp = frame->stamp();
|
||||
insertFrame->type = 7;
|
||||
insertFrame->buffer = _sps;
|
||||
insertFrame->iPrefixSize = 0;
|
||||
VideoTrack::inputFrame(insertFrame, true);
|
||||
}
|
||||
|
||||
if(!_pps.empty()){
|
||||
H264Frame::Ptr insertFrame = std::make_shared<H264Frame>();
|
||||
insertFrame->timeStamp = frame->stamp();
|
||||
insertFrame->type = 8;
|
||||
insertFrame->buffer = _pps;
|
||||
insertFrame->iPrefixSize = 0;
|
||||
VideoTrack::inputFrame(insertFrame, false);
|
||||
}
|
||||
VideoTrack::inputFrame(frame, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:{
|
||||
//B or P
|
||||
VideoTrack::inputFrame(frame, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* 解析sps获取宽高fps
|
||||
|
||||
Reference in New Issue
Block a user