rtmp: fix reading metadata from onMetadata

when there's no audio and Conn is a client, onMetadata was skipped and
tracks were read by using the fallback method. Fix this.
This commit is contained in:
aler9 2022-08-16 12:53:41 +02:00
parent a19a20abfb
commit 4990e98993
2 changed files with 79 additions and 9 deletions

View File

@ -802,7 +802,28 @@ outer:
// ReadTracks reads track informations.
func (c *Conn) ReadTracks() (*gortsplib.TrackH264, *gortsplib.TrackMPEG4Audio, error) {
msg, err := c.ReadMessage()
msg, err := func() (message.Message, error) {
for {
msg, err := c.ReadMessage()
if err != nil {
return nil, err
}
// skip play start and data start
if cmd, ok := msg.(*message.MsgCommandAMF0); ok && cmd.Name == "onStatus" {
continue
}
// skip RtmpSampleAccess
if data, ok := msg.(*message.MsgDataAMF0); ok && len(data.Payload) >= 1 {
if s, ok := data.Payload[0].(string); ok && s == "|RtmpSampleAccess" {
continue
}
}
return msg, nil
}
}()
if err != nil {
return nil, nil, err
}
@ -810,11 +831,6 @@ func (c *Conn) ReadTracks() (*gortsplib.TrackH264, *gortsplib.TrackMPEG4Audio, e
if data, ok := msg.(*message.MsgDataAMF0); ok && len(data.Payload) >= 1 {
payload := data.Payload
// skip packet
if s, ok := payload[0].(string); ok && s == "|RtmpSampleAccess" {
return c.ReadTracks()
}
if s, ok := payload[0].(string); ok && s == "@setDataFrame" {
payload = payload[1:]
}

View File

@ -495,7 +495,8 @@ func TestReadTracks(t *testing.T) {
}
for _, ca := range []string{
"standard",
"video+audio",
"video",
"metadata without codec id",
"missing metadata",
} {
@ -519,7 +520,7 @@ func TestReadTracks(t *testing.T) {
require.NoError(t, err)
switch ca {
case "standard":
case "video+audio":
require.Equal(t, &gortsplib.TrackH264{
PayloadType: 96,
SPS: sps,
@ -538,6 +539,15 @@ func TestReadTracks(t *testing.T) {
IndexDeltaLength: 3,
}, audioTrack)
case "video":
require.Equal(t, &gortsplib.TrackH264{
PayloadType: 96,
SPS: sps,
PPS: pps,
}, videoTrack)
require.Nil(t, audioTrack)
case "metadata without codec id":
require.Equal(t, &gortsplib.TrackH264{
PayloadType: 96,
@ -740,7 +750,7 @@ func TestReadTracks(t *testing.T) {
}, msg)
switch ca {
case "standard":
case "video+audio":
// C->S metadata
err = mrw.Write(&message.MsgDataAMF0{
ChunkStreamID: 4,
@ -802,6 +812,50 @@ func TestReadTracks(t *testing.T) {
})
require.NoError(t, err)
case "video":
// C->S metadata
err = mrw.Write(&message.MsgDataAMF0{
ChunkStreamID: 4,
MessageStreamID: 1,
Payload: []interface{}{
"@setDataFrame",
"onMetaData",
flvio.AMFMap{
{
K: "videodatarate",
V: float64(0),
},
{
K: "videocodecid",
V: float64(codecH264),
},
{
K: "audiodatarate",
V: float64(0),
},
{
K: "audiocodecid",
V: float64(0),
},
},
},
})
require.NoError(t, err)
// C->S H264 decoder config
buf, _ := h264conf.Conf{
SPS: sps,
PPS: pps,
}.Marshal()
err = mrw.Write(&message.MsgVideo{
ChunkStreamID: 6,
MessageStreamID: 1,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Payload: buf,
})
require.NoError(t, err)
case "metadata without codec id":
// C->S metadata
err = mrw.Write(&message.MsgDataAMF0{