mirror of
https://github.com/lkmio/lkm.git
synced 2025-09-27 11:32:26 +08:00
92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
package rtmp
|
||
|
||
import (
|
||
"github.com/yangjiechina/avformat/librtmp"
|
||
"github.com/yangjiechina/avformat/utils"
|
||
"github.com/yangjiechina/live-server/stream"
|
||
"net"
|
||
)
|
||
|
||
// Session 负责除连接和断开以外的所有RTMP生命周期处理
|
||
type Session interface {
|
||
Input(conn net.Conn, data []byte) error //接受网络数据包再交由Stack处理
|
||
|
||
Close()
|
||
}
|
||
|
||
func NewSession(conn net.Conn) Session {
|
||
impl := &sessionImpl{}
|
||
|
||
stack := librtmp.NewStack(impl)
|
||
impl.stack = stack
|
||
impl.conn = conn
|
||
return impl
|
||
}
|
||
|
||
type sessionImpl struct {
|
||
//解析rtmp协议栈
|
||
stack *librtmp.Stack
|
||
//publisher/sink
|
||
handle interface{}
|
||
|
||
isPublisher bool
|
||
conn net.Conn
|
||
}
|
||
|
||
func (s *sessionImpl) OnPublish(app, stream_ string, response chan utils.HookState) {
|
||
sourceId := app + "_" + stream_
|
||
source := NewPublisher(sourceId, s.stack, s.conn)
|
||
s.stack.SetOnPublishHandler(source)
|
||
s.stack.SetOnTransDeMuxerHandler(source)
|
||
|
||
//推流事件Source统一处理, 是否已经存在, Hook回调....
|
||
source.(*publisher).Publish(source.(*publisher), func() {
|
||
s.handle = source
|
||
s.isPublisher = true
|
||
source.Init()
|
||
|
||
response <- utils.HookStateOK
|
||
}, func(state utils.HookState) {
|
||
response <- state
|
||
})
|
||
}
|
||
|
||
func (s *sessionImpl) OnPlay(app, stream_ string, response chan utils.HookState) {
|
||
sourceId := app + "_" + stream_
|
||
|
||
//拉流事件Sink统一处理
|
||
sink := NewSink(stream.GenerateSinkId(s.conn), sourceId, s.conn)
|
||
sink.(*stream.SinkImpl).Play(sink, func() {
|
||
s.handle = sink
|
||
response <- utils.HookStateOK
|
||
}, func(state utils.HookState) {
|
||
response <- state
|
||
})
|
||
}
|
||
|
||
func (s *sessionImpl) Input(conn net.Conn, data []byte) error {
|
||
//如果是推流,并且握手成功,后续收到的包,都将发送给LoopEvent处理
|
||
if s.isPublisher {
|
||
s.handle.(*publisher).AddEvent(stream.SourceEventInput, data)
|
||
return nil
|
||
} else {
|
||
return s.stack.Input(conn, data)
|
||
}
|
||
}
|
||
|
||
func (s *sessionImpl) Close() {
|
||
if s.handle == nil {
|
||
return
|
||
}
|
||
|
||
_, ok := s.handle.(*Publisher)
|
||
if ok {
|
||
if s.isPublisher {
|
||
s.handle.(*publisher).AddEvent(stream.SourceEventClose, nil)
|
||
}
|
||
} else {
|
||
sink := s.handle.(stream.ISink)
|
||
sink.Close()
|
||
}
|
||
}
|