mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
增加rtmp/rtsp对音频G711A,G711U的支持
This commit is contained in:
parent
5fcc22bab7
commit
40afa204d5
@ -105,6 +105,12 @@ API_EXPORT void API_CALL mk_player_set_on_shutdown(mk_player ctx, on_mk_play_eve
|
|||||||
*/
|
*/
|
||||||
API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb, void *user_data);
|
API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb, void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U
|
||||||
|
* @param ctx 播放器指针
|
||||||
|
*/
|
||||||
|
API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取视频宽度
|
* 获取视频宽度
|
||||||
*/
|
*/
|
||||||
@ -120,6 +126,12 @@ API_EXPORT int API_CALL mk_player_video_height(mk_player ctx);
|
|||||||
*/
|
*/
|
||||||
API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx);
|
API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取音频codec_id -1:不存在 0:H264,1:H265,2:AAC 3.G711A 4.G711U
|
||||||
|
* @param ctx 播放器指针
|
||||||
|
*/
|
||||||
|
API_EXPORT int API_CALL mk_player_audio_codecId(mk_player ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取音频采样率
|
* 获取音频采样率
|
||||||
*/
|
*/
|
||||||
|
@ -101,6 +101,15 @@ API_EXPORT void API_CALL mk_player_set_on_data(mk_player ctx, on_mk_play_data cb
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API_EXPORT int API_CALL mk_player_video_codecId(mk_player ctx)
|
||||||
|
{
|
||||||
|
assert(ctx);
|
||||||
|
MediaPlayer::Ptr& player = *((MediaPlayer::Ptr*)ctx);
|
||||||
|
auto track = dynamic_pointer_cast<VideoTrack>(player->getTrack(TrackVideo));
|
||||||
|
return track ? track->getCodecId() : CodecInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) {
|
API_EXPORT int API_CALL mk_player_video_width(mk_player ctx) {
|
||||||
assert(ctx);
|
assert(ctx);
|
||||||
MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx);
|
MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx);
|
||||||
@ -122,6 +131,15 @@ API_EXPORT int API_CALL mk_player_video_fps(mk_player ctx) {
|
|||||||
return track ? track->getVideoFps() : 0;
|
return track ? track->getVideoFps() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
API_EXPORT int API_CALL mk_player_audio_codecId(mk_player ctx)
|
||||||
|
{
|
||||||
|
assert(ctx);
|
||||||
|
MediaPlayer::Ptr& player = *((MediaPlayer::Ptr*)ctx);
|
||||||
|
auto track = dynamic_pointer_cast<AudioTrack>(player->getTrack(TrackAudio));
|
||||||
|
return track ? track->getCodecId() : CodecInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) {
|
API_EXPORT int API_CALL mk_player_audio_samplerate(mk_player ctx) {
|
||||||
assert(ctx);
|
assert(ctx);
|
||||||
MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx);
|
MediaPlayer::Ptr &player = *((MediaPlayer::Ptr *)ctx);
|
||||||
|
@ -35,6 +35,23 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
|
|||||||
if (_allTrackReady) {
|
if (_allTrackReady) {
|
||||||
onTrackFrame(frame);
|
onTrackFrame(frame);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (frame->getTrackType() == TrackVideo)
|
||||||
|
{
|
||||||
|
checkTrackIfReady(nullptr);
|
||||||
|
|
||||||
|
if (_allTrackReady) {
|
||||||
|
onTrackFrame(frame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorL << " 还有track未准备好,丢帧 codecName: " << frame->getCodecName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}else
|
||||||
|
ErrorL << " 还有track未准备好,丢帧 codecName: " << frame->getCodecName();
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +133,7 @@ void MediaSink::emitAllTrackReady() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DebugL << "all track ready use " << _ticker.elapsedTime() << "ms";
|
||||||
if (!_trackReadyCallback.empty()) {
|
if (!_trackReadyCallback.empty()) {
|
||||||
//这是超时强制忽略未准备好的Track
|
//这是超时强制忽略未准备好的Track
|
||||||
_trackReadyCallback.clear();
|
_trackReadyCallback.clear();
|
||||||
|
@ -169,7 +169,7 @@ RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) {
|
|||||||
|
|
||||||
/////////////////////////////rtmp相关///////////////////////////////////////////
|
/////////////////////////////rtmp相关///////////////////////////////////////////
|
||||||
|
|
||||||
Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) {
|
Track::Ptr Factory::getVideoTrackByAmf(const AMFValue &amf) {
|
||||||
CodecId codecId = getCodecIdByAmf(amf);
|
CodecId codecId = getCodecIdByAmf(amf);
|
||||||
if(codecId == CodecInvalid){
|
if(codecId == CodecInvalid){
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -178,6 +178,15 @@ Track::Ptr Factory::getTrackByAmf(const AMFValue &amf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mediakit::Track::Ptr Factory::getAudioTrackByAmf(const AMFValue& amf)
|
||||||
|
{
|
||||||
|
CodecId codecId = getAudioCodecIdByAmf(amf);
|
||||||
|
if (codecId == CodecInvalid) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return getTrackByCodecId(codecId);
|
||||||
|
}
|
||||||
|
|
||||||
CodecId Factory::getCodecIdByAmf(const AMFValue &val){
|
CodecId Factory::getCodecIdByAmf(const AMFValue &val){
|
||||||
if (val.type() == AMF_STRING){
|
if (val.type() == AMF_STRING){
|
||||||
auto str = val.as_string();
|
auto str = val.as_string();
|
||||||
@ -212,6 +221,36 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CodecId Factory::getAudioCodecIdByAmf(const AMFValue& val)
|
||||||
|
{
|
||||||
|
if (val.type() == AMF_STRING) {
|
||||||
|
auto str = val.as_string();
|
||||||
|
if (str == "mp4a") {
|
||||||
|
return CodecAAC;
|
||||||
|
}
|
||||||
|
WarnL << "暂不支持该Amf:" << str;
|
||||||
|
return CodecInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val.type() != AMF_NULL) {
|
||||||
|
auto type_id = val.as_integer();
|
||||||
|
switch (type_id) {
|
||||||
|
case FLV_CODEC_AAC: return CodecAAC;
|
||||||
|
case FLV_CODEC_G711A: return CodecG711A;
|
||||||
|
case FLV_CODEC_G711U: return CodecG711U;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WarnL << "暂不支持该Amf:" << type_id;
|
||||||
|
return CodecInvalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WarnL << "Metadata不存在相应的Track";
|
||||||
|
}
|
||||||
|
|
||||||
|
return CodecInvalid;
|
||||||
|
}
|
||||||
|
|
||||||
RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) {
|
RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track) {
|
||||||
switch (track->getCodecId()){
|
switch (track->getCodecId()){
|
||||||
case CodecH264:
|
case CodecH264:
|
||||||
@ -234,8 +273,8 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) {
|
|||||||
case CodecAAC: return AMFValue("mp4a");
|
case CodecAAC: return AMFValue("mp4a");
|
||||||
case CodecH264: return AMFValue("avc1");
|
case CodecH264: return AMFValue("avc1");
|
||||||
case CodecH265: return AMFValue(FLV_CODEC_H265);
|
case CodecH265: return AMFValue(FLV_CODEC_H265);
|
||||||
case CodecG711A: return AMFValue(7);
|
case CodecG711A: return AMFValue(FLV_CODEC_G711A);
|
||||||
case CodecG711U: return AMFValue(8);
|
case CodecG711U: return AMFValue(FLV_CODEC_G711U);
|
||||||
default: return AMFValue(AMF_NULL);
|
default: return AMFValue(AMF_NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,11 +56,18 @@ public:
|
|||||||
////////////////////////////////rtmp相关//////////////////////////////////
|
////////////////////////////////rtmp相关//////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据amf对象获取响应的Track
|
* 根据amf对象获取视频相应的Track
|
||||||
* @param amf rtmp metadata中的videocodecid或audiocodecid的值
|
* @param amf rtmp metadata中的videocodecid的值
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static Track::Ptr getTrackByAmf(const AMFValue &amf);
|
static Track::Ptr getVideoTrackByAmf(const AMFValue &amf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据amf对象获取音频相应的Track
|
||||||
|
* @param amf rtmp metadata中的audiocodecid的值
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static Track::Ptr getAudioTrackByAmf(const AMFValue& amf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据amf对象获取相应的CodecId
|
* 根据amf对象获取相应的CodecId
|
||||||
@ -69,6 +76,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
static CodecId getCodecIdByAmf(const AMFValue &val);
|
static CodecId getCodecIdByAmf(const AMFValue &val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据amf对象获取音频相应的CodecId
|
||||||
|
* @param val rtmp metadata中的audiocodecid的值
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static CodecId getAudioCodecIdByAmf(const AMFValue& val);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据Track获取Rtmp的编解码器
|
* 根据Track获取Rtmp的编解码器
|
||||||
* @param track 媒体描述对象
|
* @param track 媒体描述对象
|
||||||
|
@ -28,6 +28,8 @@ const char *CodecInfo::getCodecName() {
|
|||||||
SWITCH_CASE(CodecH264);
|
SWITCH_CASE(CodecH264);
|
||||||
SWITCH_CASE(CodecH265);
|
SWITCH_CASE(CodecH265);
|
||||||
SWITCH_CASE(CodecAAC);
|
SWITCH_CASE(CodecAAC);
|
||||||
|
SWITCH_CASE(CodecG711A);
|
||||||
|
SWITCH_CASE(CodecG711U);
|
||||||
default:
|
default:
|
||||||
return "unknown codec";
|
return "unknown codec";
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ namespace mediakit{
|
|||||||
|
|
||||||
Sdp::Ptr G711Track::getSdp() {
|
Sdp::Ptr G711Track::getSdp() {
|
||||||
if(!ready()){
|
if(!ready()){
|
||||||
WarnL << "AAC Track未准备好";
|
WarnL << getCodecName() << " Track未准备好";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getCodecId() == CodecG711A ? 8 : 0, getAudioSampleBit());
|
return std::make_shared<G711Sdp>(getCodecId(), getAudioSampleRate(), getCodecId() == CodecG711A ? 8 : 0, getAudioSampleBit());
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CodecId getCodecId() const override{
|
CodecId getCodecId() const override{
|
||||||
return CodecAAC;
|
return _codecId;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool keyFrame() const override {
|
bool keyFrame() const override {
|
||||||
@ -68,6 +68,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
CodecId _codecId = CodecG711A;
|
||||||
unsigned int frameLength; // 一个帧的长度包括 raw data block
|
unsigned int frameLength; // 一个帧的长度包括 raw data block
|
||||||
unsigned char buffer[2 * 1024 + 7];
|
unsigned char buffer[2 * 1024 + 7];
|
||||||
uint32_t timeStamp;
|
uint32_t timeStamp;
|
||||||
|
@ -51,7 +51,7 @@ protected:
|
|||||||
G711Frame::Ptr obtainFrame();
|
G711Frame::Ptr obtainFrame();
|
||||||
protected:
|
protected:
|
||||||
G711Frame::Ptr _adts;
|
G711Frame::Ptr _adts;
|
||||||
CodecId _codecid = CodecG711A;
|
CodecId _codecid = CodecInvalid;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,12 +51,11 @@ void G711RtpEncoder::makeG711Rtp(const void *data, unsigned int len, bool mark,
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
G711RtpDecoder::G711RtpDecoder(const Track::Ptr &track){
|
G711RtpDecoder::G711RtpDecoder(const Track::Ptr &track){
|
||||||
auto aacTrack = dynamic_pointer_cast<G711Track>(track);
|
auto g711Track = dynamic_pointer_cast<G711Track>(track);
|
||||||
_codecid = aacTrack->getCodecId();
|
_codecid = g711Track->getCodecId();
|
||||||
if(!aacTrack || !aacTrack->ready()){
|
if(!g711Track || !g711Track->ready()){
|
||||||
WarnL << "该g711 track无效!";
|
WarnL << "该g711 track无效!";
|
||||||
}else{
|
}else{
|
||||||
//_aac_cfg = aacTrack->getAacCfg();
|
|
||||||
}
|
}
|
||||||
_adts = obtainFrame();
|
_adts = obtainFrame();
|
||||||
}
|
}
|
||||||
@ -81,6 +80,7 @@ bool G711RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
|
|||||||
|
|
||||||
_adts->frameLength = length;
|
_adts->frameLength = length;
|
||||||
memcpy(_adts->buffer, rtp_packet_buf, length);
|
memcpy(_adts->buffer, rtp_packet_buf, length);
|
||||||
|
_adts->_codecId = _codecid;
|
||||||
if (rtppack->mark == true) {
|
if (rtppack->mark == true) {
|
||||||
_adts->timeStamp = rtppack->timeStamp;
|
_adts->timeStamp = rtppack->timeStamp;
|
||||||
onGetG711(_adts);
|
onGetG711(_adts);
|
||||||
|
@ -44,7 +44,7 @@ private:
|
|||||||
G711Frame::Ptr obtainFrame();
|
G711Frame::Ptr obtainFrame();
|
||||||
private:
|
private:
|
||||||
G711Frame::Ptr _adts;
|
G711Frame::Ptr _adts;
|
||||||
CodecId _codecid = CodecG711A;
|
CodecId _codecid = CodecInvalid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,6 +75,9 @@ using namespace toolkit;
|
|||||||
#define FLV_CODEC_AAC 10
|
#define FLV_CODEC_AAC 10
|
||||||
#define FLV_CODEC_H264 7
|
#define FLV_CODEC_H264 7
|
||||||
#define FLV_CODEC_H265 12
|
#define FLV_CODEC_H265 12
|
||||||
|
#define FLV_CODEC_G711A 7
|
||||||
|
#define FLV_CODEC_G711U 8
|
||||||
|
|
||||||
|
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
|
|||||||
|
|
||||||
void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
|
void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
|
||||||
//生成Track对象
|
//生成Track对象
|
||||||
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getTrackByAmf(videoCodec));
|
_videoTrack = dynamic_pointer_cast<VideoTrack>(Factory::getVideoTrackByAmf(videoCodec));
|
||||||
if (_videoTrack) {
|
if (_videoTrack) {
|
||||||
//生成rtmpCodec对象以便解码rtmp
|
//生成rtmpCodec对象以便解码rtmp
|
||||||
_videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
|
_videoRtmpDecoder = Factory::getRtmpCodecByTrack(_videoTrack);
|
||||||
@ -78,7 +78,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
|
|||||||
|
|
||||||
void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
|
void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
|
||||||
//生成Track对象
|
//生成Track对象
|
||||||
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getTrackByAmf(audioCodec));
|
_audioTrack = dynamic_pointer_cast<AudioTrack>(Factory::getAudioTrackByAmf(audioCodec));
|
||||||
if (_audioTrack) {
|
if (_audioTrack) {
|
||||||
//生成rtmpCodec对象以便解码rtmp
|
//生成rtmpCodec对象以便解码rtmp
|
||||||
_audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
|
_audioRtmpDecoder = Factory::getRtmpCodecByTrack(_audioTrack);
|
||||||
|
Loading…
Reference in New Issue
Block a user