{"id":13613018,"url":"https://github.com/Monibuca/engine","last_synced_at":"2025-04-13T15:32:23.176Z","repository":{"id":37707179,"uuid":"243505214","full_name":"Monibuca/engine","owner":"Monibuca","description":"Monibuca 核心引擎，包含流媒体核心转发逻辑，需要配合功能插件一起组合运行","archived":false,"fork":false,"pushed_at":"2024-12-13T09:08:53.000Z","size":1753,"stargazers_count":966,"open_issues_count":16,"forks_count":205,"subscribers_count":35,"default_branch":"v4","last_synced_at":"2025-04-11T02:51:43.151Z","etag":null,"topics":["streaming","toml"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Monibuca.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-02-27T11:40:11.000Z","updated_at":"2025-04-09T06:50:45.000Z","dependencies_parsed_at":"2023-02-19T03:15:43.341Z","dependency_job_id":"4fe50b80-f8ee-44a8-9221-fba8062c4bdf","html_url":"https://github.com/Monibuca/engine","commit_stats":{"total_commits":499,"total_committers":18,"mean_commits":27.72222222222222,"dds":"0.11222444889779559","last_synced_commit":"0c7bd2717620ff9bb4683ba8fc55e9142a6c6398"},"previous_names":[],"tags_count":278,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Monibuca%2Fengine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Monibuca%2Fengine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Monibuca%2Fengine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Monibuca%2Fengine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Monibuca","download_url":"https://codeload.github.com/Monibuca/engine/tar.gz/refs/heads/v4","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248735873,"owners_count":21153490,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["streaming","toml"],"created_at":"2024-08-01T20:00:38.007Z","updated_at":"2025-04-13T15:32:23.155Z","avatar_url":"https://github.com/Monibuca.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# m7s v4核心引擎\n\n该项目为m7s的引擎部分，该部分逻辑是流媒体服务器的核心转发逻辑。包含了一个插件的引入机制，其他功能均由插件实现\n\n# 引擎的基本功能\n- 提供插件机制，对插件的启动，配置解析，事件派发等进行统一管理\n- 提供H264、H265、AAC、G711格式的转发\n- 提供可复用的AVCC格式、RTP格式、AnnexB格式、ADTS格式等预封装机制\n- 提供多Track机制，支持大小流，加密流扩展\n- 提供DataTrack机制，可用于实现房间文字聊天等功能\n- 提供时间戳同步机制，限速机制\n- 提供RTP包乱序重排机制\n- 提供订阅者追帧跳帧机制\n- 提供发布订阅对外推拉的基础架构\n- 提供鉴权机制的底层架构支持\n- 提供内存复用机制\n- 提供发布者断线重连机制\n- 提供按需拉流机制\n- 提供HTTP服务端口公用机制\n- 提供HTTP API接口自动注册机制\n- 提供HTTP接口中间件机制\n- 提供结构化日志\n- 提供流信息统计和输出\n- 提供事件总线机制，可以对所有插件广播事件\n- 提供配置热更新机制\n## 引擎自带HTTP接口\n- 获取某一个流的详情 `/api/stream?streamPath=xxx`\n- 终止某一个流 `/api/closestream?streamPath=xxx`\n- 获取engine信息 `/api/sysInfo` 返回值{Version:xxx,StartTime:xxx,IP:[xxx.xxx.xxx.xxx]}\n- 获取系统基本情况 `/api/summary` 返回值Summary数据\n- 获取所有插件信息 `/api/plugins` 返回值Plugin数据\n- 读取mp4文件再次发布为视频流 `/api/replay/mp4?streamPath=xxx\u0026dump=filepath`  filepath是文件路径\n- 读取ts文件再次发布为视频流 `/api/replay/ts?streamPath=xxx\u0026dump=filepath`  filepath是文件路径\n- 获取指定的配置信息 `/api/getconfig?name=xxx` 返回xxx插件的配置信息，如果不带参数或参数为空则返回全局配置\n- 修改并保存配置信息 `/api/modifyconfig?name=xxx\u0026yaml=1` 修改xxx插件的配置信息,在请求的body中传入修改后的配置yaml字符串\n- 热更新配置信息 `/api/updateconfig?name=xxx` 热更新xxx插件的配置信息，如果不带参数或参数为空则热更新全局配置\n- 获取所有远端拉流信息 `/api/list/pull` 返回{RemoteURL:\"\",StreamPath:\"\",Type:\"\",StartTime:\"\"}\n- 获取所有向远端推流信息 `/api/list/push` 返回{RemoteURL:\"\",StreamPath:\"\",Type:\"\",StartTime:\"\"}\n- 停止推流 `/api/stop/push?url=xxx` 停止向xxx推流 ，成功返回ok\n- 停止某个订阅者 `/api/stop/subscribe?streamPath=xxx\u0026id=xxx` 停止xxx流的xxx订阅者 ，成功返回ok\n# 引擎默认配置\n```yaml\nglobal:\n  disableall: false # 是否禁用所有插件\n  loglang: zh # 日志语言，可选值：zh,en\n  loglevel: info # 日志级别，可选值：debug,info,warn,error,panic,fatal\n  http:\n    listenaddr: :8080 # 网关地址，用于访问API\n    listenaddrtls: :8443  # 用于HTTPS方式访问API的端口配置\n    certfile: \"\"\n    keyfile: \"\"\n    cors: true  # 是否自动添加cors头\n    username: \"\"  # 用户名和密码，用于API访问时的基本身份认证\n    password: \"\"\n    readtimeout: 0 # 读取超时时间，0为不限制\n    writetimeout: 0 # 写入超时时间，0为不限制\n    idletimeout: 0 # 空闲超时时间，0为不限制\n  publish:\n      pubaudio: true # 是否发布音频流\n      pubvideo: true # 是否发布视频流\n      kickexist: false # 剔出已经存在的发布者，用于顶替原有发布者\n      publishtimeout: 10s # 发布流默认过期时间，超过该时间发布者没有恢复流将被删除\n      delayclosetimeout: 0 # 自动关闭触发后延迟的时间(期间内如果有新的订阅则取消触发关闭)，0为关闭该功能，保持连接。\n      waitclosetimeout: 0 # 发布者断开后等待时间，超过该时间发布者没有恢复流将被删除，0为关闭该功能，由订阅者决定是否删除\n      buffertime: 0 # 缓存时间，用于时光回溯，0为关闭缓存\n      idletimeout: 0 # 空闲超时时间，0为不限制\n      speedlimit: 500ms # 限速超时时间 0为不限速，对于读取文件这类流需要限速，否则读取过快（如果流的时间戳不正确，则只能关闭该功能：设置为0）\n      key:                      # 发布鉴权key\n\t    secretargname: secret     # 发布鉴权参数名\n\t    expireargname:   expire   # 发布鉴权失效时间参数名\n  subscribe:\n      subaudio: true # 是否订阅音频流\n      subvideo: true # 是否订阅视频流\n      subaudioargname: ats # 订阅音频轨道参数名\n      subvideoargname: vts # 订阅视频轨道参数名\n      subdataargname: dts # 订阅数据轨道参数名\n      subaudiotracks: [] # 订阅音频轨道名称列表\n      subvideotracks: [] # 订阅视频轨道名称列表\n      submode: 0 # 订阅模式，0为跳帧追赶模式，1为不追赶（多用于录制），2为时光回溯模式\n      syncmode: 0 # 音视频同步模式，0按照时间戳同步，1按照写入时间同步（在时间戳不正确的时候)\n      iframeonly: false # 只订阅关键帧\n      waittimeout: 10s # 等待发布者的超时时间，用于订阅尚未发布的流\n      writebuffersize: 0 # 订阅者写缓存大小，用于减少io次数，但可能影响实时性\n      key:                      # 订阅鉴权key\n\t    secretargname: secret     # 订阅鉴权参数名\n\t    expireargname:   expire   # 订阅鉴权失效时间参数名\n      internal: false # 是否内部订阅，内部订阅不会触发发布者自动断开功能\n  enableavcc : true  # 启用AVCC格式缓存，用于rtmp协议\n  enablertp : true # 启用rtp格式缓存，用于rtsp、websocket、gb28181协议\n  enableauth: true # 启用鉴权,详细查看鉴权机制\n  enablesubevent: true # 启用订阅事件，用于订阅者上下线事件,关闭可以提高性能\n  rtpreoderbufferlen: 50 # rtp乱序重排缓存长度\n  eventbussize: 10 # 事件总线缓存大小，事件较多时容易堵阻塞线程，需要增大缓存\n  poolsize: 0 # 内存池大小，0为不使用内存池\n  pulseinterval: 5s # 心跳事件间隔时间\n  console: \n    server : console.monibuca.com:44944 # 连接远程控制台的地址\n    secret: \"\" # 远程控制台的秘钥\n    publicaddr: \"\" # 实例公网地址，提供远程控制台访问的地址，不配置的话使用自动识别的地址\n    publicaddrtls: \"\" # 实例公网地址，提供远程控制台访问的地址，不配置的话使用自动识别的地址（https）\n```\n\n# 配置覆盖机制\n- 如果不存在配置文件，将使用默认配置，该配置值为代码中写死的配置值\n- 如果存在配置文件，则使用配置文件中的值覆盖默认值\n- http、publish、subscribe三个配置遵循优先级顺序\n1. 如果发布流或者订阅流中包含对应的参数，则优先使用\n2. 其次，查找对应插件的配置项中是否包含配置项\n3. 最后，使用全局配置中的配置\n\n# 流的状态图\n```mermaid\nstateDiagram-v2\n    [*] --\u003e ⌛等待发布者 : 创建\n    ⌛等待发布者 --\u003e 🟢正在发布 :发布\n    ⌛等待发布者 --\u003e 🔴已关闭 :关闭\n    ⌛等待发布者 --\u003e 🔴已关闭  :超时\n    ⌛等待发布者 --\u003e 🔴已关闭  :最后订阅者离开\n    🟢正在发布 --\u003e ⌛等待发布者: 发布者断开\n    🟢正在发布 --\u003e 🟡等待关闭: 最后订阅者离开\n    🟢正在发布 --\u003e 🔴已关闭  :关闭\n    🟡等待关闭 --\u003e 🟢正在发布 :第一个订阅者进入\n    🟡等待关闭 --\u003e 🔴已关闭  :关闭\n    🟡等待关闭 --\u003e 🔴已关闭  :超时\n    🟡等待关闭 --\u003e 🔴已关闭  :发布者断开\n```\n\n# 鉴权机制\n## 默认鉴权\n\n在publish 和 subscribe 中配置 key 引擎会自动进行鉴权,\n推流或者拉流时需要在url中添加参数 secret=xxx\u0026expire=xxx。\n\n- secret为鉴权前面，MD5(key+StreamPath+expire)\n- expire为鉴权失效时间，格式是十六进制 UNIX 时间戳\n\n### 时间戳计算\n```\n设置时间：2018.12.01 08:30:00\n十进制 UNIX 时间戳：1543624200\n十六进制 UNIX 时间戳：5C01D608（云直播鉴权配置使用十六进制 UNIX 时间戳，十六进制不区分字母大小写）\n```\n### 鉴权签名计算\n```\nsecret = MD5(key+StreamPath+expire) \nsecret = MD5(ngoeiq03+test/01+5C01D608)\nsecret = MD5(ngoeiq03test/015C01D608)\nsecret = ce797dc6238156d548ef945e6ad1ea20\n```\n\n## 单独鉴权\n\n如果需要自定义鉴权，可以在插件中实现鉴权接口，\n引擎中定义如下两个接口，插件中的发布者或者订阅者可以实现这两个接口，引擎会在发布或者订阅时调用这两个接口进行鉴权\n```go\ntype AuthSub interface {\n\tOnAuth(*util.Promise[ISubscriber]) error\n}\n\ntype AuthPub interface {\n\tOnAuth(*util.Promise[IPublisher]) error\n}\n```\n- OnAuth返回错误即鉴权失败\n- Promise方便异步鉴权，可以后续调用其Resolve或Reject方法进行鉴权结果的返回\n\n## 全局鉴权\n\n自定义鉴权也可以全局生效，\n引擎中定义如下两个全局函数的变量，插件中可以对这两个变量进行赋值，引擎会在发布或者订阅时调用这两个接口进行鉴权\n```go\nvar OnAuthSub func(p *util.Promise[ISubscriber]) error\nvar OnAuthPub func(p *util.Promise[IPublisher]) error\n```\n** 注意：如果单独鉴权和全局鉴权同时存在，优先使用单独鉴权 **\n** 全局鉴权函数可以被多次覆盖，所以需要自己实现鉴权逻辑的合并 **\n\n# Http中间件\n在HTTPConfig接口中增加了AddMiddleware方法，可以通过该方法添加中间件，中间件的定义如下\n```go\ntype Middleware func(string, http.Handler) http.Handler\ntype HTTPConfig interface {\n\tGetHTTPConfig() *HTTP\n\tListen(ctx context.Context) error\n\tHandle(string, http.Handler)\n\tAddMiddleware(Middleware)\n}\n\n```\n中间件的添加必须在FirstConfig之前，也就是在Listen之前\n例如：\n```go\ntype MyMiddlewareConfig struct {\n  \tconfig.HTTP\n}\nvar myMiddlewareConfig = \u0026MyMiddlewareConfig{}\nfunc init(){\n  myMiddlewareConfig.AddMiddleware(func(pattern string, handler http.Handler) http.Handler {\n    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n      // do something\n      handler.ServeHTTP(w, r)\n    })\n  })\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMonibuca%2Fengine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMonibuca%2Fengine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMonibuca%2Fengine/lists"}