diff --git a/src/Common/Device.cpp b/src/Common/Device.cpp index 06de6d10..4ca91fac 100644 --- a/src/Common/Device.cpp +++ b/src/Common/Device.cpp @@ -196,7 +196,7 @@ void DevChannel::initAudio(const AudioInfo& info) { } case CodecG711A : - case CodecG711U : addTrack(std::make_shared(info.codecId)); break; + case CodecG711U : addTrack(std::make_shared(info.codecId, info.iSampleRate, info.iChannel, info.iSampleBit)); break; default: WarnL << "不支持该类型的音频编码类型:" << info.codecId; break; } } diff --git a/src/Common/MediaSink.cpp b/src/Common/MediaSink.cpp index aa5e023c..53697a56 100644 --- a/src/Common/MediaSink.cpp +++ b/src/Common/MediaSink.cpp @@ -42,8 +42,8 @@ void MediaSink::addTrack(const Track::Ptr &track_in) { if (_allTrackReady) { //运行至这里说明Track状态由未就绪切换为已就绪状态,那么这帧就不应该丢弃 onTrackFrame(frame); - } else { - ErrorL << "some track is unready,drop frame of: " << frame->getCodecName(); + } else if(frame->keyFrame()){ + WarnL << "some track is unready,drop key frame of: " << frame->getCodecName(); } })); } diff --git a/src/Extension/AACRtmp.cpp b/src/Extension/AACRtmp.cpp index ac66f306..6a22e45e 100644 --- a/src/Extension/AACRtmp.cpp +++ b/src/Extension/AACRtmp.cpp @@ -104,7 +104,7 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) { //header uint8_t is_config = false; - rtmpPkt->strBuf.push_back(_ui8AudioFlags); + rtmpPkt->strBuf.push_back(_audio_flv_flags); rtmpPkt->strBuf.push_back(!is_config); //aac data @@ -117,44 +117,16 @@ void AACRtmpEncoder::inputFrame(const Frame::Ptr &frame) { rtmpPkt->typeId = MSG_AUDIO; RtmpCodec::inputRtmp(rtmpPkt, false); } - } void AACRtmpEncoder::makeAudioConfigPkt() { - makeAdtsHeader(_aac_cfg,*_adts); - int iSampleRate , iChannel , iSampleBit = 16; - getAACInfo(*_adts,iSampleRate,iChannel); - - uint8_t flvStereoOrMono = (iChannel > 1); - uint8_t flvSampleRate; - switch (iSampleRate) { - case 48000: - case 44100: - flvSampleRate = 3; - break; - case 24000: - case 22050: - flvSampleRate = 2; - break; - case 12000: - case 11025: - flvSampleRate = 1; - break; - default: - flvSampleRate = 0; - break; - } - uint8_t flvSampleBit = iSampleBit == 16; - uint8_t flvAudioType = FLV_CODEC_AAC; - - _ui8AudioFlags = (flvAudioType << 4) | (flvSampleRate << 2) | (flvSampleBit << 1) | flvStereoOrMono; - + _audio_flv_flags = getAudioRtmpFlags(std::make_shared(_aac_cfg)); RtmpPacket::Ptr rtmpPkt = ResourcePoolHelper::obtainObj(); rtmpPkt->strBuf.clear(); //header uint8_t is_config = true; - rtmpPkt->strBuf.push_back(_ui8AudioFlags); + rtmpPkt->strBuf.push_back(_audio_flv_flags); rtmpPkt->strBuf.push_back(!is_config); //aac config rtmpPkt->strBuf.append(_aac_cfg); diff --git a/src/Extension/AACRtmp.h b/src/Extension/AACRtmp.h index 4d245dd7..20f424d5 100644 --- a/src/Extension/AACRtmp.h +++ b/src/Extension/AACRtmp.h @@ -79,7 +79,7 @@ public: private: void makeAudioConfigPkt(); private: - uint8_t _ui8AudioFlags; + uint8_t _audio_flv_flags; AACTrack::Ptr _track; }; diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index 5f5e3491..4bdb965c 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -48,11 +48,11 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { } if (strcasecmp(track->_codec.data(), "PCMA") == 0) { - return std::make_shared(CodecG711A); + return std::make_shared(CodecG711A, track->_samplerate, track->_channel, 16); } if (strcasecmp(track->_codec.data(), "PCMU") == 0) { - return std::make_shared(CodecG711U); + return std::make_shared(CodecG711U, track->_samplerate, track->_channel, 16); } if (strcasecmp(track->_codec.data(), "h264") == 0) { @@ -88,29 +88,6 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { return nullptr; } -Track::Ptr Factory::getTrackByCodecId(CodecId codecId) { - switch (codecId){ - case CodecH264:{ - return std::make_shared(); - } - case CodecH265:{ - return std::make_shared(); - } - case CodecAAC:{ - return std::make_shared(); - } - case CodecG711A: { - return std::make_shared(CodecG711A); - } - case CodecG711U: { - return std::make_shared(CodecG711U); - } - default: - WarnL << "暂不支持该CodecId:" << codecId; - return nullptr; - } -} - RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) { GET_CONFIG(uint32_t,audio_mtu,Rtp::kAudioMtuSize); GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize); @@ -134,35 +111,23 @@ RtpCodec::Ptr Factory::getRtpEncoderBySdp(const Sdp::Ptr &sdp) { auto interleaved = sdp->getTrackType() * 2; auto codec_id = sdp->getCodecId(); switch (codec_id){ - case CodecH264: - return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); - case CodecH265: - return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); - case CodecAAC: - return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); - case CodecG711A: - case CodecG711U: - return std::make_shared(ssrc, mtu, sample_rate, pt, interleaved); - default: - WarnL << "暂不支持该CodecId:" << codec_id; - return nullptr; + case CodecH264 : return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); + case CodecH265 : return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); + case CodecAAC : return std::make_shared(ssrc,mtu,sample_rate,pt,interleaved); + case CodecG711A : + case CodecG711U : return std::make_shared(ssrc, mtu, sample_rate, pt, interleaved); + default : WarnL << "暂不支持该CodecId:" << codec_id; return nullptr; } } RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) { switch (track->getCodecId()){ - case CodecH264: - return std::make_shared(); - case CodecH265: - return std::make_shared(); - case CodecAAC: - return std::make_shared(track->clone()); - case CodecG711A: - case CodecG711U: - return std::make_shared(track->clone()); - default: - WarnL << "暂不支持该CodecId:" << track->getCodecName(); - return nullptr; + case CodecH264 : return std::make_shared(); + case CodecH265 : return std::make_shared(); + case CodecAAC : return std::make_shared(track->clone()); + case CodecG711A : + case CodecG711U : return std::make_shared(track->clone()); + default : WarnL << "暂不支持该CodecId:" << track->getCodecName(); return nullptr; } } @@ -190,15 +155,25 @@ static CodecId getVideoCodecIdByAmf(const AMFValue &val){ case FLV_CODEC_H264: return CodecH264; case FLV_CODEC_AAC: return CodecAAC; case FLV_CODEC_H265: return CodecH265; - default: - WarnL << "暂不支持该Amf:" << type_id; - return CodecInvalid; + default : WarnL << "暂不支持该Amf:" << type_id; return CodecInvalid; } } return CodecInvalid; } + +Track::Ptr getTrackByCodecId(CodecId codecId, int sample_rate = 0, int channels = 0, int sample_bit = 0) { + switch (codecId){ + case CodecH264 : return std::make_shared(); + case CodecH265 : return std::make_shared(); + case CodecAAC : return std::make_shared(); + case CodecG711A : + case CodecG711U : return (sample_rate && channels && sample_bit) ? std::make_shared(codecId, sample_rate, channels, sample_bit) : nullptr; + default : WarnL << "暂不支持该CodecId:" << codecId; return nullptr; + } +} + Track::Ptr Factory::getVideoTrackByAmf(const AMFValue &amf) { CodecId codecId = getVideoCodecIdByAmf(amf); if(codecId == CodecInvalid){ @@ -230,28 +205,22 @@ static CodecId getAudioCodecIdByAmf(const AMFValue &val) { return CodecInvalid; } -Track::Ptr Factory::getAudioTrackByAmf(const AMFValue& amf){ +Track::Ptr Factory::getAudioTrackByAmf(const AMFValue& amf, int sample_rate, int channels, int sample_bit){ CodecId codecId = getAudioCodecIdByAmf(amf); if (codecId == CodecInvalid) { return nullptr; } - return getTrackByCodecId(codecId); + return getTrackByCodecId(codecId, sample_rate, channels, sample_bit); } RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) { switch (track->getCodecId()){ - case CodecH264: - return std::make_shared(track); - case CodecAAC: - return std::make_shared(track); - case CodecH265: - return std::make_shared(track); - case CodecG711A: - case CodecG711U: - return std::make_shared(track); - default: - WarnL << "暂不支持该CodecId:" << track->getCodecName(); - return nullptr; + case CodecH264 : return std::make_shared(track); + case CodecAAC : return std::make_shared(track); + case CodecH265 : return std::make_shared(track); + case CodecG711A : + case CodecG711U : return std::make_shared(track); + default : WarnL << "暂不支持该CodecId:" << track->getCodecName(); return nullptr; } } diff --git a/src/Extension/Factory.h b/src/Extension/Factory.h index 07398637..6b678d34 100644 --- a/src/Extension/Factory.h +++ b/src/Extension/Factory.h @@ -24,13 +24,6 @@ namespace mediakit{ class Factory { public: - - /** - * 根据CodecId获取Track,该Track的ready()状态一般都为false - * @param codecId 编解码器id - */ - static Track::Ptr getTrackByCodecId(CodecId codecId); - ////////////////////////////////rtsp相关////////////////////////////////// /** * 根据sdp生成Track对象 @@ -61,7 +54,7 @@ public: * 根据amf对象获取音频相应的Track * @param amf rtmp metadata中的audiocodecid的值 */ - static Track::Ptr getAudioTrackByAmf(const AMFValue& amf); + static Track::Ptr getAudioTrackByAmf(const AMFValue& amf, int sample_rate, int channels, int sample_bit); /** * 根据Track获取Rtmp的编解码器 diff --git a/src/Extension/G711.cpp b/src/Extension/G711.cpp index 23194e2b..15c3d74e 100644 --- a/src/Extension/G711.cpp +++ b/src/Extension/G711.cpp @@ -12,13 +12,12 @@ namespace mediakit{ - Sdp::Ptr G711Track::getSdp() { if(!ready()){ WarnL << getCodecName() << " Track未准备好"; return nullptr; } - return std::make_shared(getCodecId()); + return std::make_shared(getCodecId(), getAudioSampleRate(), getAudioChannel()); } }//namespace mediakit diff --git a/src/Extension/G711.h b/src/Extension/G711.h index 056ac1dd..d1644201 100644 --- a/src/Extension/G711.h +++ b/src/Extension/G711.h @@ -102,8 +102,11 @@ public: /** * G711A G711U */ - G711Track(CodecId codecId){ + G711Track(CodecId codecId,int sample_rate, int channels, int sample_bit){ _codecid = codecId; + _sample_rate = sample_rate; + _channels = channels; + _sample_bit = sample_bit; } /** @@ -114,7 +117,7 @@ public: } /** - * G711的Track不需要初始化 + * 是否已经初始化 */ bool ready() override { return true; @@ -124,21 +127,21 @@ public: * 返回音频采样率 */ int getAudioSampleRate() const override{ - return 8000; + return _sample_rate; } /** * 返回音频采样位数,一般为16或8 */ int getAudioSampleBit() const override{ - return 16; + return _sample_bit; } /** * 返回音频通道数 */ int getAudioChannel() const override{ - return 1; + return _channels; } private: @@ -149,7 +152,10 @@ private: //生成sdp Sdp::Ptr getSdp() override ; private: - CodecId _codecid = CodecG711A; + CodecId _codecid; + int _sample_rate; + int _channels; + int _sample_bit; }; /** @@ -160,11 +166,17 @@ public: /** * G711采样率固定为8000 * @param codecId G711A G711U + * @param sample_rate 音频采样率 + * @param playload_type rtp playload + * @param bitrate 比特率 */ - G711Sdp(CodecId codecId) : Sdp(8000,payloadType(codecId)), _codecId(codecId){ - int pt = payloadType(codecId); - _printer << "m=audio 0 RTP/AVP " << pt << "\r\n"; - _printer << "a=rtpmap:" << pt << (codecId == CodecG711A ? " PCMA/" : " PCMU/") << 8000 << "\r\n"; + G711Sdp(CodecId codecId, + int sample_rate, + int channels, + int playload_type = 98, + int bitrate = 128) : Sdp(sample_rate,playload_type), _codecId(codecId){ + _printer << "m=audio 0 RTP/AVP " << playload_type << "\r\n"; + _printer << "a=rtpmap:" << playload_type << (codecId == CodecG711A ? " PCMA/" : " PCMU/") << sample_rate << "/" << channels << "\r\n"; _printer << "a=control:trackID=" << getTrackType() << "\r\n"; } @@ -180,14 +192,6 @@ public: return _codecId; } - int payloadType(CodecId codecId){ - switch (codecId){ - case CodecG711A : return 8; - case CodecG711U : return 0; - default : return -1; - } - } - private: _StrPrinter _printer; CodecId _codecId; diff --git a/src/Extension/G711Rtmp.cpp b/src/Extension/G711Rtmp.cpp index 854772fc..11e46d61 100644 --- a/src/Extension/G711Rtmp.cpp +++ b/src/Extension/G711Rtmp.cpp @@ -27,7 +27,7 @@ G711Frame::Ptr G711RtmpDecoder::obtainFrame() { bool G711RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) { //拷贝G711负载 - _frame->buffer.assign(pkt->strBuf.data() + 2, pkt->strBuf.size() - 2); + _frame->buffer.assign(pkt->strBuf.data() + 1, pkt->strBuf.size() - 1); _frame->timeStamp = pkt->timeStamp; //写入环形缓存 RtmpCodec::inputFrame(_frame); @@ -38,55 +38,17 @@ bool G711RtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) { ///////////////////////////////////////////////////////////////////////////////////// G711RtmpEncoder::G711RtmpEncoder(const Track::Ptr &track) : G711RtmpDecoder(track->getCodecId()) { - auto g711_track = dynamic_pointer_cast(track); - if(!g711_track){ - WarnL << "无效的G711 track, 将忽略打包为RTMP"; - return; - } - - auto iSampleRate = g711_track->getAudioSampleRate() ; - auto iChannel = g711_track->getAudioChannel(); - auto iSampleBit = g711_track->getAudioSampleBit(); - uint8_t flvStereoOrMono = (iChannel > 1); - uint8_t flvSampleRate; - switch (iSampleRate) { - case 48000: - case 44100: - flvSampleRate = 3; - break; - case 24000: - case 22050: - flvSampleRate = 2; - break; - case 12000: - case 11025: - flvSampleRate = 1; - break; - default: - flvSampleRate = 0; - break; - } - uint8_t flvSampleBit = iSampleBit == 16; - uint8_t flvAudioType ; - switch (g711_track->getCodecId()){ - case CodecG711A : flvAudioType = FLV_CODEC_G711A; break; - case CodecG711U : flvAudioType = FLV_CODEC_G711U; break; - default: WarnL << "无效的G711 track, 将忽略打包为RTMP"; return ; - } - - _g711_flags = (flvAudioType << 4) | (flvSampleRate << 2) | (flvSampleBit << 1) | flvStereoOrMono; + _audio_flv_flags = getAudioRtmpFlags(track); } void G711RtmpEncoder::inputFrame(const Frame::Ptr &frame) { - if(!_g711_flags){ + if(!_audio_flv_flags){ return; } RtmpPacket::Ptr rtmpPkt = ResourcePoolHelper::obtainObj(); rtmpPkt->strBuf.clear(); //header - uint8_t is_config = false; - rtmpPkt->strBuf.push_back(_g711_flags); - rtmpPkt->strBuf.push_back(!is_config); + rtmpPkt->strBuf.push_back(_audio_flv_flags); //g711 data rtmpPkt->strBuf.append(frame->data() + frame->prefixSize(), frame->size() - frame->prefixSize()); diff --git a/src/Extension/G711Rtmp.h b/src/Extension/G711Rtmp.h index 74b697e4..71f3e069 100644 --- a/src/Extension/G711Rtmp.h +++ b/src/Extension/G711Rtmp.h @@ -62,7 +62,7 @@ public: */ void inputFrame(const Frame::Ptr &frame) override; private: - uint8_t _g711_flags = 0; + uint8_t _audio_flv_flags = 0; }; }//namespace mediakit diff --git a/src/Rtmp/Rtmp.cpp b/src/Rtmp/Rtmp.cpp index 52a9111b..4749f3ea 100644 --- a/src/Rtmp/Rtmp.cpp +++ b/src/Rtmp/Rtmp.cpp @@ -36,11 +36,68 @@ AudioMeta::AudioMeta(const AudioTrack::Ptr &audio,int datarate){ _metadata.set("audiosamplesize", audio->getAudioSampleBit()); } if(audio->getAudioChannel() > 0){ - _metadata.set("audiochannels", audio->getAudioChannel()); _metadata.set("stereo", audio->getAudioChannel() > 1); } _codecId = audio->getCodecId(); _metadata.set("audiocodecid", Factory::getAmfByCodecId(_codecId)); } +uint8_t getAudioRtmpFlags(const Track::Ptr &track){ + switch (track->getTrackType()){ + case TrackAudio : { + auto audioTrack = dynamic_pointer_cast(track); + if (!audioTrack) { + WarnL << "获取AudioTrack失败"; + return 0; + } + auto iSampleRate = audioTrack->getAudioSampleRate(); + auto iChannel = audioTrack->getAudioChannel(); + auto iSampleBit = audioTrack->getAudioSampleBit(); + + uint8_t flvAudioType ; + switch (track->getCodecId()){ + case CodecG711A : flvAudioType = FLV_CODEC_G711A; break; + case CodecG711U : flvAudioType = FLV_CODEC_G711U; break; + case CodecAAC : { + flvAudioType = FLV_CODEC_AAC; + //aac不通过flags获取音频相关信息 + iSampleRate = 44100; + iSampleBit = 16; + iChannel = 2; + break; + } + default: WarnL << "该编码格式不支持转换为RTMP: " << track->getCodecName(); return 0; + } + + uint8_t flvSampleRate; + switch (iSampleRate) { + case 44100: + flvSampleRate = 3; + break; + case 22050: + flvSampleRate = 2; + break; + case 11025: + flvSampleRate = 1; + break; + case 16000: // nellymoser only + case 8000: // nellymoser only + case 5512: // not MP3 + flvSampleRate = 0; + break; + default: + WarnL << "FLV does not support sample rate " << iSampleRate << " ,choose from (44100, 22050, 11025)"; + return 0; + } + + uint8_t flvStereoOrMono = (iChannel > 1); + uint8_t flvSampleBit = iSampleBit == 16; + return (flvAudioType << 4) | (flvSampleRate << 2) | (flvSampleBit << 1) | flvStereoOrMono; + } + + default : return 0; + } +} + + }//namespace mediakit \ No newline at end of file diff --git a/src/Rtmp/Rtmp.h b/src/Rtmp/Rtmp.h index 073f8b04..ec4c4e72 100644 --- a/src/Rtmp/Rtmp.h +++ b/src/Rtmp/Rtmp.h @@ -161,27 +161,26 @@ public: strBuf = std::move(that.strBuf); } bool isVideoKeyFrame() const { - return typeId == MSG_VIDEO && (uint8_t) strBuf[0] >> 4 == FLV_KEY_FRAME - && (uint8_t) strBuf[1] == 1; + return typeId == MSG_VIDEO && (uint8_t) strBuf[0] >> 4 == FLV_KEY_FRAME && (uint8_t) strBuf[1] == 1; } bool isCfgFrame() const { - return (typeId == MSG_VIDEO || typeId == MSG_AUDIO) - && (uint8_t) strBuf[1] == 0; + switch (typeId){ + case MSG_VIDEO : return strBuf[1] == 0; + case MSG_AUDIO : { + switch (getMediaType()){ + case FLV_CODEC_AAC : return strBuf[1] == 0; + default : return false; + } + } + default : return false; + } } int getMediaType() const { switch (typeId) { - case MSG_VIDEO: { - return (uint8_t) strBuf[0] & 0x0F; - } - break; - case MSG_AUDIO: { - return (uint8_t) strBuf[0] >> 4; - } - break; - default: - break; + case MSG_VIDEO : return (uint8_t) strBuf[0] & 0x0F; + case MSG_AUDIO : return (uint8_t) strBuf[0] >> 4; + default : return 0; } - return 0; } int getAudioSampleRate() const { if (typeId != MSG_AUDIO) { @@ -314,6 +313,8 @@ private: CodecId _codecId; }; +//根据音频track获取flags +uint8_t getAudioRtmpFlags(const Track::Ptr &track); }//namespace mediakit diff --git a/src/Rtmp/RtmpDemuxer.cpp b/src/Rtmp/RtmpDemuxer.cpp index 26a3106f..4848a960 100644 --- a/src/Rtmp/RtmpDemuxer.cpp +++ b/src/Rtmp/RtmpDemuxer.cpp @@ -15,14 +15,55 @@ namespace mediakit { void RtmpDemuxer::loadMetaData(const AMFValue &val){ try { - makeVideoTrack(val["videocodecid"]); - makeAudioTrack(val["audiocodecid"]); + int audiosamplerate = 0; + int audiochannels = 0; + int audiosamplesize = 0; + const AMFValue *audiocodecid = nullptr; + const AMFValue *videocodecid = nullptr; + val.object_for_each([&](const string &key, const AMFValue &val) { if (key == "duration") { _fDuration = val.as_number(); return; } + + if(key == "audiosamplerate"){ + audiosamplerate = val.as_integer(); + return; + } + + if(key == "audiosamplesize"){ + audiosamplesize = val.as_integer(); + return; + } + + if(key == "stereo"){ + audiochannels = val.as_boolean() ? 2 : 1; + return; + } + + if(key == "videocodecid"){ + //找到视频 + videocodecid = &val; + return; + } + + if(key == "audiocodecid"){ + //找到音频 + audiocodecid = &val; + return; + } }); + + if(videocodecid){ + //有视频 + makeVideoTrack(*videocodecid); + } + + if(audiocodecid){ + //有音频 + makeAudioTrack(*audiocodecid, audiosamplerate, audiochannels, audiosamplesize); + } }catch (std::exception &ex){ WarnL << ex.what(); } @@ -46,7 +87,7 @@ bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) { if(!_tryedGetAudioTrack) { _tryedGetAudioTrack = true; auto codec = AMFValue(pkt->getMediaType()); - makeAudioTrack(codec); + makeAudioTrack(codec, pkt->getAudioSampleRate(), pkt->getAudioChannel(), pkt->getAudioSampleBit()); } if(_audioRtmpDecoder){ _audioRtmpDecoder->inputRtmp(pkt, false); @@ -69,6 +110,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { //设置rtmp解码器代理,生成的frame写入该Track _videoRtmpDecoder->addDelegate(_videoTrack); onAddTrack(_videoTrack); + _tryedGetVideoTrack = true; } else { //找不到相应的rtmp解码器,该track无效 _videoTrack.reset(); @@ -76,9 +118,9 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) { } } -void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) { +void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec,int sample_rate, int channels, int sample_bit) { //生成Track对象 - _audioTrack = dynamic_pointer_cast(Factory::getAudioTrackByAmf(audioCodec)); + _audioTrack = dynamic_pointer_cast(Factory::getAudioTrackByAmf(audioCodec, sample_rate, channels, sample_bit)); if (_audioTrack) { //生成rtmpCodec对象以便解码rtmp _audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack); @@ -86,6 +128,7 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) { //设置rtmp解码器代理,生成的frame写入该Track _audioRtmpDecoder->addDelegate(_audioTrack); onAddTrack(_audioTrack); + _tryedGetAudioTrack = true; } else { //找不到相应的rtmp解码器,该track无效 _audioTrack.reset(); diff --git a/src/Rtmp/RtmpDemuxer.h b/src/Rtmp/RtmpDemuxer.h index 6d1c264d..fbff5d2e 100644 --- a/src/Rtmp/RtmpDemuxer.h +++ b/src/Rtmp/RtmpDemuxer.h @@ -40,7 +40,7 @@ public: bool inputRtmp(const RtmpPacket::Ptr &pkt); private: void makeVideoTrack(const AMFValue &val); - void makeAudioTrack(const AMFValue &val); + void makeAudioTrack(const AMFValue &val, int sample_rate, int channels, int sample_bit); private: bool _tryedGetVideoTrack = false; bool _tryedGetAudioTrack = false; diff --git a/src/Rtmp/RtmpSession.cpp b/src/Rtmp/RtmpSession.cpp index 8d0d479e..8c9028fc 100644 --- a/src/Rtmp/RtmpSession.cpp +++ b/src/Rtmp/RtmpSession.cpp @@ -193,7 +193,6 @@ void RtmpSession::onCmd_deleteStream(AMFDecoder &dec) { throw std::runtime_error(StrPrinter << "Stop publishing" << endl); } - void RtmpSession::sendPlayResponse(const string &err,const RtmpMediaSource::Ptr &src){ bool authSuccess = err.empty(); bool ok = (src.operator bool() && authSuccess); diff --git a/src/Rtsp/Rtsp.cpp b/src/Rtsp/Rtsp.cpp index 8ae86f84..7828b5dc 100644 --- a/src/Rtsp/Rtsp.cpp +++ b/src/Rtsp/Rtsp.cpp @@ -172,6 +172,7 @@ void SdpParser::load(const string &sdp) { if (4 == sscanf(opt_val.data(), " %15[^ ] %d %15[^ ] %d", type, &port, rtp, &pt)) { track->_pt = pt; track->_samplerate = RtpPayload::getClockRate(pt) ; + track->_channel = RtpPayload::getAudioChannel(pt); track->_type = toTrackType(type); track->_m = opt_val; track->_port = port; @@ -214,9 +215,14 @@ void SdpParser::load(const string &sdp) { it = track._attr.find("rtpmap"); if(it != track._attr.end()){ auto rtpmap = it->second; - int pt, samplerate; + int pt, samplerate, channel; char codec[16] = {0}; - if (3 == sscanf(rtpmap.data(), "%d %15[^/]/%d", &pt, codec, &samplerate)) { + if (4 == sscanf(rtpmap.data(), "%d %15[^/]/%d/%d", &pt, codec, &samplerate, &channel)) { + track._pt = pt; + track._codec = codec; + track._samplerate = samplerate; + track._channel = channel; + }else if (3 == sscanf(rtpmap.data(), "%d %15[^/]/%d", &pt, codec, &samplerate)) { track._pt = pt; track._codec = codec; track._samplerate = samplerate; diff --git a/src/Rtsp/Rtsp.h b/src/Rtsp/Rtsp.h index a1debdf4..bf8040a3 100644 --- a/src/Rtsp/Rtsp.h +++ b/src/Rtsp/Rtsp.h @@ -128,6 +128,7 @@ public: int _pt; string _codec; int _samplerate; + int _channel; string _fmtp; string _control; string _control_surffix;