You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lal/pkg/base/rtmp_t.go

117 lines
3.7 KiB
Go

// Copyright 2020, Chef. All rights reserved.
// https://github.com/q191201771/lal
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package base
const (
// spec-rtmp_specification_1.0.pdf
// 7.1. Types of Messages
RtmpTypeIdAudio uint8 = 8
RtmpTypeIdVideo uint8 = 9
RtmpTypeIdMetadata uint8 = 18 // RtmpTypeIdDataMessageAmf0
RtmpTypeIdSetChunkSize uint8 = 1
RtmpTypeIdAck uint8 = 3
RtmpTypeIdUserControl uint8 = 4
RtmpTypeIdWinAckSize uint8 = 5
RtmpTypeIdBandwidth uint8 = 6
RtmpTypeIdCommandMessageAmf3 uint8 = 17
RtmpTypeIdCommandMessageAmf0 uint8 = 20
RtmpTypeIdAggregateMessage uint8 = 22
4 years ago
// user control message type
RtmpUserControlStreamBegin uint8 = 0
RtmpUserControlRecorded uint8 = 4
// spec-video_file_format_spec_v10.pdf
// Video tags
// VIDEODATA
// FrameType UB[4]
// CodecId UB[4]
// AVCVIDEOPACKET
// AVCPacketType UI8
// CompositionTime SI24
// Data UI8[n]
RtmpFrameTypeKey uint8 = 1
RtmpFrameTypeInter uint8 = 2
RtmpCodecIdAvc uint8 = 7
RtmpCodecIdHevc uint8 = 12
RtmpAvcPacketTypeSeqHeader uint8 = 0
RtmpAvcPacketTypeNalu uint8 = 1
RtmpHevcPacketTypeSeqHeader = RtmpAvcPacketTypeSeqHeader
RtmpHevcPacketTypeNalu = RtmpAvcPacketTypeNalu
RtmpAvcKeyFrame = RtmpFrameTypeKey<<4 | RtmpCodecIdAvc
RtmpHevcKeyFrame = RtmpFrameTypeKey<<4 | RtmpCodecIdHevc
RtmpAvcInterFrame = RtmpFrameTypeInter<<4 | RtmpCodecIdAvc
RtmpHevcInterFrame = RtmpFrameTypeInter<<4 | RtmpCodecIdHevc
// spec-video_file_format_spec_v10.pdf
// Audio tags
// AUDIODATA
// SoundFormat UB[4]
// SoundRate UB[2]
// SoundSize UB[1]
// SoundType UB[1]
// AACAUDIODATA
// AACPacketType UI8
// Data UI8[n]
RtmpSoundFormatAac uint8 = 10 // 注意视频的CodecId是后4位音频是前4位
RtmpAacPacketTypeSeqHeader = 0
RtmpAacPacketTypeRaw = 1
)
type RtmpHeader struct {
Csid int
MsgLen uint32 // 不包含header的大小
MsgTypeId uint8 // 8 audio 9 video 18 metadata
MsgStreamId int
TimestampAbs uint32 // 经过计算得到的流上的绝对时间戳,单位毫秒
}
type RtmpMsg struct {
Header RtmpHeader
Payload []byte // Payload不包含Header内容。如果需要将RtmpMsg序列化成RTMP chunk可调用rtmp.ChunkDivider相关的函数
}
func (msg RtmpMsg) IsAvcKeySeqHeader() bool {
return msg.Header.MsgTypeId == RtmpTypeIdVideo && msg.Payload[0] == RtmpAvcKeyFrame && msg.Payload[1] == RtmpAvcPacketTypeSeqHeader
}
func (msg RtmpMsg) IsHevcKeySeqHeader() bool {
return msg.Header.MsgTypeId == RtmpTypeIdVideo && msg.Payload[0] == RtmpHevcKeyFrame && msg.Payload[1] == RtmpHevcPacketTypeSeqHeader
}
func (msg RtmpMsg) IsVideoKeySeqHeader() bool {
return msg.IsAvcKeySeqHeader() || msg.IsHevcKeySeqHeader()
}
func (msg RtmpMsg) IsAvcKeyNalu() bool {
return msg.Header.MsgTypeId == RtmpTypeIdVideo && msg.Payload[0] == RtmpAvcKeyFrame && msg.Payload[1] == RtmpAvcPacketTypeNalu
}
func (msg RtmpMsg) IsHevcKeyNalu() bool {
return msg.Header.MsgTypeId == RtmpTypeIdVideo && msg.Payload[0] == RtmpHevcKeyFrame && msg.Payload[1] == RtmpHevcPacketTypeNalu
}
func (msg RtmpMsg) IsVideoKeyNalu() bool {
return msg.IsAvcKeyNalu() || msg.IsHevcKeyNalu()
}
func (msg RtmpMsg) IsAacSeqHeader() bool {
return msg.Header.MsgTypeId == RtmpTypeIdAudio && (msg.Payload[0]>>4) == RtmpSoundFormatAac && msg.Payload[1] == RtmpAacPacketTypeSeqHeader
}
func (msg RtmpMsg) Clone() (ret RtmpMsg) {
ret.Header = msg.Header
ret.Payload = make([]byte, len(msg.Payload))
copy(ret.Payload, msg.Payload)
return
}