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/remux/rtmp.go

85 lines
2.5 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 remux
import (
"github.com/q191201771/lal/pkg/base"
"github.com/q191201771/lal/pkg/rtmp"
)
// MakeDefaultRtmpHeader
//
// 使用场景:一般是输入流转换为输出流时。
// 目的:使得流格式更标准。
// 做法:设置 MsgStreamId 和 Csid其他字段保持`in`的值。
func MakeDefaultRtmpHeader(in base.RtmpHeader) (out base.RtmpHeader) {
out.MsgLen = in.MsgLen
out.TimestampAbs = in.TimestampAbs
out.MsgTypeId = in.MsgTypeId
out.MsgStreamId = rtmp.Msid1
switch in.MsgTypeId {
case base.RtmpTypeIdMetadata:
out.Csid = rtmp.CsidAmf
case base.RtmpTypeIdAudio:
out.Csid = rtmp.CsidAudio
case base.RtmpTypeIdVideo:
out.Csid = rtmp.CsidVideo
}
return
}
// ---------------------------------------------------------------------------------------------------------------------
// LazyRtmpChunkDivider 在必要时有且仅有一次做切分成chunk的操作
type LazyRtmpChunkDivider struct {
msg base.RtmpMsg
chunksWithSdf []byte
chunksWithoutSdf []byte
}
func (lcd *LazyRtmpChunkDivider) Init(msg base.RtmpMsg) {
lcd.msg = msg
}
func (lcd *LazyRtmpChunkDivider) GetEnsureWithSdf() []byte {
if lcd.chunksWithSdf == nil {
var msg []byte
if lcd.msg.Header.MsgTypeId == base.RtmpTypeIdMetadata {
msg2 := lcd.msg.Clone()
msg2.Payload, _ = rtmp.MetadataEnsureWithSdf(msg2.Payload)
msg2.Header.MsgLen = uint32(len(msg2.Payload))
msg2.Header = MakeDefaultRtmpHeader(msg2.Header)
lcd.chunksWithSdf = rtmp.Message2Chunks(msg2.Payload, &msg2.Header)
} else {
msg = lcd.msg.Payload
h := MakeDefaultRtmpHeader(lcd.msg.Header)
lcd.chunksWithSdf = rtmp.Message2Chunks(msg, &h)
}
}
return lcd.chunksWithSdf
}
func (lcd *LazyRtmpChunkDivider) GetEnsureWithoutSdf() []byte {
if lcd.chunksWithoutSdf == nil {
var msg []byte
if lcd.msg.Header.MsgTypeId == base.RtmpTypeIdMetadata {
msg2 := lcd.msg.Clone()
msg2.Payload, _ = rtmp.MetadataEnsureWithoutSdf(msg2.Payload)
msg2.Header.MsgLen = uint32(len(msg2.Payload))
msg2.Header = MakeDefaultRtmpHeader(msg2.Header)
lcd.chunksWithoutSdf = rtmp.Message2Chunks(msg2.Payload, &msg2.Header)
} else {
msg = lcd.msg.Payload
h := MakeDefaultRtmpHeader(lcd.msg.Header)
lcd.chunksWithoutSdf = rtmp.Message2Chunks(msg, &h)
}
}
return lcd.chunksWithoutSdf
}