mirror of
https://github.com/cnotch/ipchub.git
synced 2025-09-26 19:41:18 +08:00
update docs
This commit is contained in:
34
README.md
34
README.md
@@ -1,33 +1,29 @@
|
||||
# ipchub
|
||||
一个小而美的流媒体服务器,即拷即用。
|
||||
一个即拷即用、支持摄像头集中管理、多级路由及h5播放的流媒体服务器,。
|
||||
|
||||
## 项目背景
|
||||
偶尔和前同事聊天,说到一些小的监控项目需要把IP摄像头集中管理,并提供html播放能力。闲来无事就试着开发一个打发时间,也作为学习 go 语言的一个实践。
|
||||
|
||||
在此之前没有流媒体经验,没有go语言项目开发经验。看了一些文档,参考了一些开源项目,主要包括:
|
||||
+ [emitter](https://github.com/emitter-io/emitter) 学习多协议共享端口等网络编程技能
|
||||
+ [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拉流
|
||||
+ RTSP推流
|
||||
+ 流媒体消费支持
|
||||
+ RTSP流
|
||||
+ RTSP WEBSOCKET 代理
|
||||
## 主要特性
|
||||
|
||||
+ 基于纯 Golang 开发
|
||||
+ 支持 Windows、Linux、macOS 平台
|
||||
+ 支持 RTSP 推流(主动推送)
|
||||
+ 支持 RTSP 拉流(拉取摄像头或其他流媒体服务器资源)
|
||||
+ 支持 H264+AAC H5播放,包括:
|
||||
+ HTTP-FLV
|
||||
+ WEBSOCKET-FLV
|
||||
+ Websocket-FLV
|
||||
+ HTTP-HLS
|
||||
+ 流媒体多级路由
|
||||
+ 用户流媒体推拉权限管理
|
||||
+ 业务系统集成API
|
||||
|
||||
## 不做什么
|
||||
+ 不存储
|
||||
+ 不转码
|
||||
+ Websocket-RTSP(实验): 实时性更好
|
||||
+ 支持级联部署服务器,自动拉取流
|
||||
+ 支持流媒体推拉的用户权限管理
|
||||
+ 业务系统集成 RestfulAPI
|
||||
|
||||
## 文档
|
||||
+ [Quick Start](/docs/quickstart.md)
|
||||
|
30
docs/apis.md
30
docs/apis.md
@@ -1,5 +1,6 @@
|
||||
## 1 系统API
|
||||
系统API无需登录,可以匿名访问
|
||||
系统API无需登录,可以匿名访问。
|
||||
|
||||
### 1.1 服务器信息查询
|
||||
GET /api/v1/server
|
||||
#### 1.1.1 参数和响应
|
||||
@@ -23,7 +24,7 @@ duration | string | 持续时间 |
|
||||
#### 1.1.2 示例
|
||||
curl 示例:
|
||||
``` 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",
|
||||
"name": "ipchub",
|
||||
"version": "V0.8.0",
|
||||
"version": "V1.0",
|
||||
"os": "Darwin",
|
||||
"arch": "AMD64",
|
||||
"start_on": "2019-07-15T14:02:16.638804+08:00",
|
||||
@@ -64,15 +65,12 @@ streams | object | 流信息 |
|
||||
streams.sc| number | 流媒体源数量 |
|
||||
streams.cc|number|流媒体消费者数量 |
|
||||
rtsp| object| RTSP连接信息 |
|
||||
rtsp.total|number|总链接数 |
|
||||
rtsp.active | number | 活跃连接数 |
|
||||
wsp| object| WSP连接信息 |
|
||||
wsp.total|number|总链接数 |
|
||||
wsp.active | number | 活跃连接数 |
|
||||
rtsp.total|number|累计总链接数 |
|
||||
rtsp.active | number | 当前活跃连接数 |
|
||||
flv| object| flv连接信息 |
|
||||
flv.total|number|总链接数 |
|
||||
flv.active | number | 活跃连接数 |
|
||||
extra | object | 额外信息 |
|
||||
flv.total|number|累计总链接数 |
|
||||
flv.active | number | 当前活跃连接数 |
|
||||
extra | object | 运行时内存等信息 |
|
||||
|
||||
#### 1.2.1 示例
|
||||
curl 示例一:
|
||||
@@ -97,10 +95,6 @@ curl http://localhost:1554/api/v1/runtime
|
||||
"total": 0,
|
||||
"active": 0
|
||||
},
|
||||
"wsp": {
|
||||
"total": 0,
|
||||
"active": 0
|
||||
},
|
||||
"flv": {
|
||||
"total": 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
|
||||
+ websocket-flv
|
||||
ws://.../ws/room/door.flv?token=your_access_token
|
||||
+ wps
|
||||
ws://.../ws/room/door?token=your_access_token
|
||||
+ rtmp
|
||||
rtmp://.../room/door?token=your_access_token
|
||||
+ http-flv
|
||||
http://.../steams/room/door.m3u8?token=your_access_token
|
||||
|
||||
### 1.4 刷新access token
|
||||
GET api/v1/refreshtoken?token={refresh_tokebn}
|
||||
|
@@ -21,18 +21,14 @@
|
||||
]
|
||||
```
|
||||
我们配置了两个路由:
|
||||
+ /group/door
|
||||
+ /group/door : 集团大门直接连接到摄像头
|
||||
+ /hr/ : 人力资源部门的摄像头路由到下级的服务器
|
||||
假设下级服务器有 /door/video1 和 /door/video2 两个摄像头,那么你可以通过 .../hr/door/video1 和 .../hr/door/video2 访问它们。
|
||||
|
||||
集团大门直接连接到摄像头
|
||||
+ /hr/
|
||||
|
||||
人力资源部门的摄像头路由到下级的服务器中;hr的服务器包含:/door/video1和/door/video2
|
||||
|
||||
## 3. 使用
|
||||
## 3. 访问流媒体
|
||||
服务器提供了多种访问终端摄像头的方式,包括:
|
||||
+ rtsp
|
||||
+ websocket-rtsp
|
||||
+ wsp(websocket 代理模式)
|
||||
+ http-flv
|
||||
+ websocket-flv
|
||||
+ http-hls
|
||||
@@ -57,20 +53,16 @@ rtsp://localhost:1554/hr/door/video1 请求在服务器内自动变成去拉取r
|
||||
打开demo地址:http://localhost:1554/demos/rtsp
|
||||
输入:ws://localhost:1554/ws/group/door 即可访问
|
||||
|
||||
### 3.3 使用wsp访问
|
||||
和上面一样,打开demo地址:http://localhost:1554/demos/wsp
|
||||
输入:rtsp://localhost:1554/group/door 即可访问
|
||||
|
||||
### 3.4 使用http-flv访问
|
||||
### 3.3 使用http-flv访问
|
||||
打开demo地址:http://localhost:1554/demos/flv
|
||||
输入:http://locaolhost:1554/streams/group/door.flv 即可访问
|
||||
由于 Chrome 对长连接的流限制为6个,因此如果使用 Chrome 打开更多建议使用websocket-flv
|
||||
|
||||
### 3.5 使用 websocket-flv访问
|
||||
### 3.4 使用 websocket-flv访问
|
||||
打开demo地址:http://localhost:1554/demos/flv
|
||||
输入:ws://locaolhost:1554/ws/group/door.flv 即可访问
|
||||
|
||||
### 3.6 使用 http-hls访问
|
||||
### 3.5 使用 http-hls访问
|
||||
由于 iOS的Safari不支持上述任何http访问模式,请使用 http-hls
|
||||
在浏览器输入: http://localhost:1554/streams/group/door.m3m8 即可访问
|
||||
**注意:** 由于http-hls的段文件默认被放在内存中,占用大量的内存;如系统内存不足,请配置存储路径。
|
||||
@@ -81,10 +73,10 @@ rtsp://localhost:1554/hr/door/video1 请求在服务器内自动变成去拉取r
|
||||
输入:http://locaolhost:1554/streams/group/door.flv?token=7f97509e321a18ccf281607f4c0bd4fb
|
||||
其中 token 通过登录api获得
|
||||
|
||||
对于配置用户,参考配置和Api文档
|
||||
相关信息请参考[配置文档](config.md) 和 [Api 文档](apis.md)
|
||||
|
||||
## 5. 浏览器支持情况
|
||||
wsp、http-flv、websocket-flv等浏览器访问,支持:
|
||||
http-flv、websocket-flv等浏览器访问,支持:
|
||||
+ Firefox v.42+
|
||||
+ Chrome v.23+
|
||||
+ OSX Safari v.8+
|
||||
|
@@ -53,7 +53,10 @@ func (p *jsonProvider) LoadAll() ([]*User, error) {
|
||||
path := p.filePath
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
return []*User{{
|
||||
Name: "admin",
|
||||
Password: "admin",
|
||||
Admin: true}}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -122,16 +122,17 @@ func (s *Service) onLogin(w http.ResponseWriter, r *http.Request, pathParams api
|
||||
|
||||
// 提取凭证
|
||||
var uc UserCredentials
|
||||
err := json.NewDecoder(r.Body).Decode(&uc)
|
||||
if err != nil {
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&uc); err != nil {
|
||||
http.Error(w, "未提供用户名或密码", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// 尝试 Form解析
|
||||
uc.Username = r.FormValue("username")
|
||||
uc.Password = r.FormValue("password")
|
||||
if len(uc.Username) == 0 || len(uc.Password) == 0 {
|
||||
http.Error(w, "用户名或密码错误", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 验证用户和密码
|
||||
u := auth.Get(uc.Username)
|
||||
@@ -187,7 +188,6 @@ func (s *Service) onGetRuntime(w http.ResponseWriter, r *http.Request, pathParam
|
||||
Proc stats.Proc `json:"proc"`
|
||||
Streams sccc `json:"streams"`
|
||||
Rtsp stats.ConnsSample `json:"rtsp"`
|
||||
Wsp stats.ConnsSample `json:"wsp"`
|
||||
Flv stats.ConnsSample `json:"flv"`
|
||||
Extra *stats.Runtime `json:"extra,omitempty"`
|
||||
}
|
||||
@@ -198,7 +198,6 @@ func (s *Service) onGetRuntime(w http.ResponseWriter, r *http.Request, pathParam
|
||||
Proc: stats.MeasureRuntime(),
|
||||
Streams: sccc{sc, cc},
|
||||
Rtsp: stats.RtspConns.GetSample(),
|
||||
Wsp: stats.WspConns.GetSample(),
|
||||
Flv: stats.FlvConns.GetSample(),
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,6 @@ import (
|
||||
// 全局变量
|
||||
var (
|
||||
RtspConns = NewConns() // RTSP连接统计
|
||||
WspConns = NewConns() // WSP连接统计
|
||||
FlvConns = NewConns() // flv连接统计
|
||||
)
|
||||
|
||||
|
Reference in New Issue
Block a user