Skip to content

Commit

Permalink
feat: add stop subscribe api, show reasons for subscriber closure
Browse files Browse the repository at this point in the history
  • Loading branch information
langhuihui committed Aug 6, 2023
1 parent 9a352bc commit 1a347b5
Show file tree
Hide file tree
Showing 24 changed files with 235 additions and 185 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
- 热更新配置信息 `/api/updateconfig?name=xxx` 热更新xxx插件的配置信息,如果不带参数或参数为空则热更新全局配置
- 获取所有远端拉流信息 `/api/list/pull` 返回{RemoteURL:"",StreamPath:"",Type:"",StartTime:""}
- 获取所有向远端推流信息 `/api/list/push` 返回{RemoteURL:"",StreamPath:"",Type:"",StartTime:""}
- 停止推流 `/api/stoppush?url=xxx` 停止向xxx推流 ,成功返回ok
- 停止推流 `/api/stop/push?url=xxx` 停止向xxx推流 ,成功返回ok
- 停止某个订阅者 `/api/stop/subscribe?streamPath=xxx&id=xxx` 停止xxx流的xxx订阅者 ,成功返回ok
- 插入SEI帧 `/api/insertsei?streamPath=xxx&type=5` 向xxx流内插入SEI帧 ,成功返回ok。type为SEI类型,可选,默认是5
# 引擎默认配置
```yaml
Expand Down
1 change: 1 addition & 0 deletions common/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func (av *AVFrame) Reset() {
av.ADTS = nil
}
av.Timestamp = 0
av.IFrame = false
av.DataFrame.Reset()
}

Expand Down
1 change: 0 additions & 1 deletion config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ type Engine struct {
LogLang string `default:"zh"` //日志语言
LogLevel string `default:"info"` //日志级别
RTPReorderBufferLen int `default:"50"` //RTP重排序缓冲长度
SpeedLimit time.Duration `default:"500ms"` //速度限制最大等待时间
EventBusSize int `default:"10"` //事件总线大小
PulseInterval time.Duration `default:"5s"` //心跳事件间隔
DisableAll bool `default:"false"` //禁用所有插件
Expand Down
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ module m7s.live/engine/v4
go 1.19

require (
github.com/aler9/gortsplib/v2 v2.2.2
github.com/bluenviron/mediacommon v0.7.0
github.com/cnotch/ipchub v1.1.0
github.com/google/uuid v1.3.0
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mcuadros/go-defaults v1.2.0
github.com/pion/rtp v1.7.13
github.com/pion/webrtc/v3 v3.1.49
github.com/pion/rtp v1.8.0
github.com/pion/webrtc/v3 v3.1.56
github.com/q191201771/naza v0.30.8
github.com/quic-go/quic-go v0.32.0
github.com/shirou/gopsutil/v3 v3.22.10
go.uber.org/zap v1.23.0
golang.org/x/net v0.8.0
github.com/shirou/gopsutil/v3 v3.22.11
go.uber.org/zap v1.24.0
golang.org/x/net v0.12.0
golang.org/x/sync v0.1.0
gopkg.in/yaml.v3 v3.0.1
)
Expand Down Expand Up @@ -43,9 +43,9 @@ require (
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/yapingcat/gomedia v0.0.0-20230426092936-387031404274
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.4.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/tools v0.3.0 // indirect
)
8 changes: 3 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/aler9/gortsplib/v2 v2.2.2 h1:tTw8pdKSOEjlZjjE1S4ftXPHJkYOqjNNv3hjQ0Nto9M=
github.com/aler9/gortsplib/v2 v2.2.2/go.mod h1:k6uBVHGwsIc/0L5SLLqWwi6bSJUb4VR0HfvncyHlKQI=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/bluenviron/mediacommon v0.7.0 h1:dJWLLL9oDbAqfK8KuNfnDUQwNbeMAtGeRjZc9Vo95js=
github.com/bluenviron/mediacommon v0.7.0/go.mod h1:wuLJdxcITiSPgY1MvQqrX+qPlKmNfeV9wNvXth5M98I=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down Expand Up @@ -141,15 +141,13 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
github.com/yapingcat/gomedia v0.0.0-20230222121919-c67df405bf33 h1:uyZY++dluUg7iTSsNzuOVln/mC2U2KXwgKLfKLCJ74Y=
github.com/yapingcat/gomedia v0.0.0-20230222121919-c67df405bf33/go.mod h1:WSZ59bidJOO40JSJmLqlkBJrjZCtjbKKkygEMfzY/kc=
github.com/yapingcat/gomedia v0.0.0-20230426092936-387031404274 h1:cj4I+bvWX9I+Hg6tnZ7DAiOVxzhyLhdvYVKp+WpM/2c=
github.com/yapingcat/gomedia v0.0.0-20230426092936-387031404274/go.mod h1:WSZ59bidJOO40JSJmLqlkBJrjZCtjbKKkygEMfzY/kc=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
57 changes: 28 additions & 29 deletions http.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ package engine

import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strconv"
"strings"
"time"

"go.uber.org/zap"
"gopkg.in/yaml.v3"
"m7s.live/engine/v4/codec"
"m7s.live/engine/v4/config"
Expand Down Expand Up @@ -40,33 +42,12 @@ func (conf *GlobalConfig) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
}
}

func fetchSummary() *Summary {
return &summary
}

func (conf *GlobalConfig) API_summary(rw http.ResponseWriter, r *http.Request) {
y := ShouldYaml(r)
if r.Header.Get("Accept") == "text/event-stream" {
summary.Add()
defer summary.Done()
if y {
util.ReturnYaml(fetchSummary, time.Second, rw, r)
} else {
util.ReturnJson(fetchSummary, time.Second, rw, r)
}
if y {
util.ReturnYaml(util.FetchValue(&summary), time.Second, rw, r)
} else {
if !summary.Running() {
summary.collect()
}
summary.rw.RLock()
defer summary.rw.RUnlock()
if y {
if err := yaml.NewEncoder(rw).Encode(&summary); err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
} else if err := json.NewEncoder(rw).Encode(&summary); err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
util.ReturnJson(util.FetchValue(&summary), time.Second, rw, r)
}
}

Expand All @@ -84,9 +65,9 @@ func (conf *GlobalConfig) API_stream(rw http.ResponseWriter, r *http.Request) {
if streamPath := r.URL.Query().Get("streamPath"); streamPath != "" {
if s := Streams.Get(streamPath); s != nil {
if ShouldYaml(r) {
util.ReturnYaml(func() *Stream { return s }, time.Second, rw, r)
util.ReturnYaml(util.FetchValue(s), time.Second, rw, r)
} else {
util.ReturnJson(func() *Stream { return s }, time.Second, rw, r)
util.ReturnJson(util.FetchValue(s), time.Second, rw, r)
}
} else {
http.Error(rw, NO_SUCH_STREAM, http.StatusNotFound)
Expand Down Expand Up @@ -218,17 +199,35 @@ func (conf *GlobalConfig) API_list_push(w http.ResponseWriter, r *http.Request)
}, time.Second, w, r)
}

func (conf *GlobalConfig) API_stopPush(w http.ResponseWriter, r *http.Request) {
func (conf *GlobalConfig) API_stop_push(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
pusher, ok := Pushers.Load(q.Get("url"))
if ok {
pusher.(IPusher).Stop()
w.Write([]byte("ok"))
fmt.Fprintln(w, "ok")
} else {
http.Error(w, "no such pusher", http.StatusNotFound)
}
}

func (conf *GlobalConfig) API_stop_subscribe(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
streamPath := q.Get("streamPath")
id := q.Get("id")
s := Streams.Get(streamPath)
if s == nil {
http.Error(w, NO_SUCH_STREAM, http.StatusNotFound)
return
}
suber := s.Subscribers.Find(id)
if suber == nil {
http.Error(w, "no such subscriber", http.StatusNotFound)
return
}
suber.Stop(zap.String("reason", "stop by api"))
fmt.Fprintln(w, "ok")
}

func (conf *GlobalConfig) API_replay_rtpdump(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
streamPath := q.Get("streamPath")
Expand Down Expand Up @@ -314,7 +313,7 @@ func (conf *GlobalConfig) API_replay_ts(w http.ResponseWriter, r *http.Request)
} else {
tsReader := NewTSReader(&pub)
pub.SetIO(f)
go func(){
go func() {
tsReader.Feed(f)
tsReader.Close()
}()
Expand Down
11 changes: 8 additions & 3 deletions io.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"m7s.live/engine/v4/config"
"m7s.live/engine/v4/log"
"m7s.live/engine/v4/util"
Expand All @@ -36,6 +37,7 @@ type AuthPub interface {
type IO struct {
ID string
Type string
RemoteAddr string
context.Context `json:"-" yaml:"-"` //不要直接设置,应当通过OnEvent传入父级Context
context.CancelFunc `json:"-" yaml:"-"` //流关闭是关闭发布者或者订阅者
*log.Logger `json:"-" yaml:"-"`
Expand Down Expand Up @@ -92,7 +94,7 @@ type IIO interface {
receive(string, IIO) error
IsClosed() bool
OnEvent(any)
Stop()
Stop(reason ...zapcore.Field)
SetIO(any)
SetParentCtx(context.Context)
SetLogger(*log.Logger)
Expand All @@ -113,9 +115,11 @@ func (i *IO) close() bool {
}

// Stop 停止订阅或者发布,由订阅者或者发布者调用
func (io *IO) Stop() {
func (io *IO) Stop(reason ...zapcore.Field) {
if io.close() {
io.Debug("stop", zap.Stack("stack"))
io.Info("stop", reason...)
} else {
io.Warn("already stopped", reason...)
}
}

Expand Down Expand Up @@ -194,6 +198,7 @@ func (io *IO) receive(streamPath string, specific IIO) error {
} else if oldPublisher == specific {
//断线重连
} else {
s.Warn("duplicate publish", zap.String("type", oldPublisher.GetPublisher().Type))
return ErrDuplicatePublish
}
}
Expand Down
6 changes: 5 additions & 1 deletion lang/zh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ state: 状态
initialize: 初始化
"start read": 开始读取
"start pull": 开始从远端拉流
"restart pull": 重新拉流
"pull failed": 拉取失败
"wait publisher": 等待发布者发布
"wait timeout": 等待超时
Expand All @@ -45,6 +46,7 @@ reamins: 剩余
"video track attached": 视频轨道已附加
"audio track attached": 音频轨道已附加
"data track attached": 数据轨道已附加
"track back online": 轨道已恢复
"first frame read": 第一帧已读取
"fu have no start": rtp的FU起始包丢了
"disabled by env": 被环境变量禁用
Expand All @@ -54,4 +56,6 @@ reamins: 剩余
firstTs: 第一帧时间戳
firstSeq: 第一帧序列号
skipSeq: 跳过序列号
skipTs: 跳过时间戳
skipTs: 跳过时间戳
"nalu type not supported": nalu类型不支持
"create file": 创建文件
3 changes: 3 additions & 0 deletions memory-ts.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ func (ts *MemoryTs) WritePESPacket(frame *mpegts.MpegtsPESFrame, packet mpegts.M
var tsHeaderLength int
for i := 0; len(pesBuffers) > 0; i++ {
if bigLen < mpegts.TS_PACKET_SIZE {
if i == 0 {
ts.Recycle()
}
headerItem := ts.Get(mpegts.TS_PACKET_SIZE)
ts.BLL.Push(headerItem)
bwTsHeader = &headerItem.Value
Expand Down
Loading

0 comments on commit 1a347b5

Please sign in to comment.