Compare commits
250 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f8e50d00f5 | ||
![]() |
361b0522e1 | ||
![]() |
27784f0a03 | ||
![]() |
34394b99cf | ||
![]() |
f56a6c972c | ||
![]() |
7138565443 | ||
![]() |
a521c63036 | ||
![]() |
ed5e7196f7 | ||
![]() |
664a64a025 | ||
![]() |
f097e66069 | ||
![]() |
2e8d4d2f3a | ||
![]() |
8bb63c9298 | ||
![]() |
c0b2a10601 | ||
![]() |
3179b892d6 | ||
![]() |
ef3a85ec21 | ||
![]() |
1a57aeb2a2 | ||
![]() |
85b134d333 | ||
![]() |
9969966b52 | ||
![]() |
5482ab4157 | ||
![]() |
6a78440a61 | ||
![]() |
61eaaab78f | ||
![]() |
54f01a064c | ||
![]() |
09570a6515 | ||
![]() |
00ff25e173 | ||
![]() |
f0735d3883 | ||
![]() |
314191abaf | ||
![]() |
33b5c465b6 | ||
![]() |
2b1bf24fb9 | ||
![]() |
4653f7b511 | ||
![]() |
86b16fe3fb | ||
![]() |
d05bd7bc55 | ||
![]() |
6f9fe7c646 | ||
![]() |
96d886c7a5 | ||
![]() |
ca2f69539d | ||
![]() |
0fd608aefc | ||
![]() |
d5e6a517fb | ||
![]() |
e035cf0846 | ||
![]() |
e7ff340c7a | ||
![]() |
91d1d5502b | ||
![]() |
b1ef460af1 | ||
![]() |
87f08066e5 | ||
![]() |
da69aae5fa | ||
![]() |
6e8081a411 | ||
![]() |
2f7bc14986 | ||
![]() |
504e22b558 | ||
![]() |
c7b2cbfee3 | ||
![]() |
70b5c553b9 | ||
![]() |
4486c612e4 | ||
![]() |
29f574ae73 | ||
![]() |
d12052eb4a | ||
![]() |
7a0964b501 | ||
![]() |
67ad3e669d | ||
![]() |
6c78c2f456 | ||
![]() |
16cf7725f3 | ||
![]() |
9d08fa47b3 | ||
![]() |
9b6e9bfbec | ||
![]() |
a18fc77b8b | ||
![]() |
edd7a6f047 | ||
![]() |
9ec70f0454 | ||
![]() |
6ca479371e | ||
![]() |
f65bd3a760 | ||
![]() |
91a9171c5c | ||
![]() |
0b51fecf48 | ||
![]() |
493bce72cb | ||
![]() |
a48057e713 | ||
![]() |
2dd008d960 | ||
![]() |
3f7e7b3666 | ||
![]() |
0791151557 | ||
![]() |
69f5d9d976 | ||
![]() |
dec17c1f26 | ||
![]() |
e6069322f8 | ||
![]() |
36ede9b9a2 | ||
![]() |
e4bc0ad5ea | ||
![]() |
33a58b0641 | ||
![]() |
cb71b2c7e2 | ||
![]() |
38b8923e6f | ||
![]() |
8b483e5139 | ||
![]() |
34c21e5e8f | ||
![]() |
b8a23517ba | ||
![]() |
d491b6206a | ||
![]() |
93ce7391a5 | ||
![]() |
611bd78b5c | ||
![]() |
b112187125 | ||
![]() |
e0c35fce2b | ||
![]() |
7bcf2cba27 | ||
![]() |
da5f970067 | ||
![]() |
711b4cc82c | ||
![]() |
f1bcb6f2c9 | ||
![]() |
306a7ffeff | ||
![]() |
9c8a2c5d83 | ||
![]() |
1a67f63932 | ||
![]() |
c761c6ce9b | ||
![]() |
cc9c0d67e2 | ||
![]() |
6df2a3b842 | ||
![]() |
c38bd36ecc | ||
![]() |
a769f1cbf4 | ||
![]() |
8ec0515f60 | ||
![]() |
e2113e03df | ||
![]() |
56bbc0ddf8 | ||
![]() |
563f966fe4 | ||
![]() |
0e3befd285 | ||
![]() |
e60871b55b | ||
![]() |
785be6a939 | ||
![]() |
7684856ccc | ||
![]() |
2e76b74e74 | ||
![]() |
e67b3f3bc8 | ||
![]() |
c17302a8fc | ||
![]() |
02738a1482 | ||
![]() |
0e1fe9a713 | ||
![]() |
8a059c51a9 | ||
![]() |
07a34d2642 | ||
![]() |
7dca6c9411 | ||
![]() |
eddbb35136 | ||
![]() |
65c3d90275 | ||
![]() |
531bcd57f1 | ||
![]() |
18bbedcff5 | ||
![]() |
6a2818916a | ||
![]() |
612501a403 | ||
![]() |
ca3397e544 | ||
![]() |
d01d254caa | ||
![]() |
7574a6ba6f | ||
![]() |
4c918df6e6 | ||
![]() |
f677beb2b7 | ||
![]() |
3adaedf6fc | ||
![]() |
5a9cf53485 | ||
![]() |
bff77f1365 | ||
![]() |
b608c38aec | ||
![]() |
d8537ec3a3 | ||
![]() |
c055f7fceb | ||
![]() |
afb0efb2ee | ||
![]() |
51832cd9a7 | ||
![]() |
454e19f8c0 | ||
![]() |
62111b41d1 | ||
![]() |
0eca8fd657 | ||
![]() |
ca16d405d0 | ||
![]() |
e1d500447a | ||
![]() |
e7da10649c | ||
![]() |
ccd0320090 | ||
![]() |
ee9d4d06b4 | ||
![]() |
089cc593be | ||
![]() |
9abd76b1e5 | ||
![]() |
6e65cc20a2 | ||
![]() |
ff71c7bd5a | ||
![]() |
8648f2ae20 | ||
![]() |
70e7fae954 | ||
![]() |
48b7ff1dee | ||
![]() |
d46e0d45b2 | ||
![]() |
5b41f67b80 | ||
![]() |
3a8b371560 | ||
![]() |
8abae09574 | ||
![]() |
476bb4a656 | ||
![]() |
bf5b4010d7 | ||
![]() |
8cee5c2c18 | ||
![]() |
43632cf852 | ||
![]() |
e4e96f8fc1 | ||
![]() |
57acc5f357 | ||
![]() |
23faad4405 | ||
![]() |
ec86b455a9 | ||
![]() |
f848e90a50 | ||
![]() |
7d05e4cc6c | ||
![]() |
b66e52a90f | ||
![]() |
da6554f536 | ||
![]() |
2b8e8bca98 | ||
![]() |
9009431a1f | ||
![]() |
99b9cc674f | ||
![]() |
67b338007a | ||
![]() |
111ba8aa5a | ||
![]() |
d5ab178841 | ||
![]() |
3a3dd3c73c | ||
![]() |
75865960c6 | ||
![]() |
bb4c39886d | ||
![]() |
4e92f395bf | ||
![]() |
64cf6e609d | ||
![]() |
65bbb5c04f | ||
![]() |
b0c6bff8ae | ||
![]() |
439eb0afc0 | ||
![]() |
f7e6c5084c | ||
![]() |
e0f424fd2c | ||
![]() |
98995de88a | ||
![]() |
b5c5976312 | ||
![]() |
c6dbda22f9 | ||
![]() |
1e78f687d7 | ||
![]() |
701b9b63f3 | ||
![]() |
58f134cda1 | ||
![]() |
d772ed3336 | ||
![]() |
fc4f13fa00 | ||
![]() |
2ee71755b7 | ||
![]() |
7e165fe9d4 | ||
![]() |
dd7a2e8dc7 | ||
![]() |
bd7f5249aa | ||
![]() |
bb9a154a00 | ||
![]() |
e3c7c9514e | ||
![]() |
b3a485ddfb | ||
![]() |
01a74b245e | ||
![]() |
4482f0232f | ||
![]() |
919f7ad78b | ||
![]() |
0c1f1c9770 | ||
![]() |
18a9398f66 | ||
![]() |
5828b8d803 | ||
![]() |
c328db87a8 | ||
![]() |
cc89bbb61b | ||
![]() |
cd34607c86 | ||
![]() |
cfb6dacf73 | ||
![]() |
eba5b6b8f1 | ||
![]() |
597407a4e5 | ||
![]() |
3fcd22d1e7 | ||
![]() |
65de4806c4 | ||
![]() |
55eb2218be | ||
![]() |
5c0b22b1df | ||
![]() |
474581d9b1 | ||
![]() |
3907422b3e | ||
![]() |
d3b7fa04ef | ||
![]() |
d16aa756f8 | ||
![]() |
8304314e49 | ||
![]() |
c2d0cbb1d0 | ||
![]() |
67ab443f1a | ||
![]() |
c80beec8f3 | ||
![]() |
1ce4fd2db0 | ||
![]() |
a20f30d76d | ||
![]() |
afa44eb173 | ||
![]() |
592034adce | ||
![]() |
6e8ac88aaf | ||
![]() |
da66df9302 | ||
![]() |
360f7faf35 | ||
![]() |
bee477e685 | ||
![]() |
4a0c4e36e7 | ||
![]() |
1ed3e6249f | ||
![]() |
1ac06ef252 | ||
![]() |
620d96b39c | ||
![]() |
66a396df0b | ||
![]() |
029abe3187 | ||
![]() |
40fba0d348 | ||
![]() |
73941d1e0b | ||
![]() |
709c2c6ac7 | ||
![]() |
f96bc11ddb | ||
![]() |
5563ddc0d2 | ||
![]() |
95657bd6df | ||
![]() |
b9e19e75c8 | ||
![]() |
eac623639d | ||
![]() |
fea6e98ca7 | ||
![]() |
649a5b558a | ||
![]() |
b3c8d35fad | ||
![]() |
ab745145d9 | ||
![]() |
a1bdc8528b | ||
![]() |
ecb931ccb0 | ||
![]() |
13c357493f | ||
![]() |
87776b9540 | ||
![]() |
543d735c41 | ||
![]() |
966f9b9d0d | ||
![]() |
5eb7f03dec |
13
.github/FUNDING.yml
vendored
Normal 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']
|
76
.github/workflows/go.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
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.18
|
||||
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: runner.os−go−{ { 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
|
||||
releaseinfo=`curl -H "Accept: application/vnd.github+json" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/${{ github.repository }}/releases/latest`
|
||||
body=`echo $releaseinfo | jq ".body" | sed -e 's/^"//' -e 's/"$//'`
|
||||
name=`echo $releaseinfo | jq ".name" | sed -e 's/^"//' -e 's/"$//'`
|
||||
touch apps/m7s-website/src/release.txt
|
||||
echo -e "# $name\n$body" | cat - apps/m7s-website/src/release.txt > temp && mv temp apps/m7s-website/src/release.txt
|
||||
sed "/## Changelog/d" -i apps/m7s-website/src/release.txt
|
||||
git config --global user.name 'langhuihui'
|
||||
git config --global user.email '178529795@qq.com'
|
||||
git add -A
|
||||
git commit -m '[automated commit] add bin & GitHub workflow'
|
||||
|
||||
- name: push to m7s-import
|
||||
uses: ad-m/github-push-action@master
|
||||
if: success() && startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
github_token: ${{ secrets.TOKEN }}
|
||||
directory: m7s-import
|
||||
repository: langhuihui/m7s-import
|
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
*.exe
|
||||
.vscode
|
||||
.idea
|
||||
resource
|
||||
*.log
|
||||
/monibuca
|
||||
node_modules
|
||||
shutdown.bat
|
||||
shutdown.sh
|
||||
.m7s
|
||||
debug.go
|
||||
dist/
|
||||
record/
|
||||
config2.yaml
|
||||
config1.yaml
|
13
Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
#源镜像
|
||||
FROM alpine:latest
|
||||
|
||||
WORKDIR /opt
|
||||
|
||||
ADD monibuca /opt
|
||||
ADD monibuca.com.key /opt
|
||||
ADD monibuca.com.pem /opt
|
||||
#暴露端口
|
||||
EXPOSE 8080 8081 1935 554 58200 5060 8000-9000
|
||||
EXPOSE 5060/udp 58200/udp 8000-9000/udp
|
||||
#最终运行docker的命令
|
||||
ENTRYPOINT ["./m7s"]
|
21
LICENSE
Normal 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.
|
88
README.md
@@ -1 +1,87 @@
|
||||
[中文文档](http://monibuca.com/docs)
|
||||
# 主页
|
||||
|
||||
[https://m7s.live](https://m7s.live)
|
||||
|
||||
# 中文文档
|
||||
|
||||
[https://m7s.live/guide/introduction.html](https://m7s.live/guide/introduction.html)
|
||||
|
||||
# 文章
|
||||
|
||||
[重新定义流媒体服务器](https://www.infoq.cn/article/uiPl8dIuQmhipKb3q3Tz)
|
||||
|
||||
# 核心代码库和插件代码库
|
||||
|
||||
[https://github.com/Monibuca](https://github.com/Monibuca)
|
||||
|
||||
# 介绍
|
||||
|
||||
## 什么是Monibuca(m7s)?
|
||||
|
||||
Monibuca(发音:模拟不卡,m7s是其缩写,类似k8s) 是一个开源的Go语言开发的流媒体服务器开发框架。
|
||||
它基于go1.18+,此外并无任何其他依赖构建,并提供了一套插件式的二次开发模型,帮助你高效地开发流媒体服务器,你既可以直接使用官方提供的插件,也可以自己开发插件扩展任意的功能,所以Monibuca是可以支持**任意**流媒体协议的框架!
|
||||
|
||||
|
||||
> 流媒体服务器是一种用于分发流媒体的服务器端软件,可用于直播、监控、会议等需要实时观看音视频的场景。流媒体服务器区别于传统Web服务器对于实时性要求极高,需要使用各种传输协议,而Web服务器则主要以http/https协议为主。
|
||||
|
||||
Monibuca由三部分组成:引擎、插件、实例工程。
|
||||
- 引擎提供一套通用的流媒体数据缓存以及转发的机制,本身不关心协议如何实现
|
||||
- 插件提供其他所有的功能,并可以无限扩展
|
||||
- 实例工程是引入引擎和插件并启动引擎的项目工程,可以完全自己编写
|
||||
|
||||
## 插件式框架
|
||||
|
||||
Monibuca旨在构建一个通用的流媒体开发生态,所以从v1版本开始就考虑到业务和流转发的解耦,从而设计了一套可供任意扩展的插件机制。根据你的需求场景,可以灵活引入不同类型的插件:
|
||||
- 提供流媒体协议打包/解包,例如rtmp插件、rtsp插件等
|
||||
- 提供日志持久化的处理——logrotate插件
|
||||
- 提供录像功能——record插件
|
||||
- 提供丰富的调试功能——debug插件
|
||||
- 提供http回调能力——http插件
|
||||
|
||||
如果你是有经验的开发者,那么最佳的方式是在现有的插件基础上进行二次开发,并可向更多的人提供可重用的插件丰富生态。
|
||||
如果你是流媒体的初学者,那么最佳的方式是利用现有的插件拼凑出你需要的功能,并向有经验的开发者寻求帮助。
|
||||
|
||||
|
||||
## 名称的由来
|
||||
Monibuca这个单词来源于 `Monica` (莫妮卡),为了解决起名的难题,使用了三个名称分别是 `Monica` 、 `Jessica` 、`Rebecca` 用来代表服务器、播放器、推流器。由于莫妮卡、杰西卡、瑞贝卡,都带卡字,对直播来说寓意不好,所以改为莫妮不卡(`Monibuca`)、杰西不卡[Jessibuca](https://jessibuca.com)、瑞贝不卡[Rebebuca](https://rebebuca.com)。
|
||||
|
||||
## 安装
|
||||
- 官方提供已编译好的各个平台的二进制可执行文件(即绿色软件),所以无需安装任何其他软件即可运行。
|
||||
- 如果需要自己编译启动工程,则需要安装go1.18以上版本。
|
||||
|
||||
:::tip 配置go环境
|
||||
- go可以在https://golang.google.cn/dl 中下载到
|
||||
- 国内需要执行go env -w GOPROXY=https://goproxy.cn 来下载到被屏蔽的第三方库
|
||||
:::
|
||||
|
||||
官方提供了最新版本的下载链接:
|
||||
- [Linux](https://m7s.live/bin/m7s_linux_x86)
|
||||
- [Linux-arm64](https://m7s.live/bin/m7s_linux_arm64)
|
||||
- [Mac](https://m7s.live/bin/m7s_darwin_x86)
|
||||
- [Mac-arm64](https://m7s.live/bin/m7s_darwin_arm64)
|
||||
- [Windows](https://m7s.live/bin/m7s_windows_x86)
|
||||
|
||||
## 运行
|
||||
|
||||
### 可执行文件直接运行
|
||||
|
||||
- Linux 例如下载到了/opt/m7s_linux_x86,则 `cd /opt` 然后 `./m7s_linux_x86`
|
||||
- Mac 和Linux类似,需要注意的时候可能需要修改文件的可执行权限,也可以双击运行
|
||||
- Windows,直接双击m7s_windows_x86.exe即可启动
|
||||
|
||||
:::tip 运行多实例
|
||||
由于实例会监听http端口,所以如果需要运行多实例,就需要为每个实例指定不同的http端口,因此需要启动时指定配置文件,例如./m7s_linux_x86 -c config.yaml
|
||||
:::
|
||||
|
||||
### 自行编译启动工程
|
||||
1. `git clone https://github.com/langhuihui/monibuca`
|
||||
2. `cd monibuca`
|
||||
3. `go run main.go`
|
||||
|
||||
### 自行创建启动工程
|
||||
|
||||
可以观看视频教程:
|
||||
|
||||
- [从零启动 m7s V4](https://www.bilibili.com/video/BV1iq4y147N4/)
|
||||
|
||||
- [m7s v4 视频教程——插件引入](https://www.bilibili.com/video/BV1sP4y1g7BF/)
|
18
config.toml
@@ -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"]
|
36
config.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
# 支持零配置启动,即无需填写配置默认启用所有的插件。
|
||||
# 只需要填写需要修改的配置项即可。不需要将所有的配置都填写进来!!。
|
||||
# 全局配置参考 https://m7s.live/guide/config.html
|
||||
# 插件配置参考各个插件的文档
|
||||
# 插件都有一个enable配置,如果为false则不启用该插件,默认为true即不需要配置。
|
||||
|
||||
# global:
|
||||
# console:
|
||||
# secret: "ab0f6913670062af4d2f15c621205178"
|
||||
# http:
|
||||
# listenaddrtls: :8081
|
||||
# certfile: monibuca.com.pem
|
||||
# keyfile: monibuca.com.key
|
||||
# record:
|
||||
# enable: false
|
||||
# hls:
|
||||
# autorecord: true
|
||||
# fragment: 20
|
||||
# webtransport:
|
||||
# enable: false
|
||||
# certfile: monibuca.com.pem
|
||||
# keyfile: monibuca.com.key
|
||||
# gb28181:
|
||||
# # enable: false
|
||||
# rtsp:
|
||||
# # enable: false
|
||||
# pull:
|
||||
# pullonstart: true
|
||||
# pulllist:
|
||||
# live/rtsp: rtsp://admin:MOMA2021@47.94.226.17/Streaming/Channels/201?transportmode=unicast
|
||||
# hls:
|
||||
# # enable: false
|
||||
# pull:
|
||||
# pullonstart: true
|
||||
# pulllist:
|
||||
# live/hls: http://111.40.196.27/PLTV/88888888/224/3221225548/index.m3u8
|
11
config2.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
global:
|
||||
http:
|
||||
listenaddr: :8080
|
||||
rtsp:
|
||||
listenaddr: :8554
|
||||
rtmp:
|
||||
enable: false
|
||||
webtransport:
|
||||
enable: false
|
||||
hls:
|
||||
enable: false
|
21
dashboard/.gitignore
vendored
@@ -1,21 +0,0 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
|
||||
|
||||
# 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?
|
@@ -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/).
|
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
|
||||
}
|
1
dashboard/dist/css/app.b4fc79e8.css
vendored
@@ -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-7b106554{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes recording-data-v-7b106554{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.recording[data-v-7b106554]{-webkit-animation:recording-data-v-7b106554 1s infinite;animation:recording-data-v-7b106554 1s infinite}.layout[data-v-7b106554]{padding-bottom:30px;position:relative}.room[data-v-7b106554]{width:250px;margin:10px;text-align:left}.empty[data-v-7b106554]{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-7b106554],.status[data-v-7b106554]{display:-webkit-box;display:-ms-flexbox;display:flex}.status[data-v-7b106554]{position:fixed;left:5px;bottom:10px}.status>div[data-v-7b106554]{margin:0 5px}
|
17
dashboard/dist/docs/404.html
vendored
@@ -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>
|
@@ -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 |
1
dashboard/dist/docs/assets/js/1.83ce04b6.js
vendored
1
dashboard/dist/docs/assets/js/2.142d04d2.js
vendored
1
dashboard/dist/docs/assets/js/3.2b6c987b.js
vendored
@@ -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}}]);
|
1
dashboard/dist/docs/assets/js/4.ad90d74a.js
vendored
@@ -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}}]);
|
1
dashboard/dist/docs/assets/js/5.36121818.js
vendored
@@ -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}}]);
|
173
dashboard/dist/docs/develop.html
vendored
@@ -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">"github.com/langhuihui/monibuca/monica"</span>
|
||||
<span class="token string">"log"</span>
|
||||
<span class="token string">"net/http"</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">&</span>PluginConfig<span class="token punctuation">{</span>
|
||||
Name<span class="token punctuation">:</span> <span class="token string">"Jessica"</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">"server Jessica start at %s"</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">"github.com/langhuihui/monibuca/monica"</span>
|
||||
<span class="token string">"github.com/langhuihui/monibuca/monica/avformat"</span>
|
||||
<span class="token string">"github.com/langhuihui/monibuca/monica/pool"</span>
|
||||
<span class="token string">"log"</span>
|
||||
<span class="token string">"net/http"</span>
|
||||
<span class="token string">"strings"</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">&</span>PluginConfig<span class="token punctuation">{</span>
|
||||
Name<span class="token punctuation">:</span> <span class="token string">"HDL"</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">"HDL start at %s"</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">"sign"</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">"/"</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">".flv"</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">".flv"</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(&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">"Transfer-Encoding"</span><span class="token punctuation">,</span> <span class="token string">"chunked"</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">"Content-Type"</span><span class="token punctuation">,</span> <span class="token string">"video/x-flv"</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">"FLV"</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">"tcp"</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">"tcp"</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">&</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">&&</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">></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">>></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">","</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>
|
26
dashboard/dist/docs/history.html
vendored
@@ -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>
|
54
dashboard/dist/docs/index.html
vendored
@@ -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">"github.com/langhuihui/monibuca/monica"</span>
|
||||
<span class="token boolean">_</span> <span class="token string">"github.com/langhuihui/monibuca/plugins"</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">"config.toml"</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">":2020"</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">":8080"</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">":1935"</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">":81"</span>
|
||||
<span class="token comment">#[Plugins.Cluster]</span>
|
||||
<span class="token comment">#Master = "localhost:2019"</span>
|
||||
<span class="token comment">#ListenAddr = ":2019"</span>
|
||||
<span class="token comment">#</span>
|
||||
<span class="token comment">#[Plugins.Auth]</span>
|
||||
<span class="token comment">#Key="www.monibuca.com"</span>
|
||||
<span class="token comment">#[Plugins.RecordFlv]</span>
|
||||
<span class="token comment">#Path="./resouce"</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">"high"</span><span class="token punctuation">,</span><span class="token string">"medium"</span><span class="token punctuation">,</span><span class="token string">"low"</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>
|
19
dashboard/dist/docs/plugins/index.html
vendored
@@ -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>
|
26
dashboard/dist/docs/plugins/jessica.html
vendored
@@ -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">":8080"</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>
|
80
dashboard/dist/docs/service-worker.js
vendored
@@ -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, {});
|
BIN
dashboard/dist/favicon.ico
vendored
Before Width: | Height: | Size: 21 KiB |
BIN
dashboard/dist/fonts/ionicons.143146fa.woff2
vendored
BIN
dashboard/dist/fonts/ionicons.99ac3308.woff
vendored
BIN
dashboard/dist/fonts/ionicons.d535a25a.ttf
vendored
BIN
dashboard/dist/img/alipay.e872ea78.png
vendored
Before Width: | Height: | Size: 38 KiB |
870
dashboard/dist/img/ionicons.a2c4a261.svg
vendored
Before Width: | Height: | Size: 542 KiB |
BIN
dashboard/dist/img/logo.b5357057.png
vendored
Before Width: | Height: | Size: 4.8 KiB |
BIN
dashboard/dist/img/wechat.ff453262.jpg
vendored
Before Width: | Height: | Size: 102 KiB |
1
dashboard/dist/index.html
vendored
@@ -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.b4fc79e8.css rel=preload as=style><link href=/css/chunk-vendors.22ebf426.css rel=preload as=style><link href=/js/app.9cc902b4.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.b4fc79e8.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.9cc902b4.js></script></body></html>
|
535
dashboard/dist/jessibuca/ajax.js
vendored
@@ -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;
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
25
dashboard/dist/jessibuca/ff.js
vendored
460
dashboard/dist/jessibuca/renderer.js
vendored
@@ -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() })
|
||||
}
|
2
dashboard/dist/js/app.9cc902b4.js
vendored
1
dashboard/dist/js/app.9cc902b4.js.map
vendored
44
dashboard/dist/js/chunk-vendors.ae8ac63d.js
vendored
@@ -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/'
|
||||
}
|
@@ -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
|
||||
)
|
||||
})
|
||||
}
|
@@ -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"]
|
||||
```
|
||||
具体配置的含义,可以参考每个插件的说明
|
@@ -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函数
|
||||
|
||||
## 开发钩子插件
|
||||
|
@@ -1,4 +0,0 @@
|
||||
# 更新历史
|
||||
|
||||
- 2020/1/27
|
||||
1.0完成
|
@@ -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
@@ -1,63 +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": {
|
||||
"vue/no-parsing-error": [
|
||||
2,
|
||||
{
|
||||
"x-invalid-end-tag": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions"
|
||||
]
|
||||
}
|
@@ -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>
|
@@ -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 |
@@ -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}}]);
|
@@ -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}}]);
|
@@ -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}}]);
|
@@ -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}}]);
|
@@ -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}}]);
|
@@ -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}}]);
|
@@ -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}}]);
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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, {});
|
Before Width: | Height: | Size: 21 KiB |
@@ -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>
|
@@ -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;
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -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() })
|
||||
}
|
@@ -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>
|
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 102 KiB |
@@ -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>
|
||||
|
@@ -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>
|
@@ -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')
|
@@ -1,6 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import ViewUI from 'view-design'
|
||||
|
||||
Vue.use(ViewUI)
|
||||
|
||||
import 'view-design/dist/styles/iview.css'
|
@@ -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
|
@@ -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: {
|
||||
}
|
||||
})
|
@@ -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>
|
@@ -1,232 +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>
|
||||
<Button @click="onShowDetail(item)">
|
||||
<Icon type="ios-people"/>
|
||||
{{item.SubscriberInfo?item.SubscriberInfo.length:0}}
|
||||
</Button>
|
||||
<Button v-if="item.Type" @click="preview(item)">
|
||||
<Icon type="md-eye"/>
|
||||
Preview
|
||||
</Button>
|
||||
<Button @click="stopRecord(item)" v-if="isRecording(item)">
|
||||
<Icon type="ios-radio-button-on" class="recording"/>
|
||||
Stop Rec
|
||||
</Button>
|
||||
<Button @click="record(item)" v-else>
|
||||
<Icon type="ios-radio-button-on"/>
|
||||
Rec
|
||||
</Button>
|
||||
</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})
|
||||
},
|
||||
stopRecord(item){
|
||||
window.ajax.get("//" + location.host + "/api/record/flv/stop",{streamPath:item.StreamPath})
|
||||
},
|
||||
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;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.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>
|
@@ -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>
|
@@ -1,10 +0,0 @@
|
||||
module.exports = {
|
||||
chainWebpack: config => {
|
||||
config.module
|
||||
.rule('vue')
|
||||
.use('iview-loader')
|
||||
.loader('iview-loader')
|
||||
.tap(()=> ({prefix: false}))
|
||||
.end()
|
||||
}
|
||||
}
|
45
gen.go
Normal 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)
|
||||
}
|
103
go.mod
@@ -1,17 +1,94 @@
|
||||
module github.com/langhuihui/monibuca
|
||||
module monibuca
|
||||
|
||||
go 1.13
|
||||
go 1.18
|
||||
|
||||
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
|
||||
m7s.live/engine/v4 v4.9.7
|
||||
m7s.live/plugin/debug/v4 v4.0.0-20220506113031-34f3a736ceb2
|
||||
m7s.live/plugin/edge/v4 v4.0.3
|
||||
m7s.live/plugin/fmp4/v4 v4.0.0-20221126151227-22a117d1b75e
|
||||
m7s.live/plugin/gb28181/v4 v4.1.7
|
||||
m7s.live/plugin/hdl/v4 v4.0.6
|
||||
m7s.live/plugin/hls/v4 v4.0.8
|
||||
m7s.live/plugin/hook/v4 v4.0.1
|
||||
m7s.live/plugin/jessica/v4 v4.0.2
|
||||
m7s.live/plugin/logrotate/v4 v4.0.3
|
||||
m7s.live/plugin/preview/v4 v4.0.1
|
||||
m7s.live/plugin/record/v4 v4.1.0
|
||||
m7s.live/plugin/room/v4 v4.0.2
|
||||
m7s.live/plugin/rtmp/v4 v4.0.6
|
||||
m7s.live/plugin/rtsp/v4 v4.0.8
|
||||
m7s.live/plugin/snap/v4 v4.0.1
|
||||
m7s.live/plugin/webrtc/v4 v4.0.4
|
||||
m7s.live/plugin/webtransport/v4 v4.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aler9/gortsplib v0.0.0-20221120213348-150f16ae6567 // indirect
|
||||
github.com/cnotch/ipchub v1.1.0 // indirect
|
||||
github.com/discoviking/fsm v0.0.0-20150126104936-f4a273feecca // indirect
|
||||
github.com/edgeware/mp4ff v0.30.1 // indirect
|
||||
github.com/ghettovoice/gosip v0.0.0-20221121090201-9a2ed2233b6d // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.1.0 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/husanpao/ip v0.0.0-20220711082147-73160bb611a8 // indirect
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
||||
github.com/lucas-clemente/quic-go v0.31.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect
|
||||
github.com/marten-seemann/qpack v0.3.0 // indirect
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
|
||||
github.com/pion/datachannel v1.5.2 // indirect
|
||||
github.com/pion/dtls/v2 v2.1.5 // indirect
|
||||
github.com/pion/ice/v2 v2.2.12 // indirect
|
||||
github.com/pion/interceptor v0.1.12 // indirect
|
||||
github.com/pion/logging v0.2.2 // indirect
|
||||
github.com/pion/mdns v0.0.5 // indirect
|
||||
github.com/pion/randutil v0.1.0 // indirect
|
||||
github.com/pion/rtcp v1.2.10 // indirect
|
||||
github.com/pion/rtp v1.7.13 // indirect
|
||||
github.com/pion/rtp/v2 v2.0.0-20220302185659-b3d10fc096b0 // indirect
|
||||
github.com/pion/sctp v1.8.3 // indirect
|
||||
github.com/pion/sdp/v3 v3.0.6 // indirect
|
||||
github.com/pion/srtp/v2 v2.0.10 // indirect
|
||||
github.com/pion/stun v0.3.5 // indirect
|
||||
github.com/pion/transport v0.13.1 // indirect
|
||||
github.com/pion/turn/v2 v2.0.8 // indirect
|
||||
github.com/pion/udp v0.1.1 // indirect
|
||||
github.com/pion/webrtc/v3 v3.1.49 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
|
||||
github.com/q191201771/naza v0.30.8 // indirect
|
||||
github.com/quangngotan95/go-m3u8 v0.1.0 // indirect
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.10 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/tevino/abool v1.2.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
github.com/zhangpeihao/goamf v0.0.0-20140409082417-3ff2c19514a8 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.2.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/term v0.2.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/tools v0.3.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
400
go.sum
@@ -1,22 +1,384 @@
|
||||
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/aler9/gortsplib v0.0.0-20221120213348-150f16ae6567 h1:x0A9TesnU9HYv1OiyYXrdmgDHNCQkQRRF9XH/+9axHQ=
|
||||
github.com/aler9/gortsplib v0.0.0-20221120213348-150f16ae6567/go.mod h1:BOWNZ/QBkY/eVcRqUzJbPFEsRJshwxaxBT01K260Jeo=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
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/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/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/edgeware/mp4ff v0.30.1 h1:OV88fQrw8sFPjTCFThsBwubjYPHTdHgb28pSd1y9ozk=
|
||||
github.com/edgeware/mp4ff v0.30.1/go.mod h1:GNUeA6tEFksH2CrjJF2FSGdJolba8yPGmo16qZTXsm8=
|
||||
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/ghettovoice/gosip v0.0.0-20221121090201-9a2ed2233b6d h1:f1JRfm0MwkluwtUsbYxuVReDMajlc9Wn6zc2orX4sRE=
|
||||
github.com/ghettovoice/gosip v0.0.0-20221121090201-9a2ed2233b6d/go.mod h1:yTr3BEYSFe9As6XM7ldyrVgqsPwlnw8Ahc4N28VFM2g=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
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.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
||||
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 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
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-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/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/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
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/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/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
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/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/lucas-clemente/quic-go v0.31.0 h1:MfNp3fk0wjWRajw6quMFA3ap1AVtlU+2mtwmbVogB2M=
|
||||
github.com/lucas-clemente/quic-go v0.31.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c h1:VtwQ41oftZwlMnOEbMWQtSEUgU64U4s+GHk7hZK+jtY=
|
||||
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c/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/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI=
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE=
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
|
||||
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 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
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/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.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
|
||||
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||
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.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
|
||||
github.com/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E=
|
||||
github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ=
|
||||
github.com/pion/dtls/v2 v2.1.5 h1:jlh2vtIyUBShchoTDqpCCqiYCyRFJ/lvf/gQ8TALs+c=
|
||||
github.com/pion/dtls/v2 v2.1.5/go.mod h1:BqCE7xPZbPSubGasRoDFJeTsyJtdD1FanJYL0JGheqY=
|
||||
github.com/pion/ice/v2 v2.2.12 h1:n3M3lUMKQM5IoofhJo73D3qVla+mJN2nVvbSPq32Nig=
|
||||
github.com/pion/ice/v2 v2.2.12/go.mod h1:z2KXVFyRkmjetRlaVRgjO9U3ShKwzhlUylvxKfHfd5A=
|
||||
github.com/pion/interceptor v0.1.11/go.mod h1:tbtKjZY14awXd7Bq0mmWvgtHB5MDaRN7HV3OZ/uy7s8=
|
||||
github.com/pion/interceptor v0.1.12 h1:CslaNriCFUItiXS5o+hh5lpL0t0ytQkFnUcbbCs2Zq8=
|
||||
github.com/pion/interceptor v0.1.12/go.mod h1:bDtgAD9dRkBZpWHGKaoKb42FhDHTG2rX8Ii9LRALLVA=
|
||||
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.5 h1:Q2oj/JB3NqfzY9xGZ1fPzZzK7sDSD8rZPOvcIQ10BCw=
|
||||
github.com/pion/mdns v0.0.5/go.mod h1:UgssrvdD3mxpi8tMxAXbsppL3vJ4Jipw1mTCW+al01g=
|
||||
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.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo=
|
||||
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.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA=
|
||||
github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko=
|
||||
github.com/pion/rtp/v2 v2.0.0-20220302185659-b3d10fc096b0 h1:zyOGxHutZ6IhksQSMtwf3OFXB29W5R18yFQWOQJYWjU=
|
||||
github.com/pion/rtp/v2 v2.0.0-20220302185659-b3d10fc096b0/go.mod h1:Vj+rrFbJCT3yxqE/VSwaOo9DQ2pMKGPxuE7hplGOlOs=
|
||||
github.com/pion/sctp v1.8.0/go.mod h1:xFe9cLMZ5Vj6eOzpyiKjT9SwGM4KpK/8Jbw5//jc+0s=
|
||||
github.com/pion/sctp v1.8.3 h1:LWcciN2ptLkw9Ugp/Ks2E76fiWy7yk3Wm79D6oFbFNo=
|
||||
github.com/pion/sctp v1.8.3/go.mod h1:OHbDjdk7kg+L+7TJim9q/qGVefdEJohuA2SZyihccgI=
|
||||
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.10 h1:b8ZvEuI+mrL8hbr/f1YiJFB34UMrOac3R3N1yq2UN0w=
|
||||
github.com/pion/srtp/v2 v2.0.10/go.mod h1:XEeSWaK9PfuMs7zxXyiN252AHPbH12NX5q/CFDWtUuA=
|
||||
github.com/pion/stun v0.3.5 h1:uLUCBCkQby4S1cf6CGuR9QrVOKcvUwFeemaC865QHDg=
|
||||
github.com/pion/stun v0.3.5/go.mod h1:gDMim+47EeEtfWogA37n6qXZS88L5V6LqFcf+DZA2UA=
|
||||
github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q=
|
||||
github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A=
|
||||
github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g=
|
||||
github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA=
|
||||
github.com/pion/transport v0.13.1/go.mod h1:EBxbqzyv+ZrmDb82XswEE0BjfQFtuw1Nu6sjnjWCsGg=
|
||||
github.com/pion/turn/v2 v2.0.8 h1:KEstL92OUN3k5k8qxsXHpr7WWfrdp7iJZHx99ud8muw=
|
||||
github.com/pion/turn/v2 v2.0.8/go.mod h1:+y7xl719J8bAEVpSXBXvTxStjJv3hbz9YFflvkpcGPw=
|
||||
github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o=
|
||||
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
|
||||
github.com/pion/webrtc/v3 v3.1.49 h1:rbsNGxK9jMYts+xE6zYAJMUQHnGwmk/JYze8yttW+to=
|
||||
github.com/pion/webrtc/v3 v3.1.49/go.mod h1:kHf/o47QW4No1rgpsFux/h7lUhtUnwFnSFDZOXeLapw=
|
||||
github.com/pixelbender/go-sdp v1.1.0/go.mod h1:6IBlz9+BrUHoFTea7gcp4S54khtOhjCW/nVDLhmZBAs=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI=
|
||||
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/q191201771/naza v0.30.8 h1:Lhh29o65C4PmTDj2l+eKfsw9dddpgWZk4bFICtcnSaA=
|
||||
github.com/q191201771/naza v0.30.8/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/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
|
||||
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.22.10 h1:4KMHdfBRYXGF9skjDWiL4RA2N+E8dRdodU/bOZpPoVg=
|
||||
github.com/shirou/gopsutil/v3 v3.22.10/go.mod h1:QNza6r4YQoydyCfo6rH0blGfKahgibh4dQmV5xdFkQk=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
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.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/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/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.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zhangpeihao/goamf v0.0.0-20140409082417-3ff2c19514a8 h1:r1JUI0wuHlgRb8jNd3zPBBkjUdrjpVKr8SdJWc8ntg8=
|
||||
github.com/zhangpeihao/goamf v0.0.0-20140409082417-3ff2c19514a8/go.mod h1:RZd/IqzNpFANwOB9rVmsnAYpo/6KesK4PqrN1a5cRgg=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
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.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9 h1:yZNXmy+j/JpX19vZkVktWqAo7Gny4PBWYYK3zskGpx4=
|
||||
golang.org/x/exp v0.0.0-20221126150942-6ab00d035af9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
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.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.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-20201201195509-5d6afe98e0b7/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-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
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.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
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 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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-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-20191204072324-ce4227a45e2e/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-20201214095126-aec9a390925b/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/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-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/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 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.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.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
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 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
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.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
|
||||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
|
||||
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.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/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.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.0-20210107192922-496545a6307b/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.9.7 h1:xygyHq5aw6d/QXRr7O+lMrqZfwIpX9ix07+MjxgKRzo=
|
||||
m7s.live/engine/v4 v4.9.7/go.mod h1:znB5Ux7fJ/bIVKnbHrwoInztVn7z/4CrXwjc24b1exI=
|
||||
m7s.live/plugin/debug/v4 v4.0.0-20220506113031-34f3a736ceb2 h1:0QWJvozTHy7m+G/lOIGiejQ9okFIDjwzVsgXe6ZaJg8=
|
||||
m7s.live/plugin/debug/v4 v4.0.0-20220506113031-34f3a736ceb2/go.mod h1:A/C1ViacCOK7EPeeCfiwlUrC2TUtRdEqzrR0Yd9b1KQ=
|
||||
m7s.live/plugin/edge/v4 v4.0.3 h1:uPGuDLp2UG2mac68KM7/Olwp/QK8qCla+WxEuhK/o3c=
|
||||
m7s.live/plugin/edge/v4 v4.0.3/go.mod h1:AWeJV1Nu2UWsEdlcCATlQW+bz6Pz/3A11AZG9Z4hIc0=
|
||||
m7s.live/plugin/fmp4/v4 v4.0.0-20221126151227-22a117d1b75e h1:/APKrFkujtI17MBwrc/EvsjkeDuO79Uc0kHdZUF+3tg=
|
||||
m7s.live/plugin/fmp4/v4 v4.0.0-20221126151227-22a117d1b75e/go.mod h1:9/DlkfpXuBtZziwARFHZogLRnT+vjXPbO5eTrbGkY+8=
|
||||
m7s.live/plugin/gb28181/v4 v4.1.7 h1:ddhkB+teMAt6z3DV0L4Oag4NW36MDHN6oMeVUuqq90o=
|
||||
m7s.live/plugin/gb28181/v4 v4.1.7/go.mod h1:B5RDyhiuKYyQG1KCiMUGE0cP3uTbWdEgpEf8jBEuXgo=
|
||||
m7s.live/plugin/hdl/v4 v4.0.6 h1:MT2b48ZuM4X4jl0QH0WTyrmY6RW/YmpTLJBf43BSiCQ=
|
||||
m7s.live/plugin/hdl/v4 v4.0.6/go.mod h1:jwk3aGCp0OE3bQ5b3n1XjJ8DGG13iHJu4dntvjmsRa8=
|
||||
m7s.live/plugin/hls/v4 v4.0.8 h1:bqXbZbuSPVIES4q2IIPnsB7ChJrLjY0Z23ScQX5H29E=
|
||||
m7s.live/plugin/hls/v4 v4.0.8/go.mod h1:Dr37gKItRuBqDZRI+jtMTVomdOE7tUgQGEbPiYoi8r0=
|
||||
m7s.live/plugin/hook/v4 v4.0.1 h1:On3GigXkL14pQacu+lF307jJXDtCEpcmvY79a/DfW7A=
|
||||
m7s.live/plugin/hook/v4 v4.0.1/go.mod h1:uaTVDsOTiaJ8gUal4YnL5rcpUUhbExn2G8VzEvNGLE0=
|
||||
m7s.live/plugin/jessica/v4 v4.0.2 h1:5rc1+PVZhZg3U2cfTyg9SIJG/iwvgcEwnhQd02vQRbo=
|
||||
m7s.live/plugin/jessica/v4 v4.0.2/go.mod h1:26HcgIZKSjlbrq7RncdxHrt30qAeRAuoiZ6cGW6+254=
|
||||
m7s.live/plugin/logrotate/v4 v4.0.3 h1:f+teASc5Y5vDOrxXFc/ri3t7jdi6GIb6V9UMjhacb7I=
|
||||
m7s.live/plugin/logrotate/v4 v4.0.3/go.mod h1:a8hIV59GjpQDE+Ip790CU7yOHaG4+Iweci0sLvo43FU=
|
||||
m7s.live/plugin/preview/v4 v4.0.1 h1:k8iA5/bMiEWSFcy4zaZ8wG93AtJcSwxtgcQG+Y0xX5E=
|
||||
m7s.live/plugin/preview/v4 v4.0.1/go.mod h1:iYhWqFbTvTNDFplbTOrE5X9M6ED7gCKkKMuM5QmBocg=
|
||||
m7s.live/plugin/record/v4 v4.1.0 h1:lfinqM80YMwqWUmiY9fe80tj55O237L9wL6nC5p9Vqs=
|
||||
m7s.live/plugin/record/v4 v4.1.0/go.mod h1:8fXbmsS+QCQhp136FdqBVEQsbNccWFAYTQDRJW/muQU=
|
||||
m7s.live/plugin/room/v4 v4.0.2 h1:aw9hy5yuh1nlndI+PgqaobEgraV8NHTNDKce+6Ekgzw=
|
||||
m7s.live/plugin/room/v4 v4.0.2/go.mod h1:Wr0HHEuAoqQdq+zH6F/Av8prz6Vb7ilYzPjUXoeLCXU=
|
||||
m7s.live/plugin/rtmp/v4 v4.0.6 h1:k5419zCad3T63maCQS7NO5LtF/Oa7ge/iVshK2Jid9U=
|
||||
m7s.live/plugin/rtmp/v4 v4.0.6/go.mod h1:03iNi9vPhDThf2CQL4TY18H6L8410kDSHS6N8qPMr5U=
|
||||
m7s.live/plugin/rtsp/v4 v4.0.8 h1:e9SZ9W9Y3EvUzbTrLr1813pUk+KZM6l1QT3mn+WxApA=
|
||||
m7s.live/plugin/rtsp/v4 v4.0.8/go.mod h1:Ur0Afflr6xqgyZwJDqQIDtTNskhQfOpQUOEBdoVkWb0=
|
||||
m7s.live/plugin/snap/v4 v4.0.1 h1:VT8lrAGMAIOm2Ia/kAo7EaPKHj0Pfv6xw9ynd1N8GJQ=
|
||||
m7s.live/plugin/snap/v4 v4.0.1/go.mod h1:XHggonZ0lIKEX/OP2rXjV2mPpG4urmvMT3foIaFRsus=
|
||||
m7s.live/plugin/webrtc/v4 v4.0.4 h1:PBHthk7lDHSXQNbobh42GD3ipvFyocCcPJR5qnb3gXU=
|
||||
m7s.live/plugin/webrtc/v4 v4.0.4/go.mod h1:s8wpe8MQ1Cmd0QaUgaevUGGPIDWvg0C/avwqjoGd3u4=
|
||||
m7s.live/plugin/webtransport/v4 v4.0.1 h1:ZYgrg9b6u4IBHjz/rXxQ/TLHdgS3iMsyhOHbVAimCn0=
|
||||
m7s.live/plugin/webtransport/v4 v4.0.1/go.mod h1:RtqizBkC2q3QNA+gfYD1mMH6SVK8T/iprvaX+3SQ1B0=
|
||||
|
42
goreleaser.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
project_name: m7s
|
||||
archives:
|
||||
-
|
||||
files:
|
||||
- config.yaml
|
||||
- monibuca.com.key
|
||||
- monibuca.com.pem
|
||||
builds:
|
||||
- id: "with-debug"
|
||||
env: [CGO_ENABLED=0]
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Tag}}
|
||||
ignore:
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
hooks:
|
||||
pre:
|
||||
- bash -c "debug=1 go generate ./..."
|
||||
- go mod tidy
|
||||
|
||||
- id: "without-debug"
|
||||
env: [CGO_ENABLED=0]
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Tag}}
|
||||
goos:
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- arm64
|
||||
hooks:
|
||||
pre:
|
||||
- bash -c "debug=0 go generate ./..."
|
||||
- go mod tidy
|
54
main.go
@@ -1,14 +1,54 @@
|
||||
package main
|
||||
|
||||
//go:generate go run gen.go $debug
|
||||
|
||||
/*
|
||||
███ ███ ██████ ███ ██ 👑 ██████ ██ ██ ██████ █████
|
||||
████ ████ ██ ██ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
██ ████ ██ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ███████
|
||||
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
██ ██ ██████ ██ ████ ██ ██████ ██████ ██████ ██ ██
|
||||
|
||||
The live stream server for Go
|
||||
(c) dexter 2019-present
|
||||
*/
|
||||
|
||||
import (
|
||||
. "github.com/langhuihui/monibuca/monica"
|
||||
_ "github.com/langhuihui/monibuca/plugins"
|
||||
"log"
|
||||
"os"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"m7s.live/engine/v4"
|
||||
"m7s.live/engine/v4/util"
|
||||
|
||||
_ "m7s.live/plugin/debug/v4"
|
||||
_ "m7s.live/plugin/gb28181/v4"
|
||||
_ "m7s.live/plugin/hdl/v4"
|
||||
_ "m7s.live/plugin/hls/v4"
|
||||
_ "m7s.live/plugin/hook/v4"
|
||||
_ "m7s.live/plugin/jessica/v4"
|
||||
_ "m7s.live/plugin/logrotate/v4"
|
||||
_ "m7s.live/plugin/preview/v4"
|
||||
_ "m7s.live/plugin/record/v4"
|
||||
_ "m7s.live/plugin/room/v4"
|
||||
_ "m7s.live/plugin/rtmp/v4"
|
||||
_ "m7s.live/plugin/rtsp/v4"
|
||||
_ "m7s.live/plugin/snap/v4"
|
||||
_ "m7s.live/plugin/webrtc/v4"
|
||||
_ "m7s.live/plugin/webtransport/v4"
|
||||
_ "m7s.live/plugin/edge/v4"
|
||||
_ "m7s.live/plugin/fmp4/v4"
|
||||
)
|
||||
|
||||
var (
|
||||
version = "dev"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.SetOutput(os.Stdout)
|
||||
Run("config.toml")
|
||||
select {}
|
||||
fmt.Println("start monibuca version:", version)
|
||||
conf := flag.String("c", "config.yaml", "config file")
|
||||
flag.Parse()
|
||||
ctx, cancel := context.WithCancel(context.WithValue(context.Background(), "version", version))
|
||||
go util.WaitTerm(cancel)
|
||||
engine.Run(ctx, *conf)
|
||||
}
|
||||
|
27
monibuca.com.key
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAsDuh54gI4Flxg+ZrpvxWdmCnvpE1EqNfrV41+yTMZxJko32B
|
||||
6ErSCb/qu6viTqnV+Vf/YY/a7TFCt/NQHFpx3pXRhRFCM5TVaoFqWOYpU8dgACOs
|
||||
nK9cyOlAaE0s8TuPTjo9P9TZAbVyaHobTdEwImu17Nq6vAczFLanqfhKcQ22e7PR
|
||||
mk039f/7vqDUvYJiHtddjACaKfJ9XqfsLjxhKT/fSg/iYjjmD9uEidvUwbK0Uq62
|
||||
M5oTyf1R1A/z+SD4rVUaxN8JyjYsOrELoVYQAP6YY9d5e5V5KrX1JXf+7cjwU0Jy
|
||||
gcieNWvAIzq0oVVqiq43N59//FcoU+n4g2vloQIDAQABAoIBAAc7GySF119lLBwu
|
||||
WyJp3h5TTu6pxJS0MVvKrspUMzLTdV+j6a2fTEjsH/R9U/bITyhA7RCSt3fd+o/T
|
||||
oujW6S8p1IPyNlYpeCw7jSKCpxVx68V1sUJoi5UOxP7Ck+J+AB5Ek3jIAfNo/327
|
||||
7NzfhWsUIk3Kl7jZTsY9zFlT/7HtvZSO9UkNVz0m0wlkoENE7va+SbBgPEIupMqU
|
||||
oR0jZQKAcEwJi7vneLKjUhTr8v2InGYeLybLcw5ZKxYBOjFk2rELPUP26/SgNvsA
|
||||
VPvA9HBTYy9IZFNF/3O3QNnD2/Ix0zGm2LVuYAc4FqE4Zd7NssNBmi25ASZq+rdg
|
||||
YMiNJ7ECgYEA7EbusDzUId4WO8bwB9vW0Glg+8flNJ4uXqbV9eA/B5Vp71jkV9fB
|
||||
led2dmcW5FUG2kktkUNHbUXEer4eM7s74983CAb74hpUXEWY75Fp3FqOCk0eTLqE
|
||||
unke8BaUKdSSYPPWEBNHfii9GkoKRBLvGLnfOsrMB1pZouAhhwdDZu0CgYEAvvGZ
|
||||
0/bhTjdS7k9/5h7FiY1brxpFy/G8yrpZwA+tvxLLGnPNmRBljFDCSQsPliBbURD4
|
||||
T/jt2FOltfBPOJ0wMCNUmEqsnIs2fCiRr1UkEUFZ2SPOcTybk5gaiTKeXKl3i+Zq
|
||||
u1MT+qxr1HfjspuUJ0Ou9N+HIXtrwNMqxb7/DwUCgYAFELw7QQKXO0ikvW4V7Quc
|
||||
6jVvEGkEiMObud3qaIVRZ02fGPvEOlbnHNA4V5txB7We5mS4sYWNfSpqKztAhqoR
|
||||
B48JeATcYw4d8EwIDskDNVnINMEKihEgYkpcgU9p2inNNE0JiTBGLx9mueGgdft0
|
||||
Pz/e5cwb+D7ltAJj/67dPQKBgQCsLv3CcIw3lhgIolP5VaJYKcqVmiF6iWDvhx/L
|
||||
29eXyACyt96cunZ4E5M/fuPtQvxVm/HvW9BPFQ8Hg85MhSKhJhrwwdXpzHezenn1
|
||||
G9fMX5v//RP6dObuL2kucyDu+jq9Q2jXx1Dq6XTLQdlohHcS+SvZ0X/vp3ZBiaq2
|
||||
a0dhaQKBgAV3WUwkqzdmG7yzcUxMMcRO4686UNApNQlqkTieOt3n5+uDEOjxbYQz
|
||||
z8bBLDunDpW5UEQr2UEP/jT6TAZ34xXqMpXyF2BvTPzVbRYlFVzGTLQ6MmOkvykJ
|
||||
BFD6EWH2uAbzNQF1y7TlKTa6CO58+I9tP9+CL6LSfeZ+9ABuRKQ4
|
||||
-----END RSA PRIVATE KEY-----
|
66
monibuca.com.pem
Normal file
@@ -0,0 +1,66 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGdDCCBNygAwIBAgIQNDrmCqWpIXWEcjc+6M1EeDANBgkqhkiG9w0BAQwFADBZ
|
||||
MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg
|
||||
SW5jLjEjMCEGA1UEAxMaVHJ1c3RBc2lhIFJTQSBEViBUTFMgQ0EgRzIwHhcNMjIw
|
||||
NDA3MDAwMDAwWhcNMjMwNDA3MjM1OTU5WjAXMRUwEwYDVQQDEwxtb25pYnVjYS5j
|
||||
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwO6HniAjgWXGD5mum
|
||||
/FZ2YKe+kTUSo1+tXjX7JMxnEmSjfYHoStIJv+q7q+JOqdX5V/9hj9rtMUK381Ac
|
||||
WnHeldGFEUIzlNVqgWpY5ilTx2AAI6ycr1zI6UBoTSzxO49OOj0/1NkBtXJoehtN
|
||||
0TAia7Xs2rq8BzMUtqep+EpxDbZ7s9GaTTf1//u+oNS9gmIe112MAJop8n1ep+wu
|
||||
PGEpP99KD+JiOOYP24SJ29TBsrRSrrYzmhPJ/VHUD/P5IPitVRrE3wnKNiw6sQuh
|
||||
VhAA/phj13l7lXkqtfUld/7tyPBTQnKByJ41a8AjOrShVWqKrjc3n3/8VyhT6fiD
|
||||
a+WhAgMBAAGjggL4MIIC9DAfBgNVHSMEGDAWgBRfOnwREH4MZ3Fh3IujtQADZ/VX
|
||||
HDAdBgNVHQ4EFgQUXzGOkA4bBluzNCi/v4FoPmbmRkYwDgYDVR0PAQH/BAQDAgWg
|
||||
MAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEkG
|
||||
A1UdIARCMEAwNAYLKwYBBAGyMQECAjEwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9z
|
||||
ZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQIBMH0GCCsGAQUFBwEBBHEwbzBCBggrBgEF
|
||||
BQcwAoY2aHR0cDovL2NydC50cnVzdC1wcm92aWRlci5jbi9UcnVzdEFzaWFSU0FE
|
||||
VlRMU0NBRzIuY3J0MCkGCCsGAQUFBzABhh1odHRwOi8vb2NzcC50cnVzdC1wcm92
|
||||
aWRlci5jbjApBgNVHREEIjAgggxtb25pYnVjYS5jb22CEHd3dy5tb25pYnVjYS5j
|
||||
b20wggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB2AK33vvp8/xDIi509nB4+GGq0
|
||||
Zyldz7EMJMqFhjTr3IKKAAABgAMZ5TAAAAQDAEcwRQIhAOeaZWh1Myi4VcwhZIZ+
|
||||
DnqGBK+j8RgjsxXEKsLsviAUAiAhhdqtOma6qPzjCx8erWmAGALHLW3ksTzLRdiC
|
||||
TZmqegB2AHoyjFTYty22IOo44FIe6YQWcDIThU070ivBOlejUutSAAABgAMZ5OIA
|
||||
AAQDAEcwRQIhALKO6kODma4cvfI6ylGtpkLaBfa6IqoNPIo6iHWqfl0GAiAo0ksX
|
||||
l45X1RxiFCbSS8XMgOgFpXST5rMW9KFZmKNf5gB2AOg+0No+9QY1MudXKLyJa8kD
|
||||
08vREWvs62nhd31tBr1uAAABgAMZ5McAAAQDAEcwRQIgbAiIMrugBC74wShIjEhn
|
||||
6P0RNpddTPiulfQwlK/nPYcCIQC8/i3N8JJ1d8or+FqQulc3eU6PIuzg39MjX9UU
|
||||
GcN4qTANBgkqhkiG9w0BAQwFAAOCAYEAXjyA/d2/Xu1ChRqoaGaDDc4Na1ogvzkM
|
||||
X2ZXhAl0L/fPWiZjMX6DSjQmBFZZLhXC40LhnvuvVByGt0OUWrHRWU2wonH7Avhn
|
||||
IZi1BcrQXwO5vwfA4kmwaMA92PZFQMjySzmd9+44J6HacrbI6j29Tv67qeglE7z2
|
||||
NmzsuaHAW0G08A5A7LlziW53lz+CnPk60iPcNCjV60bPFJPRPhtt/a4ND2jbIALa
|
||||
u8OuFZvlggeCWW8TQlGQFhv4ux7PotHcRfcyW3HigLyNQTjLkzopVufL7BvSR4vW
|
||||
JFfb5LdOfcx5iES4AoNdld8jIxKhOviLlKV0eT25o66SwGGfP+hGcDx+Vf+2/x4n
|
||||
ukHwQVMtidiwxvDTJMPBoTZRCj5AW6A8bF8Ps4gh7Vfr3fvLRJnL+88f6GjUbmfO
|
||||
GlO4h6Za78Vl3TQcBD7296+MrBu0faAtTbd34FqgRXGQ8DHdDNLeKRP8WAzv19/L
|
||||
IhHfarLkL/bhhrGTB9McvA2jmGr4W0jf
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFBzCCA++gAwIBAgIRALIM7VUuMaC/NDp1KHQ76aswDQYJKoZIhvcNAQELBQAw
|
||||
ezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
|
||||
A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
|
||||
BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yMjAxMTAwMDAwMDBaFw0y
|
||||
ODEyMzEyMzU5NTlaMFkxCzAJBgNVBAYTAkNOMSUwIwYDVQQKExxUcnVzdEFzaWEg
|
||||
VGVjaG5vbG9naWVzLCBJbmMuMSMwIQYDVQQDExpUcnVzdEFzaWEgUlNBIERWIFRM
|
||||
UyBDQSBHMjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKjGDe0GSaBs
|
||||
Yl/VhMaTM6GhfR1TAt4mrhN8zfAMwEfLZth+N2ie5ULbW8YvSGzhqkDhGgSBlafm
|
||||
qq05oeESrIJQyz24j7icGeGyIZ/jIChOOvjt4M8EVi3O0Se7E6RAgVYcX+QWVp5c
|
||||
Sy+l7XrrtL/pDDL9Bngnq/DVfjCzm5ZYUb1PpyvYTP7trsV+yYOCNmmwQvB4yVjf
|
||||
IIpHC1OcsPBntMUGeH1Eja4D+qJYhGOxX9kpa+2wTCW06L8T6OhkpJWYn5JYiht5
|
||||
8exjAR7b8Zi3DeG9oZO5o6Qvhl3f8uGU8lK1j9jCUN/18mI/5vZJ76i+hsgdlfZB
|
||||
Rh5lmAQjD80M9TY+oD4MYUqB5XrigPfFAUwXFGehhlwCVw7y6+5kpbq/NpvM5Ba8
|
||||
SeQYUUuMA8RXpTtGlrrTPqJryfa55hTuX/ThhX4gcCVkbyujo0CYr+Uuc14IOyNY
|
||||
1fD0/qORbllbgV41wiy/2ZUWZQUodqHWkjT1CwIMbQOY5jmrSYGBwwIDAQABo4IB
|
||||
JjCCASIwHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYDVR0OBBYE
|
||||
FF86fBEQfgxncWHci6O1AANn9VccMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8E
|
||||
CDAGAQH/AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAiBgNVHSAE
|
||||
GzAZMA0GCysGAQQBsjEBAgIxMAgGBmeBDAECATBDBgNVHR8EPDA6MDigNqA0hjJo
|
||||
dHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNy
|
||||
bDA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9k
|
||||
b2NhLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHMUom5cxIje2IiFU7mOCsBr2F6CY
|
||||
eU5cyfQ/Aep9kAXYUDuWsaT85721JxeXFYkf4D/cgNd9+hxT8ZeDOJrn+ysqR7NO
|
||||
2K9AdqTdIY2uZPKmvgHOkvH2gQD6jc05eSPOwdY/10IPvmpgUKaGOa/tyygL8Og4
|
||||
3tYyoHipMMnS4OiYKakDJny0XVuchIP7ZMKiP07Q3FIuSS4omzR77kmc75/6Q9dP
|
||||
v4wa90UCOn1j6r7WhMmX3eT3Gsdj3WMe9bYD0AFuqa6MDyjIeXq08mVGraXiw73s
|
||||
Zale8OMckn/BU3O/3aFNLHLfET2H2hT6Wb3nwxjpLIfXmSVcVd8A58XH0g==
|
||||
-----END CERTIFICATE-----
|