Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
40afa204
Commit
40afa204
authored
Apr 17, 2020
by
baiyfcu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加rtmp/rtsp对音频G711A,G711U的支持
parent
5fcc22ba
隐藏空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
123 行增加
和
16 行删除
+123
-16
api/include/mk_player.h
+12
-0
api/source/mk_player.cpp
+18
-0
src/Common/MediaSink.cpp
+18
-0
src/Extension/Factory.cpp
+42
-3
src/Extension/Factory.h
+17
-3
src/Extension/Frame.cpp
+2
-0
src/Extension/G711.cpp
+1
-1
src/Extension/G711.h
+2
-1
src/Extension/G711Rtmp.h
+1
-1
src/Extension/G711Rtp.cpp
+4
-4
src/Extension/G711Rtp.h
+1
-1
src/Rtmp/Rtmp.h
+3
-0
src/Rtmp/RtmpDemuxer.cpp
+2
-2
没有找到文件。
api/include/mk_player.h
查看文件 @
40afa204
...
...
@@ -106,6 +106,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
);
/**
* 获取视频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
);
/**
* 获取视频宽度
*/
API_EXPORT
int
API_CALL
mk_player_video_width
(
mk_player
ctx
);
...
...
@@ -121,6 +127,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
);
/**
* 获取音频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
);
/**
* 获取音频采样率
*/
API_EXPORT
int
API_CALL
mk_player_audio_samplerate
(
mk_player
ctx
);
...
...
api/source/mk_player.cpp
查看文件 @
40afa204
...
...
@@ -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
)
{
assert
(
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
;
}
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
)
{
assert
(
ctx
);
MediaPlayer
::
Ptr
&
player
=
*
((
MediaPlayer
::
Ptr
*
)
ctx
);
...
...
src/Common/MediaSink.cpp
查看文件 @
40afa204
...
...
@@ -35,6 +35,23 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
if
(
_allTrackReady
)
{
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
;
}
DebugL
<<
"all track ready use "
<<
_ticker
.
elapsedTime
()
<<
"ms"
;
if
(
!
_trackReadyCallback
.
empty
())
{
//这是超时强制忽略未准备好的Track
_trackReadyCallback
.
clear
();
...
...
src/Extension/Factory.cpp
查看文件 @
40afa204
...
...
@@ -169,7 +169,7 @@ RtpCodec::Ptr Factory::getRtpDecoderByTrack(const Track::Ptr &track) {
/////////////////////////////rtmp相关///////////////////////////////////////////
Track
::
Ptr
Factory
::
getTrackByAmf
(
const
AMFValue
&
amf
)
{
Track
::
Ptr
Factory
::
get
Video
TrackByAmf
(
const
AMFValue
&
amf
)
{
CodecId
codecId
=
getCodecIdByAmf
(
amf
);
if
(
codecId
==
CodecInvalid
){
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
){
if
(
val
.
type
()
==
AMF_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
)
{
switch
(
track
->
getCodecId
()){
case
CodecH264
:
...
...
@@ -234,8 +273,8 @@ AMFValue Factory::getAmfByCodecId(CodecId codecId) {
case
CodecAAC
:
return
AMFValue
(
"mp4a"
);
case
CodecH264
:
return
AMFValue
(
"avc1"
);
case
CodecH265
:
return
AMFValue
(
FLV_CODEC_H265
);
case
CodecG711A
:
return
AMFValue
(
7
);
case
CodecG711U
:
return
AMFValue
(
8
);
case
CodecG711A
:
return
AMFValue
(
FLV_CODEC_G711A
);
case
CodecG711U
:
return
AMFValue
(
FLV_CODEC_G711U
);
default
:
return
AMFValue
(
AMF_NULL
);
}
}
...
...
src/Extension/Factory.h
查看文件 @
40afa204
...
...
@@ -56,11 +56,18 @@ public:
////////////////////////////////rtmp相关//////////////////////////////////
/**
* 根据amf对象获取
响
应的Track
* @param amf rtmp metadata中的videocodecid
或audiocodecid
的值
* 根据amf对象获取
视频相
应的Track
* @param amf rtmp metadata中的videocodecid的值
* @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
...
...
@@ -70,6 +77,13 @@ public:
static
CodecId
getCodecIdByAmf
(
const
AMFValue
&
val
);
/**
* 根据amf对象获取音频相应的CodecId
* @param val rtmp metadata中的audiocodecid的值
* @return
*/
static
CodecId
getAudioCodecIdByAmf
(
const
AMFValue
&
val
);
/**
* 根据Track获取Rtmp的编解码器
* @param track 媒体描述对象
* @return
...
...
src/Extension/Frame.cpp
查看文件 @
40afa204
...
...
@@ -28,6 +28,8 @@ const char *CodecInfo::getCodecName() {
SWITCH_CASE
(
CodecH264
);
SWITCH_CASE
(
CodecH265
);
SWITCH_CASE
(
CodecAAC
);
SWITCH_CASE
(
CodecG711A
);
SWITCH_CASE
(
CodecG711U
);
default
:
return
"unknown codec"
;
}
...
...
src/Extension/G711.cpp
查看文件 @
40afa204
...
...
@@ -15,7 +15,7 @@ namespace mediakit{
Sdp
::
Ptr
G711Track
::
getSdp
()
{
if
(
!
ready
()){
WarnL
<<
"AAC
Track未准备好"
;
WarnL
<<
getCodecName
()
<<
"
Track未准备好"
;
return
nullptr
;
}
return
std
::
make_shared
<
G711Sdp
>
(
getCodecId
(),
getAudioSampleRate
(),
getCodecId
()
==
CodecG711A
?
8
:
0
,
getAudioSampleBit
());
...
...
src/Extension/G711.h
查看文件 @
40afa204
...
...
@@ -57,7 +57,7 @@ public:
}
CodecId
getCodecId
()
const
override
{
return
CodecAAC
;
return
_codecId
;
}
bool
keyFrame
()
const
override
{
...
...
@@ -68,6 +68,7 @@ public:
return
false
;
}
public
:
CodecId
_codecId
=
CodecG711A
;
unsigned
int
frameLength
;
// 一个帧的长度包括 raw data block
unsigned
char
buffer
[
2
*
1024
+
7
];
uint32_t
timeStamp
;
...
...
src/Extension/G711Rtmp.h
查看文件 @
40afa204
...
...
@@ -51,7 +51,7 @@ protected:
G711Frame
::
Ptr
obtainFrame
();
protected
:
G711Frame
::
Ptr
_adts
;
CodecId
_codecid
=
Codec
G711A
;
CodecId
_codecid
=
Codec
Invalid
;
};
...
...
src/Extension/G711Rtp.cpp
查看文件 @
40afa204
...
...
@@ -51,12 +51,11 @@ void G711RtpEncoder::makeG711Rtp(const void *data, unsigned int len, bool mark,
/////////////////////////////////////////////////////////////////////////////////////
G711RtpDecoder
::
G711RtpDecoder
(
const
Track
::
Ptr
&
track
){
auto
aac
Track
=
dynamic_pointer_cast
<
G711Track
>
(
track
);
_codecid
=
aac
Track
->
getCodecId
();
if
(
!
aacTrack
||
!
aac
Track
->
ready
()){
auto
g711
Track
=
dynamic_pointer_cast
<
G711Track
>
(
track
);
_codecid
=
g711
Track
->
getCodecId
();
if
(
!
g711Track
||
!
g711
Track
->
ready
()){
WarnL
<<
"该g711 track无效!"
;
}
else
{
//_aac_cfg = aacTrack->getAacCfg();
}
_adts
=
obtainFrame
();
}
...
...
@@ -81,6 +80,7 @@ bool G711RtpDecoder::inputRtp(const RtpPacket::Ptr &rtppack, bool key_pos) {
_adts
->
frameLength
=
length
;
memcpy
(
_adts
->
buffer
,
rtp_packet_buf
,
length
);
_adts
->
_codecId
=
_codecid
;
if
(
rtppack
->
mark
==
true
)
{
_adts
->
timeStamp
=
rtppack
->
timeStamp
;
onGetG711
(
_adts
);
...
...
src/Extension/G711Rtp.h
查看文件 @
40afa204
...
...
@@ -44,7 +44,7 @@ private:
G711Frame
::
Ptr
obtainFrame
();
private
:
G711Frame
::
Ptr
_adts
;
CodecId
_codecid
=
Codec
G711A
;
CodecId
_codecid
=
Codec
Invalid
;
};
...
...
src/Rtmp/Rtmp.h
查看文件 @
40afa204
...
...
@@ -75,6 +75,9 @@ using namespace toolkit;
#define FLV_CODEC_AAC 10
#define FLV_CODEC_H264 7
#define FLV_CODEC_H265 12
#define FLV_CODEC_G711A 7
#define FLV_CODEC_G711U 8
namespace
mediakit
{
...
...
src/Rtmp/RtmpDemuxer.cpp
查看文件 @
40afa204
...
...
@@ -61,7 +61,7 @@ bool RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
void
RtmpDemuxer
::
makeVideoTrack
(
const
AMFValue
&
videoCodec
)
{
//生成Track对象
_videoTrack
=
dynamic_pointer_cast
<
VideoTrack
>
(
Factory
::
getTrackByAmf
(
videoCodec
));
_videoTrack
=
dynamic_pointer_cast
<
VideoTrack
>
(
Factory
::
get
Video
TrackByAmf
(
videoCodec
));
if
(
_videoTrack
)
{
//生成rtmpCodec对象以便解码rtmp
_videoRtmpDecoder
=
Factory
::
getRtmpCodecByTrack
(
_videoTrack
);
...
...
@@ -78,7 +78,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
void
RtmpDemuxer
::
makeAudioTrack
(
const
AMFValue
&
audioCodec
)
{
//生成Track对象
_audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getTrackByAmf
(
audioCodec
));
_audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
get
Audio
TrackByAmf
(
audioCodec
));
if
(
_audioTrack
)
{
//生成rtmpCodec对象以便解码rtmp
_audioRtmpDecoder
=
Factory
::
getRtmpCodecByTrack
(
_audioTrack
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论