mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-06 00:56:58 +08:00
131 lines
2.4 KiB
Go
131 lines
2.4 KiB
Go
package engine
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
. "github.com/Monibuca/engine/v4/common"
|
|
"github.com/Monibuca/engine/v4/config"
|
|
"github.com/Monibuca/engine/v4/track"
|
|
)
|
|
|
|
type AudioFrame AVFrame[AudioSlice]
|
|
type VideoFrame AVFrame[NALUSlice]
|
|
type ISubscriber interface {
|
|
IIO
|
|
receive(string, any, *config.Subscribe) bool
|
|
config.SubscribeConfig
|
|
GetSubscriber() *Subscriber
|
|
Unsubscribe()
|
|
}
|
|
type TrackPlayer struct {
|
|
context.Context
|
|
context.CancelFunc
|
|
AudioTrack *track.Audio
|
|
VideoTrack *track.Video
|
|
vr *AVRing[NALUSlice]
|
|
ar *AVRing[AudioSlice]
|
|
}
|
|
|
|
// Subscriber 订阅者实体定义
|
|
type Subscriber struct {
|
|
IO[config.Subscribe]
|
|
TrackPlayer
|
|
}
|
|
|
|
func (p *Subscriber) GetSubscriber() *Subscriber {
|
|
return p
|
|
}
|
|
|
|
func (p *Subscriber) Unsubscribe() {
|
|
p.bye(p)
|
|
}
|
|
|
|
func (s *Subscriber) GetSubscribeConfig() *config.Subscribe {
|
|
return s.Config
|
|
}
|
|
|
|
func (s *Subscriber) OnEvent(event any) any {
|
|
s.IO.OnEvent(event)
|
|
switch v := event.(type) {
|
|
case TrackRemoved:
|
|
if a, ok := v.(*track.Audio); ok && a == s.AudioTrack {
|
|
s.ar = nil
|
|
} else if v, ok := v.(*track.Video); ok && v == s.VideoTrack {
|
|
s.vr = nil
|
|
}
|
|
}
|
|
return event
|
|
}
|
|
|
|
func (s *Subscriber) AddTrack(t Track) bool {
|
|
if v, ok := t.(*track.Video); ok {
|
|
if s.Config.SubVideo {
|
|
if s.VideoTrack != nil {
|
|
return false
|
|
}
|
|
s.VideoTrack = v
|
|
s.vr = v.ReadRing()
|
|
return true
|
|
}
|
|
} else if a, ok := t.(*track.Audio); ok {
|
|
if s.Config.SubAudio {
|
|
if s.AudioTrack != nil {
|
|
return false
|
|
}
|
|
s.AudioTrack = a
|
|
s.ar = a.ReadRing()
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
// TODO: data track
|
|
}
|
|
|
|
func (s *Subscriber) IsPlaying() bool {
|
|
return s.TrackPlayer.Err() == nil && (s.AudioTrack != nil || s.VideoTrack != nil)
|
|
}
|
|
|
|
//Play 开始播放
|
|
func (s *Subscriber) Play() {
|
|
var t time.Time
|
|
for s.TrackPlayer.Err() == nil {
|
|
if s.vr != nil {
|
|
for {
|
|
vp := s.vr.Read(s.TrackPlayer)
|
|
s.OnEvent((*VideoFrame)(vp))
|
|
s.vr.MoveNext()
|
|
if vp.Timestamp.After(t) {
|
|
t = vp.Timestamp
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if s.ar != nil {
|
|
for {
|
|
ap := s.ar.Read(s.TrackPlayer)
|
|
s.OnEvent((*AudioFrame)(ap))
|
|
s.ar.MoveNext()
|
|
if ap.Timestamp.After(t) {
|
|
t = ap.Timestamp
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
type PushEvent int
|
|
type Pusher struct {
|
|
Config *config.Push
|
|
StreamPath string
|
|
RemoteURL string
|
|
PushCount int
|
|
}
|
|
|
|
// 是否需要重连
|
|
func (pub *Pusher) Reconnect() bool {
|
|
return pub.Config.RePush == -1 || pub.PushCount <= pub.Config.RePush
|
|
}
|