diff --git a/src/Common/Factory.cpp b/src/Common/Factory.cpp index b9f114e9..776dd750 100644 --- a/src/Common/Factory.cpp +++ b/src/Common/Factory.cpp @@ -75,6 +75,56 @@ Track::Ptr Factory::getTrackBySdp(const string &sdp) { } +CodecId getCodecIdByAmf(const AMFValue &val){ + if (val.type() == AMF_STRING){ + auto str = val.as_string(); + if(str == "avc1"){ + return CodecH264; + } + if(str == "mp4a"){ + return CodecAAC; + } + return CodecInvalid; + } + + if (val.type() != AMF_NULL){ + auto type_id = val.as_integer(); + switch (type_id){ + case 7:{ + return CodecH264; + } + case 10:{ + return CodecAAC; + } + default: + return CodecInvalid; + } + } + return CodecInvalid; +} + +Track::Ptr Factory::getTrackByCodecId(CodecId codecId) { + switch (codecId){ + case CodecH264:{ + return std::make_shared(); + } + case CodecAAC:{ + return std::make_shared(); + } + default: + return nullptr; + } +} + + +Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) { + CodecId codecId = getCodecIdByAmf(amf); + if(codecId == CodecInvalid){ + return nullptr; + } + return getTrackByCodecId(codecId); +} + RtpCodec::Ptr Factory::getRtpEncoderById(CodecId codecId, uint32_t ui32Ssrc, @@ -103,5 +153,6 @@ RtpCodec::Ptr Factory::getRtpDecoderById(CodecId codecId, uint32_t ui32SampleRat } } + }//namespace mediakit diff --git a/src/Common/Factory.h b/src/Common/Factory.h index f92f65f6..36aa88b1 100644 --- a/src/Common/Factory.h +++ b/src/Common/Factory.h @@ -8,6 +8,7 @@ #include #include "Player/Track.h" #include "RtspMuxer/RtspSdp.h" +#include "Rtmp/amf.h" using namespace std; using namespace toolkit; @@ -20,6 +21,9 @@ public: * 根据sdp生成Track对象 */ static Track::Ptr getTrackBySdp(const string &sdp); + static Track::Ptr getTrackByAmf(const AMFValue &amf); + static Track::Ptr getTrackByCodecId(CodecId codecId); + /** * 根据Track生成SDP对象 diff --git a/src/Player/Track.h b/src/Player/Track.h index bbe97c67..fbe0a1f9 100644 --- a/src/Player/Track.h +++ b/src/Player/Track.h @@ -232,6 +232,12 @@ class AACTrack : public AudioTrack{ public: typedef std::shared_ptr Ptr; + /** + * 延后获取adts头信息 + * 在随后的inputFrame中获取adts头信息 + */ + AACTrack(){} + /** * 构造aac类型的媒体 * @param aac_cfg aac两个字节的配置信息 @@ -285,6 +291,16 @@ public: return CodecAAC; } + /** + * 在获取aac_cfg前是无效的Track + * @return + */ + TrackType getTrackType() const override { + if(_cfg.empty()){ + return TrackInvalid; + } + return TrackAudio; + } /** * 返回音频采样率 * @return @@ -307,6 +323,18 @@ public: return _channel; } + /** + * 输入数据帧,并获取aac_cfg + * @param frame 数据帧 + */ + void inputFrame(const Frame::Ptr &frame) override{ + if(_cfg.empty() && frame->prefixSize() == 7){ + //7个字节的adts头 + _cfg = makeAdtsConfig(reinterpret_cast(frame->data())); + parseAacCfg(_cfg); + } + AudioTrack::inputFrame(frame); + } private: /** * 解析2个字节的aac配置