update docs

This commit is contained in:
notch
2020-12-28 14:46:52 +08:00
parent b1edf0a3e0
commit 3407d9b3dd
6 changed files with 49 additions and 68 deletions

View File

@@ -1,33 +1,29 @@
# ipchub # ipchub
一个小而美的流媒体服务器,即拷即用 一个即拷即用、支持摄像头集中管理、多级路由及h5播放的流媒体服务器,。
## 项目背景
偶尔和前同事聊天说到一些小的监控项目需要把IP摄像头集中管理并提供html播放能力。闲来无事就试着开发一个打发时间也作为学习 go 语言的一个实践。 偶尔和前同事聊天说到一些小的监控项目需要把IP摄像头集中管理并提供html播放能力。闲来无事就试着开发一个打发时间也作为学习 go 语言的一个实践。
在此之前没有流媒体经验没有go语言项目开发经验。看了一些文档参考了一些开源项目主要包括 在此之前没有流媒体经验没有go语言项目开发经验。看了一些文档参考了一些开源项目主要包括
+ [emitter](https://github.com/emitter-io/emitter) 学习多协议共享端口等网络编程技能 + [emitter](https://github.com/emitter-io/emitter) 学习多协议共享端口等网络编程技能
+ [EasyDarwin](https://github.com/EasyDarwin/EasyDarwin) 为加深对rtsp协议的理解 + [EasyDarwin](https://github.com/EasyDarwin/EasyDarwin) 为加深对rtsp协议的理解
+ [seal](https://github.com/calabashdad/seal.git) rtmp/flv 相关协议学习及 hls 相关处理 + [seal](https://github.com/calabashdad/seal.git) rtmp/flv hls 服务的理解
## 做什么
摄像头集中、多级路由及h5播放
功能: ## 主要特性
+ 流媒体源支持
+ RTSP拉流 + 基于纯 Golang 开发
+ RTSP推流 + 支持 Windows、Linux、macOS 平台
+ 流媒体消费支持 + 支持 RTSP 推流(主动推送)
+ RTSP流 + 支持 RTSP 拉流(拉取摄像头或其他流媒体服务器资源)
+ RTSP WEBSOCKET 代理 + 支持 H264+AAC H5播放包括
+ HTTP-FLV + HTTP-FLV
+ WEBSOCKET-FLV + Websocket-FLV
+ HTTP-HLS + HTTP-HLS
+ 流媒体多级路由 + Websocket-RTSP实验: 实时性更好
+ 用户流媒体推拉权限管理 + 支持级联部署服务器,自动拉取流
+ 业务系统集成API + 支持流媒体推拉的用户权限管理
+ 业务系统集成 RestfulAPI
## 不做什么
+ 不存储
+ 不转码
## 文档 ## 文档
+ [Quick Start](/docs/quickstart.md) + [Quick Start](/docs/quickstart.md)

View File

@@ -1,5 +1,6 @@
## 1 系统API ## 1 系统API
系统API无需登录可以匿名访问 系统API无需登录可以匿名访问
### 1.1 服务器信息查询 ### 1.1 服务器信息查询
GET /api/v1/server GET /api/v1/server
#### 1.1.1 参数和响应 #### 1.1.1 参数和响应
@@ -23,7 +24,7 @@ duration | string | 持续时间 |
#### 1.1.2 示例 #### 1.1.2 示例
curl 示例: curl 示例:
``` shell ``` shell
curl http://locahost:1554/api/v1/server curl http://localhost:1554/api/v1/server
``` ```
响应: 响应:
@@ -31,7 +32,7 @@ curl http://locahost:1554/api/v1/server
{ {
"vendor": "CAOHONGJU", "vendor": "CAOHONGJU",
"name": "ipchub", "name": "ipchub",
"version": "V0.8.0", "version": "V1.0",
"os": "Darwin", "os": "Darwin",
"arch": "AMD64", "arch": "AMD64",
"start_on": "2019-07-15T14:02:16.638804+08:00", "start_on": "2019-07-15T14:02:16.638804+08:00",
@@ -64,15 +65,12 @@ streams | object | 流信息 |
streams.sc| number | 流媒体源数量 | streams.sc| number | 流媒体源数量 |
streams.cc|number|流媒体消费者数量 | streams.cc|number|流媒体消费者数量 |
rtsp| object| RTSP连接信息 | rtsp| object| RTSP连接信息 |
rtsp.total|number|总链接数 | rtsp.total|number|累计总链接数 |
rtsp.active | number | 活跃连接数 | rtsp.active | number | 当前活跃连接数 |
wsp| object| WSP连接信息 |
wsp.total|number|总链接数 |
wsp.active | number | 活跃连接数 |
flv| object| flv连接信息 | flv| object| flv连接信息 |
flv.total|number|总链接数 | flv.total|number|累计总链接数 |
flv.active | number | 活跃连接数 | flv.active | number | 当前活跃连接数 |
extra | object | 额外信息 | extra | object | 运行时内存等信息 |
#### 1.2.1 示例 #### 1.2.1 示例
curl 示例一: curl 示例一:
@@ -97,10 +95,6 @@ curl http://localhost:1554/api/v1/runtime
"total": 0, "total": 0,
"active": 0 "active": 0
}, },
"wsp": {
"total": 0,
"active": 0
},
"flv": { "flv": {
"total": 0, "total": 0,
"active": 0 "active": 0
@@ -215,10 +209,8 @@ http://.../api/v1/streams/rtsp/room/door?token=your_access_token
http://.../streams/room/door.flv?token=your_access_token http://.../streams/room/door.flv?token=your_access_token
+ websocket-flv + websocket-flv
ws://.../ws/room/door.flv?token=your_access_token ws://.../ws/room/door.flv?token=your_access_token
+ wps + http-flv
ws://.../ws/room/door?token=your_access_token http://.../steams/room/door.m3u8?token=your_access_token
+ rtmp
rtmp://.../room/door?token=your_access_token
### 1.4 刷新access token ### 1.4 刷新access token
GET api/v1/refreshtoken?token={refresh_tokebn} GET api/v1/refreshtoken?token={refresh_tokebn}

View File

@@ -21,18 +21,14 @@
] ]
``` ```
我们配置了两个路由: 我们配置了两个路由:
+ /group/door + /group/door : 集团大门直接连接到摄像头
+ /hr/ : 人力资源部门的摄像头路由到下级的服务器
假设下级服务器有 /door/video1 和 /door/video2 两个摄像头,那么你可以通过 .../hr/door/video1 和 .../hr/door/video2 访问它们。
集团大门直接连接到摄像头 ## 3. 访问流媒体
+ /hr/
人力资源部门的摄像头路由到下级的服务器中hr的服务器包含/door/video1和/door/video2
## 3. 使用
服务器提供了多种访问终端摄像头的方式,包括: 服务器提供了多种访问终端摄像头的方式,包括:
+ rtsp + rtsp
+ websocket-rtsp + websocket-rtsp
+ wspwebsocket 代理模式)
+ http-flv + http-flv
+ websocket-flv + websocket-flv
+ http-hls + http-hls
@@ -57,20 +53,16 @@ rtsp://localhost:1554/hr/door/video1 请求在服务器内自动变成去拉取r
打开demo地址http://localhost:1554/demos/rtsp 打开demo地址http://localhost:1554/demos/rtsp
输入ws://localhost:1554/ws/group/door 即可访问 输入ws://localhost:1554/ws/group/door 即可访问
### 3.3 使用wsp访问 ### 3.3 使用http-flv访问
和上面一样打开demo地址http://localhost:1554/demos/wsp
输入rtsp://localhost:1554/group/door 即可访问
### 3.4 使用http-flv访问
打开demo地址http://localhost:1554/demos/flv 打开demo地址http://localhost:1554/demos/flv
输入http://locaolhost:1554/streams/group/door.flv 即可访问 输入http://locaolhost:1554/streams/group/door.flv 即可访问
由于 Chrome 对长连接的流限制为6个因此如果使用 Chrome 打开更多建议使用websocket-flv 由于 Chrome 对长连接的流限制为6个因此如果使用 Chrome 打开更多建议使用websocket-flv
### 3.5 使用 websocket-flv访问 ### 3.4 使用 websocket-flv访问
打开demo地址http://localhost:1554/demos/flv 打开demo地址http://localhost:1554/demos/flv
输入ws://locaolhost:1554/ws/group/door.flv 即可访问 输入ws://locaolhost:1554/ws/group/door.flv 即可访问
### 3.6 使用 http-hls访问 ### 3.5 使用 http-hls访问
由于 iOS的Safari不支持上述任何http访问模式请使用 http-hls 由于 iOS的Safari不支持上述任何http访问模式请使用 http-hls
在浏览器输入: http://localhost:1554/streams/group/door.m3m8 即可访问 在浏览器输入: http://localhost:1554/streams/group/door.m3m8 即可访问
**注意:** 由于http-hls的段文件默认被放在内存中占用大量的内存如系统内存不足请配置存储路径。 **注意:** 由于http-hls的段文件默认被放在内存中占用大量的内存如系统内存不足请配置存储路径。
@@ -81,10 +73,10 @@ rtsp://localhost:1554/hr/door/video1 请求在服务器内自动变成去拉取r
输入http://locaolhost:1554/streams/group/door.flv?token=7f97509e321a18ccf281607f4c0bd4fb 输入http://locaolhost:1554/streams/group/door.flv?token=7f97509e321a18ccf281607f4c0bd4fb
其中 token 通过登录api获得 其中 token 通过登录api获得
对于配置用户,参考配置和Api文档 相关信息请参考[配置文档](config.md) 和 [Api 文档](apis.md)
## 5. 浏览器支持情况 ## 5. 浏览器支持情况
wsp、http-flv、websocket-flv等浏览器访问支持 http-flv、websocket-flv等浏览器访问支持
+ Firefox v.42+ + Firefox v.42+
+ Chrome v.23+ + Chrome v.23+
+ OSX Safari v.8+ + OSX Safari v.8+

View File

@@ -53,7 +53,10 @@ func (p *jsonProvider) LoadAll() ([]*User, error) {
path := p.filePath path := p.filePath
if _, err := os.Stat(path); err != nil { if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil, nil return []*User{{
Name: "admin",
Password: "admin",
Admin: true}}, nil
} }
return nil, err return nil, err
} }

View File

@@ -122,15 +122,16 @@ func (s *Service) onLogin(w http.ResponseWriter, r *http.Request, pathParams api
// 提取凭证 // 提取凭证
var uc UserCredentials var uc UserCredentials
err := json.NewDecoder(r.Body).Decode(&uc)
if err != nil { if err := json.NewDecoder(r.Body).Decode(&uc); err != nil {
// 尝试 Form解析 http.Error(w, "未提供用户名或密码", http.StatusForbidden)
uc.Username = r.FormValue("username") return
uc.Password = r.FormValue("password") }
if len(uc.Username) == 0 || len(uc.Password) == 0 {
http.Error(w, "用户名或密码错误", http.StatusForbidden) // 尝试 Form解析
return if len(uc.Username) == 0 || len(uc.Password) == 0 {
} http.Error(w, "用户名或密码错误", http.StatusForbidden)
return
} }
// 验证用户和密码 // 验证用户和密码
@@ -187,7 +188,6 @@ func (s *Service) onGetRuntime(w http.ResponseWriter, r *http.Request, pathParam
Proc stats.Proc `json:"proc"` Proc stats.Proc `json:"proc"`
Streams sccc `json:"streams"` Streams sccc `json:"streams"`
Rtsp stats.ConnsSample `json:"rtsp"` Rtsp stats.ConnsSample `json:"rtsp"`
Wsp stats.ConnsSample `json:"wsp"`
Flv stats.ConnsSample `json:"flv"` Flv stats.ConnsSample `json:"flv"`
Extra *stats.Runtime `json:"extra,omitempty"` Extra *stats.Runtime `json:"extra,omitempty"`
} }
@@ -198,7 +198,6 @@ func (s *Service) onGetRuntime(w http.ResponseWriter, r *http.Request, pathParam
Proc: stats.MeasureRuntime(), Proc: stats.MeasureRuntime(),
Streams: sccc{sc, cc}, Streams: sccc{sc, cc},
Rtsp: stats.RtspConns.GetSample(), Rtsp: stats.RtspConns.GetSample(),
Wsp: stats.WspConns.GetSample(),
Flv: stats.FlvConns.GetSample(), Flv: stats.FlvConns.GetSample(),
} }

View File

@@ -11,7 +11,6 @@ import (
// 全局变量 // 全局变量
var ( var (
RtspConns = NewConns() // RTSP连接统计 RtspConns = NewConns() // RTSP连接统计
WspConns = NewConns() // WSP连接统计
FlvConns = NewConns() // flv连接统计 FlvConns = NewConns() // flv连接统计
) )