feat: add change subscribe

This commit is contained in:
langhuihui
2024-06-13 17:15:30 +08:00
parent 68a7edf678
commit 00b39aee3e
26 changed files with 890 additions and 406 deletions

View File

@@ -2,6 +2,7 @@ package m7s
import (
"context"
"errors"
"io"
"net"
"net/url"
@@ -70,11 +71,6 @@ type Subscriber struct {
VideoReader *AVRingReader
}
type SubscriberHandler struct {
OnAudio any
OnVideo any
}
func (s *Subscriber) OnVideoFrame(yield func(*AVFrame) bool) {
if !s.SubVideo || s.Publisher == nil {
return
@@ -169,24 +165,24 @@ func HandleVideo[T IAVFrame](s *Subscriber) func(func(T) bool) {
}
}
func (s *Subscriber) Handle(handler SubscriberHandler) {
func PlayBlock[A any, V any](s *Subscriber, onAudio func(A) error, onVideo func(V) error) {
var ar, vr *AVRingReader
var ah, vh reflect.Value
var a1, v1 reflect.Type
var at, vt *AVTrack
var awi, vwi int
var startAudioTs, startVideoTs time.Duration
var initState = 0
var prePublisher *Publisher
var subMode = s.SubMode //订阅模式
if s.Args.Has(s.SubModeArgName) {
subMode, _ = strconv.Atoi(s.Args.Get(s.SubModeArgName))
}
var audioFrame, videoFrame *AVFrame
if handler.OnAudio != nil && s.SubAudio {
a1 = reflect.TypeOf(handler.OnAudio).In(0)
if s.SubAudio {
a1 = reflect.TypeOf(onAudio).In(0)
}
if handler.OnVideo != nil && s.SubVideo {
v1 = reflect.TypeOf(handler.OnVideo).In(0)
if s.SubVideo {
v1 = reflect.TypeOf(onVideo).In(0)
}
createAudioReader := func() {
if s.Publisher == nil || a1 == nil {
@@ -204,9 +200,9 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
if at != nil {
ar = NewAVRingReader(at)
s.AudioReader = ar
ar.StartTs = startAudioTs
ar.Logger = s.Logger.With("reader", a1.String())
ar.Info("start read")
ah = reflect.ValueOf(handler.OnAudio)
}
}
createVideoReader := func() {
@@ -224,14 +220,15 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
}
if vt != nil {
vr = NewAVRingReader(vt)
vr.StartTs = startVideoTs
s.VideoReader = vr
vr.Logger = s.Logger.With("reader", v1.String())
vr.Info("start read")
vh = reflect.ValueOf(handler.OnVideo)
}
}
createAudioReader()
createVideoReader()
prePublisher = s.Publisher
defer func() {
if ar != nil {
ar.StopRead()
@@ -240,21 +237,17 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
vr.StopRead()
}
}()
inputs := make([]reflect.Value, 1)
sendAudioFrame := func() (err error) {
if awi >= 0 {
if s.Enabled(s, TraceLevel) {
s.Trace("send audio frame", "seq", audioFrame.Sequence)
}
inputs[0] = reflect.ValueOf(audioFrame.Wraps[awi])
err = onAudio(audioFrame.Wraps[awi].(A))
} else {
inputs[0] = reflect.ValueOf(audioFrame)
err = onAudio(any(audioFrame).(A))
}
res := ah.Call(inputs)
if len(res) > 0 && !res[0].IsNil() {
if err := res[0].Interface().(error); err != ErrInterrupt {
s.Stop(err)
}
if err != nil && !errors.Is(err, ErrInterrupt) {
s.Stop(err)
}
audioFrame = nil
return
@@ -264,19 +257,31 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
if s.Enabled(s, TraceLevel) {
s.Trace("send video frame", "seq", videoFrame.Sequence, "data", videoFrame.Wraps[vwi].String(), "size", videoFrame.Wraps[vwi].GetSize())
}
inputs[0] = reflect.ValueOf(videoFrame.Wraps[vwi])
err = onVideo(videoFrame.Wraps[vwi].(V))
} else {
inputs[0] = reflect.ValueOf(videoFrame)
err = onVideo(any(videoFrame).(V))
}
res := vh.Call(inputs)
if len(res) > 0 && !res[0].IsNil() {
if err = res[0].Interface().(error); err != ErrInterrupt {
s.Stop(err)
}
if err != nil && !errors.Is(err, ErrInterrupt) {
s.Stop(err)
}
videoFrame = nil
return
}
checkPublisherChange := func() {
if prePublisher != s.Publisher {
if ar != nil {
startAudioTs = time.Duration(ar.AbsTime) * time.Millisecond
ar.StopRead()
}
if vr != nil {
startVideoTs = time.Duration(vr.AbsTime) * time.Millisecond
vr.StopRead()
}
createAudioReader()
createVideoReader()
prePublisher = s.Publisher
}
}
var err error
for err == nil {
err = s.Err()
@@ -297,7 +302,7 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
vr.LastCodecCtx = vr.Track.ICodecCtx
if seqFrame := vr.Track.SequenceFrame; seqFrame != nil {
s.Debug("video codec changed", "data", seqFrame.String())
vh.Call([]reflect.Value{reflect.ValueOf(seqFrame)})
err = onVideo(seqFrame.(V))
}
}
if ar != nil {
@@ -315,6 +320,9 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
if !s.IFrameOnly || videoFrame.IDR {
err = sendVideoFrame()
}
if ar == nil {
break
}
}
} else {
createVideoReader()
@@ -347,7 +355,7 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
if ar.DecConfChanged() {
ar.LastCodecCtx = ar.Track.ICodecCtx
if seqFrame := ar.Track.SequenceFrame; seqFrame != nil {
ah.Call([]reflect.Value{reflect.ValueOf(seqFrame)})
err = onAudio(seqFrame.(A))
}
}
if vr != nil && videoFrame != nil {
@@ -365,5 +373,6 @@ func (s *Subscriber) Handle(handler SubscriberHandler) {
} else {
createAudioReader()
}
checkPublisherChange()
}
}