diff --git a/README.md b/README.md index e50cd748..891d16c1 100644 --- a/README.md +++ b/README.md @@ -1217,7 +1217,7 @@ For more advanced options, you can create and serve a custom web page by startin * WebRTC * [WebRTC: Real-Time Communication in Browsers](https://www.w3.org/TR/webrtc/) - * [WebRTC Ingestion Protocol (WHIP)](https://datatracker.ietf.org/doc/draft-ietf-wish-whip/) + * [WebRTC HTTP Ingestion Protocol (WHIP)](https://datatracker.ietf.org/doc/draft-ietf-wish-whip/) * [WebRTC HTTP Egress Protocol (WHEP)](https://datatracker.ietf.org/doc/draft-murillo-whep/) * Video and audio codecs diff --git a/internal/rtmp/tracks/read.go b/internal/rtmp/tracks/read.go index 2026a2b5..88b4c4b3 100644 --- a/internal/rtmp/tracks/read.go +++ b/internal/rtmp/tracks/read.go @@ -44,7 +44,7 @@ func trackFromH264DecoderConfig(data []byte) (formats.Format, error) { }, nil } -func trackFromAACDecoderConfig(data []byte) (*formats.MPEG4Audio, error) { +func trackFromAACDecoderConfig(data []byte) (formats.Format, error) { var mpegConf mpeg4audio.Config err := mpegConf.Unmarshal(data) if err != nil { @@ -261,10 +261,10 @@ func readTracksFromMetadata(r *message.ReadWriter, payload []interface{}) (forma } } -func readTracksFromMessages(r *message.ReadWriter, msg message.Message) (formats.Format, *formats.MPEG4Audio, error) { +func readTracksFromMessages(r *message.ReadWriter, msg message.Message) (formats.Format, formats.Format, error) { var startTime *time.Duration var videoTrack formats.Format - var audioTrack *formats.MPEG4Audio + var audioTrack formats.Format // analyze 1 second of packets outer: diff --git a/internal/rtmp/tracks/read_test.go b/internal/rtmp/tracks/read_test.go index 0c0b87ba..5a4e6847 100644 --- a/internal/rtmp/tracks/read_test.go +++ b/internal/rtmp/tracks/read_test.go @@ -63,7 +63,7 @@ func TestRead(t *testing.T) { nil, }, { - "metadata without codec id", + "metadata without codec id, video+audio", &formats.H264{ PayloadTyp: 96, SPS: sps, @@ -82,6 +82,16 @@ func TestRead(t *testing.T) { IndexDeltaLength: 3, }, }, + { + "metadata without codec id, video only", + &formats.H264{ + PayloadTyp: 96, + SPS: sps, + PPS: pps, + PacketizationMode: 1, + }, + nil, + }, { "missing metadata, video+audio", &formats.H264{ @@ -266,7 +276,7 @@ func TestRead(t *testing.T) { }) require.NoError(t, err) - case "metadata without codec id": + case "metadata without codec id, video+audio": err := mrw.Write(&message.DataAMF0{ ChunkStreamID: 4, MessageStreamID: 1, @@ -325,6 +335,57 @@ func TestRead(t *testing.T) { }) require.NoError(t, err) + case "metadata without codec id, video only": + err := mrw.Write(&message.DataAMF0{ + ChunkStreamID: 4, + MessageStreamID: 1, + Payload: []interface{}{ + "@setDataFrame", + "onMetaData", + flvio.AMFMap{ + { + K: "width", + V: float64(2688), + }, + { + K: "height", + V: float64(1520), + }, + { + K: "framerate", + V: float64(0o25), + }, + }, + }, + }) + require.NoError(t, err) + + buf, _ := h264conf.Conf{ + SPS: sps, + PPS: pps, + }.Marshal() + + err = mrw.Write(&message.Video{ + ChunkStreamID: message.VideoChunkStreamID, + MessageStreamID: 0x1000000, + Codec: message.CodecH264, + IsKeyFrame: true, + Type: message.VideoTypeConfig, + Payload: buf, + }) + require.NoError(t, err) + + err = mrw.Write(&message.Video{ + ChunkStreamID: message.VideoChunkStreamID, + MessageStreamID: 0x1000000, + Codec: message.CodecH264, + IsKeyFrame: true, + Type: message.VideoTypeAU, + Payload: []byte{0x01, 0x02, 0x03, 0x04}, + DTS: 1 * time.Second, + }) + require.NoError(t, err) + case "missing metadata, video+audio": buf, _ := h264conf.Conf{ SPS: sps,