修正metadata拼写错误,优化RtmpMediaSource注册机制,修复及时拉流不出画面的bug

This commit is contained in:
xiongziliang 2019-09-23 16:47:20 +08:00
parent 8ae9f56110
commit cb7c72d9d9
14 changed files with 79 additions and 67 deletions

View File

@ -45,7 +45,7 @@ public:
bool bEnableMp4 = false bool bEnableMp4 = false
){ ){
if (bEanbleRtmp) { if (bEanbleRtmp) {
_rtmp = std::make_shared<RtmpMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleMete>(dur_sec)); _rtmp = std::make_shared<RtmpMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleMeta>(dur_sec));
} }
if (bEanbleRtsp) { if (bEanbleRtsp) {
_rtsp = std::make_shared<RtspMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleSdp>(dur_sec)); _rtsp = std::make_shared<RtspMediaSourceMuxer>(vhost, strApp, strId, std::make_shared<TitleSdp>(dur_sec));

View File

@ -197,7 +197,7 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){
return CodecInvalid; return CodecInvalid;
} }
}else{ }else{
WarnL << "Metedata不存在相应的Track"; WarnL << "Metadata不存在相应的Track";
} }
return CodecInvalid; return CodecInvalid;

View File

@ -73,14 +73,14 @@ public:
/** /**
* amf对象获取响应的Track * amf对象获取响应的Track
* @param amf rtmp metedata中的videocodecid或audiocodecid的值 * @param amf rtmp metadata中的videocodecid或audiocodecid的值
* @return * @return
*/ */
static Track::Ptr getTrackByAmf(const AMFValue &amf); static Track::Ptr getTrackByAmf(const AMFValue &amf);
/** /**
* amf对象获取相应的CodecId * amf对象获取相应的CodecId
* @param val rtmp metedata中的videocodecid或audiocodecid的值 * @param val rtmp metadata中的videocodecid或audiocodecid的值
* @return * @return
*/ */
static CodecId getCodecIdByAmf(const AMFValue &val); static CodecId getCodecIdByAmf(const AMFValue &val);

View File

@ -27,35 +27,35 @@
#include "Extension/Factory.h" #include "Extension/Factory.h"
namespace mediakit{ namespace mediakit{
VideoMete::VideoMete(const VideoTrack::Ptr &video,int datarate ){ VideoMeta::VideoMeta(const VideoTrack::Ptr &video,int datarate ){
if(video->getVideoWidth() > 0 ){ if(video->getVideoWidth() > 0 ){
_metedata.set("width", video->getVideoWidth()); _metadata.set("width", video->getVideoWidth());
} }
if(video->getVideoHeight() > 0 ){ if(video->getVideoHeight() > 0 ){
_metedata.set("height", video->getVideoHeight()); _metadata.set("height", video->getVideoHeight());
} }
if(video->getVideoFps() > 0 ){ if(video->getVideoFps() > 0 ){
_metedata.set("framerate", video->getVideoFps()); _metadata.set("framerate", video->getVideoFps());
} }
_metedata.set("videodatarate", datarate); _metadata.set("videodatarate", datarate);
_codecId = video->getCodecId(); _codecId = video->getCodecId();
_metedata.set("videocodecid", Factory::getAmfByCodecId(_codecId)); _metadata.set("videocodecid", Factory::getAmfByCodecId(_codecId));
} }
AudioMete::AudioMete(const AudioTrack::Ptr &audio,int datarate){ AudioMeta::AudioMeta(const AudioTrack::Ptr &audio,int datarate){
_metedata.set("audiodatarate", datarate); _metadata.set("audiodatarate", datarate);
if(audio->getAudioSampleRate() > 0){ if(audio->getAudioSampleRate() > 0){
_metedata.set("audiosamplerate", audio->getAudioSampleRate()); _metadata.set("audiosamplerate", audio->getAudioSampleRate());
} }
if(audio->getAudioSampleBit() > 0){ if(audio->getAudioSampleBit() > 0){
_metedata.set("audiosamplesize", audio->getAudioSampleBit()); _metadata.set("audiosamplesize", audio->getAudioSampleBit());
} }
if(audio->getAudioChannel() > 0){ if(audio->getAudioChannel() > 0){
_metedata.set("audiochannels", audio->getAudioChannel()); _metadata.set("audiochannels", audio->getAudioChannel());
_metedata.set("stereo", audio->getAudioChannel() > 1); _metadata.set("stereo", audio->getAudioChannel() > 1);
} }
_codecId = audio->getCodecId(); _codecId = audio->getCodecId();
_metedata.set("audiocodecid", Factory::getAmfByCodecId(_codecId)); _metadata.set("audiocodecid", Factory::getAmfByCodecId(_codecId));
} }
}//namespace mediakit }//namespace mediakit

View File

@ -298,36 +298,36 @@ public:
/** /**
* rtmp metedata基类rtmp格式信息 * rtmp metadata基类rtmp格式信息
*/ */
class Metedata : public CodecInfo{ class Metadata : public CodecInfo{
public: public:
typedef std::shared_ptr<Metedata> Ptr; typedef std::shared_ptr<Metadata> Ptr;
Metedata():_metedata(AMF_OBJECT){} Metadata():_metadata(AMF_OBJECT){}
virtual ~Metedata(){} virtual ~Metadata(){}
const AMFValue &getMetedata() const{ const AMFValue &getMetadata() const{
return _metedata; return _metadata;
} }
protected: protected:
AMFValue _metedata; AMFValue _metadata;
}; };
/** /**
* metedata中除音视频外的其他描述部分 * metadata中除音视频外的其他描述部分
*/ */
class TitleMete : public Metedata{ class TitleMeta : public Metadata{
public: public:
typedef std::shared_ptr<TitleMete> Ptr; typedef std::shared_ptr<TitleMeta> Ptr;
TitleMete(float dur_sec = 0, TitleMeta(float dur_sec = 0,
uint64_t fileSize = 0, uint64_t fileSize = 0,
const map<string,string> &header = map<string,string>()){ const map<string,string> &header = map<string,string>()){
_metedata.set("duration", dur_sec); _metadata.set("duration", dur_sec);
_metedata.set("fileSize", 0); _metadata.set("fileSize", 0);
_metedata.set("server","ZLMediaKit"); _metadata.set("server","ZLMediaKit");
for (auto &pr : header){ for (auto &pr : header){
_metedata.set(pr.first, pr.second); _metadata.set(pr.first, pr.second);
} }
} }
@ -348,12 +348,12 @@ public:
} }
}; };
class VideoMete : public Metedata{ class VideoMeta : public Metadata{
public: public:
typedef std::shared_ptr<VideoMete> Ptr; typedef std::shared_ptr<VideoMeta> Ptr;
VideoMete(const VideoTrack::Ptr &video,int datarate = 5000); VideoMeta(const VideoTrack::Ptr &video,int datarate = 5000);
virtual ~VideoMete(){} virtual ~VideoMeta(){}
/** /**
* *
@ -375,13 +375,13 @@ private:
}; };
class AudioMete : public Metedata{ class AudioMeta : public Metadata{
public: public:
typedef std::shared_ptr<AudioMete> Ptr; typedef std::shared_ptr<AudioMeta> Ptr;
AudioMete(const AudioTrack::Ptr &audio,int datarate = 160); AudioMeta(const AudioTrack::Ptr &audio,int datarate = 160);
virtual ~AudioMete(){} virtual ~AudioMeta(){}
/** /**
* *

View File

@ -45,8 +45,8 @@ RtmpDemuxer::RtmpDemuxer(const AMFValue &val) {
} }
} }
int RtmpDemuxer::getTrackCount(const AMFValue &metedata) { int RtmpDemuxer::getTrackCount(const AMFValue &metadata) {
return (int)(metedata["videocodecid"].type() != AMF_NULL) + (int)(metedata["audiocodecid"].type() != AMF_NULL); return (int)(metadata["videocodecid"].type() != AMF_NULL) + (int)(metadata["audiocodecid"].type() != AMF_NULL);
} }
bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) { bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {

View File

@ -49,7 +49,7 @@ public:
RtmpDemuxer(){} RtmpDemuxer(){}
/** /**
* rtmp解复用器 * rtmp解复用器
* @param val rtmp的metedatanull类型 * @param val rtmp的metadatanull类型
* inputRtmp时异步探测媒体编码格式 * inputRtmp时异步探测媒体编码格式
*/ */
RtmpDemuxer(const AMFValue &val); RtmpDemuxer(const AMFValue &val);
@ -58,10 +58,10 @@ public:
/** /**
* *
* rtmp track * rtmp track
* @param metedata rtmp的metedata * @param metadata rtmp的metadata
* @return * @return
*/ */
static int getTrackCount(const AMFValue &metedata); static int getTrackCount(const AMFValue &metadata);
/** /**
* *

View File

@ -86,6 +86,9 @@ public:
virtual void onGetMetaData(const AMFValue &metadata) { virtual void onGetMetaData(const AMFValue &metadata) {
lock_guard<recursive_mutex> lock(_mtxMap); lock_guard<recursive_mutex> lock(_mtxMap);
_metadata = metadata; _metadata = metadata;
if(_pRing){
regist();
}
} }
void onWrite(const RtmpPacket::Ptr &pkt,bool isKey = true) override { void onWrite(const RtmpPacket::Ptr &pkt,bool isKey = true) override {
@ -107,7 +110,9 @@ public:
strongSelf->onReaderChanged(size); strongSelf->onReaderChanged(size);
}); });
onReaderChanged(0); onReaderChanged(0);
regist(); if(_metadata){
regist();
}
} }
_pRing->write(pkt,pkt->isVideoKeyFrame()); _pRing->write(pkt,pkt->isVideoKeyFrame());
checkNoneReader(); checkNoneReader();

View File

@ -39,7 +39,7 @@ public:
RtmpMediaSourceMuxer(const string &vhost, RtmpMediaSourceMuxer(const string &vhost,
const string &strApp, const string &strApp,
const string &strId, const string &strId,
const TitleMete::Ptr &title = nullptr) : RtmpMuxer(title){ const TitleMeta::Ptr &title = nullptr) : RtmpMuxer(title){
_mediaSouce = std::make_shared<RtmpMediaSource>(vhost,strApp,strId); _mediaSouce = std::make_shared<RtmpMediaSource>(vhost,strApp,strId);
getRtmpRing()->setDelegate(_mediaSouce); getRtmpRing()->setDelegate(_mediaSouce);
} }
@ -53,7 +53,7 @@ public:
} }
private: private:
void onAllTrackReady() override { void onAllTrackReady() override {
_mediaSouce->onGetMetaData(getMetedata()); _mediaSouce->onGetMetaData(getMetadata());
} }
private: private:
RtmpMediaSource::Ptr _mediaSouce; RtmpMediaSource::Ptr _mediaSouce;

View File

@ -29,11 +29,11 @@
namespace mediakit { namespace mediakit {
RtmpMuxer::RtmpMuxer(const TitleMete::Ptr &title) { RtmpMuxer::RtmpMuxer(const TitleMeta::Ptr &title) {
if(!title){ if(!title){
_metedata = std::make_shared<TitleMete>()->getMetedata(); _metadata = std::make_shared<TitleMeta>()->getMetadata();
}else{ }else{
_metedata = title->getMetedata(); _metadata = title->getMetadata();
} }
_rtmpRing = std::make_shared<RtmpRingInterface::RingType>(); _rtmpRing = std::make_shared<RtmpRingInterface::RingType>();
} }
@ -45,24 +45,24 @@ void RtmpMuxer::onTrackReady(const Track::Ptr &track) {
if (!encoder) { if (!encoder) {
return; return;
} }
//根据track生产metedata //根据track生产metadata
Metedata::Ptr metedate; Metadata::Ptr metadata;
switch (track->getTrackType()){ switch (track->getTrackType()){
case TrackVideo:{ case TrackVideo:{
metedate = std::make_shared<VideoMete>(dynamic_pointer_cast<VideoTrack>(track)); metadata = std::make_shared<VideoMeta>(dynamic_pointer_cast<VideoTrack>(track));
} }
break; break;
case TrackAudio:{ case TrackAudio:{
metedate = std::make_shared<AudioMete>(dynamic_pointer_cast<AudioTrack>(track)); metadata = std::make_shared<AudioMeta>(dynamic_pointer_cast<AudioTrack>(track));
} }
break; break;
default: default:
return;; return;;
} }
//添加其metedata //添加其metadata
metedate->getMetedata().object_for_each([&](const std::string &key, const AMFValue &value){ metadata->getMetadata().object_for_each([&](const std::string &key, const AMFValue &value){
_metedata.set(key,value); _metadata.set(key,value);
}); });
//设置Track的代理这样输入frame至Track时最终数据将输出到RtmpEncoder中 //设置Track的代理这样输入frame至Track时最终数据将输出到RtmpEncoder中
track->addDelegate(encoder); track->addDelegate(encoder);
@ -71,13 +71,13 @@ void RtmpMuxer::onTrackReady(const Track::Ptr &track) {
} }
const AMFValue &RtmpMuxer::getMetedata() const { const AMFValue &RtmpMuxer::getMetadata() const {
if(!isAllTrackReady()){ if(!isAllTrackReady()){
//尚未就绪 //尚未就绪
static AMFValue s_amf; static AMFValue s_amf;
return s_amf; return s_amf;
} }
return _metedata; return _metadata;
} }
RtmpRingInterface::RingType::Ptr RtmpMuxer::getRtmpRing() const { RtmpRingInterface::RingType::Ptr RtmpMuxer::getRtmpRing() const {

View File

@ -41,14 +41,14 @@ public:
/** /**
* *
*/ */
RtmpMuxer(const TitleMete::Ptr &title); RtmpMuxer(const TitleMeta::Ptr &title);
virtual ~RtmpMuxer(){} virtual ~RtmpMuxer(){}
/** /**
* SDP字符串 * SDP字符串
* @return SDP字符串 * @return SDP字符串
*/ */
const AMFValue &getMetedata() const ; const AMFValue &getMetadata() const ;
/** /**
* rtmp环形缓存 * rtmp环形缓存
@ -64,7 +64,7 @@ protected:
void onTrackReady(const Track::Ptr & track) override ; void onTrackReady(const Track::Ptr & track) override ;
private: private:
RtmpRingInterface::RingType::Ptr _rtmpRing; RtmpRingInterface::RingType::Ptr _rtmpRing;
AMFValue _metedata; AMFValue _metadata;
}; };

View File

@ -75,7 +75,7 @@ private:
_pRtmpMediaSrc->onWrite(chunkData); _pRtmpMediaSrc->onWrite(chunkData);
} }
if(!_parser){ if(!_parser){
//这个流没有metedata //这个流没有metadata
_parser.reset(new RtmpDemuxer()); _parser.reset(new RtmpDemuxer());
} }
_parser->inputRtmp(chunkData); _parser->inputRtmp(chunkData);

View File

@ -431,6 +431,7 @@ void RtmpSession::setMetaData(AMFDecoder &dec) {
} }
auto metadata = dec.load<AMFValue>(); auto metadata = dec.load<AMFValue>();
//dumpMetadata(metadata); //dumpMetadata(metadata);
_metadata_got = true;
_pPublisherSrc->onGetMetaData(metadata); _pPublisherSrc->onGetMetaData(metadata);
} }
@ -488,6 +489,11 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
_stamp[chunkData.typeId % 2].revise(0, 0, dts_out, dts_out); _stamp[chunkData.typeId % 2].revise(0, 0, dts_out, dts_out);
chunkData.timeStamp = dts_out; chunkData.timeStamp = dts_out;
} }
if(!_metadata_got){
//有些rtmp推流客户端不产生metadata我们产生一个默认的metadata目的是为了触发注册操作
_metadata_got = true;
_pPublisherSrc->onGetMetaData(TitleMeta().getMetadata());
}
_pPublisherSrc->onWrite(std::make_shared<RtmpPacket>(std::move(chunkData))); _pPublisherSrc->onWrite(std::make_shared<RtmpPacket>(std::move(chunkData)));
} }
break; break;
@ -553,7 +559,7 @@ void RtmpSession::setSocketFlags(){
void RtmpSession::dumpMetadata(const AMFValue &metadata) { void RtmpSession::dumpMetadata(const AMFValue &metadata) {
if(metadata.type() != AMF_OBJECT && metadata.type() != AMF_ECMA_ARRAY){ if(metadata.type() != AMF_OBJECT && metadata.type() != AMF_ECMA_ARRAY){
WarnL << "invalid metedata type:" << metadata.type(); WarnL << "invalid metadata type:" << metadata.type();
return ; return ;
} }
_StrPrinter printer; _StrPrinter printer;

View File

@ -87,8 +87,9 @@ private:
void onNoneReader(MediaSource &sender) override; void onNoneReader(MediaSource &sender) override;
void setSocketFlags(); void setSocketFlags();
string getStreamId(const string &str); string getStreamId(const string &str);
void dumpMetadata(const AMFValue &metedata); void dumpMetadata(const AMFValue &metadata);
private: private:
bool _metadata_got = false;
std::string _strTcUrl; std::string _strTcUrl;
MediaInfo _mediaInfo; MediaInfo _mediaInfo;
double _dNowReqID = 0; double _dNowReqID = 0;