remux

package
v0.0.0-...-6c0573e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2023 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Log = nazalog.GetGlobalLogger()

	// RtspRemuxerAddSpsPps2KeyFrameFlag https://github.com/ysjhlnu/lal/issues/205
	//
	RtspRemuxerAddSpsPps2KeyFrameFlag = false
)

Functions

func FlvTag2RtmpChunks

func FlvTag2RtmpChunks(tag httpflv.Tag) []byte

FlvTag2RtmpChunks @return 返回的内存块为内部新申请

func FlvTag2RtmpMsg

func FlvTag2RtmpMsg(tag httpflv.Tag) (msg base.RtmpMsg)

FlvTag2RtmpMsg @return msg: 返回的内存块引用参数`tag`的内存块

func FlvTagHeader2RtmpHeader

func FlvTagHeader2RtmpHeader(in httpflv.TagHeader) (out base.RtmpHeader)

func MakeDefaultRtmpHeader

func MakeDefaultRtmpHeader(in base.RtmpHeader) (out base.RtmpHeader)

MakeDefaultRtmpHeader

使用场景:一般是输入流转换为输出流时。 目的:使得流格式更标准。 做法:设置 MsgStreamId 和 Csid,其他字段保持`in`的值。

func RtmpMsg2FlvTag

func RtmpMsg2FlvTag(msg base.RtmpMsg) *httpflv.Tag

RtmpMsg2FlvTag @return 返回的内存块为新申请的独立内存块

Types

type AvPacket2RtmpRemuxer

type AvPacket2RtmpRemuxer struct {
	// contains filtered or unexported fields
}

AvPacket2RtmpRemuxer AvPacket转换为RTMP

目前AvPacket来自:

- RTSP: sdp以及rtp的合帧包 - gb28181 ps: rtp的合帧包 - customize: 业务方通过接口向lalserver输入的流 - 理论上也支持webrtc,后续接入webrtc时再验证

func NewAvPacket2RtmpRemuxer

func NewAvPacket2RtmpRemuxer() *AvPacket2RtmpRemuxer

func (*AvPacket2RtmpRemuxer) FeedAvPacket

func (r *AvPacket2RtmpRemuxer) FeedAvPacket(pkt base.AvPacket)

FeedAvPacket

输入 base.AvPacket 数据

@param pkt:

  • 如果是aac,格式是裸数据或带adts头,具体取决于前面的配置。
  • 如果是h264,格式是avcc或Annexb,具体取决于前面的配置。 内部不持有该内存块。

func (*AvPacket2RtmpRemuxer) InitWithAvConfig

func (r *AvPacket2RtmpRemuxer) InitWithAvConfig(asc, vps, sps, pps []byte)

InitWithAvConfig rtsp场景下,有时sps、pps等信息只包含在sdp中,有时包含在rtp包中, 这里提供输入sdp的sps、pps等信息的机会,如果没有,可以不调用

内部不持有输入参数的内存块

func (*AvPacket2RtmpRemuxer) OnAvPacket

func (r *AvPacket2RtmpRemuxer) OnAvPacket(pkt base.AvPacket)

func (*AvPacket2RtmpRemuxer) OnRtpPacket

func (r *AvPacket2RtmpRemuxer) OnRtpPacket(pkt rtprtcp.RtpPacket)

OnRtpPacket OnSdp OnAvPacket

实现RTSP回调数据的接口 rtsp.IBaseInSessionObserver ,使得接入时方便些

func (*AvPacket2RtmpRemuxer) OnSdp

func (r *AvPacket2RtmpRemuxer) OnSdp(sdpCtx sdp.LogicContext)

func (*AvPacket2RtmpRemuxer) WithOnRtmpMsg

func (r *AvPacket2RtmpRemuxer) WithOnRtmpMsg(onRtmpMsg rtmp.OnReadRtmpAvMsg) *AvPacket2RtmpRemuxer

func (*AvPacket2RtmpRemuxer) WithOption

func (r *AvPacket2RtmpRemuxer) WithOption(modOption func(option *base.AvPacketStreamOption))

WithOption

TODO(chef): [refactor] 返回*AvPacket2RtmpRemuxer 202208

type DummyAudioFilter

type DummyAudioFilter struct {
	// contains filtered or unexported fields
}

func NewDummyAudioFilter

func NewDummyAudioFilter(uk string, waitAudioMs int, onPop rtmp.OnReadRtmpAvMsg) *DummyAudioFilter

NewDummyAudioFilter 检测输入的rtmp流中是否有音频,如果有,则原样返回;如果没有,则制造静音音频数据叠加在rtmp流里面

@param waitAudioMs 等待音频数据时间,如果超出这个时间还没有接收到音频数据,则开始制造静音数据 @param onPop 注意,所有回调都发生在输入函数调用中

func (*DummyAudioFilter) Feed

func (filter *DummyAudioFilter) Feed(msg base.RtmpMsg)

func (*DummyAudioFilter) OnReadRtmpAvMsg

func (filter *DummyAudioFilter) OnReadRtmpAvMsg(msg base.RtmpMsg)

type Gop

type Gop struct {
	// contains filtered or unexported fields
}

func (*Gop) Clear

func (g *Gop) Clear()

func (*Gop) Feed

func (g *Gop) Feed(msg base.RtmpMsg, b []byte)

Feed

@param b: 内部持有`b`内存块

type GopCache

type GopCache struct {
	MetadataEnsureWithSetDataFrame    []byte
	MetadataEnsureWithoutSetDataFrame []byte
	VideoSeqHeader                    []byte
	AacSeqHeader                      []byte
	// contains filtered or unexported fields
}

GopCache

提供两个功能:

  1. 缓存Metadata, VideoSeqHeader, AacSeqHeader
  2. 缓存音视频GOP数据

以下,只讨论GopCache的第2点功能

音频和视频都会缓存。

GopCache也可能不缓存GOP数据,见NewGopCache函数的gopNum参数说明。

以下,我们只讨论gopNum > 0(也即gopSize > 1)的情况。

GopCache为空时,只有输入了关键帧,才能开启GOP缓存,非关键帧以及音频数据不会被缓存。 因此,单音频的流是ok的,相当于不缓存任何数据。

GopCache不为空时,输入关键帧触发生成新的GOP元素,其他情况则往最后一个GOP元素一直追加。

first用于读取第一个GOP(可能不完整),last的前一个用于写入当前GOP。

最近不完整的GOP也会被缓存,见NewGopCache函数的gopNum参数说明。

----- gopNum = 1 gopSize = 2

first     |   first       |       first   | 在后面两个状态间转换,就不画了
  |       |     |         |        |      |
  0   1   |     0   1	  |    0   1      |
  *   *   |     *   *	  |    *   *      |
  |       |         |	  |    |          |
last      |        last   |   last        |
          |               |               |
(empty)   |   (full)      |   (full)      |

GetGopCount: 0 | 1 | 1 | -----

func NewGopCache

func NewGopCache(t string, uniqueKey string, gopNum int, singleGopMaxFrameNum int) *GopCache

NewGopCache

@param gopNum: gop缓存大小。

  • 如果为0,则不缓存音频数据,也即GOP缓存功能不生效。
  • 如果>0,则缓存[0, gopNum]个GOP,最多缓存 gopNum 个GOP。注意,最后一个GOP可能是不完整的。

func (*GopCache) Clear

func (gc *GopCache) Clear()

func (*GopCache) Feed

func (gc *GopCache) Feed(msg base.RtmpMsg, b []byte) bool

Feed

@param lg: 内部可能持有lg返回的内存块

func (*GopCache) GetGopCount

func (gc *GopCache) GetGopCount() int

GetGopCount 获取GOP数量,注意,最后一个可能是不完整的

func (*GopCache) GetGopDataAt

func (gc *GopCache) GetGopDataAt(pos int) [][]byte

func (*GopCache) SetMetadata

func (gc *GopCache) SetMetadata(w []byte, wo []byte)

type GopCacheMpegts

type GopCacheMpegts struct {
	// contains filtered or unexported fields
}

func NewGopCacheMpegts

func NewGopCacheMpegts(uniqueKey string, gopNum int, singleGopMaxFrameNum int) *GopCacheMpegts

func (*GopCacheMpegts) Clear

func (gc *GopCacheMpegts) Clear()

func (*GopCacheMpegts) Feed

func (gc *GopCacheMpegts) Feed(b []byte, boundary bool)

Feed

@param b: 内部持有该内存块

func (*GopCacheMpegts) GetGopCount

func (gc *GopCacheMpegts) GetGopCount() int

GetGopCount 获取GOP数量,注意,最后一个可能是不完整的

func (*GopCacheMpegts) GetGopDataAt

func (gc *GopCacheMpegts) GetGopDataAt(pos int) [][]byte

type GopMpegts

type GopMpegts struct {
	// contains filtered or unexported fields
}

GopMpegts

单个Gop,包含多帧数据

func (*GopMpegts) Clear

func (g *GopMpegts) Clear()

func (*GopMpegts) Feed

func (g *GopMpegts) Feed(b []byte)

Feed

@param b: 内部持有`b`内存块

type IRtmp2MpegtsRemuxerObserver

type IRtmp2MpegtsRemuxerObserver interface {
	// OnPatPmt
	//
	// @param b: const只读内存块,上层可以持有,但是不允许修改
	//
	OnPatPmt(b []byte)

	// OnTsPackets
	//
	// @param tsPackets:
	//  - mpegts数据,有一个或多个188字节的ts数据组成
	//  - 回调结束后,remux.Rtmp2MpegtsRemuxer 不再使用这块内存块
	//
	// @param frame: 各字段含义见 mpegts.Frame 结构体定义
	//
	// @param boundary: 是否到达边界处,根据该字段,上层可判断诸如:
	//  - hls是否允许开启新的ts文件切片
	//  - 新的ts播放流从该位置开始播放
	//
	OnTsPackets(tsPackets []byte, frame *mpegts.Frame, boundary bool)
}

type LazyGet

type LazyGet func() []byte

type LazyRtmpChunkDivider

type LazyRtmpChunkDivider struct {
	// contains filtered or unexported fields
}

LazyRtmpChunkDivider 在必要时,有且仅有一次做切分成chunk的操作

func (*LazyRtmpChunkDivider) GetEnsureWithSdf

func (lcd *LazyRtmpChunkDivider) GetEnsureWithSdf() []byte

func (*LazyRtmpChunkDivider) GetEnsureWithoutSdf

func (lcd *LazyRtmpChunkDivider) GetEnsureWithoutSdf() []byte

func (*LazyRtmpChunkDivider) Init

func (lcd *LazyRtmpChunkDivider) Init(msg base.RtmpMsg)

type LazyRtmpMsg2FlvTag

type LazyRtmpMsg2FlvTag struct {
	// contains filtered or unexported fields
}

LazyRtmpMsg2FlvTag 在必要时,有且仅有一次做转换操作

func (*LazyRtmpMsg2FlvTag) GetEnsureWithSdf

func (l *LazyRtmpMsg2FlvTag) GetEnsureWithSdf() []byte

func (*LazyRtmpMsg2FlvTag) GetEnsureWithoutSdf

func (l *LazyRtmpMsg2FlvTag) GetEnsureWithoutSdf() []byte

func (*LazyRtmpMsg2FlvTag) Init

func (l *LazyRtmpMsg2FlvTag) Init(msg base.RtmpMsg)

type OnRtpPacket

type OnRtpPacket func(pkt rtprtcp.RtpPacket)

type OnSdp

type OnSdp func(sdpCtx sdp.LogicContext)

type Rtmp2AvPacketRemuxer

type Rtmp2AvPacketRemuxer struct {
	// contains filtered or unexported fields
}

Rtmp2AvPacketRemuxer

用途: - 将rtmp流中的视频转换成ffmpeg可解码的格式

func NewRtmp2AvPacketRemuxer

func NewRtmp2AvPacketRemuxer() *Rtmp2AvPacketRemuxer

func (*Rtmp2AvPacketRemuxer) FeedRtmpMsg

func (r *Rtmp2AvPacketRemuxer) FeedRtmpMsg(msg base.RtmpMsg, arg interface{}) error

func (*Rtmp2AvPacketRemuxer) WithOnAvPacket

func (r *Rtmp2AvPacketRemuxer) WithOnAvPacket(onAvPacket func(pkt base.AvPacket, arg interface{})) *Rtmp2AvPacketRemuxer

WithOnAvPacket

@param onAvPacket: pkt 内存由内部新申请,回调后内部不再使用

func (*Rtmp2AvPacketRemuxer) WithOption

func (r *Rtmp2AvPacketRemuxer) WithOption(modOption func(option *Rtmp2AvPacketRemuxerOption)) *Rtmp2AvPacketRemuxer

type Rtmp2AvPacketRemuxerOption

type Rtmp2AvPacketRemuxerOption struct {
	// TODO(chef): impl me 202206
	TryInPlaceFlag bool // 尝试在原有内存上直接修改
}

type Rtmp2MpegtsRemuxer

type Rtmp2MpegtsRemuxer struct {
	// contains filtered or unexported fields
}

Rtmp2MpegtsRemuxer 输入rtmp流,输出mpegts流

func NewRtmp2MpegtsRemuxer

func NewRtmp2MpegtsRemuxer(observer IRtmp2MpegtsRemuxerObserver) *Rtmp2MpegtsRemuxer

func (*Rtmp2MpegtsRemuxer) Dispose

func (s *Rtmp2MpegtsRemuxer) Dispose()

func (*Rtmp2MpegtsRemuxer) FeedRtmpMessage

func (s *Rtmp2MpegtsRemuxer) FeedRtmpMessage(msg base.RtmpMsg)

FeedRtmpMessage

@param msg: msg.Payload 调用结束后,函数内部不会持有这块内存

func (*Rtmp2MpegtsRemuxer) FlushAudio

func (s *Rtmp2MpegtsRemuxer) FlushAudio()

FlushAudio

吐出音频数据的三种情况: 1. 收到音频或视频时,音频缓存队列已达到一定长度(内部判断) 2. 打开一个新的TS文件切片时 3. 输入流关闭时

func (*Rtmp2MpegtsRemuxer) UniqueKey

func (s *Rtmp2MpegtsRemuxer) UniqueKey() string

type Rtmp2MpegtsTimestampFilter

type Rtmp2MpegtsTimestampFilter struct {
	// contains filtered or unexported fields
}

Rtmp2MpegtsTimestampFilter

(1). 通过dts和cts计算pts。 (2). 将数据包中的时间戳转换为从零开始的时间戳。

TODO(chef): [opt] 音频和视频公用一个base,避免以下情况: A: 6 7 ... V: 1 2 3 4 5 6 7 ... 另外,需要考虑音频比base还小的情况

func (*Rtmp2MpegtsTimestampFilter) Do

func (f *Rtmp2MpegtsTimestampFilter) Do(frame *mpegts.Frame)

Do

@param frame: 直接修改frame中的dts和pts

func (*Rtmp2MpegtsTimestampFilter) Init

func (f *Rtmp2MpegtsTimestampFilter) Init(uk string)

type Rtmp2RtspRemuxer

type Rtmp2RtspRemuxer struct {
	// contains filtered or unexported fields
}

Rtmp2RtspRemuxer 提供rtmp数据向sdp+rtp数据的转换

func NewRtmp2RtspRemuxer

func NewRtmp2RtspRemuxer(onSdp OnSdp, onRtpPacket OnRtpPacket) *Rtmp2RtspRemuxer

NewRtmp2RtspRemuxer @param onSdp: 每次回调为独立的内存块,回调结束后,内部不再使用该内存块 @param onRtpPacket: 每次回调为独立的内存块,回调结束后,内部不再使用该内存块

func (*Rtmp2RtspRemuxer) FeedRtmpMsg

func (r *Rtmp2RtspRemuxer) FeedRtmpMsg(msg base.RtmpMsg)

FeedRtmpMsg @param msg: 函数调用结束后,内部不持有`msg`内存块

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL