mirror of
https://github.com/Monibuca/engine.git
synced 2025-10-05 16:46:58 +08:00
精简代码
This commit is contained in:
@@ -35,9 +35,9 @@ func (r *AVRing[T]) Read(ctx context.Context) (item *AVFrame[T]) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (r *AVRing[T]) TryRead(ctx context.Context) (item *AVFrame[T]) {
|
func (r *AVRing[T]) TryRead() (item *AVFrame[T]) {
|
||||||
// if item = &r.Value; ctx.Err() == nil && !item.canRead {
|
if item = &r.Value; item.canRead {
|
||||||
// return nil
|
return
|
||||||
// }
|
}
|
||||||
// return
|
return nil
|
||||||
// }
|
}
|
||||||
|
4
io.go
4
io.go
@@ -66,6 +66,10 @@ func (io *IO[C, S]) getType() string {
|
|||||||
return io.Type
|
return io.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (io *IO[C, S]) GetConfig() *C {
|
||||||
|
return io.Config
|
||||||
|
}
|
||||||
|
|
||||||
type IIO interface {
|
type IIO interface {
|
||||||
IsClosed() bool
|
IsClosed() bool
|
||||||
OnEvent(any)
|
OnEvent(any)
|
||||||
|
@@ -186,12 +186,7 @@ func (opt *Plugin) Publish(streamPath string, pub IPublisher) bool {
|
|||||||
if !ok {
|
if !ok {
|
||||||
conf = EngineConfig
|
conf = EngineConfig
|
||||||
}
|
}
|
||||||
if ok = pub.receive(streamPath, pub, conf.GetPublishConfig()); ok {
|
return pub.receive(streamPath, pub, conf.GetPublishConfig())
|
||||||
p := pub.GetPublisher()
|
|
||||||
p.AudioTrack = p.Stream.NewAudioTrack()
|
|
||||||
p.VideoTrack = p.Stream.NewVideoTrack()
|
|
||||||
}
|
|
||||||
return ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (opt *Plugin) Subscribe(streamPath string, sub ISubscriber) bool {
|
func (opt *Plugin) Subscribe(streamPath string, sub ISubscriber) bool {
|
||||||
|
11
publisher.go
11
publisher.go
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
type IPublisher interface {
|
type IPublisher interface {
|
||||||
IIO
|
IIO
|
||||||
GetPublisher() *Publisher
|
GetConfig() *config.Publish
|
||||||
receive(string, IPublisher, *config.Publish) bool
|
receive(string, IPublisher, *config.Publish) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,8 +17,13 @@ type Publisher struct {
|
|||||||
common.VideoTrack
|
common.VideoTrack
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Publisher) GetPublisher() *Publisher {
|
func (p *Publisher) OnEvent(event any) {
|
||||||
return p
|
switch v := event.(type) {
|
||||||
|
case *Stream:
|
||||||
|
p.AudioTrack = v.NewAudioTrack()
|
||||||
|
p.VideoTrack = v.NewVideoTrack()
|
||||||
|
}
|
||||||
|
p.IO.OnEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
type PullEvent int
|
type PullEvent int
|
||||||
|
@@ -276,7 +276,7 @@ func (s *Stream) run() {
|
|||||||
}
|
}
|
||||||
suber := v.Value
|
suber := v.Value
|
||||||
s.Subscribers = append(s.Subscribers, suber)
|
s.Subscribers = append(s.Subscribers, suber)
|
||||||
sbConfig := suber.GetSubscribeConfig()
|
sbConfig := suber.GetConfig()
|
||||||
if wt := sbConfig.WaitTimeout.Duration(); wt > s.WaitTimeout {
|
if wt := sbConfig.WaitTimeout.Duration(); wt > s.WaitTimeout {
|
||||||
s.WaitTimeout = wt
|
s.WaitTimeout = wt
|
||||||
}
|
}
|
||||||
|
@@ -17,10 +17,10 @@ type VideoDeConf DecoderConfiguration[NALUSlice]
|
|||||||
type ISubscriber interface {
|
type ISubscriber interface {
|
||||||
IIO
|
IIO
|
||||||
receive(string, ISubscriber, *config.Subscribe) bool
|
receive(string, ISubscriber, *config.Subscribe) bool
|
||||||
config.SubscribeConfig
|
GetConfig() *config.Subscribe
|
||||||
GetSubscriber() *Subscriber
|
|
||||||
IsPlaying() bool
|
IsPlaying() bool
|
||||||
Play(ISubscriber)
|
Play(ISubscriber) func() error
|
||||||
|
PlayBlock(ISubscriber)
|
||||||
Stop()
|
Stop()
|
||||||
}
|
}
|
||||||
type TrackPlayer struct {
|
type TrackPlayer struct {
|
||||||
@@ -38,14 +38,6 @@ type Subscriber struct {
|
|||||||
TrackPlayer
|
TrackPlayer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Subscriber) GetSubscriber() *Subscriber {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Subscriber) GetSubscribeConfig() *config.Subscribe {
|
|
||||||
return s.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Subscriber) OnEvent(event any) {
|
func (s *Subscriber) OnEvent(event any) {
|
||||||
switch v := event.(type) {
|
switch v := event.(type) {
|
||||||
case TrackRemoved:
|
case TrackRemoved:
|
||||||
@@ -97,8 +89,8 @@ func (s *Subscriber) Stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Play 开始播放
|
// 非阻塞式读取,通过反复调用返回的函数可以尝试读取数据,读取到数据后会调用OnEvent,这种模式自由的在不同的goroutine中调用
|
||||||
func (s *Subscriber) Play(spesic ISubscriber) {
|
func (s *Subscriber) Play(spesic ISubscriber) func() error {
|
||||||
s.Info("play")
|
s.Info("play")
|
||||||
var t time.Time
|
var t time.Time
|
||||||
var startTime time.Time //读到第一个关键帧的时间
|
var startTime time.Time //读到第一个关键帧的时间
|
||||||
@@ -106,6 +98,73 @@ func (s *Subscriber) Play(spesic ISubscriber) {
|
|||||||
var audioSent bool //音频是否发送过
|
var audioSent bool //音频是否发送过
|
||||||
s.TrackPlayer.Context, s.TrackPlayer.CancelFunc = context.WithCancel(s.IO)
|
s.TrackPlayer.Context, s.TrackPlayer.CancelFunc = context.WithCancel(s.IO)
|
||||||
ctx := s.TrackPlayer.Context
|
ctx := s.TrackPlayer.Context
|
||||||
|
var nextRoundReadAudio bool //下一次读取音频
|
||||||
|
return func() error {
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
if !nextRoundReadAudio || s.ar == nil {
|
||||||
|
if s.vr != nil {
|
||||||
|
if startTime.IsZero() {
|
||||||
|
startTime = time.Now()
|
||||||
|
firstIFrame = (VideoFrame)(s.vr.Read(ctx)) // 这里阻塞读取为0耗时
|
||||||
|
s.Debug("firstIFrame", zap.Uint32("seq", firstIFrame.Sequence))
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
spesic.OnEvent(VideoDeConf(s.VideoTrack.DecoderConfiguration))
|
||||||
|
spesic.OnEvent(firstIFrame)
|
||||||
|
s.vr.MoveNext()
|
||||||
|
if firstIFrame.Timestamp.After(t) {
|
||||||
|
t = firstIFrame.Timestamp
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
} else if firstIFrame == nil {
|
||||||
|
if vp := VideoFrame(s.vr.TryRead()); vp != nil {
|
||||||
|
spesic.OnEvent(vp)
|
||||||
|
s.vr.MoveNext()
|
||||||
|
// 如果本次读取的视频时间戳比较大,下次给音频一个机会
|
||||||
|
if nextRoundReadAudio = vp.Timestamp.After(t); nextRoundReadAudio {
|
||||||
|
t = vp.Timestamp
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if s.Config.SubVideo && (s.Stream == nil || s.Stream.Publisher == nil || s.Stream.Publisher.GetConfig().PubVideo) {
|
||||||
|
// 如果订阅了视频需要等待视频轨道
|
||||||
|
// TODO: 如果发布配置了视频,订阅配置了视频,但是实际上没有视频,需要处理播放纯音频
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 正常模式下或者纯音频模式下,音频开始播放
|
||||||
|
if s.ar != nil && firstIFrame == nil {
|
||||||
|
if !audioSent {
|
||||||
|
spesic.OnEvent(AudioDeConf(s.AudioTrack.DecoderConfiguration))
|
||||||
|
audioSent = true
|
||||||
|
}
|
||||||
|
if ap := AudioFrame(s.ar.TryRead()); ap != nil {
|
||||||
|
spesic.OnEvent(ap)
|
||||||
|
s.ar.MoveNext()
|
||||||
|
// 这次如果音频比较大,则下次读取给视频一个机会
|
||||||
|
if nextRoundReadAudio = !ap.Timestamp.After(t); !nextRoundReadAudio {
|
||||||
|
t = ap.Timestamp
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//PlayBlock 阻塞式读取数据
|
||||||
|
func (s *Subscriber) PlayBlock(spesic ISubscriber) {
|
||||||
|
s.Info("playblock")
|
||||||
|
var t time.Time
|
||||||
|
var startTime time.Time //读到第一个关键帧的时间
|
||||||
|
var firstIFrame VideoFrame //起始关键帧
|
||||||
|
var audioSent bool //音频是否发送过
|
||||||
|
s.TrackPlayer.Context, s.TrackPlayer.CancelFunc = context.WithCancel(s.IO)
|
||||||
|
ctx := s.TrackPlayer.Context
|
||||||
defer s.Info("stop")
|
defer s.Info("stop")
|
||||||
for ctx.Err() == nil {
|
for ctx.Err() == nil {
|
||||||
if s.vr != nil {
|
if s.vr != nil {
|
||||||
@@ -151,7 +210,12 @@ func (s *Subscriber) Play(spesic ISubscriber) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if s.Config.SubVideo && (s.Stream == nil || s.Stream.Publisher == nil || s.Stream.Publisher.GetConfig().PubVideo) {
|
||||||
|
// 如果订阅了视频需要等待视频轨道
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
// 正常模式下或者纯音频模式下,音频开始播放
|
||||||
if s.ar != nil && firstIFrame == nil {
|
if s.ar != nil && firstIFrame == nil {
|
||||||
if !audioSent {
|
if !audioSent {
|
||||||
spesic.OnEvent(AudioDeConf(s.AudioTrack.DecoderConfiguration))
|
spesic.OnEvent(AudioDeConf(s.AudioTrack.DecoderConfiguration))
|
||||||
|
Reference in New Issue
Block a user