Compare commits

..

319 Commits

Author SHA1 Message Date
langhuihui
1399beef60 - Engine aspect
1. Add a flow state
2. Add regular expressions to remote push pull
3. Add InviteTrack event
4. Fix several bugs

- In terms of plugins

1. GB 28181 Video Streaming Automatic Shutdown for Unmanned Viewing
2. HLS fixes playback issues and upgrades Gohlslib library
3. Record repairs HLS recording, fixes API method for passing fragment parameters
4. RTMP fixes issues caused by TCP connection failure
5. Upgrade gortsplib to v4 using rtsp
6. Webrtc fixes bug in subscription multiplexing
7. Webrtransport does not configure certificates to automatically use built-in certificates

- 引擎方面

1. 增加一个流状态
2. 远端推拉增加正则表达式
3. 增加 InviteTrack 事件
4. 修复若干 bug

- 插件方面

1. gb28181 录像流无人观看自动关闭
2. hls 修复播放问题,升级 gohlslib 库
3. record 修复 hls 录制,修复 api 方式传递 fragment 参数
4. rtmp 修复因tcp 连接失败导致的问题
5. rtsp 升级 gortsplib到 v4
6. webrtc 修复订阅多路的 bug
7. webrtransport 不配置证书自动使用内置证书
2023-10-23 14:50:13 +08:00
langhuihui
84f9a02e0a fix: hls pull ts no content-length 2023-10-23 10:09:15 +08:00
langhuihui
7f97d26a2b fix: hls record and play 2023-10-18 14:06:35 +08:00
langhuihui
17dab13edf feat: pull and push support regexp
feat: add pagation support
 fix: stop subscribe when error
2023-09-28 15:42:50 +08:00
langhuihui
1218158b3e fix: panic and hls record 2023-09-25 15:12:39 +08:00
langhuihui
42b8c6256f chore: update aurora and mp4ff lib 2023-09-20 19:29:03 +08:00
langhuihui
13654367d7 fix: pull will sleep at first 2023-09-18 17:17:16 +08:00
langhuihui
bae642096c fix: rtsp plugin memory leak 2023-09-15 16:19:15 +08:00
langhuihui
51c4cd6291 fix: stream close process 2023-09-14 10:13:50 +08:00
langhuihui
8707d953fe 1. Retrying after remote streaming interruption increases waiting time and fixes retry failure issues
2. Fix concurrent request summary interface timeout
3. Parameters can be passed in during HLS subscription
4. Fix memory leaks in the monitor plugin
5. Fix panic caused by incorrect stream address during Disconnect

- 1、远端拉流中断后重试增加等待时间,修复重试失效问题
- 2、修复并发请求summary接口超时
- 3、hls订阅时可传入参数
- 4、修复monitor插件内存泄露
- 5、修复错误的流地址导致的Disconnect时panic
2023-09-10 12:19:48 +08:00
dexter
95888790f0 Merge pull request #95 from dwdcth/patch-2
Update go.yml
2023-09-07 14:41:33 +08:00
langhuihui
dfd9af1efd fix: ps解析异常 tcp 逻辑,avoid repull too fast 2023-09-07 13:11:49 +08:00
banshan
475242ff6a Update go.yml 2023-09-06 21:09:31 +08:00
langhuihui
9933950f61 feat: gb的 channel增加输出字段,fix summary timeout 2023-09-06 14:18:27 +08:00
langhuihui
055eb6c022 feat: hls add args to subscriber 2023-08-31 13:41:44 +08:00
langhuihui
7d5b0fbb32 fix: rtsp 修复错误的流地址导致的Disconnect时panic 2023-08-31 09:05:13 +08:00
langhuihui
15da702fec fix: memory leak 2023-08-29 09:43:48 +08:00
langhuihui
e8dbdb4aef fix: engine Run func
- fix receive panic
- fix ps decode memory leak
- gortsplib upgrade to v3.10.0
2023-08-25 15:05:52 +08:00
langhuihui
5a7aec092c fix: plugin-hls version must be 4.3.3 2023-08-15 08:55:26 +08:00
langhuihui
4ab1f8e9a1 - API 现在可以返回{"data":xxx,"code":0,"msg":"ok"}
格式
- 按需拉流的事件的类型从`*Stream`修改为`InvitePublish`
- 远程拉流频繁重连后导致多路远程流同时写入同一个`track`
- 在并发序列化`Tracks`时导致错误,通过加锁解决
- 修复`Record`插件录制`fmp4`格式报错
- 更新`WebRTC`插件依赖库版本
- 更新依赖库`quic-go`版本
- 优化`ps`插件中的`tcp`收流逻辑
- 优化`rtmp`插件streamId计算方法
2023-08-14 12:39:57 +08:00
langhuihui
660886fc01 fix: record g711 in mp4 2023-08-07 09:12:47 +08:00
langhuihui
a71166937e - Refactoring the Record plugin to support mp4 format (non fmp4)
- Optimize HLS plugin memory usage
- Change the default remote streaming of RTSP to TCP protocol
- Reason for subscriber closure increase closure
- Reconstruct the summary to reduce invalid collection and prevent concurrent reads and writes
- Add API for mandatory closure of subscribers
- Remote streaming encountered an unreachable address and will no longer retry indefinitely

- 重构Record插件,支持mp4格式(非fmp4)
- 优化HLS插件内存使用
- rtsp远端拉流默认改成tcp协议
- 订阅者关闭增加关闭原因
- 重构summary,减少无效采集,防止并发读写
- 增加强制关闭订阅者的api
- 远端拉流遇到无法连接的地址不再无限重试
2023-08-06 18:07:36 +08:00
langhuihui
dc54771200 update dockerfile 2023-07-14 16:46:32 +08:00
langhuihui
52bd4c54e7 - fix: record flv append not work
- fix: data track reader
- feat: ignore auth for internal subscriber
- chore: optimize webrtc subscribe

desc:
- 修复了flv的append不生效的问题
- data track读取问题
- 忽略内部订阅者的鉴权功能
- webrtc插件优化,配合webrtc视频墙功能
- gb插件默认开启范围端口
2023-07-14 16:01:57 +08:00
langhuihui
e5c9cacd8b fix:
- data track push data panic
- g711 new track attach block
- didn't stop all publisher and subscriber when rtmp closed
- ps-plugin audio not enabled

desc:
- 数据轨道写入时引发panic
- 在事件回调中创建g711会导致阻塞
- rtmp关闭时没有停止所有发布者和订阅者
- ps-plugin音频未启用
2023-07-07 15:45:07 +08:00
langhuihui
39c692a255 - feat: Initiate unit testing and benchmark testing for adding streaming publish subscriptions to the project
- fix: panic generated by concurrent creation of streams for publishing and subscribing
- fix: IdleTimeout invalid issue
- fix: read and write concurrency issues caused by subscriber blocking
- Preview plugin fixes the default port for https
- GB28181 plugin PR merge

- 启动工程增加对流的发布订阅的单元测试和基准测试
- 修复发布和订阅并发创建流产生的panic
- 修复IdleTimeout无效问题
- 修复订阅者阻塞导致读写并发问题
- preview插件修复https默认端口
- gb28181插件PR合并
2023-06-30 11:31:23 +08:00
langhuihui
507caa1414 - preview plugin (Jessibuca Pro) WebRTC protocol supports H265 and AAC formats
- WebRTC plugin adds screen sharing test page
- WebRTC plugin push stream test page adds camera selection function
- The engine adds the function of dynamically inserting SEI frames
- The engine transforms DataTrack and MediaTrack, and reuses part of the code to reduce complexity
- The event bus adds the engine initialization completion event
- The default port for connecting to the remote console is changed to 44944
- Fix the problem caused by publishing the same StreamPath at the same time

- preview插件(Jessibuca Pro)WebRTC协议支持H265以及AAC格式
- WebRTC插件增加屏幕分享测试页面
- WebRTC插件推流测试页面增加摄像头选择功能
- ​engine增加动态插入SEI帧的功能
- engine对DataTrack改造,和MediaTrack复用部分代码,减少复杂度
- 事件总线增加引擎初始化完成事件
- 连接远程控制台默认端口更换为44944
- 修复同时发布同一个StreamPath引起的问题
2023-06-17 22:04:08 +08:00
langhuihui
03070c68f6 chroe: gorelease 2023-06-11 15:20:21 +08:00
langhuihui
ec3cd569d1 feat: gb28181 add ptz api and record pause fastforword etc. 2023-06-11 14:48:27 +08:00
langhuihui
a9c433405b -Start the project and introduce the conf directory, adding several common configuration examples
-Customizable favicon.ico
-Adding Pause and Resume methods to Stream in the engine
-The engine introduces sync.Cond to replace the pseudo Spinlock
-Preview plugin introduction jessibuca pro demo
-Jessica plugin introduces support for HTTP/ws-h264/h265 bare streams
-Recording plugin adds a prompt in the log when the file cannot be created
-PS plugin fixes a bug where a single port cannot be reused after use
-Webtransport starts by default through built-in certificate mode

- 启动工程引入conf目录,添加若干常用配置示例
- 可以自定义favicon.ico
- 引擎中Stream增加Pause和Resume方法
- 引擎引入sync.Cond替代伪自旋锁
- 预览插件引入jessibuca pro demo
- jessica插件引入对http/ws-h264/h265 裸流支持
- 录制插件在无法创建文件时日志中增加提示
- ps插件修复一个单端口使用后无法重复使用的bug
- webtransport通过内置证书方式默认启动
2023-06-11 14:11:28 +08:00
langhuihui
ebc7e9001a 1 新增LL-HLS支持
该协议为苹果公司推出的低延迟HLS协议,本次更新新增了对该协议播放支持。
同rtsp库一样,采用了第三方库来实现:**github.com/bluenviron/gohlslib**

1.1 使用方法

通过访问形如http://localhost:8080/llhls/live/test/index.m3u8来播放。
其中**live/test**为streamPath,可以替换成实际的值

1.2 插件配置

在llhls下可以配置http配置,用于修改端口号。插件配置方式可以参考文档

1.3 源码说明

llhls相关代码位于**github.com/Monibuca/plugin-hls** 的 **llhls.go** 中。hls和llhls两个插件共用一个代码仓库,因此引入hls时也同时引入了llhls插件。

2 新增HLS.js测试页面

HLS.js测试页面是将hls.js的编译后的代码嵌入到了hls插件仓库中,以方便调试hls流使用。

2.1 访问地址

http://localhost:8080/hls/index.html

该页面也可以用于测试llhls

3 新增对RTMPS协议支持

该协议为RTMP协议的衍生协议,是在TCP基础上增加了TLS安全加固,原理类似HTTPS。
该协议支持是rtmp插件的增强。需要通过配置TLS端口来开启该功能。

3.1 配置

```yaml
rtmp:
  tcp:
    listenaddrtls: :4443
```

3.2 推流测试
```
ffmpeg -i source -f flv rtmps://localhost:4443/live/test
```
如果配置成443端口,则可以省略端口号

3.3 对外推拉流

已经支持,既可以在配置pull或者push中使用rtmps的远程地址

4 其他更新内容

4.1 优化了HLS纯转发模式的资源消耗

> 当只需要将HLS拉流转发时,可以使用纯转发模式
> 纯转发模式由于不需要解析HLS协议中的TS格式,因此对资源消耗比较小。
> 通过配置HLS插件的 **relaymode: 1**开启

4.2 修复了当开启时光回溯功能时的内存泄漏

具体原因是,在进行时间戳判断时忽略了当时间戳超过最大值时的情况,导致ringbuffer无限扩大
> 所谓时光回溯功能,是指可以缓存较多的数据,以订阅当前画面更早一些的画面
> 通过配置**publish**配置中的**buffertime**来开启时光回溯
> 订阅流时需要指定订阅模式,即需要在订阅时加参数`?mode=2`
> 如果需要修改参数名称(有时可能会有冲突,可以通过配置submodeargname 来改变

4.3 WebRTC插件测试页面运行URL中带有参数

为了更方便测试WebRTC功能,允许在访问测试页面时,带上参数

4.3.1 推流测试页面

**http://localhost:8080/webrtc/test/publish?streamPath=live/test**
可以推送到**live/test**。不传该参数则推送到**live/webrtc**

测试房间功能是也可以带上token参数

4.3.2 播放测试页面

**http://localhost:8080/webrtc/test/subscribe?streamPath=live/test**
可以订阅**live/test**的流。不传该参数则订阅**live/webrtc**

4.4 Stream中增加NeverTimeout属性

该属性设置成true可以是的流不再判断超时,保持流永远存活,其目的是有些流并不会产生AudioTrack和VideoTrack,比如纯转发流,或者Room的用于广播消息的流,此时可以在发布成功后,对流设置这个属性
2023-06-04 23:00:11 +08:00
langhuihui
dd01ce0bc4 1. Modifying the engine Streams global variable to sync.Map increases stability and performance
2. Add record plugin to record raw audio data function
3. Fix security issues where API reading log files may access files outside of the log directory
4. Fix noise issue during GB streaming sound playback
5. Fix a memory leak
6. The GB28181 plugin combines a PR for API query of video recordings and directly returns data, no longer through Channel data
7. GB28181 plugin list returns no more nulls
8. On demand pull and push trigger logic code optimization
9. Debug plugin adds HTTP configuration

1、引擎Streams全局变量修改为sync.Map增加了稳定性和性能
2、录制插件增加录制裸音频数据功能
3、修复API读取日志文件可能访问到日志目录外的安全问题
4、修复GB流声音播放有噪声问题
5、修复一处内存泄漏
6、GB28181插件合并一个PR用于API查询录像直接返回数据,不再通过Channel数据中返回
7、GB28181插件list返回不再出现null
8、按需拉流和推流触发逻辑代码优化
9、debug插件增加HTTP配置
2023-05-25 20:30:31 +08:00
langhuihui
2a89629149 fix: change tracks to sync.Map to void dead lock
fix: ps plugin dump
fix: record plugin nil pointer
feat: config support yaml tag name

修复: 修改tracks为sync.Map,避免死锁
修复: ps插件dump
修复: record插件空指针
特性: 配置支持yaml tag name
2023-05-21 22:20:33 +08:00
langhuihui
555b168cba 1. Add the global configuration item disableall to disable all plugins (a plugin can be individually enabled by configuring its enable)
2. Upgrade dataTrack to customTrack and freely add custom tracks
3. PS plugin adds a forwarding mode configuration item and the ability to pull PS streams through the ws protocol
4. Fix processing errors when dts exceeds the maximum value

1、增加全局配置项disableall 用于禁用全部插件(可通过配置插件的enable来单独开启某个插件)
2、dataTrack升级为customTrack,可自由添加自定义轨道
3、PS插件增加转发模式配置项,增加通过ws协议拉取ps流的功能
4、修复dts超过最大值后的处理错误
2023-05-17 07:49:28 +08:00
langhuihui
f2e0963add 1. Add a new PS plugin, move PS processing logic into it, and provide APIs to connect to PS streams
2. Added idletimeout configuration, which can be used to automatically disconnect after the first idle release
3. Handling situations where subscribers consume too slowly
4. Optimize RTMP plugin and merge write operations
5. Snap plugin adds support for URL parameters
6. Fix plugin reference errors used when publishing monitor plugins
7. The default certificate configuration for the webtransport plugin is local.monibuca.com

1、新增PS插件,将PS处理逻辑移入该插件,并提供API可接PS流
2、新增idletimeout配置,可用于首次发布空闲后自动断开
3、增加订阅者消费过慢的情况处理
4、优化rtmp插件,合并写入操作
5、snap插件增加对url参数的支持
6、修复monitor插件发布时使用的插件引用错误
7、webtransport插件默认的证书配置采用local.monibuca.com
2023-05-14 17:24:17 +08:00
langhuihui
326b4f5252 update readme 2023-05-05 18:32:34 +08:00
langhuihui
f4b4d9cb57 支持EnhancedRTMP——现可以接受OBS的H265的推流
GB插件对端口配置新增一个port配置项,可用于代替老的端口配置项
GB插件减少一处Bye引起的阻塞
2023-05-04 10:22:50 +08:00
langhuihui
0cea8a3433 1、支持读取mp4文件发布为流的能力
2、Subscribe增加Internal配置,可修改订阅者是否为内部订阅者
3、防止record插件在开始录制时阻塞事件总线
4、snap插件增加http配置,以自定义端口
5、修复一处因并发回收引起的崩溃
6、修复内置鉴权逻辑
2023-04-29 22:17:59 +08:00
langhuihui
146245c50d 1、增加内置鉴权机制(同腾讯云)
2、增加trace级别日志功能
3、修复rtsp转发webrtc部分流无法播放的问题
4、上个版本漏发了hdl插件更新
5、修复上个版本一处打印忘记去除
6、hls插件修改为暂时只接受AAC格式音频
2023-04-24 14:22:20 +08:00
langhuihui
65283c995d 1、新增环境变量覆盖配置功能
2、rtsp插件依赖库(gortsplib)升级到v3.2.1
3、rtsp插件修复对高码率流的推拉卡顿花屏问题
4、hdl插件拉取flv时增加对是否含有有视频的判断
5、修复hls关闭时出现高CPU的问题,以及close后仍然拉流问题
6、修复播放rtmp可能引起崩溃以及复推引起的内存泄露
7、兼容偶尔时间戳不对的情况
2023-04-23 11:29:10 +08:00
langhuihui
84d9e05409 1、修复engine打印流程超时日志序列化错误的问题
2、修复monitor插件订阅时引起的流的事件循环阻塞问题
3、修复webrtc插件iceserver配置未生效的问题
4、rtsp插件删除协议自动切换逻辑,改为第三方库自动切换
5、pull配置新增代理配置,对hdl和hls插件有效
6、hls插件增加转发模式配置,实现纯转发功能
2023-04-15 08:54:35 +08:00
dexter
248eefd1b0 1 修复热更新api导致的崩溃问题
2 兼容ts中streamID不在标准中定义的情况
   3 修复按需拉流中无音频时订阅者等待的问题
   4 gb插件修复收到已连接的设备的注册包的情况
   5 record插件flv头中添加meta信息
2023-04-09 12:54:49 +08:00
dexter
c95dbfb291 1、新增monitor插件,用于将监控数据写入文件中,方便后续分析
远程控制台已增加监控数据查看功能
2、增加日志多语言机制
3、engine中增加日志语言配置,默认使用zh即中文
4、engine中增加心跳时间广播,并增加心跳事件间隔配置,默认为5秒
2023-04-04 20:58:07 +08:00
dexter
e65da00dac 将常见问题加入注释 2023-03-28 20:48:19 +08:00
dexter
5a436e0965 1、修复上一个版本出现的订阅者限速失效的 bug(影响秒开)
2、修复 GB28181 接收 TCP 流缓冲为 0 的错误
3、GB28181 现在默认接收 TCP 流
4、GB28181 增加监听网卡地址的配置
5、GB28181 增加同时多路 dump 的功能
6、修复rtmp、rtsp续推后时间戳计算
7、优化 rtsp 推流如果没有音频,订阅者将不再等待音频,实现秒开
8、控制台输出链接信息,常见问题已放在入口文件的注释中。
2023-03-28 20:06:45 +08:00
dexter
4652af0975 1、通过提高时间戳精度修复rtsp推流时间戳精度丢失导致的播放卡问题
2、修复rtsp推流后,webrtc无法播放问题
3、修复由于rtp包组包逻辑问题导致rtsp拉流播放卡顿问题
4、hls插件增加http配置项,可独立设置端口
2023-03-23 09:43:27 +08:00
dexter
ba0c2fbf8e 修复avcc写入时间戳的bug,webrtc插件支持tcp连接方式 2023-03-14 09:37:54 +08:00
dexter
0c714cc258 GB插件引用的rtp从v2改回v1,engine做相应修改
对room和webrtc做了一些修改,针对room的demo进行优化
对preview插件的流列表增加了类型显示
2023-03-13 13:46:37 +08:00
dexter
d9933f0c65 readme改成英文 2023-03-10 14:04:16 +08:00
dexter
10aebe3085 1、预览插件增加对按需拉流信息的罗列
2、引入v3版的ps解包逻辑
3、修复非rtmp系的首个绝对时间戳初始化
4、修复订阅时如果无音频时首个视频帧没有被订阅的bug
2023-03-09 19:48:39 +08:00
dexter
56918b5dd4 1、WebRTC订阅AAC流时将AAC通过DataChannel传输
2、Rtmp协议接收releaseStream时不再回复client
3、优化RTSP的AAC数据的解析
4、修复RTSP出错写日志时Panic的问题
5、engine启动插件循序遵循插件注册顺序
2023-03-04 08:15:15 +08:00
dexter
b9e74c161d 修复gb无法获取通道的问题 2023-03-01 20:14:07 +08:00
dexter
33875ecb3d 修复hls插件panic的问题,和psPublisher的json序列化问题 2023-03-01 10:00:59 +08:00
dexter
eaa39044d4 将ps流接收后发布逻辑移入engine中,frame中新增adts数据 2023-02-28 20:22:00 +08:00
dexter
b01a498688 更新room插件 2023-02-27 18:15:51 +08:00
dexter
dcfb354f8c 1、优化了rtp包写入引擎时的内存复用机制
2、优化了webrtc插件
3、订阅时接收的VideoFrame和AudioFrame增加了track属性方便读取track中的数据
4、优化了push的重连逻辑以及终止重连的判断
5、获取annexb格式时如果是关键帧则自动带上sps等
2023-02-26 11:36:31 +08:00
dexter
52681147d6 修复flv录制时的时间戳,hls写入去除锁 2023-02-22 13:42:11 +08:00
dexter
3cd643fd31 修复webrtc推流错误
webrtc插件增加推流测试页面
HLS插件音视频分离
GB28181插件invite恢复使用通道ID,以及合入PR等
2023-02-21 21:33:13 +08:00
dexter
e6f73e71aa 修复WriteADTS没有写入时间戳的bug
修复webrtc推流时payloadType错误问题
修复GB28181的invite报文格式,以及ps流处理
2023-02-21 08:27:17 +08:00
dexter
9c278864c2 修复MP4录制,gb解析ps重写,rtmp插件握手兼容性 2023-02-20 00:24:06 +08:00
dexter
0b5c36b1c1 1、修复linux下没有生成fatal.log的问题
2、fatal.log现在采用追加方式写入
3、优化HLS(ts文件)内存复用
4、修复rtmp协议在接收推流时时间戳生成错误导致内存泄露等问题
5、修复datatrack没有被广播的bug(引起房间demo无法接收到信息)
2023-02-15 21:21:53 +08:00
dexter
97f7d6a22d 修复WriteTimeout传入时多乘以了Second
修复订阅RTP时无音频是的panic
WriteAVCC传入指针防止意外
2023-02-08 22:38:37 +08:00
dexter
bf18453401 1、引入ClockRate, 用于RTSP的RTP时间戳处理(MPEG2中的时间戳是固定90KHZ)
2、修复控制流Sleep传入的时间单位错误
3、优化TS格式解析内存复用,减少内存分配
4、修复rtmp接续发布功能
5、修复录像插件写入MP4文件时,视频格式错误的问题
6、更新WebTansport的插件的quic-go依赖,用于适配go1.20
2023-02-08 14:26:37 +08:00
dexter
7dc8966d55 1、当发布者离线时没有订阅者时,流的超时时间从1s改为10ms。
2、Track增加离线状态,当发布者离线时,Track状态改为离线状态,当发布者重新上线时,Track状态改为在线状态。
    3、Track在恢复在线后,记录时间戳的差值,保持后续时间戳和之前的连续。
    4、进一步优化订阅者读取音视频同步逻辑。
2023-02-06 14:22:45 +08:00
dexter
9cb7010507 1、增加SErepublish事件表示再次发布成功事件,使得SEPublish事件表示第一次发布成功。
2、修复push时ReConnectCount没有计数增加。
3、使用github.com/quic-go/quic-go v0.32.0版本。
4、修复订阅模式>1时没有从IDR帧开始的问题。
5、RTMP插件修复推流时MessageStreamID没有设置的问题。
6、RTSP插件升级第三方依赖库aler9/gortsplib 到 v2.1.0,并进行适配。
7、Stream中将保存状态变更历史信息。
2023-02-03 21:38:01 +08:00
dexter
8d5c6d6d11 增加时光回溯功能
订阅模式参数
内存回收机制
增加对时间长度的配置
解决首屏渲染无音频问题
修复rtmp对外推拉没有带入参数
修复dts生成时pts超过最大值导致错误的问题
修复rtmp解析时对扩展时间戳的处理
修复几处判空panic问题
2023-02-02 12:46:42 +08:00
dexter
3ead36ccf7 fix: 修复engine一处负优化,增加一个首屏渲染开关 2023-01-22 22:06:08 +08:00
dexter
a4e1f4950d 1.优化Track数据写入流程,调用更清晰自然
2.对Subscribe增加3个配置项,用于指定订阅指定Track时的参数名
3.修复首次写入AbsTime总是从0开始引起的问题
4.修复订阅时,读取音频数据过迟问题
5.修复对外推拉流(rtmp、rtsp)时,异常退出没有关闭远端连接问题
6.修复record和hls收到发布事件后重复订阅问题
2023-01-18 23:28:26 +08:00
dexter
53cc788857 1.将amf0编码器和解码器放到codec/amf.go中
2.对写入avcc音频进行长度判断
3.录制者设置为内部订阅者
4.修复edge插件远程拉取HDL时,初始化错误
5.增加MallocSlice函数用于减少内存复制
6.录制flv写完后对头部进行修改加入关键帧元数据使得播放flv可以拖动进度条
2023-01-16 09:34:09 +08:00
dexter
6b40297c69 1.拉取远端hls流平滑处理,解决卡顿问题。
2.拉流逻辑增加一处判空
3.设置speedlimit默认值从0改为500
4.snap插件的订阅者设置为内部订阅者防止影响自动关闭
5.gb28181的tcp范围端口不再读取ssrc值判断
2023-01-10 09:25:18 +08:00
dexter
f8e50d00f5 注释一处println 2023-01-03 19:34:40 +08:00
dexter
361b0522e1 1.修复Stream序列化循环引用问题
2.实现对subscribe中SubVideoTracks和SubAudioTracks的支持
3.修复读取ts中aac格式数据多次flush问题
4.修复subscribe结束时判断IsClosed调用对象错误
5.增加DefaultYaml功能解决插件默认配置被全局配置覆盖问题
6.修复rtsp插件订阅时参数未传入问题
7.snap插件和record插件采用DefaultYaml默认配置
2023-01-03 19:24:15 +08:00
dexter
27784f0a03 1.修复delayclosetimeout值被覆盖的bug
2.重构流中订阅者集合,减少订阅者对轨道的无效等待
3.实现内部订阅者功能,使得HLS插件不再影响最后一个订阅者离开逻辑
4.破坏性修改:pull配置中pullonstart类型改为map,pullonsubscribe修改为pullonsub,类型改为map
5.rtmp插件增加对远端流rtmps协议的支持,优化握手过程
6.修复gb28181插件对时间戳的处理bug(引起跳秒等问题)
7.hdl插件对重连机制进行优化,对于服务器返回非200的连接不再重连
2022-12-31 22:22:10 +08:00
dexter
34394b99cf 1.增加http配置中的timeout参数,用于设置http响应的超时时间
2.http配置增加自定义中间件功能
3.hdl插件和jessica插件增加对http超时的处理
2022-12-19 13:53:32 +08:00
dexter
f56a6c972c 1.优化远程Pull和Push逻辑,增加日志输出
2.解决Stream中Json序列化循环引用问题
3.引擎增加对订阅者下线的及时响应
4.GB插件增加对AAC格式的推测
2022-12-19 09:47:24 +08:00
dexter
7138565443 engine升级到4.9.0,升级hls、hook、record、room
1.增加鉴权机制(钩子函数调用)
2.去除IO类型的泛型,增加代码可读性
3.引擎增加订阅者下线事件派发
4.增加配置项:鉴权开关、订阅者上下线事件开关、事件总线缓冲大小
5.修复网页无法播放HLS问题(修复TS格式写入PMT的PID值)
6.hook插件增加对订阅者下线的通知
7.record插件修复flv分片录制时的时间戳错误(现从0开始)
8.引擎现默认打开rtp乱序重排
2022-12-15 09:45:13 +08:00
langhuihui
a521c63036 fix: 最后订阅者离开条件判断,edge插件只能拉一路的bug 2022-12-11 15:39:21 +08:00
langhuihui
ed5e7196f7 fix: http-flv远端拉流h265编码格式解析 2022-12-10 22:05:27 +08:00
dexter
664a64a025 🐛 FIX: rtp缓存适配webrtc,修复录制插件重复录制问题以及崩溃报错 2022-12-06 09:33:32 +08:00
dexter
f097e66069 🐛 FIX: GB解决非同一域的目标地址问题,引擎增加SubscribeExist功能 2022-11-30 13:25:28 +08:00
dexter
2e8d4d2f3a 📦 NEW: 加入fMP4格式直播流播放功能 2022-11-27 22:25:58 +08:00
dexter
8bb63c9298 1.发布流首次超时时间随PublishTimeout配置
2.RTP打包较大AAC音频进行分包处理
3.截图插件默认不订阅音频提高速度
4.GB插件优化PS包解析兼容性
5.RTSP插件升级gortsplib版本
6.RTMP插件修复对外推流时流路径的设置
2022-11-17 23:52:14 +08:00
dexter
c0b2a10601 👌 IMPROVE: hls支持h265以及G711,Gb28181支持AAC 2022-11-13 23:55:11 +08:00
dexter
3179b892d6 🐛 FIX: hls的h265格式以及G711支持 2022-11-13 23:36:00 +08:00
dexter
ef3a85ec21 🐛 FIX: 修复h265的TS封装格式,修复RTP打包内存泄露 2022-11-10 20:08:05 +08:00
dexter
1a57aeb2a2 🐛 FIX: rtmp握手协议,SEI帧处理 2022-10-30 11:20:44 +08:00
dexter
85b134d333 👌 IMPROVE: 增加限速设置,修复gb单端口时音频时间戳单位 2022-10-26 11:08:05 +08:00
dexter
9969966b52 🐛 FIX: gb推测视频编码格式时判断错误 2022-10-24 14:21:25 +08:00
dexter
5482ab4157 👌 IMPROVE: 更先进的rtp包乱序重排算法 2022-10-23 19:29:34 +08:00
dexter
6a78440a61 👌 IMPROVE: 优化room插件 2022-10-19 23:37:35 +08:00
dexter
61eaaab78f 🐛 FIX: gb插件dts防止自动生成 2022-10-17 11:40:03 +08:00
dexter
54f01a064c 🐛 FIX: 控制台修改配置文件的功能 2022-10-14 16:54:40 +08:00
dexter
09570a6515 🐛 FIX: 录制功能 2022-10-13 20:08:35 +08:00
dexter
00ff25e173 🐛 FIX: 兼容go1.19 和m1 2022-10-13 18:49:12 +08:00
dexter
f0735d3883 Create FUNDING.yml 2022-10-11 20:03:48 +08:00
dexter
314191abaf update record plugin 2022-10-11 19:32:57 +08:00
dexter
33b5c465b6 🐛 FIX: 修复aac包比较小的情况下导致访问越界问题 2022-10-10 22:10:37 +08:00
langhuihui
2b1bf24fb9 🐛 修复logrotate插件windows下编译失败的bug 2022-10-08 21:46:17 +08:00
dexter
4653f7b511 👌 IMPROVE: 优化对外推流数据结构,优化engine对SSE的支持 2022-10-07 22:44:55 +08:00
dexter
86b16fe3fb 👌 IMPROVE: 远程控制台连接升级为quic协议 2022-10-06 00:07:57 +08:00
dexter
d05bd7bc55 📦 NEW: 新增edge插件,提供简单级联功能 2022-10-03 18:52:47 +08:00
dexter
6f9fe7c646 🐛 FIX: rtmp插件与srs服务器互通的问题 2022-09-24 21:08:06 +08:00
dexter
96d886c7a5 🐛 FIX: hook插件读取配置文件错误 2022-09-19 00:23:16 +08:00
dexter
ca2f69539d 🐛 FIX: gb拉流信令拼接错误 2022-09-16 19:19:00 +08:00
dexter
0fd608aefc 🐛 FIX: engine中订阅关键帧被覆盖问题,gb的ptzcmd中发送的deviceID值问题,acc的rtp包超过一个mtu时的解析问题 2022-09-16 13:40:29 +08:00
dexter
d5e6a517fb 🐛 FIX: dts在无B帧情况下的生成机制修正,gb插件增加设备信息持久化重启实例后可快速恢复 2022-09-12 23:02:01 +08:00
dexter
e035cf0846 👌 IMPROVE: 增加rtsp拉流报错信息,gb插件增加ps流dump功能方便排查错误 2022-09-11 21:15:47 +08:00
dexter
e7ff340c7a 🚀 RELEASE: 修复远端拉流保存并发问题,修复gb拉流PS包解析bug,导出部分插件 2022-09-04 22:23:40 +08:00
dexter
91d1d5502b Merge pull request #66 from dwdcth/patch-1
删除"## Changelog"
2022-09-02 16:00:01 +08:00
banshan
b1ef460af1 删除"## Changelog" 2022-09-02 15:53:08 +08:00
dexter
87f08066e5 API增加获取远端导入的流以及向远端推流的信息 2022-08-28 22:36:44 +08:00
dexter
da69aae5fa 修复gb插件中的pts和dts覆盖bug,兼容rtsp协议sdp中无sps和pps问题 2022-08-21 19:35:56 +08:00
dexter
6e8081a411 1、增加配置日志级别;2、发布者增加可以配置断线延迟退出时间配置 2022-08-13 18:33:02 +08:00
dexter
2f7bc14986 Merge pull request #63 from dwdcth/v4
添加版本号
2022-08-09 16:56:47 +08:00
hetangj
504e22b558 添加版本号 2022-08-09 16:43:01 +08:00
hetangj
c7b2cbfee3 '添加版本号' 2022-08-09 16:20:01 +08:00
dexter
70b5c553b9 修复数据轨道释放导致读取错误,以及写入annexb格式时的dts生成问题 2022-08-07 19:12:38 +08:00
dexter
4486c612e4 对rtmp协议写入数据增加判空逻辑 2022-07-30 16:22:44 +08:00
dexter
29f574ae73 增加10s的fps和bps历史统计,rtsp插件增加拉流时强制指定协议的配置,修复若干bug 2022-07-24 00:15:43 +08:00
dexter
d12052eb4a 修复gb28181插件ssrc取值以及ip获取的兼容性 2022-07-17 14:04:01 +08:00
dexter
7a0964b501 Merge branch 'v4' of github.com:langhuihui/monibuca into v4 2022-07-10 20:47:40 +08:00
dexter
67ad3e669d 更新gb插件以及远程控制台显示数据部分 2022-07-10 20:47:11 +08:00
dexter
6c78c2f456 Merge pull request #60 from dwdcth/v4
保存发布信息
2022-07-06 15:39:59 +08:00
banshan
16cf7725f3 保存发布信息 2022-07-06 15:35:26 +08:00
dexter
9d08fa47b3 修复startTime经过json序列化后变成负数的问题 2022-07-06 10:13:02 +08:00
dexter
9b6e9bfbec Merge pull request #59 from dwdcth/v4
修复goreleaser 发布时编译错误
2022-07-06 10:11:32 +08:00
banshan
a18fc77b8b Update go.yml 2022-07-06 09:39:46 +08:00
dexter
edd7a6f047 消除一个hls的内存泄露,修复gb插件的一个bug 2022-07-05 10:24:45 +08:00
dexter
9ec70f0454 升级engine 2022-06-29 14:23:04 +08:00
dexter
6ca479371e 修复若干bug 2022-06-27 00:41:32 +08:00
dexter
f65bd3a760 rtp相关追帧完成,修复音频数据写入bug 2022-06-25 20:53:25 +08:00
dexter
91a9171c5c preview插件加入索引页面,engine的api/plugins输出完整配置信息 2022-06-23 00:47:17 +08:00
dexter
0b51fecf48 snap插件更新 2022-06-20 13:25:50 +08:00
dexter
493bce72cb 取消flv补完,跳帧后的时间戳修复 2022-06-20 13:11:31 +08:00
dexter
a48057e713 更新engine依赖 2022-06-17 10:39:31 +08:00
dexter
2dd008d960 新增预览插件和截图插件,录像插件增加裸流保存功能 2022-06-12 15:51:04 +08:00
wancheng1990
3f7e7b3666 Update config.yaml 2022-06-08 16:29:55 +08:00
dexter
0791151557 quic-go版本不兼容 2022-06-08 13:26:08 +08:00
dexter
69f5d9d976 修复webrtc交互错误 2022-06-08 10:25:10 +08:00
dexter
dec17c1f26 gb28181默认mediaip取sipip配置,修复webrtc插件以及record插件报错 2022-06-05 21:56:59 +08:00
dexter
e6069322f8 修复大量bug,record增加分片录制能力,hls写盘功能移入record插件中 2022-05-31 11:16:14 +08:00
dexter
36ede9b9a2 fix: hls插件拉流panic错误 2022-05-16 19:02:41 +08:00
dexter
e4bc0ad5ea Merge pull request #51 from dwdcth/patch-3
Update go.yml
2022-05-16 10:14:38 +08:00
banshan
33a58b0641 Update go.yml 2022-05-16 10:12:50 +08:00
dexter
cb71b2c7e2 Merge pull request #50 from dwdcth/patch-1
Update go.yml
2022-05-15 21:24:11 +08:00
banshan
38b8923e6f Update go.yml 2022-05-15 21:20:41 +08:00
dexter
8b483e5139 升级插件版本 2022-05-15 19:12:30 +08:00
dexter
34c21e5e8f 尝试发布beta 2022-05-15 16:30:44 +08:00
dexter
b8a23517ba Merge pull request #48 from dwdcth/v4
publish langhuihui/m7s-import
2022-05-15 11:22:58 +08:00
banshan
d491b6206a publish langhuihui/m7s-import 2022-05-04 21:34:07 +08:00
dexter
93ce7391a5 Merge pull request #46 from dwdcth/v4
V4 自动发布和readme
2022-04-25 09:23:39 +08:00
dwdcth
611bd78b5c readme 2022-04-24 11:38:12 +08:00
dwdcth
b112187125 go.yml 2022-04-24 11:16:45 +08:00
dwdcth
e0c35fce2b v4 自动发布 2022-04-24 11:04:31 +08:00
banshan
7bcf2cba27 Update go.yml 2022-04-24 10:31:43 +08:00
dexter
da5f970067 Merge pull request #44 from dwdcth/v4
darwin and windows arm64
2022-04-24 09:41:51 +08:00
dwdcth
711b4cc82c darwin and windows arm64 2022-04-23 21:39:01 +08:00
dexter
f1bcb6f2c9 删除二进制文件 2022-04-08 16:18:39 +08:00
dexter
306a7ffeff 加入WebTransport插件 2022-04-08 16:07:00 +08:00
dexter
9c8a2c5d83 加入log和rtsp两个插件引入 2022-03-22 09:26:07 +08:00
dexter
1a67f63932 更新包路径 2022-02-27 21:47:51 +08:00
dexter
c761c6ce9b 简化代码 2022-02-23 17:34:26 +08:00
dexter
cc9c0d67e2 调试rtmp插件 2022-02-19 10:39:38 +08:00
dexter
6df2a3b842 修复window编译错误 2022-01-16 23:57:45 +08:00
dexter
c38bd36ecc 修复rtsp插件和webrtc插件的bug,windows环境下实现错误写入fatal.log的功能 2022-01-16 13:17:52 +08:00
dexter
a769f1cbf4 修复启动时版本显示不对的问题 2022-01-10 09:11:33 +08:00
dexter
8ec0515f60 hls增加过滤功能,以及永久m3u8文件生成 2022-01-06 14:45:47 +08:00
dexter
e2113e03df 解决rtp包含多slice的情况 2022-01-03 22:52:46 +08:00
dexter
56bbc0ddf8 支持配置文件保存功能,增加HDL拉取远端FLV流的功能 2021-12-27 21:12:05 +08:00
dexter
563f966fe4 修复engine中stream在publish的时候有空指针错误 2021-12-20 13:45:41 +08:00
dexter
0e3befd285 rtsp列表API修复 2021-12-13 10:21:54 +08:00
dexter
e60871b55b 增加查看流数据的功能 2021-12-11 20:07:05 +08:00
dexter
785be6a939 修复gb28181中音频时间戳换算 2021-12-02 11:31:16 +08:00
dexter
7684856ccc 修复gb插件乱序重排功能,对sps加强判断 2021-11-30 16:15:56 +08:00
dexter
2e76b74e74 增加RTP乱序重排,修复接收rtsp h265的推流、rtsp时间戳修复 2021-11-28 23:33:37 +08:00
dexter
e67b3f3bc8 修复timebase为0的情况 2021-11-24 13:51:22 +08:00
dexter
c17302a8fc 针对rtp包的B帧解析优化 2021-11-23 12:54:32 +08:00
dexter
02738a1482 rtsp库更换为gortsplib 2021-11-19 22:06:36 +08:00
dexter
0e1fe9a713 增加延时自动取消发布,gb28181增加tcp多端口监听功能 2021-11-13 15:26:26 +08:00
dexter
8a059c51a9 修复HLS时长浮点计算问题,以及webrtc插件依赖问题 2021-11-04 10:32:28 +08:00
dexter
07a34d2642 修复pushbytestream的bug以及gb28181插件对sip消息的from字段判空 2021-11-01 20:55:15 +08:00
dexter
7dca6c9411 修复引擎bug 2021-10-27 21:52:49 +08:00
dexter
eddbb35136 版本升级 2021-10-13 23:12:11 +08:00
dexter
65c3d90275 更新版本 2021-08-30 15:32:25 +08:00
dexter
531bcd57f1 更新版本 2021-08-22 23:32:36 +08:00
dexter
18bbedcff5 Merge branch '3.0' of github.com:langhuihui/monibuca into 3.0 2021-08-20 23:01:55 +08:00
dexter
6a2818916a 迁移UI到gateway插件中 2021-08-20 22:59:40 +08:00
wancheng1990
612501a403 更新ui 2021-08-19 13:54:39 +08:00
dexter
ca3397e544 Update go.yml 2021-08-18 16:47:58 +08:00
dexter
d01d254caa Update go.yml 2021-08-18 16:44:32 +08:00
dexter
7574a6ba6f 升级webrtc和hls版本 2021-08-16 21:20:19 +08:00
dexter
4c918df6e6 Merge branch '3.0' of github.com:langhuihui/monibuca into 3.0 2021-08-16 14:01:31 +08:00
dexter
f677beb2b7 升级到3.3.1 2021-08-16 14:01:22 +08:00
bosscheng
3adaedf6fc update ui 2021-08-07 00:08:25 +08:00
dexter
5a9cf53485 更新rtsp版本 2021-08-04 20:12:49 +08:00
dexter
bff77f1365 Merge branch '3.0' of github.com:langhuihui/monibuca into 3.0 2021-08-03 15:38:51 +08:00
dexter
b608c38aec 更新rtsp说明以及减少summary消息包大小 2021-08-03 15:38:46 +08:00
bosscheng
d8537ec3a3 update ui 2021-08-02 21:13:14 +08:00
dexter
c055f7fceb 更新版本优化gb28181 2021-08-02 09:03:21 +08:00
dexter
afb0efb2ee 版本升级 2021-07-31 16:25:22 +08:00
dexter
51832cd9a7 对两种ringbuffer采取不同策略 2021-07-29 14:46:59 +08:00
langhuihui
454e19f8c0 更新引擎版本 2021-07-23 20:56:16 +08:00
wancheng1990
62111b41d1 update ui 2021-07-22 16:00:48 +08:00
wancheng1990
0eca8fd657 update ui 2021-07-22 13:54:05 +08:00
langhuihui
ca16d405d0 修改默认配置 2021-07-20 16:59:49 +08:00
wancheng1990
e1d500447a update ui 2021-07-20 16:08:45 +08:00
wancheng1990
e7da10649c update ui 2021-07-20 15:36:19 +08:00
李宇翔
ccd0320090 更新版本 2021-07-13 09:24:01 +08:00
bosscheng
ee9d4d06b4 update ui 2021-07-12 23:11:53 +08:00
langhuihui
089cc593be 更新版本 2021-07-12 09:43:02 +08:00
bosscheng
9abd76b1e5 更新最新ui 2021-07-11 16:46:23 +08:00
langhuihui
6e65cc20a2 3.1.1 2021-07-11 10:49:38 +08:00
wancheng1990
ff71c7bd5a update ui audo play audio 2021-07-08 11:56:36 +08:00
wancheng1990
8648f2ae20 update ui 2021-06-30 18:27:57 +08:00
langhuihui
70e7fae954 更新GB28281版本 2021-06-29 14:09:17 +08:00
langhuihui
48b7ff1dee 更新版本 2021-06-28 23:48:30 +08:00
langhuihui
d46e0d45b2 更新版本 2021-06-27 08:18:29 +08:00
wancheng1990
5b41f67b80 update ui 2021-06-26 23:27:08 +08:00
wancheng1990
3a8b371560 update ui 2021-06-23 11:35:50 +08:00
langhuihui
8abae09574 更新版本 2021-06-18 22:00:58 +08:00
wancheng1990
476bb4a656 update ui 2021-06-15 17:18:56 +08:00
李宇翔
bf5b4010d7 更新UI和GB28181 2021-06-11 10:57:18 +08:00
李宇翔
8cee5c2c18 版本更新 2021-06-04 11:33:40 +08:00
李宇翔
43632cf852 更新插件版本及UI功能 2021-06-02 08:56:41 +08:00
李宇翔
e4e96f8fc1 更新gb28181插件版本 2021-05-31 08:38:10 +08:00
langhuihui
57acc5f357 更新gb28181插件 2021-05-30 16:40:16 +08:00
langhuihui
23faad4405 更新UI和GB28181 2021-05-26 22:05:06 +08:00
langhuihui
ec86b455a9 更新gb28181插件 2021-05-09 23:48:41 +08:00
langhuihui
f848e90a50 调整gb28181录像播放功能 2021-05-09 23:10:50 +08:00
langhuihui
7d05e4cc6c 更新版本 2021-05-09 21:35:39 +08:00
李宇翔
b66e52a90f 更新UI 2021-05-07 09:12:30 +08:00
langhuihui
da6554f536 修改readMe 2021-05-05 14:11:42 +08:00
langhuihui
2b8e8bca98 打包后传输 2021-05-05 11:38:12 +08:00
langhuihui
9009431a1f 更新git action 2021-05-04 17:19:35 +08:00
dexter
99b9cc674f Update go.yml 2021-05-04 16:35:13 +08:00
dexter
67b338007a Update go.yml 2021-05-04 10:50:43 +08:00
dexter
111ba8aa5a Update go.yml 2021-05-04 10:37:30 +08:00
dexter
d5ab178841 Update go.yml 2021-05-04 03:00:48 +08:00
dexter
3a3dd3c73c Update go.yml 2021-05-04 02:54:59 +08:00
dexter
75865960c6 Update go.yml 2021-05-04 02:44:34 +08:00
dexter
bb4c39886d Update go.yml 2021-05-04 02:29:47 +08:00
dexter
4e92f395bf Update go.yml 2021-05-04 01:55:37 +08:00
dexter
64cf6e609d Create go.yml 2021-05-04 01:35:18 +08:00
langhuihui
65bbb5c04f first commit 2021-05-04 01:08:09 +08:00
李宇翔
b0c6bff8ae 更新到1.16 2021-03-24 20:07:51 +08:00
dexter
439eb0afc0 Update README.md 2021-01-20 20:07:33 +08:00
langhuihui
f7e6c5084c 更新版本增加gb28181 2021-01-11 08:24:24 +08:00
李宇翔
e0f424fd2c 更新一下版本 2020-09-04 21:13:34 +08:00
dexter
98995de88a Merge pull request #6 from mask-pp/bug_fix
hold程序方式
2020-08-13 07:50:15 +08:00
workbase
b5c5976312 Merge branch '2.0' into bug_fix 2020-08-12 11:20:51 +08:00
mask-pp
c6dbda22f9 handle住程序方式 2020-08-12 11:17:48 +08:00
langhuihui
1e78f687d7 更新版本 2020-08-09 22:08:48 +08:00
langhuihui
701b9b63f3 更新二维码 2020-08-02 21:42:46 +08:00
langhuihui
58f134cda1 更新二维码 2020-07-26 21:50:09 +08:00
langhuihui
d772ed3336 更新二维码 2020-07-19 22:02:29 +08:00
langhuihui
fc4f13fa00 修改二维码版本 2020-07-12 22:40:16 +08:00
langhuihui
2ee71755b7 更新二维码 2020-07-05 21:56:19 +08:00
李宇翔
7e165fe9d4 更新版本以及二维码 2020-06-28 15:07:19 +08:00
langhuihui
dd7a2e8dc7 更新二维码 2020-06-21 21:56:41 +08:00
langhuihui
bd7f5249aa 更新二维码和引擎版本 2020-06-14 21:24:07 +08:00
langhuihui
bb9a154a00 修改ReadMe 更新插件版本 2020-06-07 19:57:13 +08:00
李宇翔
e3c7c9514e 更新go module和增加webrtc 2020-06-01 09:23:40 +08:00
李宇翔
b3a485ddfb 更新ReadMe 2020-06-01 09:14:38 +08:00
李宇翔
01a74b245e 修改版本号和二维码 2020-05-25 09:30:13 +08:00
dexter
4482f0232f update qr code 2020-05-18 09:07:37 +08:00
langhuihui
919f7ad78b 修改开源协议为MIT 2020-05-17 14:01:04 +08:00
langhuihui
0c1f1c9770 补充一个插件 2020-05-17 13:58:47 +08:00
langhuihui
18a9398f66 使用go module防止加载engine包失败 2020-05-16 23:47:23 +08:00
李宇翔
5828b8d803 增加协议实现的功能 2020-05-15 17:30:59 +08:00
李宇翔
c328db87a8 更新二维码 2020-05-11 09:12:05 +08:00
langhuihui
cc89bbb61b 删除所有子模块 2020-05-05 14:33:44 +08:00
李宇翔
cd34607c86 更新二维码 2020-04-30 14:09:44 +08:00
李宇翔
cfb6dacf73 更新二维码 2020-04-22 15:03:53 +08:00
dexter
eba5b6b8f1 Update README_zh.md 2020-04-15 15:24:37 +08:00
dexter
597407a4e5 Update README.md 2020-04-15 15:23:50 +08:00
dexter
3fcd22d1e7 Update README_zh.md 2020-04-08 15:14:36 +08:00
dexter
65de4806c4 Update README.md 2020-04-08 15:13:31 +08:00
dexter
55eb2218be 更新二维码 2020-04-01 17:09:25 +08:00
李宇翔
5c0b22b1df 增加一键安装说明 2020-03-26 15:49:01 +08:00
李宇翔
474581d9b1 更新群二维码 2020-03-25 19:27:07 +08:00
李宇翔
3907422b3e 加个图片 2020-03-19 11:53:57 +08:00
李宇翔
d3b7fa04ef 修改文档 2020-03-19 11:47:36 +08:00
李宇翔
d16aa756f8 Merge branch 'master' of https://github.com/langhuihui/monibuca 2020-03-18 18:33:31 +08:00
李宇翔
8304314e49 英文readme开发 2020-03-18 18:32:25 +08:00
langhuihui
c2d0cbb1d0 修改获取配置文件的方法 2020-03-13 15:30:12 +08:00
李宇翔
67ab443f1a 更新readme 2020-03-11 16:18:50 +08:00
langhuihui
c80beec8f3 main.go修改为demo实例 2020-03-07 16:21:23 +08:00
langhuihui
1ce4fd2db0 转换为子模块方式 2020-03-07 14:16:38 +08:00
dexter
a20f30d76d 刷新二维码 2020-03-04 09:52:48 +08:00
langhuihui
afa44eb173 迁移说明 2020-03-01 20:02:34 +08:00
李宇翔
592034adce 加入Q&A 2020-02-27 14:02:28 +08:00
langhuihui
6e8ac88aaf 修复bug 2020-02-26 20:19:33 +08:00
李宇翔
da66df9302 添加微信交流群二维码 2020-02-26 18:20:34 +08:00
李宇翔
360f7faf35 编译静态资源 2020-02-26 16:43:20 +08:00
李宇翔
bee477e685 加入插件市场功能 2020-02-26 15:54:30 +08:00
李宇翔
4a0c4e36e7 正在加入插件市场查询 2020-02-26 15:54:30 +08:00
langhuihui
1ed3e6249f 插件市场开发 2020-02-26 15:54:29 +08:00
langhuihui
1ac06ef252 完成H265支持以及mp3格式支持 2020-02-24 23:21:00 +08:00
李宇翔
620d96b39c 预览加入h265和mp3的解码支持 2020-02-24 11:56:25 +08:00
langhuihui
66a396df0b 重启脚本修改 2020-02-21 16:01:46 +08:00
langhuihui
029abe3187 加入设计原理文档 2020-02-21 10:09:37 +08:00
langhuihui
40fba0d348 支持PES中包含多个AAC帧 2020-02-19 14:58:21 +08:00
langhuihui
73941d1e0b ADTS转RTMP协议方式传输音频包 2020-02-18 15:19:21 +08:00
langhuihui
709c2c6ac7 增加目录候选功能 2020-02-17 11:48:58 +08:00
langhuihui
f96bc11ddb 增强对实例的控制 2020-02-15 21:07:47 +08:00
langhuihui
5563ddc0d2 增强对实例的控制 2020-02-14 09:54:53 +08:00
langhuihui
95657bd6df 增强对实例的控制 2020-02-13 17:41:39 +08:00
langhuihui
b9e19e75c8 增强对实例的控制 2020-02-13 10:43:32 +08:00
langhuihui
eac623639d 界面增加重启和升级 2020-02-11 21:59:31 +08:00
langhuihui
fea6e98ca7 小功能增加 2020-02-11 17:27:05 +08:00
langhuihui
649a5b558a 增加实例管理器 2020-02-11 14:53:29 +08:00
langhuihui
b3c8d35fad 修复集群传输bug 2020-02-05 17:29:55 +08:00
langhuihui
ab745145d9 集群采集信息功能完善 2020-02-04 16:09:55 +08:00
langhuihui
a1bdc8528b 增加了许可协议以及一些日志打印 2020-02-03 21:30:41 +08:00
langhuihui
ecb931ccb0 增加集群概览显示 2020-02-02 16:20:51 +08:00
langhuihui
13c357493f 更新控制台功能 2020-02-01 15:52:54 +08:00
langhuihui
87776b9540 增加log查看和config查看 2020-01-31 14:22:21 +08:00
langhuihui
543d735c41 完善文档 2020-01-30 21:31:09 +08:00
langhuihui
966f9b9d0d 修复录制功能 2020-01-30 11:51:42 +08:00
169 changed files with 1365 additions and 36274 deletions

13
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: monibuca
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

79
.github/workflows/go.yml vendored Normal file
View File

@@ -0,0 +1,79 @@
name: Go
on:
create:
tags:
- v4*
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 1
- name: Set up Env
run: echo "version=${GITHUB_REF:11}" >> $GITHUB_ENV
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.20.7
- name: Cache Go modules
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: runner.osgo{ { hashFiles('**/go.sum') } }
restore-keys: ${{ runner.os }}-go-
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
if: success() && startsWith(github.ref, 'refs/tags/')
with:
version: v1.8.3
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Checkout m7s-import
# uses: actions/checkout@v3
# with:
# repository: langhuihui/m7s-import
# path: m7s-import
# persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
# fetch-depth: 0
# - name: Add bin to m7s-import
# if: success() && startsWith(github.ref, 'refs/tags/')
# run: |
# cd m7s-import
# mkdir -p apps/m7s-website/src/public/bin
# cp ../dist/m7s_${{ env.version }}_windows_amd64.tar.gz apps/m7s-website/src/public/bin/m7s_windows_amd64.tar.gz
# cp ../dist/m7s_${{ env.version }}_darwin_amd64.tar.gz apps/m7s-website/src/public/bin/m7s_darwin_amd64.tar.gz
# cp ../dist/m7s_${{ env.version }}_darwin_arm64.tar.gz apps/m7s-website/src/public/bin/m7s_darwin_arm64.tar.gz
# cp ../dist/m7s_${{ env.version }}_linux_amd64.tar.gz apps/m7s-website/src/public/bin/m7s_linux_amd64.tar.gz
# cp ../dist/m7s_${{ env.version }}_linux_arm64.tar.gz apps/m7s-website/src/public/bin/m7s_linux_arm64.tar.gz
# ls apps/m7s-website/src/public/bin
- name: copy
if: success() && startsWith(github.ref, 'refs/tags/')
run: |
mkdir -p bin
cp dist/m7s_${{ env.version }}_windows_amd64.tar.gz bin/m7s_windows_amd64.tar.gz
cp dist/m7s_${{ env.version }}_darwin_amd64.tar.gz bin/m7s_darwin_amd64.tar.gz
cp dist/m7s_${{ env.version }}_darwin_arm64.tar.gz bin/m7s_darwin_arm64.tar.gz
cp dist/m7s_${{ env.version }}_linux_amd64.tar.gz bin/m7s_linux_amd64.tar.gz
cp dist/m7s_${{ env.version }}_linux_arm64.tar.gz bin/m7s_linux_arm64.tar.gz
ls bin
- uses: jakejarvis/s3-sync-action@master
# with:
# args: --acl public-read --follow-symlinks --delete
env:
AWS_S3_ENDPOINT: https://${{ secrets.R2_DOMAIN }}
AWS_ACCESS_KEY_ID: ${{ secrets.R2_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET }}
AWS_S3_BUCKET: monibuca
SOURCE_DIR: 'bin'
DEST_DIR: 'bin'

25
.gitignore vendored Normal file
View File

@@ -0,0 +1,25 @@
*.exe
.vscode
.idea
resource
*.log
/monibuca
node_modules
shutdown.bat
*.sh
.m7s
debug.go
dist/
record/
config2.yaml
config1.yaml
monibuca_*
ps
ps2
ps3
devices.json
dump
.DS_Store
main
monitor
.history

15
Dockerfile Normal file
View File

@@ -0,0 +1,15 @@
#源镜像
FROM alpine:latest
WORKDIR /opt
ADD monibuca_linux /opt
ADD favicon.ico /opt
ADD config.yaml /opt
# RUN apk --no-cache add ffmpeg
#暴露端口
EXPOSE 8080 8443 1935 554 58200-59200 5060 8000-9000
EXPOSE 5060/udp 58200-59200/udp 8000-9000/udp
#最终运行docker的命令
ENTRYPOINT ["./monibuca_linux"]

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019-present, dexter
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

141
README.md
View File

@@ -1 +1,140 @@
[中文文档](http://monibuca.com/docs)
<p align="center">
<a href="https://m7s.live">
<img src="logo.png" height="96">
</a>
</p>
<p align="center">
<a href="https://docs.m7s.live">中文文档</a>
</p>
# Core code base and plug-in code base
[https://github.com/Monibuca](https://github.com/Monibuca)
# Introduction
## What is Monibuca (m7s)?
Monibuca (pronounced: analog not card, m7s is its abbreviation, similar to k8s) is an open source streaming server development framework developed in Go. It is based on go1.19+, in addition to no other dependencies built, and provides a set of plug-in secondary development model to help you efficiently develop streaming media servers, you can directly use the official plug-in, or develop your own plug-in to extend any function, so Monibuca is a framework that can support any streaming protocol!
Monibuca consists of three parts: engine, plugins, and instance project.
The engine provides a common streaming data cache and forwarding mechanism, and does not care how the protocol is implemented
The plugins offer all the other features and can be extended indefinitely
An instance project is a project project that introduces the engine and plugins and starts the engine, and can be written entirely by yourself
## Plug-in framework
Monibuca aims to build a general streaming media development ecosystem, so since the v1 version, it has considered the decoupling of services and stream forwarding, so as to design a set of plug-in mechanisms that can be arbitrarily extended. Depending on your needs, you can flexibly introduce different types of plugins:
- Provide streaming media protocol packaging/unpacking, such as RTMP plug-ins, RTSP plug-ins, etc
- Provides log persistence processing - logrotate plugin
- Provide recording function - record plugin
- Provide rich debugging functions - debug plugin
- Provide HTTP callback capability - hook plugin
If you are an experienced developer, then the best way is to carry out secondary development on the basis of existing plugins, and provide reusable plugins to more people to enrich the ecosystem. If you're a beginner in streaming, the best way to do this is to use existing plugins to cobble together the features you need and ask experienced developers for help.
# Key features
## Engine aspect
- Provides a plug-in mechanism to manage plug-in startup, configuration resolution, event distribution, etc. in a unified manner
- Provide forwarding in H264, H265, AAC, G711 format
- Provide reusable AVCC format, RTP format, AnnexB format, ADTS format and other pre-encapsulation mechanisms
- Provides a multi-track mechanism, supports large and small streams, and encrypts stream expansion
- Provide DataTrack mechanism, which can be used to implement functions such as room text chat
- Provide timestamp synchronization mechanism and speed limit mechanism
- Provides an RTP packet reorder mechanism
- Provide subscriber frame chasing and skipping mechanism (first screen second on)
- Provides the infrastructure for publish-subscribe push and pull out
- Provides underlying architecture support for authentication mechanisms
- Provides a memory reuse mechanism
- Provides a mechanism for publishers to disconnect and reconnect
- Provides an on-demand flow pulling mechanism
- Provides a common mechanism for HTTP service ports
- Provides an automatic registration mechanism for HTTP API interfaces
- Provides HTTP interface middleware mechanism
- Provides structured logs
- Provides flow information statistics and output
- Provides an event bus mechanism that broadcasts events to all plug-ins
- Provides a configuration hot update mechanism
## Plug-in aspect
- Provide RTMP protocol push-pull stream, external push-pull stream (RTMPS supported)
- Provides RTSP push and pull streams and external push and pull streams
- Provides HTTP-FLV protocol to pull streams, pull external streams, and read local FLV files
- Provides streaming of the WebSocket protocol
- Provides HLS protocol to pull streams and pull outflows
- Provides push-pull streams for the WebRTC protocol
- Provides GB28181 protocol push and dump playback analysis capabilities
- Provide support for the Onif protocol
- Provides streaming of WebTransport protocol
- Provides FMP4 protocol for pulling streams
- Provides edge server functionality to implement cascading streaming
- Provide video recording function, support FLV, MP4, HLS, RAW formats
- Provides log persistence by day, hour, minute, second, size, and number of files
- Provide a screenshot function
- Provides HTTP callback function
- Preview features available (integrated with Jessibuca Pro)
- Room function available (video conferencing possible)
- Provide the function of docking with Prometheus
Third-party plugins and paid plugins provide additional functionality and are not listed here.
Inspired by:
- [mp4ff](https://github.com/edgeware/mp4ff) mp4 file format library [@edgeware](https://github.com/edgeware)
- [gosip](https://github.com/ghettovoice/gosip) go sip library [@ghettovoice](https://github.com/ghettovoice)
- [webrtc](https://github.com/pion/webrtc) go library and whole [@pion](https://github.com/pion) team
- [gortsplib](https://github.com/aler9/gortsplib) rtsp library [@aler9](https://github.com/aler9)
## Remote console
- Provides multi-instance management
- Provide flow details display
- Provides visual editing of configurations
- Provides visual display of logs
- Provide visual management of plugins
- Provides GB device management
- Provides an interface for dynamically adding remote push-pull flows
- Provide WebRTC background wall function
- Provide multiplayer video demonstrations
# Origin of the name
The word Monibuca is derived from (Monica), and in order to solve the naming problem, three names are used to represent server, player, and streamer. Since Monica, Jessica, and Rebecca all have `卡` words, which is not good for the live broadcast (ca - `卡` means block in Chinese), it was changed to Monibuca, Jessibuca(https://jessibuca.com), and Rebebuca(https://rebebuca.com). (bu-`不` means not)
# Install
- The compiled binary executable files (i.e. green software) of each platform are officially provided, so it can run without installing any other software.
- If you need to compile and start the project yourself, you need to install go1.19 or above.
The official download link of the latest version is provided:
- [Linux](https://download.m7s.live/bin/m7s_linux_arm64.tar.gz)
- [Linux-arm64](https://download.m7s.live/bin/m7s_linux_arm64.tar.gz)
- [Mac](https://download.m7s.live/bin/m7s_darwin_arm64.tar.gz)
- [Mac-arm64](https://download.m7s.live/bin/m7s_darwin_arm64.tar.gz)
- [Windows](https://download.m7s.live/bin/m7s_windows_amd64.tar.gz)
Don't forget to fix the rights chmod +x m7s_xxx_xxx on Linux and Mac.
# Run
## Executable files run directly
- Linux, for example, downloaded to `/opt/m7s_linux_x86`, then `$ cd /opt ' and then `$ ./m7s_linux_x86`
- Similar to Linux and Mac, you may need to modify the executable permissions of the file or double-click to run
- Windows, double-click m7s directly_windows_x86.exe can be started
## Docker
```bash
docker run -id -p 1935:1935 -p 8080:8080 -p 8443:8443 -p 554:554 -p 58200:58200 -p 5060:5060/udp -p 8000:8000/udp -p 9000:9000 langhuihui/monibuca:latest
```
## Self-compiled startup project
1. `git clone https://github.com/langhuihui/monibuca`
2. `cd monibuca`
3. `go run .`
## Self-created startup project
You can watch the video tutorial:
- [从零启动 m7s V4](https://www.bilibili.com/video/BV1iq4y147N4/)
- [m7s v4 视频教程——插件引入](https://www.bilibili.com/video/BV1sP4y1g7BF/)
![公众号](https://m7s.live/images/m7s/footer/wx-mp.jpg)

9
conf/hls.yaml Normal file
View File

@@ -0,0 +1,9 @@
# hls纯转发,即从HLS->HLS
global:
disableall: true
enablertp: false
enableavcc: false
hls:
enable: true
relaymode: 1

7
conf/https.yaml Normal file
View File

@@ -0,0 +1,7 @@
# 默认的http端口是8080
# 这里指定8081为https端口
# 本地访问https://local.monibuca.com:8081请配置host文件将127.0.0.1 local.monibuca.com加入到host文件中
global:
listenaddrlts: :8081
certfile: local.monibuca.com_bundle.pem
keyfile: local.monibuca.com.key

6
conf/rtmp.yaml Normal file
View File

@@ -0,0 +1,6 @@
# 只包含rtmp关闭其他所有插件,只能用于rtmp的转发
global:
disableall: true
enablertp: false
rtmp:
enable: true

4
conf/rtmps.yaml Normal file
View File

@@ -0,0 +1,4 @@
# 开启接受rtmps
rtmp:
tcp:
listenaddrtls: :443

23
conf/rtsp.yaml Normal file
View File

@@ -0,0 +1,23 @@
# rtsp 拉流配置
global:
disableall: true # 需要转换其他协议的话需要将disableall设置为false
enableavcc: false # 如果需要转换成rtmp和flv的话需要改成true
delayclosetimeout: 2s # 无订阅者时2s后关闭拉流
rtsp:
enable: true # 如果disableall为false的话这个可以不需要写
pullprotocol: tcp
pull:
pullonstart:
rtsp/obs: rtsp://localhost:8554/live
# live/test1: rtsp://localhost:8554/live/rtsp
# live/test2: rtsp://localhost:8554/live/rtsp
# live/test3: rtsp://localhost:8554/live/rtsp
# live/test4: rtsp://localhost:8554/live/rtsp
# live/test5: rtsp://localhost:8554/live/rtsp
# live/test6: rtsp://localhost:8554/live/rtsp
# live/test7: rtsp://localhost:8554/live/rtsp
# live/test8: rtsp://localhost:8554/live/rtsp
# live/test9: rtsp://localhost:8554/live/rtsp
pullonsub: # 按需拉流
rtsp/100: rtsp://admin:admin@192.168.0.100/cam/realmonitor?channel=1&subtype=0
rtsp/101: rtsp://admin:admin@192.168.0.101/cam/realmonitor?channel=1&subtype=0

View File

@@ -1,18 +0,0 @@
[Plugins.HDL]
ListenAddr = ":2020"
[Plugins.Jessica]
ListenAddr = ":8080"
[Plugins.RTMP]
ListenAddr = ":1935"
[Plugins.GateWay]
ListenAddr = ":81"
#[Plugins.Cluster]
#Master = "localhost:2019"
#ListenAddr = ":2019"
#
#[Plugins.Auth]
#Key="www.monibuca.com"
[Plugins.RecordFlv]
Path="./resouce"
[Plugins.QoS]
Suffix = ["high","medium","low"]

12
config.yaml Normal file
View File

@@ -0,0 +1,12 @@
# 支持零配置启动,即无需填写配置默认启用所有的插件。
# 只需要填写需要修改的配置项即可。不需要将所有的配置都填写进来!!。
# 全局配置参考 https://m7s.live/guide/config.html
# 插件配置参考各个插件的文档
# 插件都有一个enable配置如果为false则不启用该插件默认为true即不需要配置。
llhls:
enable: false
hls:
enable: false
monitor:
enable: false

21
dashboard/.gitignore vendored
View File

@@ -1,21 +0,0 @@
.DS_Store
node_modules
public/docs
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -1,24 +0,0 @@
# dashboard
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -1,3 +0,0 @@
module.exports = {
}

View File

@@ -1 +0,0 @@
#app,body,html{height:100%}#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#184c18;position:relative}#app>div:first-child{position:absolute;top:10px;left:30px;font-size:x-large}.content{padding-top:60px}.feature-title[data-v-54efad41]{color:#eb5e46;font-weight:700;font-size:larger}p[data-v-54efad41]{margin:30px;font-size:20px}img[data-v-54efad41]{margin:20px}.root[data-v-e34eab40]{background:#d3d3d3}.root>img[data-v-e34eab40]{width:300px;margin:30px}@-webkit-keyframes recording-data-v-c2fdc660{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes recording-data-v-c2fdc660{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.recording[data-v-c2fdc660]{-webkit-animation:recording-data-v-c2fdc660 1s infinite;animation:recording-data-v-c2fdc660 1s infinite}.layout[data-v-c2fdc660]{padding-bottom:30px;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.room[data-v-c2fdc660]{width:250px;margin:10px;text-align:left}.empty[data-v-c2fdc660]{color:#eb5e46;width:100%;min-height:500px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.empty[data-v-c2fdc660],.status[data-v-c2fdc660]{display:-webkit-box;display:-ms-flexbox;display:flex}.status[data-v-c2fdc660]{position:fixed;left:5px;bottom:10px}.status>div[data-v-c2fdc660]{margin:0 5px}

File diff suppressed because one or more lines are too long

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.ad3166d6.css" as="style"><link rel="preload" href="/docs/assets/js/app.ad3166d6.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.83ce04b6.js"><link rel="prefetch" href="/docs/assets/js/2.142d04d2.js"><link rel="prefetch" href="/docs/assets/js/3.2b6c987b.js"><link rel="prefetch" href="/docs/assets/js/4.ad90d74a.js"><link rel="prefetch" href="/docs/assets/js/5.36121818.js">
<link rel="stylesheet" href="/docs/assets/css/styles.ad3166d6.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><div class="content"><h1>404</h1><blockquote>There's nothing here.</blockquote><a href="/docs/" class="router-link-active">Take me home.</a></div></div></div>
<script src="/docs/assets/js/app.ad3166d6.js" defer></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13"><g stroke-width="2" stroke="#aaa" fill="none"><path d="M11.29 11.71l-4-4"/><circle cx="5" cy="5" r="4"/></g></svg>

Before

Width:  |  Height:  |  Size: 216 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{161:function(t,e,s){"use strict";s.r(e);var n=s(0),i=Object(n.a)({},(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"content"},[e("h1",{attrs:{id:"更新历史"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#更新历史","aria-hidden":"true"}},[this._v("#")]),this._v(" 更新历史")]),e("ul",[e("li",[this._v("2020/1/27\n1.0完成")])])])}],!1,null,null,null);e.default=i.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{164:function(t,n,e){"use strict";e.r(n);var s=e(0),c=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"content"})}),[],!1,null,null,null);n.default=c.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{165:function(s,a,t){"use strict";t.r(a);var e=t(0),n=Object(e.a)({},(function(){var s=this.$createElement;this._self._c;return this._m(0)}),[function(){var s=this,a=s.$createElement,t=s._self._c||a;return t("div",{staticClass:"content"},[t("h1",{attrs:{id:"jessica"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#jessica","aria-hidden":"true"}},[s._v("#")]),s._v(" Jessica")]),t("p",[s._v("该插件为基于WebSocket协议传输音视频的订阅者音视频数据以裸数据的形式进行传输我们需要Jessibuca播放器来进行播放\nJessibua播放器已内置于源码中该播放器通过js解码H264并用canvas进行渲染可以运行在几乎所有的终端浏览器上面。\n在Monibuca的Web界面中预览功能就是使用的Jessibuca播放器。")]),t("h2",{attrs:{id:"配置"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#配置","aria-hidden":"true"}},[s._v("#")]),s._v(" 配置")]),t("p",[s._v("目前仅有的配置是监听的端口号")]),t("div",{staticClass:"language-toml extra-class"},[t("pre",{pre:!0,attrs:{class:"language-toml"}},[t("code",[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token table class-name"}},[s._v("Plugins.Jessica")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token key property"}},[s._v("ListenAddr")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v('":8080"')]),s._v("\n")])])])])}],!1,null,null,null);a.default=n.exports}}]);

File diff suppressed because one or more lines are too long

View File

@@ -1,173 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>插件开发 | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.ad3166d6.css" as="style"><link rel="preload" href="/docs/assets/js/app.ad3166d6.js" as="script"><link rel="preload" href="/docs/assets/js/2.142d04d2.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.83ce04b6.js"><link rel="prefetch" href="/docs/assets/js/3.2b6c987b.js"><link rel="prefetch" href="/docs/assets/js/4.ad90d74a.js"><link rel="prefetch" href="/docs/assets/js/5.36121818.js">
<link rel="stylesheet" href="/docs/assets/css/styles.ad3166d6.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">起步</a></li><li><a href="/docs/develop.html" class="active sidebar-link">插件开发</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/develop.html#插件的定义" class="sidebar-link">插件的定义</a></li><li class="sidebar-sub-header"><a href="/docs/develop.html#插件的安装" class="sidebar-link">插件的安装</a></li><li class="sidebar-sub-header"><a href="/docs/develop.html#开发订阅者插件" class="sidebar-link">开发订阅者插件</a></li><li class="sidebar-sub-header"><a href="/docs/develop.html#开发发布者插件" class="sidebar-link">开发发布者插件</a></li><li class="sidebar-sub-header"><a href="/docs/develop.html#开发钩子插件" class="sidebar-link">开发钩子插件</a></li></ul></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"><h1 id="插件开发"><a href="#插件开发" aria-hidden="true" class="header-anchor">#</a> 插件开发</h1><h2 id="插件的定义"><a href="#插件的定义" aria-hidden="true" class="header-anchor">#</a> 插件的定义</h2><p>所谓的插件,没有什么固定的规则,只需要完成<code>安装</code>操作即可。插件可以实现任意的功能扩展,最常见的是实现某种传输协议用来推流或者拉流</p><h2 id="插件的安装"><a href="#插件的安装" aria-hidden="true" class="header-anchor">#</a> 插件的安装</h2><p>下面是内置插件jessica的源码代表了典型的插件安装</p><div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">package</span> jessica
<span class="token keyword">import</span> <span class="token punctuation">(</span>
<span class="token punctuation">.</span> <span class="token string">&quot;github.com/langhuihui/monibuca/monica&quot;</span>
<span class="token string">&quot;log&quot;</span>
<span class="token string">&quot;net/http&quot;</span>
<span class="token punctuation">)</span>
<span class="token keyword">var</span> config <span class="token operator">=</span> <span class="token function">new</span><span class="token punctuation">(</span>ListenerConfig<span class="token punctuation">)</span>
<span class="token keyword">func</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">InstallPlugin</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>PluginConfig<span class="token punctuation">{</span>
Name<span class="token punctuation">:</span> <span class="token string">&quot;Jessica&quot;</span><span class="token punctuation">,</span>
Type<span class="token punctuation">:</span> PLUGIN_SUBSCRIBER<span class="token punctuation">,</span>
Config<span class="token punctuation">:</span> config<span class="token punctuation">,</span>
Run<span class="token punctuation">:</span> run<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;server Jessica start at %s&quot;</span><span class="token punctuation">,</span> config<span class="token punctuation">.</span>ListenAddr<span class="token punctuation">)</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span>config<span class="token punctuation">.</span>ListenAddr<span class="token punctuation">,</span> http<span class="token punctuation">.</span><span class="token function">HandlerFunc</span><span class="token punctuation">(</span>WsHandler<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>当主程序读取配置文件完成解析后会调用各个插件的Run函数上面代码中执行了一个http的端口监听</p><h2 id="开发订阅者插件"><a href="#开发订阅者插件" aria-hidden="true" class="header-anchor">#</a> 开发订阅者插件</h2><p>所谓订阅者就是用来从流媒体服务器接收音视频流的程序例如RTMP协议执行play命令后、http-flv请求响应程序、websocket响应程序。内置插件中录制flv程序也是一个特殊的订阅者。
下面是http-flv插件的源码供参考</p><div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">package</span> HDL
<span class="token keyword">import</span> <span class="token punctuation">(</span>
<span class="token punctuation">.</span> <span class="token string">&quot;github.com/langhuihui/monibuca/monica&quot;</span>
<span class="token string">&quot;github.com/langhuihui/monibuca/monica/avformat&quot;</span>
<span class="token string">&quot;github.com/langhuihui/monibuca/monica/pool&quot;</span>
<span class="token string">&quot;log&quot;</span>
<span class="token string">&quot;net/http&quot;</span>
<span class="token string">&quot;strings&quot;</span>
<span class="token punctuation">)</span>
<span class="token keyword">var</span> config <span class="token operator">=</span> <span class="token function">new</span><span class="token punctuation">(</span>ListenerConfig<span class="token punctuation">)</span>
<span class="token keyword">func</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">InstallPlugin</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>PluginConfig<span class="token punctuation">{</span>
Name<span class="token punctuation">:</span> <span class="token string">&quot;HDL&quot;</span><span class="token punctuation">,</span>
Type<span class="token punctuation">:</span> PLUGIN_SUBSCRIBER<span class="token punctuation">,</span>
Config<span class="token punctuation">:</span> config<span class="token punctuation">,</span>
Run<span class="token punctuation">:</span> run<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;HDL start at %s&quot;</span><span class="token punctuation">,</span> config<span class="token punctuation">.</span>ListenAddr<span class="token punctuation">)</span>
log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span>config<span class="token punctuation">.</span>ListenAddr<span class="token punctuation">,</span> http<span class="token punctuation">.</span><span class="token function">HandlerFunc</span><span class="token punctuation">(</span>HDLHandler<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">HDLHandler</span><span class="token punctuation">(</span>w http<span class="token punctuation">.</span>ResponseWriter<span class="token punctuation">,</span> r <span class="token operator">*</span>http<span class="token punctuation">.</span>Request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
sign <span class="token operator">:=</span> r<span class="token punctuation">.</span>URL<span class="token punctuation">.</span><span class="token function">Query</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">&quot;sign&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> AuthHooks<span class="token punctuation">.</span><span class="token function">Trigger</span><span class="token punctuation">(</span>sign<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
w<span class="token punctuation">.</span><span class="token function">WriteHeader</span><span class="token punctuation">(</span><span class="token number">403</span><span class="token punctuation">)</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
stringPath <span class="token operator">:=</span> strings<span class="token punctuation">.</span><span class="token function">TrimLeft</span><span class="token punctuation">(</span>r<span class="token punctuation">.</span>RequestURI<span class="token punctuation">,</span> <span class="token string">&quot;/&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> strings<span class="token punctuation">.</span><span class="token function">HasSuffix</span><span class="token punctuation">(</span>stringPath<span class="token punctuation">,</span> <span class="token string">&quot;.flv&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
stringPath <span class="token operator">=</span> strings<span class="token punctuation">.</span><span class="token function">TrimRight</span><span class="token punctuation">(</span>stringPath<span class="token punctuation">,</span> <span class="token string">&quot;.flv&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token boolean">_</span><span class="token punctuation">,</span> ok <span class="token operator">:=</span> AllRoom<span class="token punctuation">.</span><span class="token function">Load</span><span class="token punctuation">(</span>stringPath<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span>
<span class="token comment">//atomic.AddInt32(&amp;hdlId, 1)</span>
w<span class="token punctuation">.</span><span class="token function">Header</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Set</span><span class="token punctuation">(</span><span class="token string">&quot;Transfer-Encoding&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;chunked&quot;</span><span class="token punctuation">)</span>
w<span class="token punctuation">.</span><span class="token function">Header</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Set</span><span class="token punctuation">(</span><span class="token string">&quot;Content-Type&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;video/x-flv&quot;</span><span class="token punctuation">)</span>
w<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span>avformat<span class="token punctuation">.</span>FLVHeader<span class="token punctuation">)</span>
p <span class="token operator">:=</span> OutputStream<span class="token punctuation">{</span>
Sign<span class="token punctuation">:</span> sign<span class="token punctuation">,</span>
SendHandler<span class="token punctuation">:</span> <span class="token keyword">func</span><span class="token punctuation">(</span>packet <span class="token operator">*</span>pool<span class="token punctuation">.</span>SendPacket<span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> avformat<span class="token punctuation">.</span><span class="token function">WriteFLVTag</span><span class="token punctuation">(</span>w<span class="token punctuation">,</span> packet<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
SubscriberInfo<span class="token punctuation">:</span> SubscriberInfo<span class="token punctuation">{</span>
ID<span class="token punctuation">:</span> r<span class="token punctuation">.</span>RemoteAddr<span class="token punctuation">,</span> Type<span class="token punctuation">:</span> <span class="token string">&quot;FLV&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
p<span class="token punctuation">.</span><span class="token function">Play</span><span class="token punctuation">(</span>stringPath<span class="token punctuation">)</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
w<span class="token punctuation">.</span><span class="token function">WriteHeader</span><span class="token punctuation">(</span><span class="token number">404</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>其中核心逻辑就是创建OutputStream对象每一个订阅者需要提供SendHandler函数用来接收来自发布者广播出来的音视频数据。
最后调用该对象的Play函数进行播放。请注意Play函数会阻塞当前goroutine。</p><h2 id="开发发布者插件"><a href="#开发发布者插件" aria-hidden="true" class="header-anchor">#</a> 开发发布者插件</h2><p>所谓发布者就是提供音视频数据的程序例如接收来自OBS、ffmpeg的推流的程序。内置插件中集群功能里面有一个特殊的发布者它接收来自源服务器的音视频数据然后在本服务器中广播音视频。
以此为例,我们需要提供一个结构体定义来表示特定的发布者:</p><div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">type</span> Receiver <span class="token keyword">struct</span> <span class="token punctuation">{</span>
InputStream
io<span class="token punctuation">.</span>Reader
<span class="token operator">*</span>bufio<span class="token punctuation">.</span>Writer
<span class="token punctuation">}</span>
</code></pre></div><p>其中InputStream 是固定的,必须包含,且必须以组合继承的方式定义。其余的成员则是任意的。
发布者的发布动作需要特定条件的触发,例如在集群插件中,当本服务器有订阅者订阅了某个流,而该流并没有发布者的时候就会触发向源服务器拉流的函数:</p><div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">PullUpStream</span><span class="token punctuation">(</span>streamPath <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
addr<span class="token punctuation">,</span> err <span class="token operator">:=</span> net<span class="token punctuation">.</span><span class="token function">ResolveTCPAddr</span><span class="token punctuation">(</span><span class="token string">&quot;tcp&quot;</span><span class="token punctuation">,</span> config<span class="token punctuation">.</span>Master<span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token function">MayBeError</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
conn<span class="token punctuation">,</span> err <span class="token operator">:=</span> net<span class="token punctuation">.</span><span class="token function">DialTCP</span><span class="token punctuation">(</span><span class="token string">&quot;tcp&quot;</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> addr<span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token function">MayBeError</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
brw <span class="token operator">:=</span> bufio<span class="token punctuation">.</span><span class="token function">NewReadWriter</span><span class="token punctuation">(</span>bufio<span class="token punctuation">.</span><span class="token function">NewReader</span><span class="token punctuation">(</span>conn<span class="token punctuation">)</span><span class="token punctuation">,</span> bufio<span class="token punctuation">.</span><span class="token function">NewWriter</span><span class="token punctuation">(</span>conn<span class="token punctuation">)</span><span class="token punctuation">)</span>
p <span class="token operator">:=</span> <span class="token operator">&amp;</span>Receiver<span class="token punctuation">{</span>
Reader<span class="token punctuation">:</span> conn<span class="token punctuation">,</span>
Writer<span class="token punctuation">:</span> brw<span class="token punctuation">.</span>Writer<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> p<span class="token punctuation">.</span><span class="token function">Publish</span><span class="token punctuation">(</span>streamPath<span class="token punctuation">,</span> p<span class="token punctuation">)</span> <span class="token punctuation">{</span>
p<span class="token punctuation">.</span><span class="token function">WriteByte</span><span class="token punctuation">(</span>MSG_SUBSCRIBE<span class="token punctuation">)</span>
p<span class="token punctuation">.</span><span class="token function">WriteString</span><span class="token punctuation">(</span>streamPath<span class="token punctuation">)</span>
p<span class="token punctuation">.</span><span class="token function">WriteByte</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
p<span class="token punctuation">.</span><span class="token function">Flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> v <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>Subscribers <span class="token punctuation">{</span>
p<span class="token punctuation">.</span><span class="token function">Auth</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">defer</span> p<span class="token punctuation">.</span><span class="token function">Cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token punctuation">{</span>
cmd<span class="token punctuation">,</span> err <span class="token operator">:=</span> brw<span class="token punctuation">.</span><span class="token function">ReadByte</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token function">MayBeError</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">switch</span> cmd <span class="token punctuation">{</span>
<span class="token keyword">case</span> MSG_AUDIO<span class="token punctuation">:</span>
<span class="token keyword">if</span> audio<span class="token punctuation">,</span> err <span class="token operator">:=</span> p<span class="token punctuation">.</span><span class="token function">readAVPacket</span><span class="token punctuation">(</span>avformat<span class="token punctuation">.</span>FLV_TAG_TYPE_AUDIO<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
p<span class="token punctuation">.</span><span class="token function">PushAudio</span><span class="token punctuation">(</span>audio<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">case</span> MSG_VIDEO<span class="token punctuation">:</span>
<span class="token keyword">if</span> video<span class="token punctuation">,</span> err <span class="token operator">:=</span> p<span class="token punctuation">.</span><span class="token function">readAVPacket</span><span class="token punctuation">(</span>avformat<span class="token punctuation">.</span>FLV_TAG_TYPE_VIDEO<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token operator">&amp;&amp;</span> <span class="token function">len</span><span class="token punctuation">(</span>video<span class="token punctuation">.</span>Payload<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">2</span> <span class="token punctuation">{</span>
tmp <span class="token operator">:=</span> video<span class="token punctuation">.</span>Payload<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token comment">// 第一个字节保存着视频的相关信息.</span>
video<span class="token punctuation">.</span>VideoFrameType <span class="token operator">=</span> tmp <span class="token operator">&gt;&gt;</span> <span class="token number">4</span> <span class="token comment">// 帧类型 4Bit, H264一般为1或者2</span>
p<span class="token punctuation">.</span><span class="token function">PushVideo</span><span class="token punctuation">(</span>video<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">case</span> MSG_AUTH<span class="token punctuation">:</span>
cmd<span class="token punctuation">,</span> err <span class="token operator">=</span> brw<span class="token punctuation">.</span><span class="token function">ReadByte</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token function">MayBeError</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
bytes<span class="token punctuation">,</span> err <span class="token operator">:=</span> brw<span class="token punctuation">.</span><span class="token function">ReadBytes</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token function">MayBeError</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
subId <span class="token operator">:=</span> strings<span class="token punctuation">.</span><span class="token function">Split</span><span class="token punctuation">(</span><span class="token function">string</span><span class="token punctuation">(</span>bytes<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">:</span><span class="token function">len</span><span class="token punctuation">(</span>bytes<span class="token punctuation">)</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">&quot;,&quot;</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
<span class="token keyword">if</span> v<span class="token punctuation">,</span> ok <span class="token operator">:=</span> p<span class="token punctuation">.</span>Subscribers<span class="token punctuation">[</span>subId<span class="token punctuation">]</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span>
<span class="token keyword">if</span> cmd <span class="token operator">!=</span> <span class="token number">1</span> <span class="token punctuation">{</span>
v<span class="token punctuation">.</span><span class="token function">Cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>正在该函数中会向源服务器建立tcp连接然后发送特定命令表示需要拉流当我们接收到源服务器的数据的时候就调用PushVideo和PushAudio函数来广播音视频。</p><p>核心逻辑是调用InputStream的Publish以及PushVideo、PushAudio函数</p><h2 id="开发钩子插件"><a href="#开发钩子插件" aria-hidden="true" class="header-anchor">#</a> 开发钩子插件</h2></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/" class="prev router-link-active">
起步
</a></span><span class="next"><a href="/docs/history.html">
更新日志
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.ad3166d6.js" defer></script><script src="/docs/assets/js/2.142d04d2.js" defer></script>
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>更新历史 | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.ad3166d6.css" as="style"><link rel="preload" href="/docs/assets/js/app.ad3166d6.js" as="script"><link rel="preload" href="/docs/assets/js/3.2b6c987b.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.83ce04b6.js"><link rel="prefetch" href="/docs/assets/js/2.142d04d2.js"><link rel="prefetch" href="/docs/assets/js/4.ad90d74a.js"><link rel="prefetch" href="/docs/assets/js/5.36121818.js">
<link rel="stylesheet" href="/docs/assets/css/styles.ad3166d6.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">起步</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="active sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"><h1 id="更新历史"><a href="#更新历史" aria-hidden="true" class="header-anchor">#</a> 更新历史</h1><ul><li>2020/1/27
1.0完成</li></ul></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/develop.html" class="prev">
插件开发
</a></span><span class="next"><a href="/docs/plugins/jessica.html">
Jessica
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.ad3166d6.js" defer></script><script src="/docs/assets/js/3.2b6c987b.js" defer></script>
</body>
</html>

View File

@@ -1,54 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Monibuca快速起步 | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.ad3166d6.css" as="style"><link rel="preload" href="/docs/assets/js/app.ad3166d6.js" as="script"><link rel="preload" href="/docs/assets/js/1.83ce04b6.js" as="script"><link rel="prefetch" href="/docs/assets/js/2.142d04d2.js"><link rel="prefetch" href="/docs/assets/js/3.2b6c987b.js"><link rel="prefetch" href="/docs/assets/js/4.ad90d74a.js"><link rel="prefetch" href="/docs/assets/js/5.36121818.js">
<link rel="stylesheet" href="/docs/assets/css/styles.ad3166d6.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-exact-active router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="active sidebar-link">起步</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/#介绍" class="sidebar-link">介绍</a></li><li class="sidebar-sub-header"><a href="/docs/#启动" class="sidebar-link">启动</a></li><li class="sidebar-sub-header"><a href="/docs/#配置" class="sidebar-link">配置</a></li></ul></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"><h1 id="monibuca快速起步"><a href="#monibuca快速起步" aria-hidden="true" class="header-anchor">#</a> Monibuca快速起步</h1><h2 id="介绍"><a href="#介绍" aria-hidden="true" class="header-anchor">#</a> 介绍</h2><p>Monibuca 是一个开源的流媒体服务器开发框架适用于快速定制化开发流媒体服务器可以对接CDN厂商作为回源服务器也可以自己搭建集群部署环境。
丰富的内置插件提供了流媒体服务器的常见功能例如rtmp server、http-flv、视频录制、QoS等。除此以外还内置了后台web界面方便观察服务器运行的状态。
也可以自己开发后台管理界面通过api方式获取服务器的运行信息。
Monibuca 提供了可供定制化开发的插件机制,可以任意扩展其功能。</p><h2 id="启动"><a href="#启动" aria-hidden="true" class="header-anchor">#</a> 启动</h2><p>启用所有内置插件</p><div class="language-go extra-class"><pre class="language-go"><code><span class="token keyword">package</span> main
<span class="token keyword">import</span> <span class="token punctuation">(</span>
<span class="token punctuation">.</span> <span class="token string">&quot;github.com/langhuihui/monibuca/monica&quot;</span>
<span class="token boolean">_</span> <span class="token string">&quot;github.com/langhuihui/monibuca/plugins&quot;</span>
<span class="token punctuation">)</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;config.toml&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">select</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="配置"><a href="#配置" aria-hidden="true" class="header-anchor">#</a> 配置</h2><p>要使用<code>Monibuca</code>,需要编写一个<code>toml</code>格式的配置文件,通常可以放在程序的同级目录下例如:<code>config.toml</code>(名称不是必须为<code>config</code>)</p><p>该配置文件主要是为了定制各个插件的配置,例如监听端口号等,具体还是要看各个插件的设计。</p><blockquote><p>如果你编写了自己的插件,就必须在该配置文件中写入对自己插件的配置信息</p></blockquote><p>如果注释掉部分插件的配置,那么该插件就不会启用,典型的配置如下:</p><div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">Plugins.HDL</span><span class="token punctuation">]</span>
<span class="token key property">ListenAddr</span> <span class="token punctuation">=</span> <span class="token string">&quot;:2020&quot;</span>
<span class="token punctuation">[</span><span class="token table class-name">Plugins.Jessica</span><span class="token punctuation">]</span>
<span class="token key property">ListenAddr</span> <span class="token punctuation">=</span> <span class="token string">&quot;:8080&quot;</span>
<span class="token punctuation">[</span><span class="token table class-name">Plugins.RTMP</span><span class="token punctuation">]</span>
<span class="token key property">ListenAddr</span> <span class="token punctuation">=</span> <span class="token string">&quot;:1935&quot;</span>
<span class="token punctuation">[</span><span class="token table class-name">Plugins.GateWay</span><span class="token punctuation">]</span>
<span class="token key property">ListenAddr</span> <span class="token punctuation">=</span> <span class="token string">&quot;:81&quot;</span>
<span class="token comment">#[Plugins.Cluster]</span>
<span class="token comment">#Master = &quot;localhost:2019&quot;</span>
<span class="token comment">#ListenAddr = &quot;:2019&quot;</span>
<span class="token comment">#</span>
<span class="token comment">#[Plugins.Auth]</span>
<span class="token comment">#Key=&quot;www.monibuca.com&quot;</span>
<span class="token comment">#[Plugins.RecordFlv]</span>
<span class="token comment">#Path=&quot;./resouce&quot;</span>
<span class="token punctuation">[</span><span class="token table class-name">Plugins.QoS</span><span class="token punctuation">]</span>
<span class="token key property">Suffix</span> <span class="token punctuation">=</span> <span class="token punctuation">[</span><span class="token string">&quot;high&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;medium&quot;</span><span class="token punctuation">,</span><span class="token string">&quot;low&quot;</span><span class="token punctuation">]</span>
</code></pre></div><p>具体配置的含义,可以参考每个插件的说明</p></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><!----><span class="next"><a href="/docs/develop.html">
插件开发
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.ad3166d6.js" defer></script><script src="/docs/assets/js/1.83ce04b6.js" defer></script>
</body>
</html>

View File

@@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.ad3166d6.css" as="style"><link rel="preload" href="/docs/assets/js/app.ad3166d6.js" as="script"><link rel="preload" href="/docs/assets/js/4.ad90d74a.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.83ce04b6.js"><link rel="prefetch" href="/docs/assets/js/2.142d04d2.js"><link rel="prefetch" href="/docs/assets/js/3.2b6c987b.js"><link rel="prefetch" href="/docs/assets/js/5.36121818.js">
<link rel="stylesheet" href="/docs/assets/css/styles.ad3166d6.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">起步</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"></div><div class="page-edit"><!----><!----></div><!----></div></div></div>
<script src="/docs/assets/js/app.ad3166d6.js" defer></script><script src="/docs/assets/js/4.ad90d74a.js" defer></script>
</body>
</html>

View File

@@ -1,26 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Jessica | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.ad3166d6.css" as="style"><link rel="preload" href="/docs/assets/js/app.ad3166d6.js" as="script"><link rel="preload" href="/docs/assets/js/5.36121818.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.83ce04b6.js"><link rel="prefetch" href="/docs/assets/js/2.142d04d2.js"><link rel="prefetch" href="/docs/assets/js/3.2b6c987b.js"><link rel="prefetch" href="/docs/assets/js/4.ad90d74a.js">
<link rel="stylesheet" href="/docs/assets/css/styles.ad3166d6.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">起步</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading open"><span>内置插件</span><span class="arrow down"></span></p><ul class="sidebar-group-items"><li><a href="/docs/plugins/jessica.html" class="active sidebar-link">Jessica</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/plugins/jessica.html#配置" class="sidebar-link">配置</a></li></ul></li></ul></div></li></ul></div><div class="page"><div class="content"><h1 id="jessica"><a href="#jessica" aria-hidden="true" class="header-anchor">#</a> Jessica</h1><p>该插件为基于WebSocket协议传输音视频的订阅者音视频数据以裸数据的形式进行传输我们需要Jessibuca播放器来进行播放
Jessibua播放器已内置于源码中该播放器通过js解码H264并用canvas进行渲染可以运行在几乎所有的终端浏览器上面。
在Monibuca的Web界面中预览功能就是使用的Jessibuca播放器。</p><h2 id="配置"><a href="#配置" aria-hidden="true" class="header-anchor">#</a> 配置</h2><p>目前仅有的配置是监听的端口号</p><div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">Plugins.Jessica</span><span class="token punctuation">]</span>
<span class="token key property">ListenAddr</span> <span class="token punctuation">=</span> <span class="token string">&quot;:8080&quot;</span>
</code></pre></div></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/history.html" class="prev">
更新日志
</a></span><!----></p></div></div></div></div>
<script src="/docs/assets/js/app.ad3166d6.js" defer></script><script src="/docs/assets/js/5.36121818.js" defer></script>
</body>
</html>

View File

@@ -1,80 +0,0 @@
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js");
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [
{
"url": "404.html",
"revision": "a3d9e915fd09958cab2da343fcad58b0"
},
{
"url": "assets/css/styles.ad3166d6.css",
"revision": "4a6b650244e5b709f84a81ad0565b485"
},
{
"url": "assets/img/search.83621669.svg",
"revision": "83621669651b9a3d4bf64d1a670ad856"
},
{
"url": "assets/js/1.83ce04b6.js",
"revision": "3cabebb5c79c8280aee24ac6e4545650"
},
{
"url": "assets/js/2.142d04d2.js",
"revision": "027f4f643a10a465692035fe692cd94f"
},
{
"url": "assets/js/3.2b6c987b.js",
"revision": "27a988ab518e3f04db65045269d55841"
},
{
"url": "assets/js/4.ad90d74a.js",
"revision": "dcbfc54b67e9e6e33dbb2a303e842bdc"
},
{
"url": "assets/js/5.36121818.js",
"revision": "550520f0f388530dfbc4cc40a3dee264"
},
{
"url": "assets/js/app.ad3166d6.js",
"revision": "fdeb68e4b7b08c2c7bdcaf7462f34b16"
},
{
"url": "develop.html",
"revision": "f7461297bdc3ce303d517f0fc6dedd78"
},
{
"url": "history.html",
"revision": "c4ba2b13246f7a9e0039852fe381de6e"
},
{
"url": "index.html",
"revision": "3371a6066d0c2229a521d0659f25b174"
},
{
"url": "plugins/index.html",
"revision": "511b5cef98368f5f0ab35e667766e367"
},
{
"url": "plugins/jessica.html",
"revision": "65ca2965d5d514441d64b4d5e38cd696"
}
].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

View File

@@ -1 +0,0 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Monibuca</title><script src=jessibuca/ajax.js></script><script src=jessibuca/renderer.js></script><link href=/css/app.e2fa93b0.css rel=preload as=style><link href=/css/chunk-vendors.22ebf426.css rel=preload as=style><link href=/js/app.d106a496.js rel=preload as=script><link href=/js/chunk-vendors.ae8ac63d.js rel=preload as=script><link href=/css/chunk-vendors.22ebf426.css rel=stylesheet><link href=/css/app.e2fa93b0.css rel=stylesheet></head><body><noscript><strong>We're sorry but dashboard doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.ae8ac63d.js></script><script src=/js/app.d106a496.js></script></body></html>

View File

@@ -1,535 +0,0 @@
// a simple ajax
!(function () {
var jsonType = 'application/json';
var htmlType = 'text/html';
var xmlTypeRE = /^(?:text|application)\/xml/i;
var blankRE = /^\s*$/; // \s
/*
* default setting
* */
var _settings = {
type: "GET",
beforeSend: noop,
success: noop,
error: noop,
complete: noop,
context: null,
xhr: function () {
return new window.XMLHttpRequest();
},
accepts: {
json: jsonType,
xml: 'application/xml, text/xml',
html: htmlType,
text: 'text/plain'
},
crossDomain: false,
timeout: 0,
username: null,
password: null,
processData: true,
promise: noop
};
function noop() {
}
var ajax = function (options) {
//
var settings = extend({}, options || {});
//
for (var key in _settings) {
if (settings[key] === undefined) {
settings[key] = _settings[key];
}
}
//
try {
var q = {};
var promise = new Promise(function (resolve, reject) {
q.resolve = resolve;
q.reject = reject;
});
promise.resolve = q.resolve;
promise.reject = q.reject;
settings.promise = promise;
}
catch (e) {
//
settings.promise = {
resolve: noop,
reject: noop
};
}
//
if (!settings.crossDomain) {
settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) && RegExp.$2 !== window.location.href;
}
var dataType = settings.dataType;
// jsonp
if (dataType === 'jsonp') {
//
var hasPlaceholder = /=\?/.test(settings.url);
if (!hasPlaceholder) {
var jsonpCallback = (settings.jsonp || 'callback') + '=?';
settings.url = appendQuery(settings.url, jsonpCallback)
}
return JSONP(settings);
}
// url
if (!settings.url) {
settings.url = window.location.toString();
}
//
serializeData(settings);
var mime = settings.accepts[dataType]; // mime
var baseHeader = {}; // header
var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol; // protocol
var xhr = _settings.xhr();
var abortTimeout;
// X-Requested-With header
// For cross-domain requests, seeing as conditions for a preflight are
// akin to a jigsaw puzzle, we simply never set it to be sure.
// (it can always be set on a per-request basis or even using ajaxSetup)
// For same-domain requests, won't change header if already provided.
if (!settings.crossDomain && !baseHeader['X-Requested-With']) {
baseHeader['X-Requested-With'] = 'XMLHttpRequest';
}
// mime
if (mime) {
//
baseHeader['Accept'] = mime;
if (mime.indexOf(',') > -1) {
mime = mime.split(',', 2)[0]
}
//
xhr.overrideMimeType && xhr.overrideMimeType(mime);
}
// contentType
if (settings.contentType || (settings.data && settings.type.toUpperCase() !== 'GET')) {
baseHeader['Content-Type'] = (settings.contentType || 'application/x-www-form-urlencoded; charset=UTF-8');
}
// headers
settings.headers = extend(baseHeader, settings.headers || {});
// on ready state change
xhr.onreadystatechange = function () {
// readystate
if (xhr.readyState === 4) {
clearTimeout(abortTimeout);
var result;
var error = false;
//
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
dataType = dataType || mimeToDataType(xhr.getResponseHeader('content-type'));
result = xhr.responseText;
try {
// xml
if (dataType === 'xml') {
result = xhr.responseXML;
}
// json
else if (dataType === 'json') {
result = blankRE.test(result) ? null : JSON.parse(result);
}
}
catch (e) {
error = e;
}
if (error) {
ajaxError(error, 'parseerror', xhr, settings);
}
else {
ajaxSuccess(result, xhr, settings);
}
}
else {
ajaxError(null, 'error', xhr, settings);
}
}
};
// async
var async = 'async' in settings ? settings.async : true;
// open
xhr.open(settings.type, settings.url, async, settings.username, settings.password);
// xhrFields
if (settings.xhrFields) {
for (var name in settings.xhrFields) {
xhr[name] = settings.xhrFields[name];
}
}
// Override mime type if needed
if (settings.mimeType && xhr.overrideMimeType) {
xhr.overrideMimeType(settings.mimeType);
}
// set request header
for (var name in settings.headers) {
// Support: IE<9
// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
// request header to a null-value.
//
// To keep consistent with other XHR implementations, cast the value
// to string and ignore `undefined`.
if (settings.headers[name] !== undefined) {
xhr.setRequestHeader(name, settings.headers[name] + "");
}
}
// before send
if (ajaxBeforeSend(xhr, settings) === false) {
xhr.abort();
return false;
}
// timeout
if (settings.timeout > 0) {
abortTimeout = window.setTimeout(function () {
xhr.onreadystatechange = noop;
xhr.abort();
ajaxError(null, 'timeout', xhr, settings);
}, settings.timeout);
}
// send
xhr.send(settings.data ? settings.data : null);
return settings.promise;
};
/*
* method get
* */
ajax.get = function (url, data, success, dataType) {
if (isFunction(data)) {
dataType = dataType || success;
success = data;
data = undefined;
}
return ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
};
/*
* method post
*
* dataType:
* */
ajax.post = function (url, data, success, dataType) {
if (isFunction(data)) {
dataType = dataType || success;
success = data;
data = undefined;
}
return ajax({
type: 'POST',
url: url,
data: data,
success: success,
dataType: dataType
})
};
/*
* method getJSON
* */
ajax.getJSON = function (url, data, success) {
if (isFunction(data)) {
success = data;
data = undefined;
}
return ajax({
url: url,
data: data,
success: success,
dataType: 'json'
})
};
/*
* method ajaxSetup
* */
ajax.ajaxSetup = function (target, settings) {
return settings ? extend(extend(target, _settings), settings) : extend(_settings, target);
};
/*
* utils
*
* */
// triggers and extra global event ajaxBeforeSend that's like ajaxSend but cancelable
function ajaxBeforeSend(xhr, settings) {
var context = settings.context;
//
if (settings.beforeSend.call(context, xhr, settings) === false) {
return false;
}
}
// ajax success
function ajaxSuccess(data, xhr, settings) {
var context = settings.context;
var status = 'success';
settings.success.call(context, data, status, xhr);
settings.promise.resolve(data, status, xhr);
ajaxComplete(status, xhr, settings);
}
// status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
function ajaxComplete(status, xhr, settings) {
var context = settings.context;
settings.complete.call(context, xhr, status);
}
// type: "timeout", "error", "abort", "parsererror"
function ajaxError(error, type, xhr, settings) {
var context = settings.context;
settings.error.call(context, xhr, type, error);
settings.promise.reject(xhr, type, error);
ajaxComplete(type, xhr, settings);
}
// jsonp
/*
* tks: https://www.cnblogs.com/rubylouvre/archive/2011/02/13/1953087.html
* */
function JSONP(options) {
//
var callbackName = options.jsonpCallback || 'jsonp' + (new Date().getTime());
var script = window.document.createElement('script');
var abort = function () {
// 设置 window.xxx = noop
if (callbackName in window) {
window[callbackName] = noop;
}
};
var xhr = {abort: abort};
var abortTimeout;
var head = window.document.getElementsByTagName('head')[0] || window.document.documentElement;
// ie8+
script.onerror = function (error) {
_error(error);
};
function _error(error) {
window.clearTimeout(abortTimeout);
xhr.abort();
ajaxError(error.type, xhr, error.type, options);
_removeScript();
}
window[callbackName] = function (data) {
window.clearTimeout(abortTimeout);
ajaxSuccess(data, xhr, options);
_removeScript();
};
//
serializeData(options);
script.src = options.url.replace(/=\?/, '=' + callbackName);
//
script.src = appendQuery(script.src, '_=' + (new Date()).getTime());
//
script.async = true;
// script charset
if (options.scriptCharset) {
script.charset = options.scriptCharset;
}
//
head.insertBefore(script, head.firstChild);
//
if (options.timeout > 0) {
abortTimeout = window.setTimeout(function () {
xhr.abort();
ajaxError('timeout', xhr, 'timeout', options);
_removeScript();
}, options.timeout);
}
// remove script
function _removeScript() {
if (script.clearAttributes) {
script.clearAttributes();
} else {
script.onload = script.onreadystatechange = script.onerror = null;
}
if (script.parentNode) {
script.parentNode.removeChild(script);
}
//
script = null;
delete window[callbackName];
}
return options.promise;
}
// mime to data type
function mimeToDataType(mime) {
return mime && (mime === htmlType ? 'html' : mime === jsonType ? 'json' : xmlTypeRE.test(mime) && 'xml') || 'text'
}
// append query
function appendQuery(url, query) {
return (url + '&' + query).replace(/[&?]{1,2}/, '?');
}
// serialize data
function serializeData(options) {
// formData
if (isObject(options) && !isFormData(options.data) && options.processData) {
options.data = param(options.data);
}
if (options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
options.url = appendQuery(options.url, options.data);
}
}
// serialize
function serialize(params, obj, traditional, scope) {
var _isArray = isArray(obj);
for (var key in obj) {
var value = obj[key];
if (scope) {
key = traditional ? scope : scope + '[' + (_isArray ? '' : key) + ']';
}
// handle data in serializeArray format
if (!scope && _isArray) {
params.add(value.name, value.value);
}
else if (traditional ? _isArray(value) : isObject(value)) {
serialize(params, value, traditional, key);
}
else {
params.add(key, value);
}
}
}
// param
function param(obj, traditional) {
var params = [];
//
params.add = function (k, v) {
this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
};
serialize(params, obj, traditional);
return params.join('&').replace('%20', '+');
}
// extend
function extend(target) {
var slice = Array.prototype.slice;
var args = slice.call(arguments, 1);
//
for (var i = 0, length = args.length; i < length; i++) {
var source = args[i] || {};
for (var key in source) {
if (source.hasOwnProperty(key) && source[key] !== undefined) {
target[key] = source[key];
}
}
}
return target;
}
// is object
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
// is formData
function isFormData(obj) {
return obj instanceof FormData;
}
// is array
function isArray(value) {
return Object.prototype.toString.call(value) === "[object Array]";
}
// is function
function isFunction(value) {
return typeof value === "function";
}
// browser
window.ajax = ajax;
})();

File diff suppressed because one or more lines are too long

View File

@@ -1,460 +0,0 @@
function Jessibuca(opt) {
this.canvasElement = opt.canvas;
this.contextOptions = opt.contextOptions;
this.videoBuffer = opt.videoBuffer || 1
if (!opt.forceNoGL) this.initContextGL();
if (this.contextGL) {
this.initProgram();
this.initBuffers();
this.initTextures();
};
this.decoderWorker = new Worker(opt.decoder || '264_mp3.js')
var _this = this
function draw(output) {
_this.drawNextOutputPicture(_this.width, _this.height, null, output)
postMessage({ cmd: "setBuffer", buffer: output }, '*', [output[0].buffer, output[1].buffer, output[2].buffer])
}
this.decoderWorker.onmessage = function (event) {
var msg = event.data
switch (msg.cmd) {
case "init":
console.log("decoder worker init")
postMessage({ cmd: "setVideoBuffer", time: _this.videoBuffer }, "*")
if (_this.onLoad) {
_this.onLoad()
delete _this.onLoad;
}
break
case "initSize":
_this.width = msg.w
_this.height = msg.h
if (_this.isWebGL()) {
// var buffer = new ArrayBuffer(msg.w * msg.h + (msg.w * msg.h >> 1))
// this.postMessage({ cmd: "setBuffer", buffer: buffer }, [buffer])
}
else {
_this.initRGB(msg.w, msg.h)
}
break
case "render":
if (_this.onPlay) {
_this.onPlay()
delete _this.onPlay;
}
// if (msg.compositionTime) {
// console.log(msg.compositionTime)
// setTimeout(draw, msg.compositionTime, msg.output)
// } else {
// draw(msg.output)
// }
draw(msg.output)
break
case "initAudio":
_this.initAudioPlay(msg.frameCount, msg.samplerate, msg.channels)
break
case "playAudio":
_this.playAudio(msg.buffer)
break
case "print":
console.log(msg.text);
break
case "printErr":
console.error(msg.text);
break
}
}
};
window.AudioContext = window.AudioContext || window.webkitAudioContext;
function _unlock() {
var context = Jessibuca.prototype.audioContext = Jessibuca.prototype.audioContext || new window.AudioContext();
context.resume();
var source = context.createBufferSource();
source.buffer = context.createBuffer(1, 1, 22050);
source.connect(context.destination);
if (source.noteOn)
source.noteOn(0);
else
source.start(0);
}
// document.addEventListener("mousedown", _unlock, true);
// document.addEventListener("touchend", _unlock, true);
Jessibuca.prototype.audioEnabled = function (flag) {
if (flag) {
_unlock()
this.audioEnabled = function (flag) {
if (flag) {
this.audioContext.resume();
} else {
this.audioContext.suspend();
}
}
}
}
Jessibuca.prototype.playAudio = function (data) {
var context = this.audioContext;
var isPlaying = false;
var isDecoding = false;
if (!context) return false;
var audioBuffers = [];
var decodeQueue = []
var _this = this
var playNextBuffer = function (e) {
// isPlaying = false;
if (audioBuffers.length) {
playBuffer(audioBuffers.shift())
}
//if (audioBuffers.length > 1) audioBuffers.shift();
};
var playBuffer = function (buffer) {
isPlaying = true;
var audioBufferSouceNode = context.createBufferSource();
audioBufferSouceNode.buffer = buffer;
audioBufferSouceNode.connect(context.destination);
// audioBufferSouceNode.onended = playNextBuffer;
audioBufferSouceNode.start();
if (!_this.audioInterval) {
_this.audioInterval = setInterval(playNextBuffer, buffer.duration * 1000 - 1);
}
// setTimeout(playNextBuffer, buffer.duration * 1000)
}
var tryPlay = function (buffer) {
if (decodeQueue.length) {
context.decodeAudioData(decodeQueue.shift(), tryPlay, console.error);
} else {
isDecoding = false
}
if (isPlaying) {
audioBuffers.push(buffer);
} else {
playBuffer(buffer)
}
}
var playAudio = function (data) {
decodeQueue.push(...data)
if (!isDecoding) {
isDecoding = true
context.decodeAudioData(decodeQueue.shift(), tryPlay, console.error);
}
}
this.playAudio = playAudio
playAudio(data)
}
Jessibuca.prototype.initAudioPlay = function (frameCount, samplerate, channels) {
var context = this.audioContext;
var isPlaying = false;
var audioBuffers = [];
if (!context) return false;
var resampled = samplerate < 22050;
var audioBuffer = resampled ? context.createBuffer(channels, frameCount << 1, samplerate << 1) : context.createBuffer(channels, frameCount, samplerate);
var playNextBuffer = function () {
isPlaying = false;
console.log("~", audioBuffers.length)
if (audioBuffers.length) {
playAudio(audioBuffers.shift());
}
//if (audioBuffers.length > 1) audioBuffers.shift();
};
var copyToCtxBuffer = channels > 1 ? function (fromBuffer) {
for (var channel = 0; channel < channels; channel++) {
var nowBuffering = audioBuffer.getChannelData(channel);
if (resampled) {
for (var i = 0; i < frameCount; i++) {
nowBuffering[i * 2] = nowBuffering[i * 2 + 1] = fromBuffer[i * (channel + 1)] / 32768;
}
} else
for (var i = 0; i < frameCount; i++) {
nowBuffering[i] = fromBuffer[i * (channel + 1)] / 32768;
}
}
} : function (fromBuffer) {
var nowBuffering = audioBuffer.getChannelData(0);
for (var i = 0; i < nowBuffering.length; i++) {
nowBuffering[i] = fromBuffer[i] / 32768;
}
// nowBuffering.set(fromBuffer);
};
var playAudio = function (fromBuffer) {
if (isPlaying) {
audioBuffers.push(fromBuffer);
console.log(audioBuffers.length)
return;
}
isPlaying = true;
copyToCtxBuffer(fromBuffer);
var source = context.createBufferSource();
source.buffer = audioBuffer;
source.connect(context.destination);
source.onended = playNextBuffer;
//setTimeout(playNextBuffer, audioBufferTime-audioBuffers.length*200);
source.start();
};
this.playAudio = playAudio;
}
/**
* Returns true if the canvas supports WebGL
*/
Jessibuca.prototype.isWebGL = function () {
return !!this.contextGL;
};
/**
* Create the GL context from the canvas element
*/
Jessibuca.prototype.initContextGL = function () {
var canvas = this.canvasElement;
var gl = null;
var validContextNames = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"];
var nameIndex = 0;
while (!gl && nameIndex < validContextNames.length) {
var contextName = validContextNames[nameIndex];
try {
if (this.contextOptions) {
gl = canvas.getContext(contextName, this.contextOptions);
} else {
gl = canvas.getContext(contextName);
};
} catch (e) {
gl = null;
}
if (!gl || typeof gl.getParameter !== "function") {
gl = null;
}
++nameIndex;
};
this.contextGL = gl;
};
/**
* Initialize GL shader program
*/
Jessibuca.prototype.initProgram = function () {
var gl = this.contextGL;
var vertexShaderScript = [
'attribute vec4 vertexPos;',
'attribute vec4 texturePos;',
'varying vec2 textureCoord;',
'void main()',
'{',
'gl_Position = vertexPos;',
'textureCoord = texturePos.xy;',
'}'
].join('\n');
var fragmentShaderScript = [
'precision highp float;',
'varying highp vec2 textureCoord;',
'uniform sampler2D ySampler;',
'uniform sampler2D uSampler;',
'uniform sampler2D vSampler;',
'const mat4 YUV2RGB = mat4',
'(',
'1.1643828125, 0, 1.59602734375, -.87078515625,',
'1.1643828125, -.39176171875, -.81296875, .52959375,',
'1.1643828125, 2.017234375, 0, -1.081390625,',
'0, 0, 0, 1',
');',
'void main(void) {',
'highp float y = texture2D(ySampler, textureCoord).r;',
'highp float u = texture2D(uSampler, textureCoord).r;',
'highp float v = texture2D(vSampler, textureCoord).r;',
'gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;',
'}'
].join('\n');
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderScript);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.log('Vertex shader failed to compile: ' + gl.getShaderInfoLog(vertexShader));
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderScript);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.log('Fragment shader failed to compile: ' + gl.getShaderInfoLog(fragmentShader));
}
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.log('Program failed to compile: ' + gl.getProgramInfoLog(program));
}
gl.useProgram(program);
this.shaderProgram = program;
};
/**
* Initialize vertex buffers and attach to shader program
*/
Jessibuca.prototype.initBuffers = function () {
var gl = this.contextGL;
var program = this.shaderProgram;
var vertexPosBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, -1, 1, 1, -1, -1, -1]), gl.STATIC_DRAW);
var vertexPosRef = gl.getAttribLocation(program, 'vertexPos');
gl.enableVertexAttribArray(vertexPosRef);
gl.vertexAttribPointer(vertexPosRef, 2, gl.FLOAT, false, 0, 0);
var texturePosBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]), gl.STATIC_DRAW);
var texturePosRef = gl.getAttribLocation(program, 'texturePos');
gl.enableVertexAttribArray(texturePosRef);
gl.vertexAttribPointer(texturePosRef, 2, gl.FLOAT, false, 0, 0);
this.texturePosBuffer = texturePosBuffer;
};
/**
* Initialize GL textures and attach to shader program
*/
Jessibuca.prototype.initTextures = function () {
var gl = this.contextGL;
var program = this.shaderProgram;
var yTextureRef = this.initTexture();
var ySamplerRef = gl.getUniformLocation(program, 'ySampler');
gl.uniform1i(ySamplerRef, 0);
this.yTextureRef = yTextureRef;
var uTextureRef = this.initTexture();
var uSamplerRef = gl.getUniformLocation(program, 'uSampler');
gl.uniform1i(uSamplerRef, 1);
this.uTextureRef = uTextureRef;
var vTextureRef = this.initTexture();
var vSamplerRef = gl.getUniformLocation(program, 'vSampler');
gl.uniform1i(vSamplerRef, 2);
this.vTextureRef = vTextureRef;
};
/**
* Create and configure a single texture
*/
Jessibuca.prototype.initTexture = function () {
var gl = this.contextGL;
var textureRef = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, textureRef);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.bindTexture(gl.TEXTURE_2D, null);
return textureRef;
};
/**
* Draw picture data to the canvas.
* If this object is using WebGL, the data must be an I420 formatted ArrayBuffer,
* Otherwise, data must be an RGBA formatted ArrayBuffer.
*/
Jessibuca.prototype.drawNextOutputPicture = function (width, height, croppingParams, data) {
var gl = this.contextGL;
if (gl) {
this.drawNextOuptutPictureGL(width, height, croppingParams, data);
} else {
this.drawNextOuptutPictureRGBA(width, height, croppingParams, data);
}
};
/**
* Draw the next output picture using WebGL
*/
Jessibuca.prototype.drawNextOuptutPictureGL = function (width, height, croppingParams, data) {
var gl = this.contextGL;
var texturePosBuffer = this.texturePosBuffer;
var yTextureRef = this.yTextureRef;
var uTextureRef = this.uTextureRef;
var vTextureRef = this.vTextureRef;
this.contextGL.viewport(0, 0, this.canvasElement.width, this.canvasElement.height);
// if (!croppingParams) {
// gl.viewport(0, 0, width, height);
// } else {
// gl.viewport(0, 0, croppingParams.width, croppingParams.height);
// var tTop = croppingParams.top / height;
// var tLeft = croppingParams.left / width;
// var tBottom = croppingParams.height / height;
// var tRight = croppingParams.width / width;
// var texturePosValues = new Float32Array([tRight, tTop, tLeft, tTop, tRight, tBottom, tLeft, tBottom]);
// gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
// gl.bufferData(gl.ARRAY_BUFFER, texturePosValues, gl.DYNAMIC_DRAW);
// }
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, yTextureRef);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data[0]);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, uTextureRef);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width / 2, height / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data[1]);
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, vTextureRef);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width / 2, height / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data[2]);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
};
/**
* Draw next output picture using ARGB data on a 2d canvas.
*/
Jessibuca.prototype.drawNextOuptutPictureRGBA = function (width, height, croppingParams, data) {
// var canvas = this.canvasElement;
//var argbData = data;
//var ctx = canvas.getContext('2d');
// var imageData = ctx.getImageData(0, 0, width, height);
//this.imageData = this.ctx2d.getImageData(0, 0, width, height);
this.imageData.data.set(data);
//Module.print(typeof this.imageData.data);
if (!croppingParams) {
this.ctx2d.putImageData(this.imageData, 0, 0);
} else {
this.ctx2d.putImageData(this.imageData, -croppingParams.left, -croppingParams.top, 0, 0, croppingParams.width, croppingParams.height);
}
};
Jessibuca.prototype.ctx2d = null;
Jessibuca.prototype.imageData = null;
Jessibuca.prototype.initRGB = function (width, height) {
this.ctx2d = this.canvasElement.getContext('2d');
this.imageData = this.ctx2d.getImageData(0, 0, width, height);
this.clear = function () {
this.ctx2d.clearRect(0, 0, width, height)
};
//Module.print(this.imageData);
};
Jessibuca.prototype.close = function () {
if (this.audioInterval) {
clearInterval(this.audioInterval)
}
this.decoderWorker.postMessage({ cmd: "close" })
this.contextGL.clear(this.contextGL.COLOR_BUFFER_BIT);
}
Jessibuca.prototype.destroy = function(){
this.decoderWorker.terminate()
}
Jessibuca.prototype.play = function (url) {
this.decoderWorker.postMessage({ cmd: "play", url: url, isWebGL: this.isWebGL() })
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,20 +0,0 @@
module.exports = {
dest: 'public/docs',
serviceWorker: true,
themeConfig: {
sidebar: [
['/', '起步'],
['/develop', '插件开发'],
[ '/history', '更新日志' ],
{
title: '内置插件',
path: '/plugins/',
children: [
'/plugins/jessica'
]
},
]
},
title: 'Monibuca',
base: '/docs/'
}

View File

@@ -1,38 +0,0 @@
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
export default ({
Vue, // the version of Vue being used in the VuePress app
options, // the options for the root Vue instance
router, // the router instance for the app
siteData // site metadata
}) => {
// ...apply enhancements to the app
const requireComponent = require.context(
// The relative path of the components folder
'../../src/components',
// Whether or not to look in subfolders
true,
// The regular expression used to match base component filenames
/.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
// Get component config
const componentConfig = requireComponent(fileName)
const fc = fileName.split('/')
const f = fc[fc.length - 1]
// Get PascalCase name of component
const componentName = upperFirst(
camelCase(
f.replace(/.*\//, '$1').replace(/\.\w+$/,'')
)
)
// Register component globally
Vue.component(
componentName,
componentConfig.default || componentConfig
)
})
}

View File

@@ -1,53 +0,0 @@
# Monibuca快速起步
## 介绍
Monibuca 是一个开源的流媒体服务器开发框架适用于快速定制化开发流媒体服务器可以对接CDN厂商作为回源服务器也可以自己搭建集群部署环境。
丰富的内置插件提供了流媒体服务器的常见功能例如rtmp server、http-flv、视频录制、QoS等。除此以外还内置了后台web界面方便观察服务器运行的状态。
也可以自己开发后台管理界面通过api方式获取服务器的运行信息。
Monibuca 提供了可供定制化开发的插件机制,可以任意扩展其功能。
## 启动
启用所有内置插件
```go
package main
import (
. "github.com/langhuihui/monibuca/monica"
_ "github.com/langhuihui/monibuca/plugins"
)
func main() {
Run("config.toml")
select {}
}
```
## 配置
要使用`Monibuca`,需要编写一个`toml`格式的配置文件,通常可以放在程序的同级目录下例如:`config.toml`(名称不是必须为`config`)
该配置文件主要是为了定制各个插件的配置,例如监听端口号等,具体还是要看各个插件的设计。
> 如果你编写了自己的插件,就必须在该配置文件中写入对自己插件的配置信息
如果注释掉部分插件的配置,那么该插件就不会启用,典型的配置如下:
```toml
[Plugins.HDL]
ListenAddr = ":2020"
[Plugins.Jessica]
ListenAddr = ":8080"
[Plugins.RTMP]
ListenAddr = ":1935"
[Plugins.GateWay]
ListenAddr = ":81"
#[Plugins.Cluster]
#Master = "localhost:2019"
#ListenAddr = ":2019"
#
#[Plugins.Auth]
#Key="www.monibuca.com"
#[Plugins.RecordFlv]
#Path="./resouce"
[Plugins.QoS]
Suffix = ["high","medium","low"]
```
具体配置的含义,可以参考每个插件的说明

View File

@@ -1,178 +0,0 @@
# 插件开发
## 插件的定义
所谓的插件,没有什么固定的规则,只需要完成`安装`操作即可。插件可以实现任意的功能扩展,最常见的是实现某种传输协议用来推流或者拉流
## 插件的安装
下面是内置插件jessica的源码代表了典型的插件安装
```go
package jessica
import (
. "github.com/langhuihui/monibuca/monica"
"log"
"net/http"
)
var config = new(ListenerConfig)
func init() {
InstallPlugin(&PluginConfig{
Name: "Jessica",
Type: PLUGIN_SUBSCRIBER,
Config: config,
Run: run,
})
}
func run() {
log.Printf("server Jessica start at %s", config.ListenAddr)
log.Fatal(http.ListenAndServe(config.ListenAddr, http.HandlerFunc(WsHandler)))
}
```
当主程序读取配置文件完成解析后会调用各个插件的Run函数上面代码中执行了一个http的端口监听
## 开发订阅者插件
所谓订阅者就是用来从流媒体服务器接收音视频流的程序例如RTMP协议执行play命令后、http-flv请求响应程序、websocket响应程序。内置插件中录制flv程序也是一个特殊的订阅者。
下面是http-flv插件的源码供参考
```go
package HDL
import (
. "github.com/langhuihui/monibuca/monica"
"github.com/langhuihui/monibuca/monica/avformat"
"github.com/langhuihui/monibuca/monica/pool"
"log"
"net/http"
"strings"
)
var config = new(ListenerConfig)
func init() {
InstallPlugin(&PluginConfig{
Name: "HDL",
Type: PLUGIN_SUBSCRIBER,
Config: config,
Run: run,
})
}
func run() {
log.Printf("HDL start at %s", config.ListenAddr)
log.Fatal(http.ListenAndServe(config.ListenAddr, http.HandlerFunc(HDLHandler)))
}
func HDLHandler(w http.ResponseWriter, r *http.Request) {
sign := r.URL.Query().Get("sign")
if err := AuthHooks.Trigger(sign); err != nil {
w.WriteHeader(403)
return
}
stringPath := strings.TrimLeft(r.RequestURI, "/")
if strings.HasSuffix(stringPath, ".flv") {
stringPath = strings.TrimRight(stringPath, ".flv")
}
if _, ok := AllRoom.Load(stringPath); ok {
//atomic.AddInt32(&hdlId, 1)
w.Header().Set("Transfer-Encoding", "chunked")
w.Header().Set("Content-Type", "video/x-flv")
w.Write(avformat.FLVHeader)
p := OutputStream{
Sign: sign,
SendHandler: func(packet *pool.SendPacket) error {
return avformat.WriteFLVTag(w, packet)
},
SubscriberInfo: SubscriberInfo{
ID: r.RemoteAddr, Type: "FLV",
},
}
p.Play(stringPath)
} else {
w.WriteHeader(404)
}
}
```
其中核心逻辑就是创建OutputStream对象每一个订阅者需要提供SendHandler函数用来接收来自发布者广播出来的音视频数据。
最后调用该对象的Play函数进行播放。请注意Play函数会阻塞当前goroutine。
## 开发发布者插件
所谓发布者就是提供音视频数据的程序例如接收来自OBS、ffmpeg的推流的程序。内置插件中集群功能里面有一个特殊的发布者它接收来自源服务器的音视频数据然后在本服务器中广播音视频。
以此为例,我们需要提供一个结构体定义来表示特定的发布者:
```go
type Receiver struct {
InputStream
io.Reader
*bufio.Writer
}
```
其中InputStream 是固定的,必须包含,且必须以组合继承的方式定义。其余的成员则是任意的。
发布者的发布动作需要特定条件的触发,例如在集群插件中,当本服务器有订阅者订阅了某个流,而该流并没有发布者的时候就会触发向源服务器拉流的函数:
```go
func PullUpStream(streamPath string) {
addr, err := net.ResolveTCPAddr("tcp", config.Master)
if MayBeError(err) {
return
}
conn, err := net.DialTCP("tcp", nil, addr)
if MayBeError(err) {
return
}
brw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
p := &Receiver{
Reader: conn,
Writer: brw.Writer,
}
if p.Publish(streamPath, p) {
p.WriteByte(MSG_SUBSCRIBE)
p.WriteString(streamPath)
p.WriteByte(0)
p.Flush()
for _, v := range p.Subscribers {
p.Auth(v)
}
} else {
return
}
defer p.Cancel()
for {
cmd, err := brw.ReadByte()
if MayBeError(err) {
return
}
switch cmd {
case MSG_AUDIO:
if audio, err := p.readAVPacket(avformat.FLV_TAG_TYPE_AUDIO); err == nil {
p.PushAudio(audio)
}
case MSG_VIDEO:
if video, err := p.readAVPacket(avformat.FLV_TAG_TYPE_VIDEO); err == nil && len(video.Payload) > 2 {
tmp := video.Payload[0] // 第一个字节保存着视频的相关信息.
video.VideoFrameType = tmp >> 4 // 帧类型 4Bit, H264一般为1或者2
p.PushVideo(video)
}
case MSG_AUTH:
cmd, err = brw.ReadByte()
if MayBeError(err) {
return
}
bytes, err := brw.ReadBytes(0)
if MayBeError(err) {
return
}
subId := strings.Split(string(bytes[0:len(bytes)-1]), ",")[0]
if v, ok := p.Subscribers[subId]; ok {
if cmd != 1 {
v.Cancel()
}
}
}
}
}
```
正在该函数中会向源服务器建立tcp连接然后发送特定命令表示需要拉流当我们接收到源服务器的数据的时候就调用PushVideo和PushAudio函数来广播音视频。
核心逻辑是调用InputStream的Publish以及PushVideo、PushAudio函数
## 开发钩子插件

View File

@@ -1,4 +0,0 @@
# 更新历史
- 2020/1/27
1.0完成

View File

@@ -1,10 +0,0 @@
# Jessica
该插件为基于WebSocket协议传输音视频的订阅者音视频数据以裸数据的形式进行传输我们需要Jessibuca播放器来进行播放
Jessibua播放器已内置于源码中该播放器通过js解码H264并用canvas进行渲染可以运行在几乎所有的终端浏览器上面。
在Monibuca的Web界面中预览功能就是使用的Jessibuca播放器。
## 配置
目前仅有的配置是监听的端口号
```toml
[Plugins.Jessica]
ListenAddr = ":8080"
```

19251
dashboard/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,64 +0,0 @@
{
"name": "dashboard",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"docs:build": "vuepress build docs",
"docs:dev": "vuepress dev docs"
},
"dependencies": {
"@antv/g2plot": "^0.11.22",
"core-js": "^3.4.4",
"view-design": "^4.0.0",
"vue": "^2.6.10",
"vue-router": "^3.1.3",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.1.0",
"@vue/cli-plugin-eslint": "^4.1.0",
"@vue/cli-plugin-router": "^4.1.0",
"@vue/cli-plugin-vuex": "^4.1.0",
"@vue/cli-service": "^4.1.0",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"iview-loader": "^1.3.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"loadash": "^1.0.0",
"vue-cli-plugin-iview": "^2.0.0",
"vue-cli-plugin-vuepress": "^0.1.1",
"vue-template-compiler": "^2.6.10",
"vuepress": "^0.10.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {
"no-console": "off",
"vue/no-parsing-error": [
2,
{
"x-invalid-end-tag": false
}
]
}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.685ed1cc.js"><link rel="prefetch" href="/docs/assets/js/2.a6d3efaf.js"><link rel="prefetch" href="/docs/assets/js/3.a9fbea98.js"><link rel="prefetch" href="/docs/assets/js/4.727e40e9.js"><link rel="prefetch" href="/docs/assets/js/5.78b155e8.js"><link rel="prefetch" href="/docs/assets/js/6.35a311c9.js"><link rel="prefetch" href="/docs/assets/js/7.ab3a52c1.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><div class="content"><h1>404</h1><blockquote>How did we get here?</blockquote><a href="/docs/" class="router-link-active">Take me home.</a></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13"><g stroke-width="2" stroke="#aaa" fill="none"><path d="M11.29 11.71l-4-4"/><circle cx="5" cy="5" r="4"/></g></svg>

Before

Width:  |  Height:  |  Size: 216 B

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{168:function(t,e,n){"use strict";n.r(e);var a=n(0),s=Object(a.a)({},(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"content"},[e("h1",{attrs:{id:"关于-monibuca"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#关于-monibuca","aria-hidden":"true"}},[this._v("#")]),this._v(" 关于 Monibuca")])])}],!1,null,null,null);e.default=s.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{167:function(t,e,s){"use strict";s.r(e);var a=s(0),i=Object(a.a)({},(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"content"},[e("h1",{attrs:{id:"page-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#page-2","aria-hidden":"true"}},[this._v("#")]),this._v(" Page 2")]),e("p",[this._v("this is a second page")])])}],!1,null,null,null);e.default=i.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[3],{166:function(t,n,e){"use strict";e.r(n);var s=e(0),c=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"content"})}),[],!1,null,null,null);n.default=c.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{165:function(t,e,i){"use strict";i.r(e);var s=i(0),a=Object(s.a)({},(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"content"},[e("h1",{attrs:{id:"page-3-with-custom-link-page"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#page-3-with-custom-link-page","aria-hidden":"true"}},[this._v("#")]),this._v(" Page 3 with custom link page")]),e("p",[this._v("this is a third page")])])}],!1,null,null,null);e.default=a.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[5],{164:function(t,e,s){"use strict";s.r(e);var a=s(0),i=Object(a.a)({},(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("div",{staticClass:"content"},[e("h1",{attrs:{id:"page-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#page-1","aria-hidden":"true"}},[this._v("#")]),this._v(" Page 1")]),e("p",[this._v("this is a page")])])}],!1,null,null,null);e.default=i.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[6],{163:function(t,n,e){"use strict";e.r(n);var s=e(0),c=Object(s.a)({},(function(){var t=this.$createElement;return(this._self._c||t)("div",{staticClass:"content"})}),[],!1,null,null,null);n.default=c.exports}}]);

View File

@@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[7],{162:function(t,s,a){"use strict";a.r(s);var e=a(0),i=Object(e.a)({},(function(){var t=this.$createElement;this._self._c;return this._m(0)}),[function(){var t=this.$createElement,s=this._self._c||t;return s("div",{staticClass:"content"},[s("h1",{attrs:{id:"jessica"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#jessica","aria-hidden":"true"}},[this._v("#")]),this._v(" Jessica")]),s("h2",{attrs:{id:"配置"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#配置","aria-hidden":"true"}},[this._v("#")]),this._v(" 配置")])])}],!1,null,null,null);s.default=i.exports}}]);

File diff suppressed because one or more lines are too long

View File

@@ -1,25 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Page 2 | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="preload" href="/docs/assets/js/2.a6d3efaf.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.685ed1cc.js"><link rel="prefetch" href="/docs/assets/js/3.a9fbea98.js"><link rel="prefetch" href="/docs/assets/js/4.727e40e9.js"><link rel="prefetch" href="/docs/assets/js/5.78b155e8.js"><link rel="prefetch" href="/docs/assets/js/6.35a311c9.js"><link rel="prefetch" href="/docs/assets/js/7.ab3a52c1.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">介绍</a></li><li><a href="/docs/install.html" class="sidebar-link">安装</a></li><li><a href="/docs/config.html" class="active sidebar-link">配置</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"><h1 id="page-2"><a href="#page-2" aria-hidden="true" class="header-anchor">#</a> Page 2</h1><p>this is a second page</p></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/install.html" class="prev">
安装
</a></span><span class="next"><a href="/docs/develop.html">
插件开发
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script><script src="/docs/assets/js/2.a6d3efaf.js" defer></script>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="preload" href="/docs/assets/js/3.a9fbea98.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.685ed1cc.js"><link rel="prefetch" href="/docs/assets/js/2.a6d3efaf.js"><link rel="prefetch" href="/docs/assets/js/4.727e40e9.js"><link rel="prefetch" href="/docs/assets/js/5.78b155e8.js"><link rel="prefetch" href="/docs/assets/js/6.35a311c9.js"><link rel="prefetch" href="/docs/assets/js/7.ab3a52c1.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">介绍</a></li><li><a href="/docs/install.html" class="sidebar-link">安装</a></li><li><a href="/docs/config.html" class="sidebar-link">配置</a></li><li><a href="/docs/develop.html" class="active sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/config.html" class="prev">
配置
</a></span><span class="next"><a href="/docs/history.html">
更新日志
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script><script src="/docs/assets/js/3.a9fbea98.js" defer></script>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Page 3 with custom link page | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="preload" href="/docs/assets/js/4.727e40e9.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.685ed1cc.js"><link rel="prefetch" href="/docs/assets/js/2.a6d3efaf.js"><link rel="prefetch" href="/docs/assets/js/3.a9fbea98.js"><link rel="prefetch" href="/docs/assets/js/5.78b155e8.js"><link rel="prefetch" href="/docs/assets/js/6.35a311c9.js"><link rel="prefetch" href="/docs/assets/js/7.ab3a52c1.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">介绍</a></li><li><a href="/docs/install.html" class="sidebar-link">安装</a></li><li><a href="/docs/config.html" class="sidebar-link">配置</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="active sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"><h1 id="page-3-with-custom-link-page"><a href="#page-3-with-custom-link-page" aria-hidden="true" class="header-anchor">#</a> Page 3 with custom link page</h1><p>this is a third page</p></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/develop.html" class="prev">
插件开发
</a></span><span class="next"><a href="/docs/plugins/jessica.html">
Jessica
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script><script src="/docs/assets/js/4.727e40e9.js" defer></script>
</body>
</html>

View File

@@ -1,22 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>关于 Monibuca | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="preload" href="/docs/assets/js/1.685ed1cc.js" as="script"><link rel="prefetch" href="/docs/assets/js/2.a6d3efaf.js"><link rel="prefetch" href="/docs/assets/js/3.a9fbea98.js"><link rel="prefetch" href="/docs/assets/js/4.727e40e9.js"><link rel="prefetch" href="/docs/assets/js/5.78b155e8.js"><link rel="prefetch" href="/docs/assets/js/6.35a311c9.js"><link rel="prefetch" href="/docs/assets/js/7.ab3a52c1.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-exact-active router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="active sidebar-link">介绍</a></li><li><a href="/docs/install.html" class="sidebar-link">安装</a></li><li><a href="/docs/config.html" class="sidebar-link">配置</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"><h1 id="关于-monibuca"><a href="#关于-monibuca" aria-hidden="true" class="header-anchor">#</a> 关于 Monibuca</h1></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><!----><span class="next"><a href="/docs/install.html">
安装
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script><script src="/docs/assets/js/1.685ed1cc.js" defer></script>
</body>
</html>

View File

@@ -1,25 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Page 1 | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="preload" href="/docs/assets/js/5.78b155e8.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.685ed1cc.js"><link rel="prefetch" href="/docs/assets/js/2.a6d3efaf.js"><link rel="prefetch" href="/docs/assets/js/3.a9fbea98.js"><link rel="prefetch" href="/docs/assets/js/4.727e40e9.js"><link rel="prefetch" href="/docs/assets/js/6.35a311c9.js"><link rel="prefetch" href="/docs/assets/js/7.ab3a52c1.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">介绍</a></li><li><a href="/docs/install.html" class="active sidebar-link">安装</a></li><li><a href="/docs/config.html" class="sidebar-link">配置</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"><h1 id="page-1"><a href="#page-1" aria-hidden="true" class="header-anchor">#</a> Page 1</h1><p>this is a page</p></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/" class="prev router-link-active">
介绍
</a></span><span class="next"><a href="/docs/config.html">
配置
</a>
</span></p></div></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script><script src="/docs/assets/js/5.78b155e8.js" defer></script>
</body>
</html>

View File

@@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="preload" href="/docs/assets/js/6.35a311c9.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.685ed1cc.js"><link rel="prefetch" href="/docs/assets/js/2.a6d3efaf.js"><link rel="prefetch" href="/docs/assets/js/3.a9fbea98.js"><link rel="prefetch" href="/docs/assets/js/4.727e40e9.js"><link rel="prefetch" href="/docs/assets/js/5.78b155e8.js"><link rel="prefetch" href="/docs/assets/js/7.ab3a52c1.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">介绍</a></li><li><a href="/docs/install.html" class="sidebar-link">安装</a></li><li><a href="/docs/config.html" class="sidebar-link">配置</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading"><span>内置插件</span><span class="arrow right"></span></p><!----></div></li></ul></div><div class="page"><div class="content"></div><div class="page-edit"><!----><!----></div><!----></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script><script src="/docs/assets/js/6.35a311c9.js" defer></script>
</body>
</html>

View File

@@ -1,22 +0,0 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Jessica | Monibuca</title>
<meta name="description" content="">
<link rel="preload" href="/docs/assets/css/styles.92893aed.css" as="style"><link rel="preload" href="/docs/assets/js/app.92893aed.js" as="script"><link rel="preload" href="/docs/assets/js/7.ab3a52c1.js" as="script"><link rel="prefetch" href="/docs/assets/js/1.685ed1cc.js"><link rel="prefetch" href="/docs/assets/js/2.a6d3efaf.js"><link rel="prefetch" href="/docs/assets/js/3.a9fbea98.js"><link rel="prefetch" href="/docs/assets/js/4.727e40e9.js"><link rel="prefetch" href="/docs/assets/js/5.78b155e8.js"><link rel="prefetch" href="/docs/assets/js/6.35a311c9.js">
<link rel="stylesheet" href="/docs/assets/css/styles.92893aed.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div><a href="/docs/" class="home-link router-link-active"><!----><span class="site-name">
Monibuca
</span></a><div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""><!----></div><!----></div></header><div class="sidebar-mask"></div><div class="sidebar"><!----><ul class="sidebar-links"><li><a href="/docs/" class="sidebar-link">介绍</a></li><li><a href="/docs/install.html" class="sidebar-link">安装</a></li><li><a href="/docs/config.html" class="sidebar-link">配置</a></li><li><a href="/docs/develop.html" class="sidebar-link">插件开发</a></li><li><a href="/docs/history.html" class="sidebar-link">更新日志</a></li><li><div class="sidebar-group collapsable"><p class="sidebar-heading open"><span>内置插件</span><span class="arrow down"></span></p><ul class="sidebar-group-items"><li><a href="/docs/plugins/jessica.html" class="active sidebar-link">Jessica</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/docs/plugins/jessica.html#配置" class="sidebar-link">配置</a></li></ul></li></ul></div></li></ul></div><div class="page"><div class="content"><h1 id="jessica"><a href="#jessica" aria-hidden="true" class="header-anchor">#</a> Jessica</h1><h2 id="配置"><a href="#配置" aria-hidden="true" class="header-anchor">#</a> 配置</h2></div><div class="page-edit"><!----><!----></div><div class="page-nav"><p class="inner"><span class="prev">
<a href="/docs/history.html" class="prev">
更新日志
</a></span><!----></p></div></div></div></div>
<script src="/docs/assets/js/app.92893aed.js" defer></script><script src="/docs/assets/js/7.ab3a52c1.js" defer></script>
</body>
</html>

View File

@@ -1,96 +0,0 @@
/**
* Welcome to your Workbox-powered service worker!
*
* You'll need to register this file in your web app and you should
* disable HTTP caching for this file too.
* See https://goo.gl/nhQhGp
*
* The rest of the code is auto-generated. Please don't update this file
* directly; instead, make changes to your Workbox build configuration
* and re-run your build process.
* See https://goo.gl/2aRDsh
*/
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js");
/**
* The workboxSW.precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
self.__precacheManifest = [
{
"url": "404.html",
"revision": "0e4ff0fd403c5d29a13752bf3ef14d6d"
},
{
"url": "assets/css/styles.92893aed.css",
"revision": "07fa9a1fb782ef296585900714fac621"
},
{
"url": "assets/img/search.83621669.svg",
"revision": "83621669651b9a3d4bf64d1a670ad856"
},
{
"url": "assets/js/1.685ed1cc.js",
"revision": "97247c4d4a60db87b22488bfdf99197d"
},
{
"url": "assets/js/2.a6d3efaf.js",
"revision": "dca15d8c2b94dadcdce4386e7d628716"
},
{
"url": "assets/js/3.a9fbea98.js",
"revision": "7f6bca508f94f8f508a61cd05b582084"
},
{
"url": "assets/js/4.727e40e9.js",
"revision": "b8fca87e9c559c1fe3fa03b76d15c3bd"
},
{
"url": "assets/js/5.78b155e8.js",
"revision": "73d1f3053737ad68ee4ec4fa395fcae9"
},
{
"url": "assets/js/6.35a311c9.js",
"revision": "8bd2ad3294cf6a29e7326ca860d43250"
},
{
"url": "assets/js/7.ab3a52c1.js",
"revision": "437c1f4739f884dcff81135f7bc8450c"
},
{
"url": "assets/js/app.92893aed.js",
"revision": "6962a63ee86d8a65c9ae46100427d812"
},
{
"url": "config.html",
"revision": "73b0335d99419df53f57913cd7303509"
},
{
"url": "develop.html",
"revision": "bc1b3cad3f88b61fee351464cffc7d0f"
},
{
"url": "history.html",
"revision": "dc6b1088d3cc72f1f3a402c56a441a57"
},
{
"url": "index.html",
"revision": "577c237555d953d8a22d045212f0a92e"
},
{
"url": "install.html",
"revision": "d06af57877e4695ae1a81528e2f128f1"
},
{
"url": "plugins/index.html",
"revision": "e578381fed44a65589053470ea33795d"
},
{
"url": "plugins/jessica.html",
"revision": "fe406bf63d2d349727c63d6045fd2efa"
}
].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Monibuca</title>
<script src="jessibuca/ajax.js"></script>
<script src="jessibuca/renderer.js"></script>
</head>
<body>
<noscript>
<strong>We're sorry but dashboard doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -1,535 +0,0 @@
// a simple ajax
!(function () {
var jsonType = 'application/json';
var htmlType = 'text/html';
var xmlTypeRE = /^(?:text|application)\/xml/i;
var blankRE = /^\s*$/; // \s
/*
* default setting
* */
var _settings = {
type: "GET",
beforeSend: noop,
success: noop,
error: noop,
complete: noop,
context: null,
xhr: function () {
return new window.XMLHttpRequest();
},
accepts: {
json: jsonType,
xml: 'application/xml, text/xml',
html: htmlType,
text: 'text/plain'
},
crossDomain: false,
timeout: 0,
username: null,
password: null,
processData: true,
promise: noop
};
function noop() {
}
var ajax = function (options) {
//
var settings = extend({}, options || {});
//
for (var key in _settings) {
if (settings[key] === undefined) {
settings[key] = _settings[key];
}
}
//
try {
var q = {};
var promise = new Promise(function (resolve, reject) {
q.resolve = resolve;
q.reject = reject;
});
promise.resolve = q.resolve;
promise.reject = q.reject;
settings.promise = promise;
}
catch (e) {
//
settings.promise = {
resolve: noop,
reject: noop
};
}
//
if (!settings.crossDomain) {
settings.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(settings.url) && RegExp.$2 !== window.location.href;
}
var dataType = settings.dataType;
// jsonp
if (dataType === 'jsonp') {
//
var hasPlaceholder = /=\?/.test(settings.url);
if (!hasPlaceholder) {
var jsonpCallback = (settings.jsonp || 'callback') + '=?';
settings.url = appendQuery(settings.url, jsonpCallback)
}
return JSONP(settings);
}
// url
if (!settings.url) {
settings.url = window.location.toString();
}
//
serializeData(settings);
var mime = settings.accepts[dataType]; // mime
var baseHeader = {}; // header
var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol; // protocol
var xhr = _settings.xhr();
var abortTimeout;
// X-Requested-With header
// For cross-domain requests, seeing as conditions for a preflight are
// akin to a jigsaw puzzle, we simply never set it to be sure.
// (it can always be set on a per-request basis or even using ajaxSetup)
// For same-domain requests, won't change header if already provided.
if (!settings.crossDomain && !baseHeader['X-Requested-With']) {
baseHeader['X-Requested-With'] = 'XMLHttpRequest';
}
// mime
if (mime) {
//
baseHeader['Accept'] = mime;
if (mime.indexOf(',') > -1) {
mime = mime.split(',', 2)[0]
}
//
xhr.overrideMimeType && xhr.overrideMimeType(mime);
}
// contentType
if (settings.contentType || (settings.data && settings.type.toUpperCase() !== 'GET')) {
baseHeader['Content-Type'] = (settings.contentType || 'application/x-www-form-urlencoded; charset=UTF-8');
}
// headers
settings.headers = extend(baseHeader, settings.headers || {});
// on ready state change
xhr.onreadystatechange = function () {
// readystate
if (xhr.readyState === 4) {
clearTimeout(abortTimeout);
var result;
var error = false;
//
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
dataType = dataType || mimeToDataType(xhr.getResponseHeader('content-type'));
result = xhr.responseText;
try {
// xml
if (dataType === 'xml') {
result = xhr.responseXML;
}
// json
else if (dataType === 'json') {
result = blankRE.test(result) ? null : JSON.parse(result);
}
}
catch (e) {
error = e;
}
if (error) {
ajaxError(error, 'parseerror', xhr, settings);
}
else {
ajaxSuccess(result, xhr, settings);
}
}
else {
ajaxError(null, 'error', xhr, settings);
}
}
};
// async
var async = 'async' in settings ? settings.async : true;
// open
xhr.open(settings.type, settings.url, async, settings.username, settings.password);
// xhrFields
if (settings.xhrFields) {
for (var name in settings.xhrFields) {
xhr[name] = settings.xhrFields[name];
}
}
// Override mime type if needed
if (settings.mimeType && xhr.overrideMimeType) {
xhr.overrideMimeType(settings.mimeType);
}
// set request header
for (var name in settings.headers) {
// Support: IE<9
// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
// request header to a null-value.
//
// To keep consistent with other XHR implementations, cast the value
// to string and ignore `undefined`.
if (settings.headers[name] !== undefined) {
xhr.setRequestHeader(name, settings.headers[name] + "");
}
}
// before send
if (ajaxBeforeSend(xhr, settings) === false) {
xhr.abort();
return false;
}
// timeout
if (settings.timeout > 0) {
abortTimeout = window.setTimeout(function () {
xhr.onreadystatechange = noop;
xhr.abort();
ajaxError(null, 'timeout', xhr, settings);
}, settings.timeout);
}
// send
xhr.send(settings.data ? settings.data : null);
return settings.promise;
};
/*
* method get
* */
ajax.get = function (url, data, success, dataType) {
if (isFunction(data)) {
dataType = dataType || success;
success = data;
data = undefined;
}
return ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
};
/*
* method post
*
* dataType:
* */
ajax.post = function (url, data, success, dataType) {
if (isFunction(data)) {
dataType = dataType || success;
success = data;
data = undefined;
}
return ajax({
type: 'POST',
url: url,
data: data,
success: success,
dataType: dataType
})
};
/*
* method getJSON
* */
ajax.getJSON = function (url, data, success) {
if (isFunction(data)) {
success = data;
data = undefined;
}
return ajax({
url: url,
data: data,
success: success,
dataType: 'json'
})
};
/*
* method ajaxSetup
* */
ajax.ajaxSetup = function (target, settings) {
return settings ? extend(extend(target, _settings), settings) : extend(_settings, target);
};
/*
* utils
*
* */
// triggers and extra global event ajaxBeforeSend that's like ajaxSend but cancelable
function ajaxBeforeSend(xhr, settings) {
var context = settings.context;
//
if (settings.beforeSend.call(context, xhr, settings) === false) {
return false;
}
}
// ajax success
function ajaxSuccess(data, xhr, settings) {
var context = settings.context;
var status = 'success';
settings.success.call(context, data, status, xhr);
settings.promise.resolve(data, status, xhr);
ajaxComplete(status, xhr, settings);
}
// status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
function ajaxComplete(status, xhr, settings) {
var context = settings.context;
settings.complete.call(context, xhr, status);
}
// type: "timeout", "error", "abort", "parsererror"
function ajaxError(error, type, xhr, settings) {
var context = settings.context;
settings.error.call(context, xhr, type, error);
settings.promise.reject(xhr, type, error);
ajaxComplete(type, xhr, settings);
}
// jsonp
/*
* tks: https://www.cnblogs.com/rubylouvre/archive/2011/02/13/1953087.html
* */
function JSONP(options) {
//
var callbackName = options.jsonpCallback || 'jsonp' + (new Date().getTime());
var script = window.document.createElement('script');
var abort = function () {
// 设置 window.xxx = noop
if (callbackName in window) {
window[callbackName] = noop;
}
};
var xhr = {abort: abort};
var abortTimeout;
var head = window.document.getElementsByTagName('head')[0] || window.document.documentElement;
// ie8+
script.onerror = function (error) {
_error(error);
};
function _error(error) {
window.clearTimeout(abortTimeout);
xhr.abort();
ajaxError(error.type, xhr, error.type, options);
_removeScript();
}
window[callbackName] = function (data) {
window.clearTimeout(abortTimeout);
ajaxSuccess(data, xhr, options);
_removeScript();
};
//
serializeData(options);
script.src = options.url.replace(/=\?/, '=' + callbackName);
//
script.src = appendQuery(script.src, '_=' + (new Date()).getTime());
//
script.async = true;
// script charset
if (options.scriptCharset) {
script.charset = options.scriptCharset;
}
//
head.insertBefore(script, head.firstChild);
//
if (options.timeout > 0) {
abortTimeout = window.setTimeout(function () {
xhr.abort();
ajaxError('timeout', xhr, 'timeout', options);
_removeScript();
}, options.timeout);
}
// remove script
function _removeScript() {
if (script.clearAttributes) {
script.clearAttributes();
} else {
script.onload = script.onreadystatechange = script.onerror = null;
}
if (script.parentNode) {
script.parentNode.removeChild(script);
}
//
script = null;
delete window[callbackName];
}
return options.promise;
}
// mime to data type
function mimeToDataType(mime) {
return mime && (mime === htmlType ? 'html' : mime === jsonType ? 'json' : xmlTypeRE.test(mime) && 'xml') || 'text'
}
// append query
function appendQuery(url, query) {
return (url + '&' + query).replace(/[&?]{1,2}/, '?');
}
// serialize data
function serializeData(options) {
// formData
if (isObject(options) && !isFormData(options.data) && options.processData) {
options.data = param(options.data);
}
if (options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
options.url = appendQuery(options.url, options.data);
}
}
// serialize
function serialize(params, obj, traditional, scope) {
var _isArray = isArray(obj);
for (var key in obj) {
var value = obj[key];
if (scope) {
key = traditional ? scope : scope + '[' + (_isArray ? '' : key) + ']';
}
// handle data in serializeArray format
if (!scope && _isArray) {
params.add(value.name, value.value);
}
else if (traditional ? _isArray(value) : isObject(value)) {
serialize(params, value, traditional, key);
}
else {
params.add(key, value);
}
}
}
// param
function param(obj, traditional) {
var params = [];
//
params.add = function (k, v) {
this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
};
serialize(params, obj, traditional);
return params.join('&').replace('%20', '+');
}
// extend
function extend(target) {
var slice = Array.prototype.slice;
var args = slice.call(arguments, 1);
//
for (var i = 0, length = args.length; i < length; i++) {
var source = args[i] || {};
for (var key in source) {
if (source.hasOwnProperty(key) && source[key] !== undefined) {
target[key] = source[key];
}
}
}
return target;
}
// is object
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
// is formData
function isFormData(obj) {
return obj instanceof FormData;
}
// is array
function isArray(value) {
return Object.prototype.toString.call(value) === "[object Array]";
}
// is function
function isFunction(value) {
return typeof value === "function";
}
// browser
window.ajax = ajax;
})();

File diff suppressed because one or more lines are too long

View File

@@ -1,460 +0,0 @@
function Jessibuca(opt) {
this.canvasElement = opt.canvas;
this.contextOptions = opt.contextOptions;
this.videoBuffer = opt.videoBuffer || 1
if (!opt.forceNoGL) this.initContextGL();
if (this.contextGL) {
this.initProgram();
this.initBuffers();
this.initTextures();
};
this.decoderWorker = new Worker(opt.decoder || '264_mp3.js')
var _this = this
function draw(output) {
_this.drawNextOutputPicture(_this.width, _this.height, null, output)
postMessage({ cmd: "setBuffer", buffer: output }, '*', [output[0].buffer, output[1].buffer, output[2].buffer])
}
this.decoderWorker.onmessage = function (event) {
var msg = event.data
switch (msg.cmd) {
case "init":
console.log("decoder worker init")
postMessage({ cmd: "setVideoBuffer", time: _this.videoBuffer }, "*")
if (_this.onLoad) {
_this.onLoad()
delete _this.onLoad;
}
break
case "initSize":
_this.width = msg.w
_this.height = msg.h
if (_this.isWebGL()) {
// var buffer = new ArrayBuffer(msg.w * msg.h + (msg.w * msg.h >> 1))
// this.postMessage({ cmd: "setBuffer", buffer: buffer }, [buffer])
}
else {
_this.initRGB(msg.w, msg.h)
}
break
case "render":
if (_this.onPlay) {
_this.onPlay()
delete _this.onPlay;
}
// if (msg.compositionTime) {
// console.log(msg.compositionTime)
// setTimeout(draw, msg.compositionTime, msg.output)
// } else {
// draw(msg.output)
// }
draw(msg.output)
break
case "initAudio":
_this.initAudioPlay(msg.frameCount, msg.samplerate, msg.channels)
break
case "playAudio":
_this.playAudio(msg.buffer)
break
case "print":
console.log(msg.text);
break
case "printErr":
console.error(msg.text);
break
}
}
};
window.AudioContext = window.AudioContext || window.webkitAudioContext;
function _unlock() {
var context = Jessibuca.prototype.audioContext = Jessibuca.prototype.audioContext || new window.AudioContext();
context.resume();
var source = context.createBufferSource();
source.buffer = context.createBuffer(1, 1, 22050);
source.connect(context.destination);
if (source.noteOn)
source.noteOn(0);
else
source.start(0);
}
// document.addEventListener("mousedown", _unlock, true);
// document.addEventListener("touchend", _unlock, true);
Jessibuca.prototype.audioEnabled = function (flag) {
if (flag) {
_unlock()
this.audioEnabled = function (flag) {
if (flag) {
this.audioContext.resume();
} else {
this.audioContext.suspend();
}
}
}
}
Jessibuca.prototype.playAudio = function (data) {
var context = this.audioContext;
var isPlaying = false;
var isDecoding = false;
if (!context) return false;
var audioBuffers = [];
var decodeQueue = []
var _this = this
var playNextBuffer = function (e) {
// isPlaying = false;
if (audioBuffers.length) {
playBuffer(audioBuffers.shift())
}
//if (audioBuffers.length > 1) audioBuffers.shift();
};
var playBuffer = function (buffer) {
isPlaying = true;
var audioBufferSouceNode = context.createBufferSource();
audioBufferSouceNode.buffer = buffer;
audioBufferSouceNode.connect(context.destination);
// audioBufferSouceNode.onended = playNextBuffer;
audioBufferSouceNode.start();
if (!_this.audioInterval) {
_this.audioInterval = setInterval(playNextBuffer, buffer.duration * 1000 - 1);
}
// setTimeout(playNextBuffer, buffer.duration * 1000)
}
var tryPlay = function (buffer) {
if (decodeQueue.length) {
context.decodeAudioData(decodeQueue.shift(), tryPlay, console.error);
} else {
isDecoding = false
}
if (isPlaying) {
audioBuffers.push(buffer);
} else {
playBuffer(buffer)
}
}
var playAudio = function (data) {
decodeQueue.push(...data)
if (!isDecoding) {
isDecoding = true
context.decodeAudioData(decodeQueue.shift(), tryPlay, console.error);
}
}
this.playAudio = playAudio
playAudio(data)
}
Jessibuca.prototype.initAudioPlay = function (frameCount, samplerate, channels) {
var context = this.audioContext;
var isPlaying = false;
var audioBuffers = [];
if (!context) return false;
var resampled = samplerate < 22050;
var audioBuffer = resampled ? context.createBuffer(channels, frameCount << 1, samplerate << 1) : context.createBuffer(channels, frameCount, samplerate);
var playNextBuffer = function () {
isPlaying = false;
console.log("~", audioBuffers.length)
if (audioBuffers.length) {
playAudio(audioBuffers.shift());
}
//if (audioBuffers.length > 1) audioBuffers.shift();
};
var copyToCtxBuffer = channels > 1 ? function (fromBuffer) {
for (var channel = 0; channel < channels; channel++) {
var nowBuffering = audioBuffer.getChannelData(channel);
if (resampled) {
for (var i = 0; i < frameCount; i++) {
nowBuffering[i * 2] = nowBuffering[i * 2 + 1] = fromBuffer[i * (channel + 1)] / 32768;
}
} else
for (var i = 0; i < frameCount; i++) {
nowBuffering[i] = fromBuffer[i * (channel + 1)] / 32768;
}
}
} : function (fromBuffer) {
var nowBuffering = audioBuffer.getChannelData(0);
for (var i = 0; i < nowBuffering.length; i++) {
nowBuffering[i] = fromBuffer[i] / 32768;
}
// nowBuffering.set(fromBuffer);
};
var playAudio = function (fromBuffer) {
if (isPlaying) {
audioBuffers.push(fromBuffer);
console.log(audioBuffers.length)
return;
}
isPlaying = true;
copyToCtxBuffer(fromBuffer);
var source = context.createBufferSource();
source.buffer = audioBuffer;
source.connect(context.destination);
source.onended = playNextBuffer;
//setTimeout(playNextBuffer, audioBufferTime-audioBuffers.length*200);
source.start();
};
this.playAudio = playAudio;
}
/**
* Returns true if the canvas supports WebGL
*/
Jessibuca.prototype.isWebGL = function () {
return !!this.contextGL;
};
/**
* Create the GL context from the canvas element
*/
Jessibuca.prototype.initContextGL = function () {
var canvas = this.canvasElement;
var gl = null;
var validContextNames = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"];
var nameIndex = 0;
while (!gl && nameIndex < validContextNames.length) {
var contextName = validContextNames[nameIndex];
try {
if (this.contextOptions) {
gl = canvas.getContext(contextName, this.contextOptions);
} else {
gl = canvas.getContext(contextName);
};
} catch (e) {
gl = null;
}
if (!gl || typeof gl.getParameter !== "function") {
gl = null;
}
++nameIndex;
};
this.contextGL = gl;
};
/**
* Initialize GL shader program
*/
Jessibuca.prototype.initProgram = function () {
var gl = this.contextGL;
var vertexShaderScript = [
'attribute vec4 vertexPos;',
'attribute vec4 texturePos;',
'varying vec2 textureCoord;',
'void main()',
'{',
'gl_Position = vertexPos;',
'textureCoord = texturePos.xy;',
'}'
].join('\n');
var fragmentShaderScript = [
'precision highp float;',
'varying highp vec2 textureCoord;',
'uniform sampler2D ySampler;',
'uniform sampler2D uSampler;',
'uniform sampler2D vSampler;',
'const mat4 YUV2RGB = mat4',
'(',
'1.1643828125, 0, 1.59602734375, -.87078515625,',
'1.1643828125, -.39176171875, -.81296875, .52959375,',
'1.1643828125, 2.017234375, 0, -1.081390625,',
'0, 0, 0, 1',
');',
'void main(void) {',
'highp float y = texture2D(ySampler, textureCoord).r;',
'highp float u = texture2D(uSampler, textureCoord).r;',
'highp float v = texture2D(vSampler, textureCoord).r;',
'gl_FragColor = vec4(y, u, v, 1) * YUV2RGB;',
'}'
].join('\n');
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderScript);
gl.compileShader(vertexShader);
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
console.log('Vertex shader failed to compile: ' + gl.getShaderInfoLog(vertexShader));
}
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderScript);
gl.compileShader(fragmentShader);
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
console.log('Fragment shader failed to compile: ' + gl.getShaderInfoLog(fragmentShader));
}
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.log('Program failed to compile: ' + gl.getProgramInfoLog(program));
}
gl.useProgram(program);
this.shaderProgram = program;
};
/**
* Initialize vertex buffers and attach to shader program
*/
Jessibuca.prototype.initBuffers = function () {
var gl = this.contextGL;
var program = this.shaderProgram;
var vertexPosBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 1, -1, 1, 1, -1, -1, -1]), gl.STATIC_DRAW);
var vertexPosRef = gl.getAttribLocation(program, 'vertexPos');
gl.enableVertexAttribArray(vertexPosRef);
gl.vertexAttribPointer(vertexPosRef, 2, gl.FLOAT, false, 0, 0);
var texturePosBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]), gl.STATIC_DRAW);
var texturePosRef = gl.getAttribLocation(program, 'texturePos');
gl.enableVertexAttribArray(texturePosRef);
gl.vertexAttribPointer(texturePosRef, 2, gl.FLOAT, false, 0, 0);
this.texturePosBuffer = texturePosBuffer;
};
/**
* Initialize GL textures and attach to shader program
*/
Jessibuca.prototype.initTextures = function () {
var gl = this.contextGL;
var program = this.shaderProgram;
var yTextureRef = this.initTexture();
var ySamplerRef = gl.getUniformLocation(program, 'ySampler');
gl.uniform1i(ySamplerRef, 0);
this.yTextureRef = yTextureRef;
var uTextureRef = this.initTexture();
var uSamplerRef = gl.getUniformLocation(program, 'uSampler');
gl.uniform1i(uSamplerRef, 1);
this.uTextureRef = uTextureRef;
var vTextureRef = this.initTexture();
var vSamplerRef = gl.getUniformLocation(program, 'vSampler');
gl.uniform1i(vSamplerRef, 2);
this.vTextureRef = vTextureRef;
};
/**
* Create and configure a single texture
*/
Jessibuca.prototype.initTexture = function () {
var gl = this.contextGL;
var textureRef = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, textureRef);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.bindTexture(gl.TEXTURE_2D, null);
return textureRef;
};
/**
* Draw picture data to the canvas.
* If this object is using WebGL, the data must be an I420 formatted ArrayBuffer,
* Otherwise, data must be an RGBA formatted ArrayBuffer.
*/
Jessibuca.prototype.drawNextOutputPicture = function (width, height, croppingParams, data) {
var gl = this.contextGL;
if (gl) {
this.drawNextOuptutPictureGL(width, height, croppingParams, data);
} else {
this.drawNextOuptutPictureRGBA(width, height, croppingParams, data);
}
};
/**
* Draw the next output picture using WebGL
*/
Jessibuca.prototype.drawNextOuptutPictureGL = function (width, height, croppingParams, data) {
var gl = this.contextGL;
var texturePosBuffer = this.texturePosBuffer;
var yTextureRef = this.yTextureRef;
var uTextureRef = this.uTextureRef;
var vTextureRef = this.vTextureRef;
this.contextGL.viewport(0, 0, this.canvasElement.width, this.canvasElement.height);
// if (!croppingParams) {
// gl.viewport(0, 0, width, height);
// } else {
// gl.viewport(0, 0, croppingParams.width, croppingParams.height);
// var tTop = croppingParams.top / height;
// var tLeft = croppingParams.left / width;
// var tBottom = croppingParams.height / height;
// var tRight = croppingParams.width / width;
// var texturePosValues = new Float32Array([tRight, tTop, tLeft, tTop, tRight, tBottom, tLeft, tBottom]);
// gl.bindBuffer(gl.ARRAY_BUFFER, texturePosBuffer);
// gl.bufferData(gl.ARRAY_BUFFER, texturePosValues, gl.DYNAMIC_DRAW);
// }
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, yTextureRef);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width, height, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data[0]);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, uTextureRef);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width / 2, height / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data[1]);
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, vTextureRef);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.LUMINANCE, width / 2, height / 2, 0, gl.LUMINANCE, gl.UNSIGNED_BYTE, data[2]);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
};
/**
* Draw next output picture using ARGB data on a 2d canvas.
*/
Jessibuca.prototype.drawNextOuptutPictureRGBA = function (width, height, croppingParams, data) {
// var canvas = this.canvasElement;
//var argbData = data;
//var ctx = canvas.getContext('2d');
// var imageData = ctx.getImageData(0, 0, width, height);
//this.imageData = this.ctx2d.getImageData(0, 0, width, height);
this.imageData.data.set(data);
//Module.print(typeof this.imageData.data);
if (!croppingParams) {
this.ctx2d.putImageData(this.imageData, 0, 0);
} else {
this.ctx2d.putImageData(this.imageData, -croppingParams.left, -croppingParams.top, 0, 0, croppingParams.width, croppingParams.height);
}
};
Jessibuca.prototype.ctx2d = null;
Jessibuca.prototype.imageData = null;
Jessibuca.prototype.initRGB = function (width, height) {
this.ctx2d = this.canvasElement.getContext('2d');
this.imageData = this.ctx2d.getImageData(0, 0, width, height);
this.clear = function () {
this.ctx2d.clearRect(0, 0, width, height)
};
//Module.print(this.imageData);
};
Jessibuca.prototype.close = function () {
if (this.audioInterval) {
clearInterval(this.audioInterval)
}
this.decoderWorker.postMessage({ cmd: "close" })
this.contextGL.clear(this.contextGL.COLOR_BUFFER_BIT);
}
Jessibuca.prototype.destroy = function(){
this.decoderWorker.terminate()
}
Jessibuca.prototype.play = function (url) {
this.decoderWorker.postMessage({ cmd: "play", url: url, isWebGL: this.isWebGL() })
}

View File

@@ -1,80 +0,0 @@
<template>
<div id="app">
<div>Monibuca</div>
<Menu mode="horizontal" :active-name="selectedMenu" style="position: absolute;top: 0;right: 0;">
<MenuItem name="home" to="/">首页</MenuItem>
<MenuItem name="docs" to="/docs" target="_blank">
文档
</MenuItem>
<MenuItem name="console" to="console">
控制台
</MenuItem>
<Submenu name="plugins">
<template slot="title">
内置插件
</template>
<MenuGroup title="发布者/订阅者">
<MenuItem name="cluster">集群</MenuItem>
<MenuItem name="rtmp">RTMP</MenuItem>
</MenuGroup>
<MenuGroup title="订阅者">
<MenuItem name="jessica">Jessica</MenuItem>
<MenuItem name="HDL">Http-Flv</MenuItem>
<MenuItem name="record">录制Flv</MenuItem>
</MenuGroup>
<MenuGroup title="发布者">
<MenuItem name="HLS">HLS</MenuItem>
<MenuItem name="TS">TS</MenuItem>
</MenuGroup>
<MenuGroup title="钩子">
<MenuItem name="Auth">验证</MenuItem>
<MenuItem name="QoS">QoS</MenuItem>
<MenuItem name="gateway">网关</MenuItem>
</MenuGroup>
</Submenu>
<MenuItem name="4" to="about">
支持
</MenuItem>
</Menu>
<router-view class="content"></router-view>
<div>Copyright © 2019-2020 dexter 苏ICP备20001212号</div>
</div>
</template>
<script>
export default {
name: 'app',
data(){
return {
selectedMenu:"home"
}
}
}
</script>
<style>
body,html{
height: 100%;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #184c18;
position: relative;
height: 100%;
}
#app > div:first-child {
position: absolute;
top: 10px;
left: 30px;
font-size: x-large;
}
.content{
padding-top: 60px;
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

View File

@@ -1,50 +0,0 @@
<template>
<Modal
v-bind="$attrs" draggable
v-on="$listeners"
:title="url"
@on-ok="onClosePreview"
@on-cancel="onClosePreview">
<canvas id="canvas" width="488" height="275" style="background: black"/>
</Modal>
</template>
<script>
let h5lc = null;
export default {
name: 'Jessibuca',
props: {
audioEnabled: Boolean,
},
data(){
return {
url:""
}
},
watch: {
audioEnabled(value){
h5lc.audioEnabled(value)
}
},
mounted() {
h5lc = new window.Jessibuca({
canvas: document.getElementById("canvas"),
decoder: "jessibuca/ff.js"
});
},
destroyed() {
this.onClosePreview()
h5lc.destroy()
},
methods: {
play(url){
this.url = url
h5lc.play(url)
},
onClosePreview() {
h5lc.close();
},
}
}
</script>

View File

@@ -1,18 +0,0 @@
<template>
<Poptip trigger="hover" :content="'⌚️'+ new Date(value).toLocaleString()">
<Time :time="new Date(value)"></Time>
</Poptip>
</template>
<script>
export default {
name: "StartTime",
props:{
value:String
}
}
</script>
<style scoped>
</style>

View File

@@ -1,13 +0,0 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/iview.js'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')

View File

@@ -1,6 +0,0 @@
import Vue from 'vue'
import ViewUI from 'view-design'
Vue.use(ViewUI)
import 'view-design/dist/styles/iview.css'

View File

@@ -1,32 +0,0 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About'
import Console from '../views/Console'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
}, {
path: '/console',
name: 'console',
component: Console
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router

View File

@@ -1,45 +0,0 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
let summaryES = null
export default new Vuex.Store({
state: {
summary:{
NetWork:[],
Rooms:[],
Memory:{
Used: 0,
Usage: 0
},
CPUUsage:0,
HardDisk:{
Used: 0,
Usage: 0
}
}
},
mutations: {
update(state,payload){
Object.assign(state,payload)
}
},
actions: {
fetchSummary({commit}){
summaryES = new EventSource(
"//" + location.host + "/api/summary"
);
summaryES.onmessage = evt=>{
if (!evt.data) return
let summary = JSON.parse(evt.data)
commit("update",{summary})
}
},
stopFetchSummary(){
summaryES.close()
}
},
modules: {
}
})

View File

@@ -1,21 +0,0 @@
<template>
<div class="root">
<h1>
赞助 Monibuca 的研发
</h1>
<p>
Monibuca 是采用 MIT 许可的开源项目使用完全免费 但是随着项目规模的增长也需要有相应的资金支持才能持续项目的维护的开发你可以通过下列的方法来赞助 Monibuca 的开发
</p>
<img src="../assets/alipay.png">
<img src="../assets/wechat.jpg">
</div>
</template>
<style scoped>
.root{
background: lightgray;
}
.root>img{
width: 300px;
margin: 30px;
}
</style>

View File

@@ -1,240 +0,0 @@
<template>
<div class="layout">
<ButtonGroup vertical>
<Button icon="ios-folder"></Button>
<Button icon="md-bug"></Button>
<Button icon="md-settings"></Button>
</ButtonGroup>
<Card v-for="item in Rooms" :key="item.StreamPath" class="room">
<p slot="title">
{{typeMap[item.Type]||item.Type}}{{item.StreamPath}}
</p>
<StartTime slot="extra" :value="item.StartTime"></StartTime>
<p>
{{SoundFormat(item.AudioInfo.SoundFormat)}} {{item.AudioInfo.PacketCount}}
{{SoundRate(item.AudioInfo.SoundRate)}} 声道:{{item.AudioInfo.SoundType}}
</p>
<p>
{{CodecID(item.VideoInfo.CodecID)}} {{item.VideoInfo.PacketCount}}
{{item.VideoInfo.SPSInfo.Width}}x{{item.VideoInfo.SPSInfo.Height}}
</p>
<ButtonGroup size="small">
<Button @click="onShowDetail(item)" icon="ios-people">
{{item.SubscriberInfo?item.SubscriberInfo.length:0}}
</Button>
<Button v-if="item.Type" @click="preview(item)" icon="md-eye">
</Button>
<Button @click="stopRecord(item)" class="recording" v-if="isRecording(item)" icon="ios-radio-button-on">
</Button>
<Button @click="record(item)" v-else icon="ios-radio-button-on">
</Button>
</ButtonGroup>
</Card>
<div v-if="Rooms.length==0" class="empty">
<Icon type="md-wine" size="50"/>
没有任何房间
</div>
<div class="status">
<Alert>
带宽消耗 📥{{totalInNetSpeed}} 📤{{totalOutNetSpeed}}
</Alert>
<Alert :type="memoryStatus">
内存使用{{networkFormat(Memory.Used,"M")}} 占比{{Memory.Usage.toFixed(2)}}%
</Alert>
<Alert :type="cpuStatus">
CPU使用{{CPUUsage.toFixed(2)}}%
</Alert>
<Alert :type="hardDiskStatus">
磁盘使用{{networkFormat(HardDisk.Used,"M")}} 占比{{HardDisk.Usage.toFixed(2)}}%
</Alert>
</div>
<Jessibuca ref="jessibuca" v-model="showPreview"></Jessibuca>
</div>
</template>
<script>
import {mapActions, mapState} from 'vuex'
import Jessibuca from "../components/Jessibuca";
import StartTime from "../components/StartTime";
const uintInc = {
"": "K",
K: "M",
M: "G",
G: null
}
const SoundFormat = {
0: "Linear PCM, platform endian",
1: "ADPCM",
2: "MP3",
3: "Linear PCM, little endian",
4: "Nellymoser 16kHz mono",
5: "Nellymoser 8kHz mono",
6: "Nellymoser",
7: "G.711 A-law logarithmic PCM",
8: "G.711 mu-law logarithmic PCM",
9: "reserved",
10: "AAC",
11: "Speex",
14: "MP3 8Khz",
15: "Device-specific sound"
}
const CodecID = {
1: "JPEG (currently unused)",
2: "Sorenson H.263",
3: "Screen video",
4: "On2 VP6",
5: "On2 VP6 with alpha channel",
6: "Screen video version 2",
7: "AVC",
12: "H265"
}
export default {
name: "Console",
components: {
Jessibuca, StartTime
},
data() {
return {
showPreview: false,
typeMap: {
TS: "🎬", HLS: "🍎", "": "⏳", Match365: "🏆", RTMP: "📸"
}
}
},
computed: {
...mapState({
Rooms: state => state.summary.Rooms || [],
Memory: state => state.summary.Memory,
CPUUsage: state => state.summary.CPUUsage,
HardDisk: state => state.summary.HardDisk,
cpuStatus: state => {
if (state.summary.CPUUsage > 99)
return "error"
return state.summary.CPUUsage > 50 ? "warning" : "success"
},
memoryStatus(state) {
if (state.summary.CPUUsage > 99)
return "error"
return state.summary.CPUUsage > 50 ? "warning" : "success"
},
hardDiskStatus(state) {
if (state.summary.CPUUsage > 99)
return "error"
return state.summary.CPUUsage > 50 ? "warning" : "success"
},
totalInNetSpeed(state) {
return this.networkFormat(state.summary.NetWork.reduce((aac, c) => aac + c.ReceiveSpeed, 0)) + "/S"
},
totalOutNetSpeed(state) {
return this.networkFormat(state.summary.NetWork.reduce((aac, c) => aac + c.SentSpeed, 0)) + "/S"
}
}),
},
methods: {
...mapActions([
'fetchSummary',
'stopFetchSummary'
]),
preview(item) {
this.$refs.jessibuca.play("ws://" + location.hostname + ":8080/" + item.StreamPath)
this.showPreview = true
}, onShowDetail() {
// this.showDetail = true
// this.currentSub = item
},
networkFormat(value, unit = "") {
if (value > 1024 && uintInc[unit]) {
return this.networkFormat(value / 1024, uintInc[unit])
}
return value.toFixed(2).replace(".00", "") + unit + "B"
},
SoundFormat(soundFormat) {
return SoundFormat[soundFormat]
},
CodecID(codec) {
return CodecID[codec]
},
SoundRate(rate) {
return rate > 1000 ? (rate / 1000) + "kHz" : rate + "Hz"
},
record(item) {
window.ajax.get("//" + location.host + "/api/record/flv", {streamPath: item.StreamPath}, x => {
if (x == "success") {
this.$Message.success('开始录制');
} else {
this.$Message.error(x);
}
})
},
stopRecord(item) {
window.ajax.get("//" + location.host + "/api/record/flv/stop", {streamPath: item.StreamPath}, x => {
if (x == "success") {
this.$Message.success('停止录制');
} else {
this.$Message.error(x);
}
})
},
isRecording(item) {
return item.SubscriberInfo && item.SubscriberInfo.find(x => x.Type == "FlvRecord")
}
},
mounted() {
this.fetchSummary()
},
destroyed() {
this.stopFetchSummary()
}
}
</script>
<style scoped>
@keyframes recording {
0% {
opacity: 0.2;
}
50% {
opacity: 1;
}
100% {
opacity: 0.2;
}
}
.recording {
animation: recording 1s infinite;
}
.layout {
padding-bottom: 30px;
display: flex;
flex-wrap: wrap;
}
.room {
width: 250px;
margin: 10px;
text-align: left;
}
.empty {
color: #eb5e46;
width: 100%;
min-height: 500px;
display: flex;
justify-content: center;
align-items: center;
}
.status {
position: fixed;
display: flex;
left: 5px;
bottom: 10px;
}
.status > div {
margin: 0 5px;
}
</style>

View File

@@ -1,53 +0,0 @@
<template>
<div>
<img src="../assets/logo.png">
<div>
<p>
Monibuca 是一个开源的Go语言实现的流媒体服务器开发框架
</p>
<Button type="success" to="/docs" target="_blank">🚀START</Button>
<span style="margin: 0 10px"></span>
<Button type="default" target="_blank" to="https://github.com/langhuihui/monibuca">
<svg style="vertical-align: text-top" width="16" height="16" aria-labelledby="simpleicons-github-dark-icon" lang="" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title id="simpleicons-github-dark-icon" lang="en">GitHub Dark icon</title><path fill="#7F8C8D" d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path></svg>
GITHUB</Button>
</div>
<Row style="margin: 30px;">
<Col span="8">
<Card :bordered="false" style="margin: 30px">
<div slot="title" class="feature-title">高性能</div>
<div>针对流媒体服务器独特的性质进行的优化充分利用Golang的goroutine的性质对大量的连接的读写进行合理的分配计算资源以及尽可能的减少内存Copy操作使用对象池减少Golang的GC时间</div>
</Card>
</Col>
<Col span="8">
<Card :bordered="false" style="margin: 30px">
<div slot="title" class="feature-title">🔧可扩展</div>
<div>流媒体服务器的个性化定制变的更简单基于Golang语言开发效率更高独创的插件机制可以方便用户定制个性化的功能组合更高效率的利用服务器资源</div>
</Card>
</Col>
<Col span="8">
<Card :bordered="false" style="margin: 30px">
<div slot="title" class="feature-title">📈可视化</div>
<div>功能强大的仪表盘可以直观的看到服务器运行的状态消耗的资源以及其他统计信息用户可以利用控制台对服务器进行配置和控制点击右上角菜单栏里面的控制台可以看到演示</div>
</Card>
</Col>
</Row>
</div>
</template>
<script>
</script>
<style scoped>
.feature-title{
color: #eb5e46;
font-weight: bold;
font-size: larger;
}
p {
margin: 30px;
font-size: 20px;
}
img{
margin: 20px;
}
</style>

View File

@@ -1,10 +0,0 @@
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('iview-loader')
.loader('iview-loader')
.tap(()=> ({prefix: false}))
.end()
}
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

45
gen.go Normal file
View File

@@ -0,0 +1,45 @@
//go:build ignore
package main
import (
"fmt"
"io/ioutil"
"os"
)
var debugShim string = `package main
import "net/http"
func init() {
notSupport := func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("not support"))
}
http.HandleFunc("/debug/charts/", notSupport)
http.HandleFunc("/debug/charts/data", notSupport)
http.HandleFunc("/debug/charts/data-feed", notSupport)
}
`
var debug string = `package main
import (
_ "github.com/mkevac/debugcharts"
)
`
func main() {
if len(os.Args) < 2 {
fmt.Println("usage: go run gen.go <path>")
os.Exit(1)
}
var content string
if os.Args[1] == "1" {
content = debug
} else {
content = debugShim
}
ioutil.WriteFile("debug.go", []byte(content), 0666)
}

114
go.mod
View File

@@ -1,17 +1,105 @@
module github.com/langhuihui/monibuca
module monibuca
go 1.13
go 1.20
require (
github.com/BurntSushi/toml v0.3.1
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/funny/slab v0.0.0-20180511031532-b1fad5e5d478
github.com/funny/utest v0.0.0-20161029064919-43870a374500 // indirect
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee // indirect
github.com/gobwas/pool v0.2.0 // indirect
github.com/gobwas/ws v1.0.2
github.com/quangngotan95/go-m3u8 v0.1.0
github.com/shirou/gopsutil v2.19.12+incompatible
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 // indirect
go.uber.org/zap v1.26.0
m7s.live/engine/v4 v4.14.0
m7s.live/plugin/debug/v4 v4.0.1
m7s.live/plugin/fmp4/v4 v4.0.5
m7s.live/plugin/gb28181/v4 v4.4.3
m7s.live/plugin/hdl/v4 v4.1.9
m7s.live/plugin/hls/v4 v4.3.6
m7s.live/plugin/hook/v4 v4.0.2
m7s.live/plugin/jessica/v4 v4.2.1
m7s.live/plugin/logrotate/v4 v4.0.4
m7s.live/plugin/monitor/v4 v4.0.4
m7s.live/plugin/preview/v4 v4.1.2
m7s.live/plugin/record/v4 v4.4.4
m7s.live/plugin/room/v4 v4.0.11
m7s.live/plugin/rtmp/v4 v4.2.7
m7s.live/plugin/rtsp/v4 v4.3.0
m7s.live/plugin/snap/v4 v4.0.7
m7s.live/plugin/webrtc/v4 v4.2.2
m7s.live/plugin/webtransport/v4 v4.0.9
)
require (
github.com/Eyevinn/mp4ff v0.38.0 // indirect
github.com/abema/go-mp4 v1.1.1 // indirect
github.com/aler9/writerseeker v1.1.0 // indirect
github.com/asticode/go-astikit v0.30.0 // indirect
github.com/asticode/go-astits v1.13.0 // indirect
github.com/bluenviron/gohlslib v1.0.0 // indirect
github.com/bluenviron/gortsplib/v4 v4.2.1 // indirect
github.com/bluenviron/mediacommon v1.5.0 // indirect
github.com/cnotch/ipchub v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denisbrodbeck/machineid v1.0.1 // indirect
github.com/discoviking/fsm v0.0.0-20150126104936-f4a273feecca // indirect
github.com/ghettovoice/gosip v0.0.0-20230903092020-b059959586db // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.3.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 // indirect
github.com/google/uuid v1.3.1 // indirect
github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8 // indirect
github.com/logrusorgru/aurora/v4 v4.0.0 // indirect
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect
github.com/marten-seemann/qpack v0.3.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mcuadros/go-defaults v1.2.0 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/onsi/ginkgo/v2 v2.12.1 // indirect
github.com/pion/datachannel v1.5.5 // indirect
github.com/pion/dtls/v2 v2.2.7 // indirect
github.com/pion/ice/v2 v2.3.11 // indirect
github.com/pion/interceptor v0.1.19 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/mdns v0.0.9 // indirect
github.com/pion/randutil v0.1.0 // indirect
github.com/pion/rtcp v1.2.10 // indirect
github.com/pion/rtp v1.8.2 // indirect
github.com/pion/sctp v1.8.9 // indirect
github.com/pion/sdp/v3 v3.0.6 // indirect
github.com/pion/srtp/v2 v2.0.17 // indirect
github.com/pion/stun v0.6.1 // indirect
github.com/pion/transport/v2 v2.2.4 // indirect
github.com/pion/turn/v2 v2.1.3 // indirect
github.com/pion/webrtc/v3 v3.2.20 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
github.com/q191201771/naza v0.30.48 // indirect
github.com/quangngotan95/go-m3u8 v0.1.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
github.com/quic-go/quic-go v0.38.1 // indirect
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect
github.com/shirou/gopsutil/v3 v3.23.8 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/tevino/abool v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
github.com/yapingcat/gomedia v0.0.0-20230905155010-55b9713fcec1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.13.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
m7s.live/plugin/ps/v4 v4.1.3 // indirect
)

473
go.sum
View File

@@ -1,22 +1,457 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/funny/slab v0.0.0-20180511031532-b1fad5e5d478 h1:Db9StoJ6RZN3YttC0Pm0I4Y5izITRYch3RMbT59BYN0=
github.com/funny/slab v0.0.0-20180511031532-b1fad5e5d478/go.mod h1:0j1+svBH8ABEIPdUP0AIg4qedsybnXGJBakCEw8cfoo=
github.com/funny/utest v0.0.0-20161029064919-43870a374500 h1:Z0r1CZnoIWFB/Uiwh1BU5FYmuFe6L5NPi6XWQEmsTRg=
github.com/funny/utest v0.0.0-20161029064919-43870a374500/go.mod h1:mUn39tBov9jKnTWV1RlOYoNzxdBFHiSzXWdY1FoNGGg=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/Eyevinn/mp4ff v0.38.0 h1:9DrGxg0qDTsjJuj7MoE0a8IWZP8AnwfRd98csXgrWhs=
github.com/Eyevinn/mp4ff v0.38.0/go.mod h1:w/6GSa5ghZ1VavzJK6McQ2/flx8mKtcrKDr11SsEweA=
github.com/abema/go-mp4 v1.1.1 h1:OfzkdMO6SWTBR1ltNSVwlTHatrAK9I3iYLQfkdEMMuc=
github.com/abema/go-mp4 v1.1.1/go.mod h1:vPl9t5ZK7K0x68jh12/+ECWBCXoWuIDtNgPtU2f04ws=
github.com/aler9/writerseeker v1.1.0 h1:t+Sm3tjp8scNlqyoa8obpeqwciMNOvdvsxjxEb3Sx3g=
github.com/aler9/writerseeker v1.1.0/go.mod h1:QNCcjSKnLsYoTfMmXkEEfgbz6nNXWxKSaBY+hGJGWDA=
github.com/asticode/go-astikit v0.30.0 h1:DkBkRQRIxYcknlaU7W7ksNfn4gMFsB0tqMJflxkRsZA=
github.com/asticode/go-astikit v0.30.0/go.mod h1:h4ly7idim1tNhaVkdVBeXQZEE3L0xblP7fCWbgwipF0=
github.com/asticode/go-astits v1.13.0 h1:XOgkaadfZODnyZRR5Y0/DWkA9vrkLLPLeeOvDwfKZ1c=
github.com/asticode/go-astits v1.13.0/go.mod h1:QSHmknZ51pf6KJdHKZHJTLlMegIrhega3LPWz3ND/iI=
github.com/bluenviron/gohlslib v1.0.0 h1:UOI7wW7EdXPnnoflPL+WRiUB+bDSyrR9AXtu029n5EY=
github.com/bluenviron/gohlslib v1.0.0/go.mod h1:fwqXogd2G/CJ/0kD6TTALmWI3KAm66nZoI+06O02YKI=
github.com/bluenviron/gortsplib/v4 v4.2.1 h1:LugQr3TIKoj6GjOf470teDP8goWiL8PTrX2OaF+L2Vc=
github.com/bluenviron/gortsplib/v4 v4.2.1/go.mod h1:VOoeI2VxRKh5eEg6Y48DGb/oLxU1i+X0Xzv9z8dvsUQ=
github.com/bluenviron/mediacommon v1.5.0 h1:lS0YKNo22ZOyCsYcLh3jn3TgUALqYw0f7RVwalC09vI=
github.com/bluenviron/mediacommon v1.5.0/go.mod h1:Ij/kE1LEucSjryNBVTyPL/gBI0d6/Css3f5PyrM957w=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/cnotch/apirouter v0.0.0-20200731232942-89e243a791f3/go.mod h1:5deJPLON/x/s2dLOQfuKS0lenhOIT4xX0pvtN/OEIuY=
github.com/cnotch/ipchub v1.1.0 h1:hH0lh2mU3AZXPiqMwA0pdtqrwo7PFIMRGush9OobMUs=
github.com/cnotch/ipchub v1.1.0/go.mod h1:2PbeBs2q2VxxTVCn1eYCDwpAWuVXbq1+N0FU7GimOH4=
github.com/cnotch/loader v0.0.0-20200405015128-d9d964d09439/go.mod h1:oWpDagHB6p+Kqqq7RoRZKyC4XAXft50hR8pbTxdbYYs=
github.com/cnotch/queue v0.0.0-20200326024423-6e88bdbf2ad4/go.mod h1:zOssjAlNusOxvtaqT+EMA+Iyi8rrtKr4/XfzN1Fgoeg=
github.com/cnotch/queue v0.0.0-20201224060551-4191569ce8f6/go.mod h1:zOssjAlNusOxvtaqT+EMA+Iyi8rrtKr4/XfzN1Fgoeg=
github.com/cnotch/scheduler v0.0.0-20200522024700-1d2da93eefc5/go.mod h1:F4GE3SZkJZ8an1Y0ZCqvSM3jeozNuKzoC67erG1PhIo=
github.com/cnotch/xlog v0.0.0-20201208005456-cfda439cd3a0/go.mod h1:RW9oHsR79ffl3sR3yMGgxYupMn2btzdtJUwoxFPUE5E=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMSRhl4D7AQ=
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
github.com/discoviking/fsm v0.0.0-20150126104936-f4a273feecca h1:cTTdXpkQ1aVbOOmHwdwtYuwUZcQtcMrleD1UXLWhAq8=
github.com/discoviking/fsm v0.0.0-20150126104936-f4a273feecca/go.mod h1:W+3LQaEkN8qAwwcw0KC546sUEnX86GIT8CcMLZC4mG0=
github.com/emitter-io/address v1.0.0/go.mod h1:GfZb5+S/o8694B1GMGK2imUYQyn2skszMvGNA5D84Ug=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/ghettovoice/gosip v0.0.0-20230903092020-b059959586db h1:qelpTmyJjcdeMcFKl+iZm5L8EIdV99Qz/3MIUbAm/xk=
github.com/ghettovoice/gosip v0.0.0-20230903092020-b059959586db/go.mod h1:rlD1yLOErWYohWTryG/2bTTpmzB79p52ntLA/uIFXeI=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.1.0-rc.1/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
github.com/gobwas/ws v1.3.0 h1:sbeU3Y4Qzlb+MOzIe6mQGf7QR4Hkv6ZD0qhGkBFL2O0=
github.com/gobwas/ws v1.3.0/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8 h1:gpptm606MZYGaMHMsB4Srmb6EbW/IVHnt04rcMXnkBQ=
github.com/google/pprof v0.0.0-20230912144702-c363fe2c2ed8/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8 h1:4Jk58quTZmzJcTrLlbB5L1Q6qXu49EIjCReWxcBFWKo=
github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8/go.mod h1:medl9/CfYoQlqAXtAARmMW5dAX2UOdwwkhaszYPk0AM=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/kelindar/process v0.0.0-20170730150328-69a29e249ec3/go.mod h1:+lTCLnZFXOkqwD8sLPl6u4erAc0cP8wFegQHfipz7KE=
github.com/kelindar/rate v1.0.0/go.mod h1:AjT4G+hTItNwt30lucEGZIz8y7Uk5zPho6vurIZ+1Es=
github.com/kelindar/tcp v1.0.0/go.mod h1:JB5hj1cshLU60XrLij2BBxW3JQ4hOye8vqbyvuKb52k=
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/logrusorgru/aurora/v4 v4.0.0 h1:sRjfPpun/63iADiSvGGjgA1cAYegEWMPCJdUpJYn9JA=
github.com/logrusorgru/aurora/v4 v4.0.0/go.mod h1:lP0iIa2nrnT/qoFXcOZSrZQpJ1o6n2CUf/hyHi2Q4ZQ=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
github.com/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE=
github.com/marten-seemann/qpack v0.3.0/go.mod h1:cGfKPBiP4a9EQdxCwEwI/GEeWAsjSekBvx/X8mh58+g=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mcuadros/go-defaults v1.2.0 h1:FODb8WSf0uGaY8elWJAkoLL0Ri6AlZ1bFlenk56oZtc=
github.com/mcuadros/go-defaults v1.2.0/go.mod h1:WEZtHEVIGYVDqkKSWBdWKUVdRyKlMfulPaGDWIVeCWY=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.5/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA=
github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/orcaman/writerseeker v0.0.0-20200621085525-1d3f536ff85e h1:s2RNOM/IGdY0Y6qfTeUKhDawdHDpK9RGBdx80qN4Ttw=
github.com/orcaman/writerseeker v0.0.0-20200621085525-1d3f536ff85e/go.mod h1:nBdnFKj15wFbf94Rwfq4m30eAcyY9V/IyKAGQFtqkW0=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8=
github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0=
github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8=
github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s=
github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw=
github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E=
github.com/pion/interceptor v0.1.18/go.mod h1:tpvvF4cPM6NGxFA1DUMbhabzQBxdWMATDGEUYOR9x6I=
github.com/pion/interceptor v0.1.19 h1:tq0TGBzuZQqipyBhaC1mVUCfCh8XjDKUuibq9rIl5t4=
github.com/pion/interceptor v0.1.19/go.mod h1:VANhFxdJezB8mwToMMmrmyHyP9gym6xLqIUch31xryg=
github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY=
github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms=
github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI=
github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4=
github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc=
github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA=
github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8=
github.com/pion/rtcp v1.2.10 h1:nkr3uj+8Sp97zyItdN60tE/S6vk4al5CPRR6Gejsdjc=
github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I=
github.com/pion/rtp v1.6.2/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
github.com/pion/rtp v1.8.1/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/rtp v1.8.2 h1:oKMM0K1/QYQ5b5qH+ikqDSZRipP5mIxPJcgcvw5sH0w=
github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU=
github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0=
github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs=
github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g=
github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI=
github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw=
github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw=
github.com/pion/srtp/v2 v2.0.17 h1:ECuOk+7uIpY6HUlTb0nXhfvu4REG2hjtC4ronYFCZE4=
github.com/pion/srtp/v2 v2.0.17/go.mod h1:y5WSHcJY4YfNB/5r7ca5YjHeIr1H3LM1rKArGGs8jMc=
github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4=
github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8=
github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40=
github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI=
github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g=
github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc=
github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo=
github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0=
github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM=
github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0=
github.com/pion/turn/v2 v2.1.3 h1:pYxTVWG2gpC97opdRc5IGsQ1lJ9O/IlNhkzj7MMrGAA=
github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY=
github.com/pion/webrtc/v3 v3.2.20 h1:BQJiXQsJq9LgLp3op7rLy1y8d2WD+LtiS9cpY0uQ22A=
github.com/pion/webrtc/v3 v3.2.20/go.mod h1:vVURQTBOG5BpWKOJz3nlr23NfTDeyKVmubRNqzQp+Tg=
github.com/pixelbender/go-sdp v1.1.0/go.mod h1:6IBlz9+BrUHoFTea7gcp4S54khtOhjCW/nVDLhmZBAs=
github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig=
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/q191201771/naza v0.30.48 h1:lbYUaa7A15kJKYwOiU4AbFS1Zo8oQwppl2tLEbJTqnw=
github.com/q191201771/naza v0.30.48/go.mod h1:n+dpJjQSh90PxBwxBNuifOwQttywvSIN5TkWSSYCeBk=
github.com/quangngotan95/go-m3u8 v0.1.0 h1:8oseBjJn5IKHQKdRZwSNskkua3NLrRtlvXXtoVgBzMk=
github.com/quangngotan95/go-m3u8 v0.1.0/go.mod h1:smzfWHlYpBATVNu1GapKLYiCtEo5JxridIgvvudZ+Wc=
github.com/shirou/gopsutil v2.19.12+incompatible h1:WRstheAymn1WOPesh+24+bZKFkqrdCR8JOc77v4xV3Q=
github.com/shirou/gopsutil v2.19.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE=
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4=
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybLANtM3mBXNUtOfsCFXeTsnBqCsx1KM=
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE=
github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518/go.mod h1:CKI4AZ4XmGV240rTHfO0hfE83S6/a3/Q1siZJ/vXf7A=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/sunfish-shogi/bufseekio v0.0.0-20210207115823-a4185644b365/go.mod h1:dEzdXgvImkQ3WLI+0KQpmEx8T/C/ma9KeS3AfmU899I=
github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5/go.mod h1:f1SCnEOt6sc3fOJfPQDRDzHOtSXuTtnz0ImG9kPRDV0=
github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA=
github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/yapingcat/gomedia v0.0.0-20230905155010-55b9713fcec1 h1:ilNIuDBR+UKA3qefiyWRoFufIFn3E4tgEXbBM4ILH28=
github.com/yapingcat/gomedia v0.0.0-20230905155010-55b9713fcec1/go.mod h1:WSZ59bidJOO40JSJmLqlkBJrjZCtjbKKkygEMfzY/kc=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg=
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
m7s.live/engine/v4 v4.14.0 h1:bvsRe2Ho8M95X9SZ/Sw+pzHJRWmt+f7F7S8LwfS8tHU=
m7s.live/engine/v4 v4.14.0/go.mod h1:cRR/WOZbPSAQfYxIHuCkj1YMg+C54CYlFpOJ88q+OG4=
m7s.live/plugin/debug/v4 v4.0.1 h1:sX0UADsiikwSol8qx+8aQzGeaFa8yJFa/cUKpBs5Lzw=
m7s.live/plugin/debug/v4 v4.0.1/go.mod h1:A/C1ViacCOK7EPeeCfiwlUrC2TUtRdEqzrR0Yd9b1KQ=
m7s.live/plugin/fmp4/v4 v4.0.5 h1:0madI/TKvrLkYVAKuPK1HBvbVf0RJg0g2WruET3S+9c=
m7s.live/plugin/fmp4/v4 v4.0.5/go.mod h1:4ShxA9Ud2LeYZ/xQaPTWEVfjpK844ijoXxLqhCA607A=
m7s.live/plugin/gb28181/v4 v4.4.3 h1:Vrgtgq8bstX2R7EtuSjiqEHjwaP74HpRanvhNsr2kEk=
m7s.live/plugin/gb28181/v4 v4.4.3/go.mod h1:mK5embLQwDULFJjA7jBls1Cwvow98lTWS6n/uZ7Ampk=
m7s.live/plugin/hdl/v4 v4.1.9 h1:exhX4sEjvlkUknz1/np9kldjMkGgRFwBxs567XLPo24=
m7s.live/plugin/hdl/v4 v4.1.9/go.mod h1:SzMML8acGj8QD5AwihVTnTuCAdKCOpdf+q/CYl/3/Hc=
m7s.live/plugin/hls/v4 v4.3.6 h1:yEfwpv8WZLMqnrnsO8gu6IuKAMP1oblTcuA5CMzKbE8=
m7s.live/plugin/hls/v4 v4.3.6/go.mod h1:ol/+hCmdqip2Ns1zIDXHWoDD7xk5Dp76AhqlIwrbRSc=
m7s.live/plugin/hook/v4 v4.0.2 h1:fKwsx7gDAzfKfCz0C+knoY4wg/qnlQloM996l3jUWNc=
m7s.live/plugin/hook/v4 v4.0.2/go.mod h1:zoyGSwIIdt4NGFdqrKHLFCwwMk4oAOF+dlvSV6cizGU=
m7s.live/plugin/jessica/v4 v4.2.1 h1:GbQ8V2ElHT7Q/0y1cyXCzw/DvTnqkpP1kCOpVd+0d6Y=
m7s.live/plugin/jessica/v4 v4.2.1/go.mod h1:62tI6vio/PkJhuIbkrIKZm9jAEHwkzXe4Uk1EJaK5iQ=
m7s.live/plugin/logrotate/v4 v4.0.4 h1:y3X+aJ/FSftWMa4yDWF+662xfV5lrEaOZofV8SGQLTc=
m7s.live/plugin/logrotate/v4 v4.0.4/go.mod h1:a8hIV59GjpQDE+Ip790CU7yOHaG4+Iweci0sLvo43FU=
m7s.live/plugin/monitor/v4 v4.0.4 h1:vJ/gZctUej9s5ukjsNXDvl6JWqK5I+7L6W0REXR2Xpg=
m7s.live/plugin/monitor/v4 v4.0.4/go.mod h1:wYcjvXM03RK00DGA/R7zfiENNT7jDFQhp0rEBvO1mTw=
m7s.live/plugin/preview/v4 v4.1.2 h1:ENjeg36xWiPqI2FM0lJzs0t8gyeomEvUFtT5ygu+BrQ=
m7s.live/plugin/preview/v4 v4.1.2/go.mod h1:iYhWqFbTvTNDFplbTOrE5X9M6ED7gCKkKMuM5QmBocg=
m7s.live/plugin/ps/v4 v4.1.3 h1:Lbvu3ZlX/s3w9lcOwF0SCOCvxtxongPexCIn6x4yukw=
m7s.live/plugin/ps/v4 v4.1.3/go.mod h1:RAb507iNmPG43I5kUA6ewF1fTRHDRsKbIVkIdLdKeeI=
m7s.live/plugin/record/v4 v4.4.4 h1:zP+fgDPmLlm+9eEnKNVfvKB3gjuB0M1P1sE4Gzgjo5M=
m7s.live/plugin/record/v4 v4.4.4/go.mod h1:lwVE6xn4sGQBLOWgshw3L1fa5zyEM7NlmQ8otTQGXUY=
m7s.live/plugin/room/v4 v4.0.11 h1:a4XOzHmsTrvi3N809IMaFGpimiJUMz8D9+BRnBk44Oc=
m7s.live/plugin/room/v4 v4.0.11/go.mod h1:bGNV2Me/k2KBfbO+fiUdC+HKJBE2wS84HczzSHfrSAI=
m7s.live/plugin/rtmp/v4 v4.2.7 h1:eQtrcTuuBZVInvRaDUROcLMeLXJWXo79LAnymRd0L3Y=
m7s.live/plugin/rtmp/v4 v4.2.7/go.mod h1:UqI1l1+3Y2zg2oOUkfVJ719hcv10bMYVAlg5e+gqy2E=
m7s.live/plugin/rtsp/v4 v4.3.0 h1:Q6R7uijgtzCPFbe1JBvB2x7IUs/KV7fvn52UQHoc9Cw=
m7s.live/plugin/rtsp/v4 v4.3.0/go.mod h1:P4cRC2F3f84Vh7Vjjkjv7GZtzKuEVmeNW1NN406K9vY=
m7s.live/plugin/snap/v4 v4.0.7 h1:9otl/K5Iq+wlnrcTEIOnBXGarNXd+Fl4r+684Uz+V+k=
m7s.live/plugin/snap/v4 v4.0.7/go.mod h1:XHggonZ0lIKEX/OP2rXjV2mPpG4urmvMT3foIaFRsus=
m7s.live/plugin/webrtc/v4 v4.2.2 h1:QV+ghnBFnKleWm072Pptmrta+SxNyR8PvCAafuIo4W4=
m7s.live/plugin/webrtc/v4 v4.2.2/go.mod h1:R8KUay6qQ1nQCUFwqUgI7OXSD0Hgv9dBifrZUmD2suE=
m7s.live/plugin/webtransport/v4 v4.0.9 h1:G1HUDgi1MvdOE08XIES5bI/cRTy7LrtCU/StCql+f6o=
m7s.live/plugin/webtransport/v4 v4.0.9/go.mod h1:OBTNwQ4TLMaWV4C6Q2un1YKEJaMwk26qdgfI3hX1+qw=

Some files were not shown because too many files have changed in this diff Show More