GithubHelp home page GithubHelp logo

monibuca / engine Goto Github PK

View Code? Open in Web Editor NEW
935.0 935.0 199.0 1.68 MB

Monibuca 核心引擎,包含流媒体核心转发逻辑,需要配合功能插件一起组合运行

License: MIT License

Go 100.00%
streaming toml

engine's Introduction

Introduction

Monibuca is a highly scalable high-performance streaming server development framework developed purely for Go

Usage

package main

import (
	"context"

	"m7s.live/m7s/v5"
	_ "m7s.live/m7s/v5/plugin/debug"
	_ "m7s.live/m7s/v5/plugin/hdl"
	_ "m7s.live/m7s/v5/plugin/rtmp"
)

func main() {
	m7s.Run(context.Background(), "config.yaml")
}

More Example

see example directory

Create Plugin

import (
	"m7s.live/m7s/v5"
)

type MyPlugin struct {
	m7s.Plugin
}

var _ = m7s.InstallPlugin[MyPlugin]()

engine's People

Contributors

bigbeer1 avatar charlestamz avatar dwdcth avatar evrins avatar gaoyangtok avatar haowanxing avatar langhuihui avatar mask-pp avatar patchoulistar avatar pggiroro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

engine's Issues

热更新配置接口

1.调用热更新配置接口或者先modify再热更新,会报错
2.具体错误 Unmarshal error:reflect : NumField of non-struct type config.Plugin

rtmp推流有问题

windows10下:
推流:
ffmpeg -i test.mp4 -f flv rtmp://localhost/live/test

image

拉流:
ffplay -i rtmp://localhost/live/test

image

拉流订阅后就退出了:
image

以为是拉流的问题,后面跟代码发现,是推流不正常!

image

也就是PushByteStream()函数进来后,只做了下判断,啥也没干... 对RTMP协议不是很熟悉,前面对msg包的处理逻辑看的不是很明白,是前面对msg包处理的问题还是其他情况?

关于Monibuca许可疑问

dexter~你好,请问Monibuca用于商用需要付费吗?官方插件项目没有著名许可协议,是不是支持engine才是GPL协议,官方插件不是呢?如果是自己写的插件有没有限制呢?

v4版本如何推流鉴权?

请问在自定义插件中的OnEvent方法接收哪个事件中处理?现在我在“SEpublish”事件中通过Stream.Close()的方法进行处理,因为obs有断线重连功能,就出现反复连接->断开,感觉这样不是很友好。

MemoryTS 输出的ts 文件 没有音频编码信息

参考 hls 插件实现 ,使用memoryTs 输出的ts 文件没有音频编码信息,大致的代码如下:
直接使用hls 插件,输出的 ts 也无法获取 音视频信息,测试 拉流地址
http://huadonglive.starschinalive.com/stars/cjpd_stars-hd.m3u8?auth_key=1677980353-0-0-76a9f3c2dbaef16cf6b0f9d12b52eb5d

   func (hls *HLSWriter) OnEvent(event any) {
	switch v := event.(type) {
	case *track.Video:
		if hls.Audio != nil {
			hls.ts.WritePMTPacket(hls.Audio.CodecID, v.CodecID)
		} else {
			hls.ts.WritePMTPacket(0, v.CodecID)
		}
		hls.AddTrack(v)
	case *track.Audio:
		if hls.Video != nil {
			hls.ts.WritePMTPacket(v.CodecID, hls.Video.CodecID)
		} else {
			hls.ts.WritePMTPacket(v.CodecID, 0)
		}
		hls.AddTrack(v)
	case AudioFrame:
		pes := &mpegts.MpegtsPESFrame{
			Pid:                       mpegts.PID_AUDIO,
			IsKeyFrame:                false,
			ContinuityCounter:         hls.audio_cc,
			ProgramClockReferenceBase: uint64(v.DTS),
		}
		if err := hls.ts.WriteAudioFrame(v, pes); err != nil {
			hls.Error("WriteVideoFrame", zap.Error(err))
			return
		}
		hls.audio_cc = pes.ContinuityCounter
	case VideoFrame:
		if v.IFrame {
			// hls.ts.WriteTo(hFile)
			hls.frag(hls.Stream.Path, v.AbsTime, v)
		}
		pes := &mpegts.MpegtsPESFrame{
			Pid:                       mpegts.PID_VIDEO,
			IsKeyFrame:                v.IFrame,
			ContinuityCounter:         hls.video_cc,
			ProgramClockReferenceBase: uint64(v.DTS),
		}
		if err := hls.ts.WriteVideoFrame(v, pes); err != nil {
			hls.Error("WriteVideoFrame", zap.Error(err))
			return
		}
		hls.video_cc = pes.ContinuityCounter

	default:
		hls.Subscriber.OnEvent(event)
	}
}

ffprobe 信息如下

[mpegts @ 0x11fde40] PES packet size mismatch
    Last message repeated 5 times
[mpegts @ 0x11fde40] decoding for stream 0 failed
[mpegts @ 0x11fde40] decoding for stream 1 failed
[mpegts @ 0x11fde40] PES packet size mismatch
    Last message repeated 5 times
[mpegts @ 0x11fde40] Could not find codec parameters for stream 1 (Audio: aac ([15][0][0][0] / 0x000F), 0 channels, fltp): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from 'monibuca/output/hls/gtzy/cctv5P480/s15/cctv5-2303081101-18747-18765.ts':
  Duration: 00:00:00.27, start: 18765.786033, bitrate: 589 kb/s
  Program 1 
    Stream #0:0[0x101]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 640x480 [SAR 4:3 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x102]: Audio: aac ([15][0][0][0] / 0x000F), 0 channels, fltp

panic问题

subscriber.go文件中,该函数 r 空指针引发panic.

func (a AudioFrame) GetADTS() (r net.Buffers) {
	r = append(append(r, a.ADTS.Value), a.AUList.ToBuffers()...)
	return
}

Config parser incorrectly ignores YAML tags in config structs

The YAML parser in the config file is currently not respecting the yaml tag present in our custom plugin configuration struct

MyCustomOption string `yaml:"my_custom_option"`

like this ->

type MyPluginConfig struct {
  config.HTTP
  config.Publish
  config.Pull
  config.Subscribe
  config.Push
  MyCustomOption string `yaml:"my_custom_option"`
}

Technically the config parser should search for my_custom_option in the yaml config but the issue is it tries to find mycustomoption and doesn't use the yaml tag from plugin struct.

This behavior contradicts the expected usage of the yaml tag in the struct, which is meant to provide a clear mapping between the struct field and the corresponding key in the YAML configuration.

CRITICAL: Monibuca Alters FPS from 60 FPS to 62.5 FPS

Description:

I've recently run into an issue with the Monibuca streaming server while streaming a 60 FPS video file named frame_counter_4k_60fps.flv. I used the following FFmpeg command to stream the video:

ffmpeg -re -i /ramdisk/frame_counter_4k_60fps.flv -c copy -f flv rtmp://127.0.0.1/app/hello123
Input #0, flv, from '/ramdisk/frame_counter_4k_60fps.flv':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf59.16.100
  Duration: 00:01:00.04, start: 0.019000, bitrate: 658 kb/s
  Stream #0:0: Video: h264 (High), yuv420p(progressive), 3840x2160 [SAR 1:1 DAR 16:9], 640 kb/s, 60 fps, 60 tbr, 1k tbn
  Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 2 kb/s
Output #0, flv, to 'rtmp://127.0.0.1/app/hello123':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf60.3.100
  Stream #0:0: Video: h264 (High) ([7][0][0][0] / 0x0007), yuv420p(progressive), 3840x2160 [SAR 1:1 DAR 16:9], q=2-31, 640 kb/s, 60 fps, 60 tbr, 1k tbn
  Stream #0:1: Audio: aac (LC) ([10][0][0][0] / 0x000A), 48000 Hz, stereo, fltp, 2 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)

When I attempted to play back the RTMP stream using:

ffmpeg -i rtmp://127.0.0.1/app/hello123
 Duration: N/A, start: 0.013000, bitrate: N/A
  Stream #0:0: Video: h264 (High), yuv420p(progressive), 3840x2160 [SAR 1:1 DAR 16:9], 62.50 fps, 60 tbr, 1k tbn
  Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp

or through the HTTP MP4 URL:

http://127.0.0.1:8080/fmp4/app/hello123.mp4

I observed that the output video's frame rate was altered to 62.5 FPS.

For reference, here are some observations:

  • Original 60 FPS was changed to 62.5 FPS.
  • Original 29.97 FPS was altered to 30.30 FPS.
  • Original 30 FPS was also altered to 30.30 FPS.

Moreover, I've also noticed that both the FPS (frames per second) and TBR (target bitrate) values are modified in the output video.

I've attached both the

Expected Behaviour:
The Monibuca streaming server should retain the original frame rate and TBR values of the input video without modifying them.

Actual Behaviour:
The server changes the frame rate and TBR values during streaming.

Steps to Reproduce:

  1. Stream the file frame_counter_4k_60fps.flv using the provided FFmpeg command.
  2. Playback the RTMP stream using FFmpeg with the provided command.
  3. Observe the altered frame rate and TBR values.

I'd appreciate any guidance or resolution on this matter.

go get 失败

C:\Users\Administrator>go get github.com/Monibuca/monica
unrecognized import path "golang.org/x/sys/windows": https fetch: Get "https://g
olang.org/x/sys/windows?go-get=1": dial tcp 216.239.37.1:443: connectex: A conne
ction attempt failed because the connected party did not properly respond after
a period of time, or established connection failed because connected host has fa
iled to respond.

建议核心引擎添加 RTP forward功能

建议参考janus的 RTP forward功能,如果Monibuca能接收 其他网关的RTP forward 和输出 RTP forward,就可以轻松实现:

  1. rtmp/rtsp... -> Monibuca rtp -> janus(media soup ...) webrtc
  2. Monibuca rtp -> 人工智能分析(人脸识别,车辆识别) -> 结构化数据
  3. Monibuca rtp -> ffmpge/gstream -> Monibuca rtp (Monibuca遵循轻量不做编解码,由外部做)
  4. Monibuca rtp -> Monibuca rtp 实现Monibuca之间的级联
  5. Monibuca rtp <-> sip(freeswitch)
    参考资料:janus 在 fosdem 2020 的演讲ppt
    https://fosdem.org/2020/schedule/event/janus/attachments/audio/3993/export/events/attachments/janus/audio/3993/fosdem2020_janus_rtp_forwarders.pdf
    作者提到janus的下一步开发计划"Maybe implement RTP forwarding as a core feature instead?"

V4 重新拉流异常

rtsp:
pull:
repull: -1

配置不限次数重新拉流
6ff5db780f738d80015c4eec948cc45
但是 流无法播放。

这个时候再手动同参数进行拉流 倒是可以。

rtmp推流异常

rtmp配置kickexist: true后,两个obs用相同的地址进行推流,m7s异常退出了,生成fatal.log:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x18 pc=0xfde0a9]

goroutine 105 [running]:
m7s.live/engine/v4.(*Stream).action(0xc00039f790, 0x2)
……/m7s/workspace/engine/stream.go:226 +0x3e9
m7s.live/engine/v4.(*Stream).run(0xc00039f790)
……/m7s/workspace/engine/stream.go:394 +0x1a5e
created by m7s.live/engine/v4.findOrCreateStream
……/m7s/workspace/engine/stream.go:206 +0x55f

优化代码风格

多利用空行,分割代码段, 增强代码可读性.
现在看到的func基本都是一个空行都没.

engine go build error:invalid character U+007E '~'

[root@localhost engine]# go build

m7s.live/engine/v4/util

util/big_endian.go:4:2: invalid character U+007E '~'
util/big_endian.go:4:7: syntax error: unexpected |, expecting semicolon or newline or }
util/big_endian.go:7:6: missing function body
util/big_endian.go:7:11: syntax error: unexpected [, expecting (
util/big_endian.go:14:6: missing function body
util/big_endian.go:14:12: syntax error: unexpected [, expecting (
util/big_endian.go:22:6: missing function body
util/big_endian.go:22:11: syntax error: unexpected [, expecting (

API可否增加一个状态通知接口

配置文件当中配置一个全局API接口地址,当系统中的流任务有新增,断开,出错,开始录制,结束录制等等状态时候,都给API接口发一个回调通知。
目前我发现只能通过API去循环检测各种list内容,效率比较低,而且控制台对各种状态都有输出,不知道是否能考虑增加一下。

RTMP播放4k视频卡顿

测试环境

  • 系统: ubuntu 20.04
  • 内存:16G
  • CPU: 4.01 GHz 四核Intel Core i7
  • 网络: 127.0.0.1本地循环网络
  • 测试版本: engine/v2 v2.3.0 plugin-rtmp v1.2.5 默认配置

问题描述

推送一路rtmp,然后ffplay 播放rtmp,画面很卡顿。
测试视频HD.Club-4K-Chimei-inn-20mbps.mp4
下载: http://pan.baidu.com/s/1ntG1d0H 密码: r7ag

#Monibuca/plugin-rtmp#9

空指针引发panic问题

track/reader-av.go中,item空指针引发panic问题

func (r *AVRingReader) TryRead() (item *common.AVFrame) { 
	if item = &r.Value; item.CanRead {
		return
	}
	return nil
}

UDP8000端口占用问题

您好,我在本机测试,想启动程序,但我有其它程序已经占用了udp的8000和8001端口,配置文件里也没有看到咱们的程序要占用8000和8001,但明显停掉其它占用端口的程序咱们的软件就可以启动,否则不行,默认使用了这两个端口,不知道要改哪儿,以便启动.谢谢

nalu类型不对,buff不够大错误

2022/03/14 18:23:32 123,nalType not support yet:31,[0]=0xFF
2022/03/14 18:23:35 RTP SequenceNumber error 58411 59178
2022/03/14 18:23:35 RTP SequenceNumber error 59178 59241
2022/03/14 18:23:35 123,nalType not support yet:16,[0]=0x70
2022/03/14 18:23:39 RTP SequenceNumber error 59772 60550
2022/03/14 18:23:44 RTP Unmarshal error buffer too small
2022/03/14 18:23:44 RTP SequenceNumber error 61140 61937
2022/03/14 18:23:44 123,nalType not support yet:16,[0]=0x50
2022/03/14 18:23:46 RTP SequenceNumber error 62036 62723
2022/03/14 18:23:48 RTP SequenceNumber error 62877 63592
2022/03/14 18:23:51 RTP SequenceNumber error 63756 64482
2022/03/14 18:23:54 STAP-A declared size(24524) is larger then buffer(565)
2022/03/14 18:23:54 RTP SequenceNumber error 64664 65434
2022/03/14 18:23:57 RTP SequenceNumber error 141 961
2022/03/14 18:24:01 RTP SequenceNumber error 1500 2233
2022/03/14 18:24:03 123 subscriber 172.20.20.137:54997 removed remains:4
2022/03/14 18:24:04 MTAP16 declared size(14990) is larger then buffer(589)
2022/03/14 18:24:04 RTP SequenceNumber error 2515 3117
2022/03/14 18:24:08 RTP SequenceNumber error 3326 4078
2022/03/14 18:24:08 RTP SequenceNumber error 4103 4790
2022/03/14 18:24:09 123 subscriber 172.20.20.137:55005 removed remains:3
2022/03/14 18:24:10 RTP SequenceNumber error 4864 5553
2022/03/14 18:24:14 123,nalType not support yet:4,[0]=0xC4
2022/03/14 18:24:14 123,nalType not support yet:19,[0]=0xB3

megts 包的顺序可能是乱的,目前的解析存在问题 MpegTsStream.Feed

diff --git a/codec/mpegts/mpegts.go b/codec/mpegts/mpegts.go
index 2b1b4e4..9f0298a 100644
--- a/codec/mpegts/mpegts.go
+++ b/codec/mpegts/mpegts.go
@@ -71,15 +71,15 @@ const (
 	STREAM_TYPE_PRIVATE_DATA     = 0x06
 	STREAM_TYPE_MHEG             = 0x07
 
-	STREAM_TYPE_H264  = 0x1B
-	STREAM_TYPE_H265  = 0x24
-	STREAM_TYPE_AAC   = 0x0F
-	STREAM_TYPE_G711A = 0x90
-	STREAM_TYPE_G711U = 0x91
+	STREAM_TYPE_H264   = 0x1B
+	STREAM_TYPE_H265   = 0x24
+	STREAM_TYPE_AAC    = 0x0F
+	STREAM_TYPE_G711A  = 0x90
+	STREAM_TYPE_G711U  = 0x91
 	STREAM_TYPE_G722_1 = 0x92
 	STREAM_TYPE_G723_1 = 0x93
-	STREAM_TYPE_G726  = 0x94
-	STREAM_TYPE_G729  = 0x99
+	STREAM_TYPE_G726   = 0x94
+	STREAM_TYPE_G729   = 0x99
 
 	STREAM_TYPE_ADPCM = 0x11
 	STREAM_TYPE_PCM   = 0x0A
@@ -543,50 +543,74 @@ func (s *MpegTsStream) ReadPMT(packet *MpegTsPacket, pr io.Reader) (err error) {
 	}
 	return
 }
+
+type streamStatus struct {
+	firstTsPkt *MpegTsPacket
+	frame      int64
+	tsPktArr   []MpegTsPacket
+}
+
 func (s *MpegTsStream) Feed(ts io.Reader, onStream func(MpegTsPmtStream), onPES func(MpegTsPESPacket)) error {
-	var frame int64
-	var tsPktArr []MpegTsPacket
+
+	streamsStatus := make(map[uint16]*streamStatus)
 	for {
 		packet, err := ReadTsPacket(ts)
 		if err == io.EOF {
 			// 文件结尾 把最后面的数据发出去
-			pesPkt, err := TsToPES(tsPktArr)
-			if err != nil {
-				return err
+			for _, ss := range streamsStatus {
+
+				if len(ss.tsPktArr) > 0 {
+					pesPkt, err := TsToPES(ss.tsPktArr)
+					if err != nil {
+						return err
+					}
+					onPES(pesPkt)
+				}
 			}
-			onPES(pesPkt)
 			return nil
 		}
 		if err != nil {
 			return err
 		}
 		pr := bytes.NewReader(packet.Payload)
-		err = s.ReadPAT(&packet, pr)
-		if err != nil {
-			return err
+
+		if PID_PAT == packet.Header.Pid {
+			err = s.ReadPAT(&packet, pr)
+			if err != nil {
+				return err
+			}
 		}
 		err = s.ReadPMT(&packet, pr)
 		if err != nil {
 			return err
 		}
+
 		// 在读取PMT中已经将所有的音视频PES的索引信息全部保存了起来
 		// 接着读取所有TS包里面的PID,找出PID==elementaryPID的TS包,就是音视频数据
 		for _, v := range s.pmt.Stream {
 			if v.ElementaryPID == packet.Header.Pid {
+				ss := streamsStatus[v.ElementaryPID]
+				if ss == nil {
+					ss = &streamStatus{}
+					streamsStatus[v.ElementaryPID] = ss
+				}
 				if packet.Header.PayloadUnitStartIndicator == 1 {
-					if frame != 0 {
-						pesPkt, err := TsToPES(tsPktArr)
+					if ss.frame != 0 {
+						pesPkt, err := TsToPES(ss.tsPktArr)
 						if err != nil {
 							return err
 						}
 						onPES(pesPkt)
-						tsPktArr = nil
+						ss.tsPktArr = nil
+					}
+
+					if ss.firstTsPkt == nil {
+						ss.firstTsPkt = &packet
+						onStream(v)
 					}
-					s.firstTsPkt = &packet
-					onStream(v)
-					frame++
+					ss.frame++
 				}
-				tsPktArr = append(tsPktArr, packet)
+				ss.tsPktArr = append(ss.tsPktArr, packet)
 			}
 		}
 	}

一样的GB28281接入设置,v3可以用,v4报错

17:47:12 INFO install {"plugin": "Debug", "version": "v4.0.0-20220506113031-34f3a736ceb2"}
17:47:12 INFO install {"plugin": "GB28181", "version": "v4.0.0-20220607131724-e110acfb56d3"}
17:47:12 INFO install {"plugin": "HDL", "version": "v4.0.0-20220520061858-640094798008"}
17:47:12 INFO install {"plugin": "HLS", "version": "v4.0.0-20220526032106-b2c401b1cbb5"}
17:47:12 INFO install {"plugin": "Hook", "version": "v4.0.0-20220510140048-d4f76fd1c415"}
17:47:12 INFO install {"plugin": "Jessica", "version": "v4.0.0-20220511035009-ac66c57b299d"}
17:47:12 INFO install {"plugin": "LogRotate", "version": "v4.0.0-20220506113619-1a557d4707a5"}
17:47:12 INFO install {"plugin": "Preview", "version": "v4.0.0-20220612074126-ea770517a67e"}
17:47:12 INFO install {"plugin": "Record", "version": "v4.0.0-20220612043738-8f9b23601007"}
17:47:12 INFO install {"plugin": "Room", "version": "v4.0.0-20220512035851-f980d4a7f6a0"}
17:47:12 INFO install {"plugin": "RTMP", "version": "v4.0.0-20220526123604-cbe785dedaae"}
17:47:12 INFO install {"plugin": "RTSP", "version": "v4.0.0-20220605130937-f9bc450d0186"}
17:47:12 INFO install {"plugin": "WebRTC", "version": "v4.0.0-20220606135438-05117be5d638"}
17:47:12 INFO install {"plugin": "WebTransport", "version": "v4.0.0-20220606132852-13c8e2349a26"}
17:47:12 INFO install {"plugin": "Snap", "version": "v4.0.0-20220612035905-720756e0d9ce"}
17:47:12 INFO Ⓜ starting m7s v4
17:47:12 INFO http handle added:/api/closestream {"engine": true}
17:47:12 INFO http handle added:/api/getconfig {"engine": true}
17:47:12 INFO http handle added:/api/modifyconfig {"engine": true}
17:47:12 INFO http handle added:/api/plugins {"engine": true}
17:47:12 INFO http handle added:/api/stream {"engine": true}
17:47:12 INFO http handle added:/api/summary {"engine": true}
17:47:12 INFO http handle added:/api/sysinfo {"engine": true}
17:47:12 INFO http handle added:/api/updateconfig {"engine": true}
17:47:12 INFO http handle added:/ {"engine": true}
17:47:12 DEBUG {"config": "global", "config": engine:
publish:
pubaudio: true
pubvideo: true
kickexist: false
publishtimeout: 10
waitclosetimeout: 0
subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
http:
listenaddr: :8080
listenaddrtls: ""
certfile: ""
keyfile: ""
cors: true
username: ""
password: ""
rtpreorder: false
enableavcc: true
enablertp: true
enableflv: true
consoleurl: wss://console.monibuca.com/ws/v1
secret: ""}
17:47:12 INFO 🌐 http listen at :8080
17:47:12 INFO http handle added:/ {"plugin": "Jessica"}
17:47:12 INFO http handle added to engine:/jessica/ {"plugin": "Jessica"}
17:47:12 DEBUG config {"plugin": "Jessica", "config": http:
listenaddr: :8080
listenaddrtls: ""
certfile: ""
keyfile: ""
cors: true
username: ""
password: ""
subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10}
17:47:12 DEBUG config {"plugin": "WebTransport", "config": listenaddr: :4433
certfile: ""
keyfile: ""}
17:47:12 WARN no cert or key file specified, plugin disabled {"plugin": "WebTransport"}
17:47:12 INFO http handle added to engine:/hls/api/list {"plugin": "HLS"}
17:47:12 INFO http handle added to engine:/hls/api/pull {"plugin": "HLS"}
17:47:12 INFO http handle added to engine:/hls/api/save {"plugin": "HLS"}
17:47:12 INFO http handle added to engine:/hls/ {"plugin": "HLS"}
17:47:12 DEBUG config {"plugin": "HLS", "config": publish:
pubaudio: true
pubvideo: true
kickexist: false
publishtimeout: 10
waitclosetimeout: 0
pull:
repull: 0
pullonstart: false
pullonsubscribe: false
pulllist: {}
subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
fragment: 10
window: 2
filter: ""
path: ""}
17:47:12 INFO http handle added to engine:/logrotate/api/download {"plugin": "LogRotate"}
17:47:12 INFO http handle added to engine:/logrotate/api/find {"plugin": "LogRotate"}
17:47:12 INFO http handle added to engine:/logrotate/api/list {"plugin": "LogRotate"}
17:47:12 INFO http handle added to engine:/logrotate/api/open {"plugin": "LogRotate"}
17:47:12 INFO http handle added to engine:/logrotate/api/tail {"plugin": "LogRotate"}
17:47:12 DEBUG config {"plugin": "LogRotate", "config": path: ./logs
size: 0
days: 1
formatter: 2006-01-02T15}
17:47:12 INFO http handle added to engine:/preview/ {"plugin": "Preview"}
17:47:12 DEBUG config {"plugin": "Preview", "config": {}}
17:47:12 INFO http handle added to engine:/rtsp/api/pull {"plugin": "RTSP"}
17:47:12 INFO http handle added to engine:/rtsp/api/push {"plugin": "RTSP"}
17:47:12 INFO http handle added to engine:/rtsp/api/list {"plugin": "RTSP"}
17:47:12 DEBUG config {"plugin": "RTSP", "config": publish:
pubaudio: true
pubvideo: true
kickexist: false
publishtimeout: 10
waitclosetimeout: 0
subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
pull:
repull: 0
pullonstart: false
pullonsubscribe: false
pulllist: {}
push:
repush: 0
pushlist: {}
listenaddr: :554
udpaddr: :8000
rtcpaddr: :8001
readbuffersize: 2048
map: {}}
17:47:12 INFO http handle added to engine:/snap/ {"plugin": "Snap"}
17:47:12 DEBUG config {"plugin": "Snap", "config": subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
ffmpeg: ffmpeg
path: ""
filter: ""}
17:47:12 INFO http handle added to engine:/debug/profile {"plugin": "Debug"}
17:47:12 INFO http handle added to engine:/debug/ {"plugin": "Debug"}
17:47:12 INFO http handle added to engine:/debug/trace {"plugin": "Debug"}
17:47:12 DEBUG config {"plugin": "Debug", "config": {}}
17:47:12 INFO http handle added to engine:/gb28181/api/bye {"plugin": "GB28181"}
17:47:12 INFO http handle added to engine:/gb28181/api/control {"plugin": "GB28181"}
17:47:12 INFO http handle added to engine:/gb28181/api/invite {"plugin": "GB28181"}
17:47:12 INFO http handle added to engine:/gb28181/api/list {"plugin": "GB28181"}
17:47:12 INFO http handle added to engine:/gb28181/api/position {"plugin": "GB28181"}
17:47:12 INFO http handle added to engine:/gb28181/api/records {"plugin": "GB28181"}
17:47:12 DEBUG config {"plugin": "GB28181", "config": autoinvite: true
prefetchrecord: false
sipnetwork: udp
sipip: 127.0.0.1
sipport: 5060
serial: "34020000002000000001"
realm: "3402000000"
username: ""
password: ""
acktimeout: 10
registervalidity: 60
registerinterval: 60
heartbeatinterval: 60
heartbeatretry: 3
mediaip: ""
mediaport: 58200
medianetwork: udp
mediaportmin: 0
mediaportmax: 0
mediaidletimeout: 30
logverbose: false
removebaninterval: 600
udpcachesize: 0
publish:
pubaudio: true
pubvideo: true
kickexist: false
publishtimeout: 10
waitclosetimeout: 0
server:
ignores: {}}
17:47:12 INFO Server gb28181 start at :5060 {"plugin": "GB28181"}
17:47:12 DEBUG config {"plugin": "Hook", "config": keepalive: 0
retrytimes: 3
baseurl: ""
header: {}
urllist: {}
requestlist: {}
extra: {}}
17:47:12 INFO http handle added to engine:/record/api/list {"plugin": "Record"}
17:47:12 INFO http handle added to engine:/record/api/start {"plugin": "Record"}
17:47:12 INFO http handle added to engine:/record/api/stop {"plugin": "Record"}
17:47:12 INFO http handle added to engine:/record/ {"plugin": "Record"}
17:47:12 DEBUG config {"plugin": "Record", "config": subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
flv:
ext: .flv
path: ./flv
autorecord: false
filter: ""
fragment: 0
mp4:
ext: .mp4
path: ./mp4
autorecord: false
filter: ""
fragment: 0
hls:
ext: .m3u8
path: ./hls
autorecord: false
filter: ""
fragment: 0
raw:
ext: .
path: ./raw
autorecord: false
filter: ""
fragment: 0}
17:47:12 INFO Media udp server start. {"plugin": "GB28181", "port": 58200}
17:47:12 INFO http handle added:/api/list {"plugin": "HDL"}
17:47:12 INFO http handle added to engine:/hdl/api/list {"plugin": "HDL"}
17:47:12 INFO http handle added:/api/pull {"plugin": "HDL"}
17:47:12 INFO http handle added to engine:/hdl/api/pull {"plugin": "HDL"}
17:47:12 INFO http handle added:/ {"plugin": "HDL"}
17:47:12 INFO http handle added to engine:/hdl/ {"plugin": "HDL"}
17:47:12 DEBUG config {"plugin": "HDL", "config": http:
listenaddr: :8080
listenaddrtls: ""
certfile: ""
keyfile: ""
cors: true
username: ""
password: ""
publish:
pubaudio: true
pubvideo: true
kickexist: false
publishtimeout: 10
waitclosetimeout: 0
subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
pull:
repull: 0
pullonstart: false
pullonsubscribe: false
pulllist: {}}
17:47:12 INFO http handle added:/ {"plugin": "Room"}
17:47:12 INFO http handle added to engine:/room/ {"plugin": "Room"}
17:47:12 DEBUG config {"plugin": "Room", "config": http:
listenaddr: :8080
listenaddrtls: ""
certfile: ""
keyfile: ""
cors: true
username: ""
password: ""
appname: room
size: 20
private: {}
verify:
url: ""
method: ""
header: {}}
17:47:12 DEBUG config {"plugin": "RTMP", "config": publish:
pubaudio: true
pubvideo: true
kickexist: false
publishtimeout: 10
waitclosetimeout: 0
subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
tcp:
listenaddr: :1935
listennum: 0
pull:
repull: 0
pullonstart: false
pullonsubscribe: false
pulllist: {}
push:
repush: 0
pushlist: {}
chunksize: 4096
keepalive: false}
17:47:12 INFO server rtmp start at {"plugin": "RTMP", "listen addr": ":1935"}
17:47:12 INFO http handle added to engine:/webrtc/play/ {"plugin": "WebRTC"}
17:47:12 INFO http handle added to engine:/webrtc/push/ {"plugin": "WebRTC"}
17:47:12 DEBUG config {"plugin": "WebRTC", "config": publish:
pubaudio: true
pubvideo: true
kickexist: false
publishtimeout: 10
waitclosetimeout: 0
subscribe:
subaudio: true
subvideo: true
iframeonly: false
waittimeout: 10
iceservers: []
publicip: []
portmin: 0
portmax: 0
pli: 2s}
17:47:34 DEBUG 34020000001110000030 {"plugin": "GB28181"}
17:47:34 DEBUG StoreDevice {"plugin": "GB28181", "id": "34020000001110000030"}
17:47:34 DEBUG SIP->Catalog:MESSAGE sip:34020000001110000030@3402000000 SIP/2.0
From: sip:[email protected]:5060;tag=141518326
To: sip:34020000001110000030@3402000000
Call-ID: 1415183261
User-Agent: Monibuca
CSeq: 1 MESSAGE
Contact: sip:[email protected]:5060;tag=141518326
Content-Type: Application/MANSCDP+xml
Expires: 3600
Content-Length: 118

Catalog
1
34020000001110000030

{"plugin": "GB28181"}
17:47:34 DEBUG SIP->Catalog:MESSAGE sip:34020000001110000030@3402000000 SIP/2.0
From: sip:[email protected]:5060;tag=259111161
To: sip:34020000001110000030@3402000000
Call-ID: 2591111611
User-Agent: Monibuca
CSeq: 2 MESSAGE
Contact: sip:[email protected]:5060;tag=259111161
Content-Type: Application/MANSCDP+xml
Expires: 3600
Content-Length: 118
17:47:34 DEBUG ⌛->🟢 {"stream": "34020000001110000030/34020000001320000001", "action": "publish"}
17:47:34 INFO subscribe {"plugin": "HLS", "path": "34020000001110000030/34020000001320000001"}
17:47:34 DEBUG Stream Found {"stream": "34020000001110000030/34020000001320000001"}
17:47:34 INFO suber +1 {"stream": "34020000001110000030/34020000001320000001", "id": "", "type": "HLSWriter", "remains": 1}
17:47:34 DEBUG wrong action {"stream": "34020000001110000030/34020000001320000001", "action": "first enter"}
17:47:39 DEBUG 🟢 ->⌛ {"stream": "34020000001110000030/34020000001320000001", "action": "publish lost"}
17:47:49 DEBUG timeout {"stream": "34020000001110000030/34020000001320000001", "state": "⌛"}
17:47:49 DEBUG ⌛->🔴 {"stream": "34020000001110000030/34020000001320000001", "action": "timeout"}

macos无法多次启停无法推流

使用系统:macos 10.15
步骤描述:

  1. 启动go run main.go,设备拉流,播放正常
  2. 使用sh shutdown.sh 关闭,调整参数再次启动
  3. 启动正常,无法正常接收流,这是抓的包,发现正常认证,无法推流

image

4.再次杀死sh shutdown.sh ,发现gb插件端口被占用,使用命令发现5060无进程占用

image

image

如果整台电脑重启,可恢复

新版本鉴权接口的疑问

参照官方文档,我的全局鉴权插件代码如下:
`package auth
import (
"errors"
. "m7s.live/engine/v4"
"m7s.live/engine/v4/util"
)

type AuthConfig struct {
Publish bool
Salt string
}

type AuthPublisher struct {
Publisher
Auth *AuthConfig
}

var plugin = InstallPlugin(&AuthConfig{
Publish: true,
Salt: "1EC96355",
})

func init() {
plugin.Warn("Publisher Auth init")
OnAuthPub = func(p *util.Promise[IPublisher]) error {
var puber = p.Value
switch v := puber.(type) {
case *AuthPublisher:
// do auth
if v.Auth.Publish {
args := v.Args
sign := args.Get("sign")
auth := v.Auth.verifyAuth(v.Stream.Path, sign)
if !auth {
return errors.New("error! Unauthorized")
}
}
return nil
}
return nil
}
}

func (a *AuthConfig) OnEvent(event any) {
switch event.(type) {
case FirstConfig:
plugin.Info("Auth start with", zap.String("Salt", a.Salt))
}
}
func (a *AuthConfig) verifyAuth(path string, sign string) bool {
return true
}`

但我发现代码运行不到// do auth部分,OnAuthPub返回的应该是nil,推流依然失败,请问大神,代码问题在哪?

小白请教:普通的视频服务网站需要这样的架构吗?

大神您好,看了您发的很多资料,近段时间一直有个疑问,不需要直播的网站,只是播放一下视频,服务端也需要设计成这样么?需要推流吗?因为在html里插入的mp4文件,浏览器也能播放,是否因为考虑性能才需要这样的服务?
感谢您百忙之中解惑。您这个项目真是非常贴心。

运行一段时间后,空指针导致panic退出

版本:v4.12.0
util/list.go文件中,在Push方法中调用p.Pre.InsertAfter(item),p.Pre为空指针,导致在调用InsertAfter方法时,代码行:insert.list = item.list,item空指针导致程序异常退出。

func (p *List[T]) Push(item *ListItem[T]) {
	if item.list != nil {
		panic("item already in list")
	}
	if p.Length == 0 {
		p.Next = &p.ListItem
		p.Pre = &p.ListItem
		p.ListItem.list = p
	}
	p.Pre.InsertAfter(item)
}

func (item *ListItem[T]) InsertAfter(insert *ListItem[T]) {
	if insert.list != nil {
		panic("item already in list")
	}
	insert.list = item.list
	insert.Next = item.Next
	insert.Pre = item
	item.Next.Pre = insert
	item.Next = insert
	item.list.Length++
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.