mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-27 03:25:56 +08:00
151 lines
3.2 KiB
Go
151 lines
3.2 KiB
Go
package rtsp
|
|
|
|
import (
|
|
task "github.com/langhuihui/gotask"
|
|
"m7s.live/v5/pkg/config"
|
|
|
|
"m7s.live/v5"
|
|
pkg "m7s.live/v5/pkg"
|
|
)
|
|
|
|
// Plugin-specific progress step names for RTSP
|
|
const (
|
|
StepDescribe pkg.StepName = "describe"
|
|
StepSetup pkg.StepName = "setup"
|
|
StepPlay pkg.StepName = "play"
|
|
)
|
|
|
|
// Fixed steps for RTSP pull workflow
|
|
var rtspPullSteps = []pkg.StepDef{
|
|
{Name: pkg.StepPublish, Description: "Publishing stream"},
|
|
{Name: pkg.StepConnection, Description: "Connecting to RTSP server"},
|
|
{Name: StepDescribe, Description: "Sending DESCRIBE request"},
|
|
{Name: StepSetup, Description: "Setting up media tracks"},
|
|
{Name: StepPlay, Description: "Starting media playback"},
|
|
{Name: pkg.StepStreaming, Description: "Receiving and processing media data"},
|
|
}
|
|
|
|
const (
|
|
DIRECTION_PULL = "pull"
|
|
DIRECTION_PUSH = "push"
|
|
)
|
|
|
|
type Client struct {
|
|
Stream
|
|
pullCtx m7s.PullJob
|
|
pushCtx m7s.PushJob
|
|
direction string
|
|
}
|
|
|
|
func (c *Client) Start() (err error) {
|
|
if c.direction == DIRECTION_PULL { // no progress tracking
|
|
c.pullCtx.SetProgressStepsDefs(rtspPullSteps)
|
|
if err = c.pullCtx.Publish(); err != nil {
|
|
c.pullCtx.Fail(err.Error())
|
|
return
|
|
}
|
|
if err = c.NetConnection.Connect(c.pullCtx.RemoteURL); err != nil {
|
|
c.pullCtx.Fail(err.Error())
|
|
return
|
|
}
|
|
} else {
|
|
err = c.NetConnection.Connect(c.pushCtx.RemoteURL)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (c *Client) GetPullJob() *m7s.PullJob {
|
|
return &c.pullCtx
|
|
}
|
|
|
|
func (c *Client) GetPushJob() *m7s.PushJob {
|
|
return &c.pushCtx
|
|
}
|
|
|
|
func NewPuller(_ config.Pull) m7s.IPuller {
|
|
client := &Client{
|
|
direction: DIRECTION_PULL,
|
|
}
|
|
client.NetConnection = &NetConnection{}
|
|
client.SetDescription(task.OwnerTypeKey, "RTSPPuller")
|
|
return client
|
|
}
|
|
|
|
func NewPusher() m7s.IPusher {
|
|
client := &Client{
|
|
direction: DIRECTION_PUSH,
|
|
}
|
|
client.NetConnection = &NetConnection{}
|
|
client.SetDescription(task.OwnerTypeKey, "RTSPPusher")
|
|
return client
|
|
}
|
|
|
|
func (c *Client) Run() (err error) {
|
|
if err = c.Options(); err != nil {
|
|
return
|
|
}
|
|
if c.direction == DIRECTION_PULL {
|
|
c.pullCtx.GoToStepConst(StepDescribe)
|
|
|
|
var medias []*Media
|
|
if medias, err = c.Describe(); err != nil {
|
|
return
|
|
}
|
|
receiver := &Receiver{Publisher: c.pullCtx.Publisher, Stream: c.Stream}
|
|
if err = receiver.SetMedia(medias); err != nil {
|
|
return
|
|
}
|
|
|
|
c.pullCtx.GoToStepConst(StepSetup)
|
|
|
|
for i, media := range medias {
|
|
switch media.Kind {
|
|
case "audio", "video":
|
|
_, err = c.SetupMedia(media, "play", i)
|
|
if err != nil {
|
|
return
|
|
}
|
|
default:
|
|
c.Warn("media kind not support", "kind", media.Kind)
|
|
}
|
|
}
|
|
|
|
c.pullCtx.GoToStepConst(StepPlay)
|
|
|
|
if err = c.Play(); err != nil {
|
|
return
|
|
}
|
|
|
|
c.pullCtx.GoToStepConst(pkg.StepStreaming)
|
|
|
|
return receiver.Receive()
|
|
} else {
|
|
err = c.pushCtx.Subscribe()
|
|
if err != nil {
|
|
return
|
|
}
|
|
sender := &Sender{Subscriber: c.pushCtx.Subscriber, Stream: c.Stream}
|
|
var medias []*Media
|
|
medias, err = sender.GetMedia()
|
|
err = c.Announce(medias)
|
|
if err != nil {
|
|
return
|
|
}
|
|
for i, media := range medias {
|
|
switch media.Kind {
|
|
case "audio", "video":
|
|
_, err = c.SetupMedia(media, "record", i)
|
|
if err != nil {
|
|
return
|
|
}
|
|
default:
|
|
c.Warn("media kind not support", "kind", media.Kind)
|
|
}
|
|
}
|
|
if err = c.Record(); err != nil {
|
|
return
|
|
}
|
|
return sender.Send()
|
|
}
|
|
}
|