diff --git a/README.md b/README.md index 06e49e4..0fbca85 100644 --- a/README.md +++ b/README.md @@ -58,11 +58,15 @@ Java WVP @648540858 [wvp-GB28181-pro](https://github.com/648540858/wvp-GB28181-p [GB/T28181 全栈开发日记[6]:React 快速接入 jessibuca.js 播放器](https://juejin.cn/post/7462229773982351410) +[GB/T28181 全栈开发日记[7]:实现 RTMP 鉴权与播放](https://juejin.cn/post/7463504223177261119) + 开发中... > 有没有使用资料? -[RTMP 推拉流规则](https://juejin.cn/post/7463046634558718004) +[RTMP 推拉流规则](https://juejin.cn/post/7463124448540934194) + +[如何使用 OBS RTMP 推流到 GB/T28181平台](https://juejin.cn/post/7463350947100786739) 码字中... diff --git a/docs/rtmp.webp b/docs/rtmp.webp new file mode 100644 index 0000000..50f5e2a Binary files /dev/null and b/docs/rtmp.webp differ diff --git a/internal/core/media/stream_push.go b/internal/core/media/stream_push.go index e325613..4f22b28 100755 --- a/internal/core/media/stream_push.go +++ b/internal/core/media/stream_push.go @@ -123,7 +123,7 @@ func (c *Core) Publish(ctx context.Context, in PublishInput) error { if !result.IsAuthDisabled { if s := hook.MD5(in.Session + in.Secret); s != in.Sign { slog.Info("推流鉴权失败", "got", in.Sign, "expect", s) - return fmt.Errorf("rtmp secret error, got[%s]", in.Sign) + return fmt.Errorf("Unauthorized, rtmp secret error, got[%s]", in.Sign) } } @@ -163,7 +163,7 @@ func (c *Core) OnPlay(ctx context.Context, in OnPlayInput) error { } if in.Session != result.Session { slog.Info("拉流鉴权失败", "got", in.Session, "expect", result.Session) - return fmt.Errorf("session error, got[%s]", in.Session) + return fmt.Errorf("Unauthorized, session error, got[%s]", in.Session) } return nil } diff --git a/internal/core/sms/node_manager.go b/internal/core/sms/node_manager.go index 3dfbe54..25b82a8 100644 --- a/internal/core/sms/node_manager.go +++ b/internal/core/sms/node_manager.go @@ -159,6 +159,7 @@ func (n *NodeManager) connection(server *MediaServer, serverPort int) { hookPrefix := fmt.Sprintf("http://%s:%d/webhook", server.HookIP, serverPort) req := zlm.SetServerConfigRequest{ + RtcExternIP: zlm.NewString(server.IP), GeneralMediaServerID: zlm.NewString(server.ID), HookEnable: zlm.NewString("1"), HookOnFlowReport: zlm.NewString(""), diff --git a/internal/web/api/api.go b/internal/web/api/api.go index 903a10c..1936ff1 100644 --- a/internal/web/api/api.go +++ b/internal/web/api/api.go @@ -98,26 +98,32 @@ func setupRouter(r *gin.Engine, uc *Usecase) { } var session string if !push.IsAuthDisabled && push.Session != "" { - session = "?session=" + push.Session + session = "session=" + push.Session } + // 播放规则 + // https://github.com/zlmediakit/ZLMediaKit/wiki/%E6%92%AD%E6%94%BEurl%E8%A7%84%E5%88%99 return &playOutput{ App: push.App, Stream: push.Stream, Items: []streamAddrItem{ { Label: "默认线路", - WSFLV: fmt.Sprintf("ws://%s:%d/%s.live.flv", host, svr.Ports.WsFLV, stream), - HTTPFLV: fmt.Sprintf("http://%s:%d/%s.live.flv", host, svr.Ports.FLV, stream), - RTMP: fmt.Sprintf("rtmp://%s:%d/%s", host, svr.Ports.RTMP, stream) + session, - RTSP: fmt.Sprintf("rtsp://%s:%d/%s", host, svr.Ports.RTSP, stream), + WSFLV: fmt.Sprintf("ws://%s:%d/%s.live.flv", host, svr.Ports.HTTP, stream) + "?" + session, + HTTPFLV: fmt.Sprintf("http://%s:%d/%s.live.flv", host, svr.Ports.HTTP, stream) + "?" + session, + RTMP: fmt.Sprintf("rtmp://%s:%d/%s", host, svr.Ports.RTMP, stream) + "?" + session, + RTSP: fmt.Sprintf("rtsp://%s:%d/%s", host, svr.Ports.RTSP, stream) + "?" + session, + WebRTC: fmt.Sprintf("webrtc://%s:%d/index/api/webrtc?app=%s&stream=%s&type=play", host, svr.Ports.HTTP, push.App, push.Stream) + "&" + session, + HLS: fmt.Sprintf("http://%s:%d/%s/hls.fmp4.m3u8", host, svr.Ports.HTTP, stream) + "?" + session, }, { Label: "SSL 线路", - WSFLV: fmt.Sprintf("wss://%s:%d/%s.live.flv", host, svr.Ports.WsFLVs, stream), - HTTPFLV: fmt.Sprintf("https://%s:%d/%s.live.flv", host, svr.Ports.FLVs, stream), + WSFLV: fmt.Sprintf("wss://%s:%d/%s.live.flv", host, svr.Ports.HTTP, stream) + session, + HTTPFLV: fmt.Sprintf("https://%s:%d/%s.live.flv", host, svr.Ports.HTTP, stream) + session, RTMP: fmt.Sprintf("rtmps://%s:%d/%s", host, svr.Ports.RTMPs, stream) + session, - RTSP: fmt.Sprintf("rtsps://%s:%d/%s", host, svr.Ports.RTSPs, stream), + RTSP: fmt.Sprintf("rtsps://%s:%d/%s", host, svr.Ports.RTSPs, stream) + session, + WebRTC: fmt.Sprintf("webrtc://%s:%d/index/api/webrtc?app=%s&stream=%s&type=play", host, svr.Ports.HTTPS, push.App, push.Stream) + "&" + session, + HLS: fmt.Sprintf("https://%s:%d/%s/hls.fmp4.m3u8", host, svr.Ports.HTTPS, stream) + "?" + session, }, }, }, nil @@ -135,6 +141,8 @@ type streamAddrItem struct { HTTPFLV string `json:"http_flv"` RTMP string `json:"rtmp"` RTSP string `json:"rtsp"` + WebRTC string `json:"webrtc"` + HLS string `json:"hls"` } type getHealthOutput struct {