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

168 lines
5.4 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Copyright 2019, 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 rtmp
import (
"crypto/tls"
"github.com/q191201771/lal/pkg/base"
)
type PushSession struct {
IsFresh bool
core *ClientSession
}
type PushSessionOption struct {
// 从调用Push函数到可以发送音视频数据的前一步也即收到服务端返回的rtmp publish对应结果的信令的超时时间
// 如果为0则没有超时时间
PushTimeoutMs int
WriteAvTimeoutMs int
WriteBufSize int // io层发送音视频数据的缓冲大小如果为0则没有缓冲
WriteChanSize int // io层发送音视频数据的异步队列大小如果为0则同步发送
HandshakeComplexFlag bool
// TlsConfig
// rtmps时使用。
// 不关心可以不填。
// 业务方可以通过这个字段自定义 tls.Config
// 注意如果使用rtmps并且该字段为nil那么内部会使用 base.DefaultTlsConfigClient 生成 tls.Config
TlsConfig *tls.Config
}
var defaultPushSessionOption = PushSessionOption{
PushTimeoutMs: 10000,
WriteAvTimeoutMs: 0,
WriteBufSize: 0,
WriteChanSize: 0,
HandshakeComplexFlag: false,
}
type ModPushSessionOption func(option *PushSessionOption)
func NewPushSession(modOptions ...ModPushSessionOption) *PushSession {
opt := defaultPushSessionOption
for _, fn := range modOptions {
fn(&opt)
}
return &PushSession{
IsFresh: true,
core: NewClientSession(base.SessionTypeRtmpPush, func(option *ClientSessionOption) {
option.DoTimeoutMs = opt.PushTimeoutMs
option.WriteAvTimeoutMs = opt.WriteAvTimeoutMs
option.WriteBufSize = opt.WriteBufSize
option.WriteChanSize = opt.WriteChanSize
option.HandshakeComplexFlag = opt.HandshakeComplexFlag
}),
}
}
// Start 阻塞直到和对端完成推流前握手部分的工作也即收到RTMP Publish response或者发生错误
func (s *PushSession) Start(rawUrl string) error {
return s.core.Start(rawUrl)
}
// Push deprecated. use Start instead.
func (s *PushSession) Push(rawUrl string) error {
return s.Start(rawUrl)
}
// Write 发送数据
//
// @param b:
//
// 注意,`b`数据应该是已经打包成rtmp chunk格式的数据。这里的数据就对应socket发送的数据内部不会再修改数据内容。
// 如果要发送 base.RtmpMsg 数据,请使用 WriteMsg 函数。
func (s *PushSession) Write(b []byte) error {
// TODO(chef): [opt] 使用Write函数时确保metadata有@SetDataFrame 202207
return s.core.Write(b)
}
// WriteMsg
//
// 内部会根据 msg 的包头字段和包体数据,打包成 rtmp chunk 格式的数据,然后发送。
// 如果想要自己控制打包过程,请使用 Write 函数直接发送数据。
func (s *PushSession) WriteMsg(msg base.RtmpMsg) error {
return s.Write(Message2Chunks(msg.Payload, &msg.Header))
}
// Flush 将缓存的数据立即刷新发送
// 是否有缓存策略,请参见配置及内部实现
func (s *PushSession) Flush() error {
return s.core.Flush()
}
// ---------------------------------------------------------------------------------------------------------------------
// IClientSessionLifecycle interface
// ---------------------------------------------------------------------------------------------------------------------
// Dispose 文档请参考: IClientSessionLifecycle interface
func (s *PushSession) Dispose() error {
return s.core.Dispose()
}
// WaitChan 文档请参考: IClientSessionLifecycle interface
func (s *PushSession) WaitChan() <-chan error {
return s.core.WaitChan()
}
// ---------------------------------------------------------------------------------------------------------------------
// ISessionUrlContext interface
// ---------------------------------------------------------------------------------------------------------------------
// Url 文档请参考: interface ISessionUrlContext
func (s *PushSession) Url() string {
return s.core.Url()
}
// AppName 文档请参考: interface ISessionUrlContext
func (s *PushSession) AppName() string {
return s.core.AppName()
}
// StreamName 文档请参考: interface ISessionUrlContext
func (s *PushSession) StreamName() string {
return s.core.StreamName()
}
// RawQuery 文档请参考: interface ISessionUrlContext
func (s *PushSession) RawQuery() string {
return s.core.RawQuery()
}
// ---------------------------------------------------------------------------------------------------------------------
// IObject interface
// ---------------------------------------------------------------------------------------------------------------------
// UniqueKey 文档请参考: interface IObject
func (s *PushSession) UniqueKey() string {
return s.core.UniqueKey()
}
// ---------------------------------------------------------------------------------------------------------------------
// ISessionStat interface
// ---------------------------------------------------------------------------------------------------------------------
// GetStat 文档请参考: interface ISessionStat
func (s *PushSession) GetStat() base.StatSession {
return s.core.GetStat()
}
// UpdateStat 文档请参考: interface ISessionStat
func (s *PushSession) UpdateStat(intervalSec uint32) {
s.core.UpdateStat(intervalSec)
}
// IsAlive 文档请参考: interface ISessionStat
func (s *PushSession) IsAlive() (readAlive, writeAlive bool) {
return s.core.IsAlive()
}