Browse Source

cleanup (#1754)

pull/1755/head
Alessandro Ros 2 years ago committed by GitHub
parent
commit
22fe65509b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      README.md
  2. 39
      internal/core/rtmp_conn.go
  3. 7
      internal/core/rtmp_server_test.go
  4. 4
      internal/core/rtmp_source_test.go
  5. 2
      internal/formatprocessor/mpeg2audio.go
  6. 2
      internal/formatprocessor/mpeg4audio.go
  7. 41
      internal/rtmp/conn.go
  8. 38
      internal/rtmp/conn_test.go
  9. 21
      internal/rtmp/message/msg_audio.go
  10. 37
      internal/rtmp/message/msg_video.go
  11. 5
      internal/rtmp/message/reader_test.go

12
README.md

@ -10,10 +10,10 @@ Live streams can be published to the server with: @@ -10,10 +10,10 @@ Live streams can be published to the server with:
|protocol|variants|codecs|
|--------|--------|------|
|RTSP clients (FFmpeg, GStreamer, etc)|UDP, TCP, RTSPS|H264, H265, VP8, VP9, AV1, MPEG-2 video, M-JPEG, MPEG-4 video, MPEG-2 audio (MP3), MPEG-4 Audio (AAC), Opus, G711, G722, LPCM and any RTP-compatible codec|
|RTSP servers and cameras|UDP, UDP-Multicast, TCP, RTSPS|H264, H265, VP8, VP9, AV1, MPEG-2 video, M-JPEG, MPEG-4 video, MPEG-2 audio (MP3), MPEG-4 Audio (AAC), Opus, G711, G722, LPCM and any RTP-compatible codec|
|RTMP clients (OBS Studio)|RTMP, RTMPS|H264, H265, MPEG-2 audio (MP3), MPEG-4 Audio (AAC)|
|RTMP servers and cameras|RTMP, RTMPS|H264, MPEG-2 audio (MP3), MPEG-4 Audio (AAC)|
|RTSP clients (FFmpeg, GStreamer, etc)|UDP, TCP, RTSPS|H264, H265, VP8, VP9, AV1, MPEG-2 Video, M-JPEG, MPEG-4 Video (H263, Xvid), MPEG-2 Audio (MP3), MPEG-4 Audio (AAC), Opus, G711, G722, LPCM and any RTP-compatible codec|
|RTSP servers and cameras|UDP, UDP-Multicast, TCP, RTSPS|H264, H265, VP8, VP9, AV1, MPEG-2 Video, M-JPEG, MPEG-4 Video (H263, Xvid), MPEG-2 Audio (MP3), MPEG-4 Audio (AAC), Opus, G711, G722, LPCM and any RTP-compatible codec|
|RTMP clients (OBS Studio)|RTMP, RTMPS|H264, H265, MPEG-2 Audio (MP3), MPEG-4 Audio (AAC)|
|RTMP servers and cameras|RTMP, RTMPS|H264, MPEG-2 Audio (MP3), MPEG-4 Audio (AAC)|
|HLS servers and cameras|Low-Latency HLS, MP4-based HLS, legacy HLS|H264, H265, MPEG-4 Audio (AAC), Opus|
|UDP/MPEG-TS streams|Unicast, broadcast, multicast|H264, H265, MPEG-4 Audio (AAC), Opus|
|Raspberry Pi Cameras||H264|
@ -22,8 +22,8 @@ And can be read from the server with: @@ -22,8 +22,8 @@ And can be read from the server with:
|protocol|variants|codecs|
|--------|--------|------|
|RTSP|UDP, UDP-Multicast, TCP, RTSPS|H264, H265, VP8, VP9, AV1, MPEG-2 video, M-JPEG, MPEG-4 video, MPEG-2 audio (MP3), MPEG-4 Audio (AAC), Opus, G711, G722, LPCM and any RTP-compatible codec|
|RTMP|RTMP, RTMPS|H264, MPEG-2 audio (MP3), MPEG-4 Audio (AAC)|
|RTSP|UDP, UDP-Multicast, TCP, RTSPS|H264, H265, VP8, VP9, AV1, MPEG-2 Video, M-JPEG, MPEG-4 Video (H263, Xvid), MPEG-2 Audio (MP3), MPEG-4 Audio (AAC), Opus, G711, G722, LPCM and any RTP-compatible codec|
|RTMP|RTMP, RTMPS|H264, MPEG-2 Audio (MP3), MPEG-4 Audio (AAC)|
|HLS|Low-Latency HLS, MP4-based HLS, legacy HLS|H264, H265, MPEG-4 Audio (AAC), Opus|
|WebRTC||H264, VP8, VP9, Opus, G711, G722|

39
internal/core/rtmp_conn.go

@ -48,7 +48,8 @@ func getRTMPWriteFunc(medi *media.Media, format formats.Format, stream *stream) @@ -48,7 +48,8 @@ func getRTMPWriteFunc(medi *media.Media, format formats.Format, stream *stream)
return func(msg interface{}) error {
tmsg := msg.(*message.MsgVideo)
if tmsg.H264Type == flvio.AVC_SEQHDR {
switch tmsg.Type {
case message.MsgVideoTypeConfig:
var conf h264conf.Conf
err := conf.Unmarshal(tmsg.Payload)
if err != nil {
@ -65,9 +66,8 @@ func getRTMPWriteFunc(medi *media.Media, format formats.Format, stream *stream) @@ -65,9 +66,8 @@ func getRTMPWriteFunc(medi *media.Media, format formats.Format, stream *stream)
AU: au,
NTP: time.Now(),
})
}
if tmsg.H264Type == flvio.AVC_NALU {
case message.MsgVideoTypeAU:
au, err := h264.AVCCUnmarshal(tmsg.Payload)
if err != nil {
return fmt.Errorf("unable to decode AVCC: %v", err)
@ -114,15 +114,15 @@ func getRTMPWriteFunc(medi *media.Media, format formats.Format, stream *stream) @@ -114,15 +114,15 @@ func getRTMPWriteFunc(medi *media.Media, format formats.Format, stream *stream)
return func(msg interface{}) error {
tmsg := msg.(*message.MsgAudio)
if tmsg.AACType != flvio.AAC_RAW {
return nil
if tmsg.AACType == message.MsgAudioAACTypeAU {
return stream.writeUnit(medi, format, &formatprocessor.UnitMPEG4Audio{
PTS: tmsg.DTS,
AUs: [][]byte{tmsg.Payload},
NTP: time.Now(),
})
}
return stream.writeUnit(medi, format, &formatprocessor.UnitMPEG4Audio{
PTS: tmsg.DTS,
AUs: [][]byte{tmsg.Payload},
NTP: time.Now(),
})
return nil
}
default:
@ -366,7 +366,7 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error { @@ -366,7 +366,7 @@ func (c *rtmpConn) runRead(ctx context.Context, u *url.URL) error {
if videoFormat == nil && audioFormat == nil {
return fmt.Errorf(
"the stream doesn't contain any supported codec, which are currently H264, MPEG2-Audio, MPEG4-Audio")
"the stream doesn't contain any supported codec, which are currently H264, MPEG-2 Audio, MPEG-4 Audio")
}
defer res.stream.readerRemove(c)
@ -496,8 +496,9 @@ func (c *rtmpConn) findVideoFormat(stream *stream, ringBuffer *ringbuffer.RingBu @@ -496,8 +496,9 @@ func (c *rtmpConn) findVideoFormat(stream *stream, ringBuffer *ringbuffer.RingBu
err = c.conn.WriteMessage(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: idrPresent,
H264Type: flvio.AVC_NALU,
Type: message.MsgVideoTypeAU,
Payload: avcc,
DTS: dts,
PTSDelta: pts - dts,
@ -560,7 +561,7 @@ func (c *rtmpConn) findAudioFormat(stream *stream, ringBuffer *ringbuffer.RingBu @@ -560,7 +561,7 @@ func (c *rtmpConn) findAudioFormat(stream *stream, ringBuffer *ringbuffer.RingBu
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_RAW,
AACType: message.MsgAudioAACTypeAU,
Payload: au,
DTS: pts + time.Duration(i)*mpeg4audio.SamplesPerAccessUnit*
time.Second/time.Duration(audioFormatMPEG4.ClockRate()),
@ -621,11 +622,21 @@ func (c *rtmpConn) findAudioFormat(stream *stream, ringBuffer *ringbuffer.RingBu @@ -621,11 +622,21 @@ func (c *rtmpConn) findAudioFormat(stream *stream, ringBuffer *ringbuffer.RingBu
channels = flvio.SOUND_MONO
}
rate := uint8(flvio.SOUND_44Khz)
switch h.SampleRate {
case 5500:
rate = flvio.SOUND_5_5Khz
case 11025:
rate = flvio.SOUND_11Khz
case 22050:
rate = flvio.SOUND_22Khz
}
msg := &message.MsgAudio{
ChunkStreamID: message.MsgAudioChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecMPEG2Audio,
Rate: flvio.SOUND_44Khz,
Rate: rate,
Depth: flvio.SOUND_16BIT,
Channels: channels,
Payload: frame,

7
internal/core/rtmp_server_test.go

@ -10,7 +10,6 @@ import ( @@ -10,7 +10,6 @@ import (
"github.com/bluenviron/gortsplib/v3/pkg/formats"
"github.com/bluenviron/mediacommon/pkg/codecs/mpeg4audio"
"github.com/notedit/rtmp/format/flv/flvio"
"github.com/stretchr/testify/require"
"github.com/aler9/mediamtx/internal/rtmp"
@ -149,8 +148,9 @@ func TestRTMPServerPublishRead(t *testing.T) { @@ -149,8 +148,9 @@ func TestRTMPServerPublishRead(t *testing.T) {
err = conn1.WriteMessage(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_NALU,
Type: message.MsgVideoTypeAU,
Payload: []byte{
0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 1
0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04, // IDR 2
@ -163,8 +163,9 @@ func TestRTMPServerPublishRead(t *testing.T) { @@ -163,8 +163,9 @@ func TestRTMPServerPublishRead(t *testing.T) {
require.Equal(t, &message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_NALU,
Type: message.MsgVideoTypeAU,
Payload: []byte{
0x00, 0x00, 0x00, 0x19, // SPS
0x67, 0x42, 0xc0, 0x28, 0xd9, 0x00, 0x78, 0x02,

4
internal/core/rtmp_source_test.go

@ -10,7 +10,6 @@ import ( @@ -10,7 +10,6 @@ import (
"github.com/bluenviron/gortsplib/v3/pkg/formats"
"github.com/bluenviron/gortsplib/v3/pkg/url"
"github.com/bluenviron/mediacommon/pkg/codecs/mpeg4audio"
"github.com/notedit/rtmp/format/flv/flvio"
"github.com/pion/rtp"
"github.com/stretchr/testify/require"
@ -90,8 +89,9 @@ func TestRTMPSource(t *testing.T) { @@ -90,8 +89,9 @@ func TestRTMPSource(t *testing.T) {
err = conn.WriteMessage(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_NALU,
Type: message.MsgVideoTypeAU,
Payload: []byte{0x00, 0x00, 0x00, 0x04, 0x05, 0x02, 0x03, 0x04},
})
require.NoError(t, err)

2
internal/formatprocessor/mpeg2audio.go

@ -9,7 +9,7 @@ import ( @@ -9,7 +9,7 @@ import (
"github.com/pion/rtp"
)
// UnitMPEG2Audio is a MPEG2-audio data unit.
// UnitMPEG2Audio is a MPEG-2 Audio data unit.
type UnitMPEG2Audio struct {
RTPPackets []*rtp.Packet
NTP time.Time

2
internal/formatprocessor/mpeg4audio.go

@ -9,7 +9,7 @@ import ( @@ -9,7 +9,7 @@ import (
"github.com/pion/rtp"
)
// UnitMPEG4Audio is a MPEG4-audio data unit.
// UnitMPEG4Audio is a MPEG-4 Audio data unit.
type UnitMPEG4Audio struct {
RTPPackets []*rtp.Packet
NTP time.Time

41
internal/rtmp/conn.go

@ -21,10 +21,6 @@ import ( @@ -21,10 +21,6 @@ import (
"github.com/aler9/mediamtx/internal/rtmp/message"
)
const (
codecH264 = 7
)
func resultIsOK1(res *message.MsgCommandAMF0) bool {
if len(res.Arguments) < 2 {
return false
@ -641,7 +637,7 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo @@ -641,7 +637,7 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo
case 0:
return false, nil
case codecH264:
case message.CodecH264:
return true, nil
}
@ -651,7 +647,7 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo @@ -651,7 +647,7 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo
}
}
return false, fmt.Errorf("unsupported video codec %v", v)
return false, fmt.Errorf("unsupported video codec: %v", v)
}()
if err != nil {
return nil, nil, err
@ -694,6 +690,11 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo @@ -694,6 +690,11 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo
}
for {
if (!hasVideo || videoTrack != nil) &&
(!hasAudio || audioTrack != nil) {
return videoTrack, audioTrack, nil
}
msg, err := c.ReadMessage()
if err != nil {
return nil, nil, err
@ -706,12 +707,12 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo @@ -706,12 +707,12 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo
}
if videoTrack == nil {
if tmsg.H264Type == flvio.AVC_SEQHDR {
if tmsg.Type == message.MsgVideoTypeConfig {
videoTrack, err = trackFromH264DecoderConfig(tmsg.Payload)
if err != nil {
return nil, nil, err
}
} else if tmsg.H264Type == 1 && tmsg.IsKeyFrame {
} else if tmsg.Type == message.MsgVideoTypeAU && tmsg.IsKeyFrame {
nalus, err := h264.AVCCUnmarshal(tmsg.Payload)
if err != nil {
return nil, nil, err
@ -753,7 +754,7 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo @@ -753,7 +754,7 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo
}
if audioTrack == nil {
if tmsg.Codec == message.CodecMPEG4Audio && tmsg.AACType == flvio.AVC_SEQHDR {
if tmsg.Codec == message.CodecMPEG4Audio && tmsg.AACType == message.MsgAudioAACTypeConfig {
audioTrack, err = trackFromAACDecoderConfig(tmsg.Payload)
if err != nil {
return nil, nil, err
@ -761,11 +762,6 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo @@ -761,11 +762,6 @@ func (c *Conn) readTracksFromMetadata(payload []interface{}) (formats.Format, fo
}
}
}
if (!hasVideo || videoTrack != nil) &&
(!hasAudio || audioTrack != nil) {
return videoTrack, audioTrack, nil
}
}
}
@ -784,7 +780,7 @@ outer: @@ -784,7 +780,7 @@ outer:
startTime = &v
}
if tmsg.H264Type == flvio.AVC_SEQHDR {
if tmsg.Type == message.MsgVideoTypeConfig {
if videoTrack == nil {
var err error
videoTrack, err = trackFromH264DecoderConfig(tmsg.Payload)
@ -809,7 +805,7 @@ outer: @@ -809,7 +805,7 @@ outer:
startTime = &v
}
if tmsg.AACType == flvio.AVC_SEQHDR {
if tmsg.AACType == message.MsgAudioAACTypeConfig {
if audioTrack == nil {
var err error
audioTrack, err = trackFromAACDecoderConfig(tmsg.Payload)
@ -921,7 +917,7 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format) @@ -921,7 +917,7 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format)
V: func() float64 {
switch videoTrack.(type) {
case *formats.H264:
return codecH264
return message.CodecH264
default:
return 0
@ -954,12 +950,10 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format) @@ -954,12 +950,10 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format)
return err
}
if h264Track, ok := videoTrack.(*formats.H264); ok {
sps, pps := h264Track.SafeParams()
if videoTrack, ok := videoTrack.(*formats.H264); ok {
// write decoder config only if SPS and PPS are available.
// if they're not available yet, they're sent later.
if sps != nil && pps != nil {
if sps, pps := videoTrack.SafeParams(); sps != nil && pps != nil {
buf, _ := h264conf.Conf{
SPS: sps,
PPS: pps,
@ -968,8 +962,9 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format) @@ -968,8 +962,9 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format)
err = c.WriteMessage(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Type: message.MsgVideoTypeConfig,
Payload: buf,
})
if err != nil {
@ -991,7 +986,7 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format) @@ -991,7 +986,7 @@ func (c *Conn) WriteTracks(videoTrack formats.Format, audioTrack formats.Format)
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: enc,
})
if err != nil {

38
internal/rtmp/conn_test.go

@ -793,7 +793,7 @@ func TestReadTracks(t *testing.T) { @@ -793,7 +793,7 @@ func TestReadTracks(t *testing.T) {
},
{
K: "videocodecid",
V: float64(codecH264),
V: float64(message.CodecH264),
},
{
K: "audiodatarate",
@ -816,8 +816,9 @@ func TestReadTracks(t *testing.T) { @@ -816,8 +816,9 @@ func TestReadTracks(t *testing.T) {
err = mrw.Write(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Type: message.MsgVideoTypeConfig,
Payload: buf,
})
require.NoError(t, err)
@ -836,7 +837,7 @@ func TestReadTracks(t *testing.T) { @@ -836,7 +837,7 @@ func TestReadTracks(t *testing.T) {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: enc,
})
require.NoError(t, err)
@ -855,7 +856,7 @@ func TestReadTracks(t *testing.T) { @@ -855,7 +856,7 @@ func TestReadTracks(t *testing.T) {
},
{
K: "videocodecid",
V: float64(codecH264),
V: float64(message.CodecH264),
},
{
K: "audiodatarate",
@ -878,8 +879,9 @@ func TestReadTracks(t *testing.T) { @@ -878,8 +879,9 @@ func TestReadTracks(t *testing.T) {
err = mrw.Write(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Type: message.MsgVideoTypeConfig,
Payload: buf,
})
require.NoError(t, err)
@ -917,8 +919,9 @@ func TestReadTracks(t *testing.T) { @@ -917,8 +919,9 @@ func TestReadTracks(t *testing.T) {
err = mrw.Write(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Type: message.MsgVideoTypeConfig,
Payload: buf,
})
require.NoError(t, err)
@ -937,7 +940,7 @@ func TestReadTracks(t *testing.T) { @@ -937,7 +940,7 @@ func TestReadTracks(t *testing.T) {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: enc,
})
require.NoError(t, err)
@ -951,8 +954,9 @@ func TestReadTracks(t *testing.T) { @@ -951,8 +954,9 @@ func TestReadTracks(t *testing.T) {
err = mrw.Write(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Type: message.MsgVideoTypeConfig,
Payload: buf,
})
require.NoError(t, err)
@ -971,7 +975,7 @@ func TestReadTracks(t *testing.T) { @@ -971,7 +975,7 @@ func TestReadTracks(t *testing.T) {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: enc,
})
require.NoError(t, err)
@ -991,7 +995,7 @@ func TestReadTracks(t *testing.T) { @@ -991,7 +995,7 @@ func TestReadTracks(t *testing.T) {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: enc,
})
require.NoError(t, err)
@ -1003,7 +1007,7 @@ func TestReadTracks(t *testing.T) { @@ -1003,7 +1007,7 @@ func TestReadTracks(t *testing.T) {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: enc,
DTS: 1 * time.Second,
})
@ -1023,7 +1027,7 @@ func TestReadTracks(t *testing.T) { @@ -1023,7 +1027,7 @@ func TestReadTracks(t *testing.T) {
},
{
K: "videocodecid",
V: float64(codecH264),
V: float64(message.CodecH264),
},
{
K: "audiodatarate",
@ -1064,8 +1068,9 @@ func TestReadTracks(t *testing.T) { @@ -1064,8 +1068,9 @@ func TestReadTracks(t *testing.T) {
err = mrw.Write(&message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: 1,
Type: message.MsgVideoTypeAU,
Payload: avcc,
})
require.NoError(t, err)
@ -1084,7 +1089,7 @@ func TestReadTracks(t *testing.T) { @@ -1084,7 +1089,7 @@ func TestReadTracks(t *testing.T) {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: enc,
})
require.NoError(t, err)
@ -1364,8 +1369,9 @@ func TestWriteTracks(t *testing.T) { @@ -1364,8 +1369,9 @@ func TestWriteTracks(t *testing.T) {
require.Equal(t, &message.MsgVideo{
ChunkStreamID: message.MsgVideoChunkStreamID,
MessageStreamID: 0x1000000,
Codec: message.CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Type: message.MsgVideoTypeConfig,
Payload: []byte{
0x1, 0x64, 0x0,
0xc, 0xff, 0xe1, 0x0, 0x15, 0x67, 0x64, 0x0,
@ -1385,7 +1391,7 @@ func TestWriteTracks(t *testing.T) { @@ -1385,7 +1391,7 @@ func TestWriteTracks(t *testing.T) {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_SEQHDR,
AACType: message.MsgAudioAACTypeConfig,
Payload: []byte{0x12, 0x10},
}, msg)
}

21
internal/rtmp/message/msg_audio.go

@ -19,6 +19,15 @@ const ( @@ -19,6 +19,15 @@ const (
CodecMPEG4Audio = 10
)
// MsgAudioAACType is the AAC type of a MsgAudio.
type MsgAudioAACType uint8
// MsgAudioAACType values.
const (
MsgAudioAACTypeConfig MsgAudioAACType = 0
MsgAudioAACTypeAU MsgAudioAACType = 1
)
// MsgAudio is an audio message.
type MsgAudio struct {
ChunkStreamID byte
@ -28,7 +37,7 @@ type MsgAudio struct { @@ -28,7 +37,7 @@ type MsgAudio struct {
Rate uint8
Depth uint8
Channels uint8
AACType uint8 // only for CodecMPEG4Audio
AACType MsgAudioAACType // only for CodecMPEG4Audio
Payload []byte
}
@ -56,7 +65,13 @@ func (m *MsgAudio) Unmarshal(raw *rawmessage.Message) error { @@ -56,7 +65,13 @@ func (m *MsgAudio) Unmarshal(raw *rawmessage.Message) error {
if m.Codec == CodecMPEG2Audio {
m.Payload = raw.Body[1:]
} else {
m.AACType = raw.Body[1]
m.AACType = MsgAudioAACType(raw.Body[1])
switch m.AACType {
case MsgAudioAACTypeConfig, MsgAudioAACTypeAU:
default:
return fmt.Errorf("unsupported audio message type: %d", m.AACType)
}
m.Payload = raw.Body[2:]
}
@ -78,7 +93,7 @@ func (m MsgAudio) Marshal() (*rawmessage.Message, error) { @@ -78,7 +93,7 @@ func (m MsgAudio) Marshal() (*rawmessage.Message, error) {
if m.Codec == CodecMPEG2Audio {
copy(body[1:], m.Payload)
} else {
body[1] = m.AACType
body[1] = uint8(m.AACType)
copy(body[2:], m.Payload)
}

37
internal/rtmp/message/msg_video.go

@ -15,13 +15,29 @@ const ( @@ -15,13 +15,29 @@ const (
MsgVideoChunkStreamID = 6
)
// supported video codecs
const (
CodecH264 = 7
)
// MsgVideoType is the type of a video message.
type MsgVideoType uint8
// MsgVideoType values.
const (
MsgVideoTypeConfig MsgVideoType = 0
MsgVideoTypeAU MsgVideoType = 1
MsgVideoTypeEOS MsgVideoType = 2
)
// MsgVideo is a video message.
type MsgVideo struct {
ChunkStreamID byte
DTS time.Duration
MessageStreamID uint32
Codec uint8
IsKeyFrame bool
H264Type uint8
Type MsgVideoType
PTSDelta time.Duration
Payload []byte
}
@ -38,12 +54,19 @@ func (m *MsgVideo) Unmarshal(raw *rawmessage.Message) error { @@ -38,12 +54,19 @@ func (m *MsgVideo) Unmarshal(raw *rawmessage.Message) error {
m.IsKeyFrame = (raw.Body[0] >> 4) == flvio.FRAME_KEY
codec := raw.Body[0] & 0x0F
if codec != flvio.VIDEO_H264 {
return fmt.Errorf("unsupported video codec: %d", codec)
m.Codec = raw.Body[0] & 0x0F
switch m.Codec {
case CodecH264:
default:
return fmt.Errorf("unsupported video codec: %d", m.Codec)
}
m.H264Type = raw.Body[1]
m.Type = MsgVideoType(raw.Body[1])
switch m.Type {
case MsgVideoTypeConfig, MsgVideoTypeAU, MsgVideoTypeEOS:
default:
return fmt.Errorf("unsupported video message type: %d", m.Type)
}
tmp := uint32(raw.Body[2])<<16 | uint32(raw.Body[3])<<8 | uint32(raw.Body[4])
m.PTSDelta = time.Duration(tmp) * time.Millisecond
@ -62,8 +85,8 @@ func (m MsgVideo) Marshal() (*rawmessage.Message, error) { @@ -62,8 +85,8 @@ func (m MsgVideo) Marshal() (*rawmessage.Message, error) {
} else {
body[0] = flvio.FRAME_INTER << 4
}
body[0] |= flvio.VIDEO_H264
body[1] = m.H264Type
body[0] |= m.Codec
body[1] = uint8(m.Type)
tmp := uint32(m.PTSDelta / time.Millisecond)
body[2] = uint8(tmp >> 16)

5
internal/rtmp/message/reader_test.go

@ -53,7 +53,7 @@ var readWriterCases = []struct { @@ -53,7 +53,7 @@ var readWriterCases = []struct {
Rate: flvio.SOUND_44Khz,
Depth: flvio.SOUND_16BIT,
Channels: flvio.SOUND_STEREO,
AACType: flvio.AAC_RAW,
AACType: MsgAudioAACTypeAU,
Payload: []byte{0x5A, 0xC0, 0x77, 0x40},
},
[]byte{
@ -220,8 +220,9 @@ var readWriterCases = []struct { @@ -220,8 +220,9 @@ var readWriterCases = []struct {
ChunkStreamID: 6,
DTS: 2543534 * time.Millisecond,
MessageStreamID: 0x1000000,
Codec: CodecH264,
IsKeyFrame: true,
H264Type: flvio.AVC_SEQHDR,
Type: MsgVideoTypeConfig,
PTSDelta: 10 * time.Millisecond,
Payload: []byte{0x01, 0x02, 0x03},
},

Loading…
Cancel
Save