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
41509800
Commit
41509800
authored
4 years ago
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完善对无metadata的rtmp流的兼容性
parent
e7f263b0
显示空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
88 行增加
和
86 行删除
+88
-86
src/Extension/Factory.cpp
+16
-2
src/Extension/Factory.h
+2
-1
src/Rtmp/Rtmp.cpp
+20
-0
src/Rtmp/Rtmp.h
+2
-1
src/Rtmp/RtmpDemuxer.cpp
+15
-19
src/Rtmp/RtmpDemuxer.h
+1
-1
src/Rtmp/RtmpMediaSourceImp.h
+19
-1
src/Rtmp/RtmpMuxer.cpp
+3
-43
src/Rtmp/amf.cpp
+8
-14
src/Rtmp/amf.h
+2
-4
没有找到文件。
src/Extension/Factory.cpp
查看文件 @
41509800
...
...
@@ -221,13 +221,27 @@ Track::Ptr Factory::getAudioTrackByAmf(const AMFValue& amf, int sample_rate, int
return
getTrackByCodecId
(
codecId
,
sample_rate
,
channels
,
sample_bit
);
}
RtmpCodec
::
Ptr
Factory
::
getRtmpCodecByTrack
(
const
Track
::
Ptr
&
track
)
{
RtmpCodec
::
Ptr
Factory
::
getRtmpCodecByTrack
(
const
Track
::
Ptr
&
track
,
bool
is_encode
)
{
switch
(
track
->
getCodecId
()){
case
CodecH264
:
return
std
::
make_shared
<
H264RtmpEncoder
>
(
track
);
case
CodecAAC
:
return
std
::
make_shared
<
AACRtmpEncoder
>
(
track
);
case
CodecH265
:
return
std
::
make_shared
<
H265RtmpEncoder
>
(
track
);
case
CodecG711A
:
case
CodecG711U
:
return
std
::
make_shared
<
G711RtmpEncoder
>
(
track
);
case
CodecG711U
:
{
auto
audio_track
=
dynamic_pointer_cast
<
AudioTrack
>
(
track
);
if
(
is_encode
&&
(
audio_track
->
getAudioSampleRate
()
!=
8000
||
audio_track
->
getAudioChannel
()
!=
1
||
audio_track
->
getAudioSampleBit
()
!=
16
))
{
//rtmp对g711只支持8000/1/16规格,但是ZLMediaKit可以解析其他规格的G711
WarnL
<<
"RTMP只支持8000/1/16规格的G711,目前规格是:"
<<
audio_track
->
getAudioSampleRate
()
<<
"/"
<<
audio_track
->
getAudioChannel
()
<<
"/"
<<
audio_track
->
getAudioSampleBit
()
<<
",该音频已被忽略"
;
return
nullptr
;
}
return
std
::
make_shared
<
G711RtmpEncoder
>
(
track
);
}
default
:
WarnL
<<
"暂不支持该CodecId:"
<<
track
->
getCodecName
();
return
nullptr
;
}
}
...
...
This diff is collapsed.
Click to expand it.
src/Extension/Factory.h
查看文件 @
41509800
...
...
@@ -59,8 +59,9 @@ public:
/**
* 根据Track获取Rtmp的编解码器
* @param track 媒体描述对象
* @param is_encode 是否为编码器还是解码器
*/
static
RtmpCodec
::
Ptr
getRtmpCodecByTrack
(
const
Track
::
Ptr
&
track
);
static
RtmpCodec
::
Ptr
getRtmpCodecByTrack
(
const
Track
::
Ptr
&
track
,
bool
is_encode
);
/**
* 根据codecId获取rtmp的codec描述
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/Rtmp.cpp
查看文件 @
41509800
...
...
@@ -100,4 +100,23 @@ uint8_t getAudioRtmpFlags(const Track::Ptr &track){
}
void
Metadata
::
addTrack
(
AMFValue
&
metadata
,
const
Track
::
Ptr
&
track
)
{
Metadata
::
Ptr
new_metadata
;
switch
(
track
->
getTrackType
())
{
case
TrackVideo
:
{
new_metadata
=
std
::
make_shared
<
VideoMeta
>
(
dynamic_pointer_cast
<
VideoTrack
>
(
track
));
}
break
;
case
TrackAudio
:
{
new_metadata
=
std
::
make_shared
<
AudioMeta
>
(
dynamic_pointer_cast
<
AudioTrack
>
(
track
));
}
break
;
default
:
return
;
}
new_metadata
->
getMetadata
().
object_for_each
([
&
](
const
std
::
string
&
key
,
const
AMFValue
&
value
)
{
metadata
.
set
(
key
,
value
);
});
}
}
//
namespace
mediakit
\ No newline at end of file
This diff is collapsed.
Click to expand it.
src/Rtmp/Rtmp.h
查看文件 @
41509800
...
...
@@ -220,6 +220,8 @@ public:
const
AMFValue
&
getMetadata
()
const
{
return
_metadata
;
}
static
void
addTrack
(
AMFValue
&
metadata
,
const
Track
::
Ptr
&
track
);
protected
:
AMFValue
_metadata
;
};
...
...
@@ -261,7 +263,6 @@ private:
CodecId
_codecId
;
};
class
AudioMeta
:
public
Metadata
{
public
:
typedef
std
::
shared_ptr
<
AudioMeta
>
Ptr
;
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpDemuxer.cpp
查看文件 @
41509800
...
...
@@ -13,60 +13,56 @@
namespace
mediakit
{
void
RtmpDemuxer
::
loadMetaData
(
const
AMFValue
&
val
){
bool
RtmpDemuxer
::
loadMetaData
(
const
AMFValue
&
val
){
bool
ret
=
false
;
try
{
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"
){
if
(
key
==
"audiosamplerate"
)
{
audiosamplerate
=
val
.
as_integer
();
return
;
}
if
(
key
==
"audiosamplesize"
){
if
(
key
==
"audiosamplesize"
)
{
audiosamplesize
=
val
.
as_integer
();
return
;
}
if
(
key
==
"stereo"
){
if
(
key
==
"stereo"
)
{
audiochannels
=
val
.
as_boolean
()
?
2
:
1
;
return
;
}
if
(
key
==
"videocodecid"
){
if
(
key
==
"videocodecid"
)
{
//找到视频
videocodecid
=
&
val
;
return
;
}
if
(
key
==
"audiocodecid"
){
if
(
key
==
"audiocodecid"
)
{
//找到音频
audiocodecid
=
&
val
;
return
;
}
});
if
(
videocodecid
){
if
(
videocodecid
)
{
//有视频
ret
=
true
;
makeVideoTrack
(
*
videocodecid
);
}
if
(
audiocodecid
){
if
(
audiocodecid
)
{
//有音频
ret
=
true
;
makeAudioTrack
(
*
audiocodecid
,
audiosamplerate
,
audiochannels
,
audiosamplesize
);
}
}
catch
(
std
::
exception
&
ex
)
{
}
catch
(
std
::
exception
&
ex
)
{
WarnL
<<
ex
.
what
();
}
return
ret
;
}
bool
RtmpDemuxer
::
inputRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
...
...
@@ -105,7 +101,7 @@ void RtmpDemuxer::makeVideoTrack(const AMFValue &videoCodec) {
_videoTrack
=
dynamic_pointer_cast
<
VideoTrack
>
(
Factory
::
getVideoTrackByAmf
(
videoCodec
));
if
(
_videoTrack
)
{
//生成rtmpCodec对象以便解码rtmp
_videoRtmpDecoder
=
Factory
::
getRtmpCodecByTrack
(
_videoTrack
);
_videoRtmpDecoder
=
Factory
::
getRtmpCodecByTrack
(
_videoTrack
,
false
);
if
(
_videoRtmpDecoder
)
{
//设置rtmp解码器代理,生成的frame写入该Track
_videoRtmpDecoder
->
addDelegate
(
_videoTrack
);
...
...
@@ -123,7 +119,7 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec,int sample_rate, int
_audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getAudioTrackByAmf
(
audioCodec
,
sample_rate
,
channels
,
sample_bit
));
if
(
_audioTrack
)
{
//生成rtmpCodec对象以便解码rtmp
_audioRtmpDecoder
=
Factory
::
getRtmpCodecByTrack
(
_audioTrack
);
_audioRtmpDecoder
=
Factory
::
getRtmpCodecByTrack
(
_audioTrack
,
false
);
if
(
_audioRtmpDecoder
)
{
//设置rtmp解码器代理,生成的frame写入该Track
_audioRtmpDecoder
->
addDelegate
(
_audioTrack
);
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpDemuxer.h
查看文件 @
41509800
...
...
@@ -30,7 +30,7 @@ public:
RtmpDemuxer
()
=
default
;
virtual
~
RtmpDemuxer
()
=
default
;
void
loadMetaData
(
const
AMFValue
&
metadata
);
bool
loadMetaData
(
const
AMFValue
&
metadata
);
/**
* 开始解复用
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpMediaSourceImp.h
查看文件 @
41509800
...
...
@@ -49,9 +49,14 @@ public:
* 设置metadata
*/
void
setMetaData
(
const
AMFValue
&
metadata
)
override
{
_demuxer
->
loadMetaData
(
metadata
);
if
(
!
_demuxer
->
loadMetaData
(
metadata
)){
//该metadata无效,需要重新生成
_metadata
=
metadata
;
_recreate_metadata
=
true
;
}
else
{
RtmpMediaSource
::
setMetaData
(
metadata
);
}
}
/**
* 输入rtmp并解析
...
...
@@ -138,6 +143,11 @@ public:
_muxer
->
addTrack
(
track
);
track
->
addDelegate
(
_muxer
);
}
if
(
_recreate_metadata
){
//需要重新生成metadata
Metadata
::
addTrack
(
_metadata
,
track
);
}
}
/**
...
...
@@ -146,11 +156,19 @@ public:
void
onAllTrackReady
()
override
{
setTrackSource
(
_muxer
);
_all_track_ready
=
true
;
if
(
_recreate_metadata
){
//需要重新生成metadata
RtmpMediaSource
::
setMetaData
(
_metadata
);
}
}
private
:
RtmpDemuxer
::
Ptr
_demuxer
;
MultiMediaSourceMuxer
::
Ptr
_muxer
;
AMFValue
_metadata
;
bool
_all_track_ready
=
false
;
bool
_recreate_metadata
=
false
;
};
}
/* namespace mediakit */
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpMuxer.cpp
查看文件 @
41509800
...
...
@@ -23,47 +23,9 @@ RtmpMuxer::RtmpMuxer(const TitleMeta::Ptr &title) {
}
void
RtmpMuxer
::
addTrack
(
const
Track
::
Ptr
&
track
)
{
//根据track生产metadata
Metadata
::
Ptr
metadata
;
switch
(
track
->
getTrackType
()){
case
TrackVideo
:{
metadata
=
std
::
make_shared
<
VideoMeta
>
(
dynamic_pointer_cast
<
VideoTrack
>
(
track
));
}
break
;
case
TrackAudio
:{
metadata
=
std
::
make_shared
<
AudioMeta
>
(
dynamic_pointer_cast
<
AudioTrack
>
(
track
));
}
break
;
default
:
return
;
}
switch
(
track
->
getCodecId
()){
case
CodecG711A
:
case
CodecG711U
:{
auto
audio_track
=
dynamic_pointer_cast
<
AudioTrack
>
(
track
);
if
(
!
audio_track
){
return
;
}
if
(
audio_track
->
getAudioSampleRate
()
!=
8000
||
audio_track
->
getAudioChannel
()
!=
1
||
audio_track
->
getAudioSampleBit
()
!=
16
)
{
WarnL
<<
"RTMP只支持8000/1/16规格的G711,目前规格是:"
<<
audio_track
->
getAudioSampleRate
()
<<
"/"
<<
audio_track
->
getAudioChannel
()
<<
"/"
<<
audio_track
->
getAudioSampleBit
()
<<
",该音频已被忽略"
;
return
;
}
break
;
}
default
:
break
;
}
auto
&
encoder
=
_encoder
[
track
->
getTrackType
()];
//生成rtmp编码器,克隆该Track,防止循环引用
encoder
=
Factory
::
getRtmpCodecByTrack
(
track
->
clone
());
encoder
=
Factory
::
getRtmpCodecByTrack
(
track
->
clone
()
,
true
);
if
(
!
encoder
)
{
return
;
}
...
...
@@ -71,10 +33,8 @@ void RtmpMuxer::addTrack(const Track::Ptr &track) {
//设置rtmp输出环形缓存
encoder
->
setRtmpRing
(
_rtmpRing
);
//添加其metadata
metadata
->
getMetadata
().
object_for_each
([
&
](
const
std
::
string
&
key
,
const
AMFValue
&
value
){
_metadata
.
set
(
key
,
value
);
});
//添加metadata
Metadata
::
addTrack
(
_metadata
,
track
);
}
void
RtmpMuxer
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/amf.cpp
查看文件 @
41509800
...
...
@@ -44,6 +44,7 @@ inline void AMFValue::destroy() {
break
;
}
}
inline
void
AMFValue
::
init
()
{
switch
(
_type
)
{
case
AMF_OBJECT
:
...
...
@@ -60,14 +61,13 @@ inline void AMFValue::init() {
default
:
break
;
}
}
AMFValue
::
AMFValue
(
AMFType
type
)
:
_type
(
type
)
{
init
();
}
AMFValue
::~
AMFValue
()
{
destroy
();
}
...
...
@@ -78,7 +78,6 @@ AMFValue::AMFValue(const char *s) :
*
_value
.
string
=
s
;
}
AMFValue
::
AMFValue
(
const
std
::
string
&
s
)
:
_type
(
AMF_STRING
)
{
init
();
...
...
@@ -108,15 +107,7 @@ AMFValue::AMFValue(const AMFValue &from) :
*
this
=
from
;
}
AMFValue
::
AMFValue
(
AMFValue
&&
from
)
{
*
this
=
std
::
forward
<
AMFValue
>
(
from
);
}
AMFValue
&
AMFValue
::
operator
=
(
const
AMFValue
&
from
)
{
return
*
this
=
const_cast
<
AMFValue
&&>
(
from
);
}
AMFValue
&
AMFValue
::
operator
=
(
AMFValue
&&
from
)
{
AMFValue
&
AMFValue
::
operator
=
(
const
AMFValue
&
from
)
{
destroy
();
_type
=
from
.
_type
;
init
();
...
...
@@ -144,7 +135,6 @@ AMFValue& AMFValue::operator =(AMFValue &&from) {
break
;
}
return
*
this
;
}
void
AMFValue
::
clear
()
{
...
...
@@ -236,7 +226,6 @@ string AMFValue::to_string() const{
}
}
const
AMFValue
&
AMFValue
::
operator
[](
const
char
*
str
)
const
{
if
(
_type
!=
AMF_OBJECT
&&
_type
!=
AMF_ECMA_ARRAY
)
{
throw
std
::
runtime_error
(
"AMF not a object"
);
...
...
@@ -338,6 +327,7 @@ AMFEncoder & AMFEncoder::operator <<(const char *s) {
}
return
*
this
;
}
AMFEncoder
&
AMFEncoder
::
operator
<<
(
const
std
::
string
&
s
)
{
if
(
!
s
.
empty
())
{
buf
+=
char
(
AMF0_STRING
);
...
...
@@ -349,18 +339,22 @@ AMFEncoder & AMFEncoder::operator <<(const std::string &s) {
}
return
*
this
;
}
AMFEncoder
&
AMFEncoder
::
operator
<<
(
std
::
nullptr_t
)
{
buf
+=
char
(
AMF0_NULL
);
return
*
this
;
}
AMFEncoder
&
AMFEncoder
::
write_undefined
()
{
buf
+=
char
(
AMF0_UNDEFINED
);
return
*
this
;
}
AMFEncoder
&
AMFEncoder
::
operator
<<
(
const
int
n
){
return
(
*
this
)
<<
(
double
)
n
;
}
AMFEncoder
&
AMFEncoder
::
operator
<<
(
const
double
n
)
{
buf
+=
char
(
AMF0_NUMBER
);
uint64_t
encoded
=
0
;
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/amf.h
查看文件 @
41509800
...
...
@@ -40,6 +40,7 @@ public:
typedef
std
::
map
<
std
::
string
,
AMFValue
>
mapType
;
typedef
std
::
vector
<
AMFValue
>
arrayType
;
~
AMFValue
();
AMFValue
(
AMFType
type
=
AMF_NULL
);
AMFValue
(
const
char
*
s
);
AMFValue
(
const
std
::
string
&
s
);
...
...
@@ -47,10 +48,7 @@ public:
AMFValue
(
int
i
);
AMFValue
(
bool
b
);
AMFValue
(
const
AMFValue
&
from
);
AMFValue
(
AMFValue
&&
from
);
AMFValue
&
operator
=
(
const
AMFValue
&
from
);
AMFValue
&
operator
=
(
AMFValue
&&
from
);
~
AMFValue
();
AMFValue
&
operator
=
(
const
AMFValue
&
from
);
void
clear
();
AMFType
type
()
const
;
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论