- 最新功能体验可以将 API Host 改为
pili-lte.qiniuapi.com
。
请求包:
POST /v1/streams
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
Content-Type: application/json
{
"hub": <HubName:string>, # 必须
"title": <StreamTitle:string>, #可选,流名称,缺省由系统自动生成一个
"publishKey": <StreamPublishKey:string>, #可选,设定一个密钥用于生成动态 publishToken 进行推流鉴权,缺省为系统自动生成
"publishSecurity": <PublishSecurity:string> #可选,值为 "dynamic" 或 "static"
}
返回包:
200 OK
Content-Type: application/json
{
"id": "<StreamId>",
"hub": "<HubName>",
"title": "<StreamTitle>",
"publishKey": "<StreamPublishKey>",
"publishSecurity": "<PublishSecurity>",
"disabled": false,
"profiles": ["<ProfileName>"],
"hosts": {
"publish": {
"rtmp": "<RtmpPublishHost>"
},
"live": {
"rtmp": "<RtmpPlayHost>",
"hls": "<HLSPlayHost>",
"hdl": "<HDLPlayHost>"
},
"playback": {
"hls"; "<HLSPlaybackHost>"
}
}
}
-
<StreamId>
=<Zone>.<HubName>.<StreamTitle>
-
<StreamTitle>
格式要求:^[a-zA-Z0-9_-]{4,100}$
-
<PublishSecurity>
: 可选,推流的安全策略,值为dynamic
或static
,缺省是dynamic
-
RTMP 推流地址格式是:
rtmp://<hosts["publish"]["rtmp"]>/<HubName>/<StreamTitle>
-
当
<PublishSecurity>="static"
时,RTMP 推流地址格式是:rtmp://<hosts["publish"]["rtmp"]>/<HubName>/<StreamTitle>?key=<StreamPublishKey>
-
当
<PublishSecurity>="dynamic"
时,RTMP 推流地址格式是:rtmp://<hosts["publish"]["rtmp"]>/<HubName>/<StreamTitle>?nonce=<Nonce>&token=<PublishToken>
。<Nonce>
有效值为比上次推流使用的<Nonce>
大的任意值。 -
<PublishToken> = hmac_sha1("/<HubName>/<StreamTitle>?nonce=<Nonce>&<OtherKey>=<OtherValue>", "<StreamPublishKey>")
-
RTMP 直播播放地址格式是:
rtmp://<hosts["live"]["rtmp"]>/<HubName>/<StreamTitle>[@<ProfileName>]
-
HTTP FLV 直播播放地址格式是:
http://<hosts["live"]["hdl"]>/<HubName>/<StreamTitle>[@<ProfileName>].flv
-
HLS 直播播放地址格式是:
http://<hosts["live"]["hls"]>/<HubName>/<StreamTitle>[@<ProfileName>].m3u8
-
HLS 回放点播地址格式是:
http://<hosts["playback"]["hls"]>/<HubName>/<StreamTitle>[@<ProfileName>].m3u8?start=<startTime>&end=<endTime>
-
[@<ProfileName>]
表示可选,<ProfileName>
表示在云端配置的实时转码规格别名(例如:720p
,480p
),需要额外申请开通。
请求包:
GET /v1/streams/<StreamId>
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
返回包:
200 OK
Content-Type: application/json
{
"id": "<StreamId>",
"hub": "<HubName>",
"title": "<StreamTitle>",
"publishKey": "<StreamPublishKey>",
"publishSecurity": "<PublishSecurity>",
"disabled": false,
"profiles": ["<ProfileName>"],
"hosts": {
"publish": {
"rtmp": "<RtmpPublishHost>"
},
"live": {
"rtmp": "<RtmpPlayHost>",
"hls": "<HLSPlayHost>",
"hdl": "<HDLPlayHost>"
},
"playback": {
"hls"; "<HLSPlaybackHost>"
}
}
}
请求包:
<HubName>
: 必选。<Status>
: 可选。只能使用connected。<StartMark>
: 可选。如果未指定则从头开始。<LimitCount>
: 可选。如果未指定则用内部的一个上限值(比如1000)。
GET /v1/streams?status=<Status>&hub=<HubName>&marker=<StartMarker>&limit=<LimitCount>&title=<TitlePrefix>
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
返回包:
200 OK
Content-Type: application/json
{
"marker": <NextMarker:string>,
"items": [
{
"id": "<StreamId>",
"hub": "<HubName>",
"title": "<StreamTitle>",
"publishKey": "<StreamPublishKey>",
"publishSecurity": "<PublishSecurity>",
"disabled": false,
"profiles": ["<ProfileName>"],
"hosts": {
"publish": {
"rtmp": "<RtmpPublishHost>"
},
"live": {
"rtmp": "<RtmpPlayHost>",
"hls": "<HLSPlayHost>",
"hdl": "<HDLPlayHost>"
},
"playback": {
"hls"; "<HLSPlaybackHost>"
}
}
}
]
}
请求包:
GET /v1/streams/<StreamId>/status
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
返回包:
"<Status>"
connected
disconnected
200 OK
Content-Type: application/json
{
"addr": "<RemoteAddress>",
"startFrom": "<StartFromTime>",
"bytesPerSecond": <CurrentBytesPerSecond>,
"framesPerSecond": {
"audio": <AudioFramesPerSecond>,
"video": <VideoFramesPerSecond>,
"data": <DataFramesPerSecond>
},
"status": "<Status>"
}
请求包:
POST /v1/streams/<StreamId>
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
Content-Type: application/json
{
"publishKey": <StreamPublishKey:string>,
"publishSecurity": <PublishSecurity:string>,
"disabled": true // or false
}
返回包:
200 OK
Content-Type: application/json
{
"id": "<StreamId>",
"hub": "<HubName>",
"title": "<StreamTitle>",
"publishKey": "<StreamPublishKey>",
"publishSecurity": "<PublishSecurity>",
"disabled": true,
"profiles": ["<ProfileName>"],
"hosts": {
"publish": {
"rtmp": "<RtmpPublishHost>"
},
"live": {
"rtmp": "<RtmpPlayHost>",
"hls": "<HLSPlayHost>",
"hdl": "<HDLPlayHost>"
},
"playback": {
"hls"; "<HLSPlaybackHost>"
}
}
}
请求包:
DELETE /v1/streams/<StreamId>
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
返回包:
204 No Content
请求包:
GET /v1/streams/<StreamId>/segments?start=<StartUnixTimestamp>&end=<EndUnixTimestamp>&limit=<Limit>
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
start
- 可选,开始时间,UnixTimestamp 数值。end
- 可选,结束时间,UnixTimestamp 数值。
返回包:
200 OK
Content-Type: application/json
{
"start": <StreamStartUnixTimestamp>,
"end": <StreamEndUnixTimestamp>,
"duration": <TotalDurationOfRequestSegments>,
"segments": [
{
"start": <StartUnixTimestamp>,
"end": <EndUnixTimestamp>
},
{
"start": <StartUnixTimestamp>,
"end": <EndUnixTimestamp>
}
]
}
HLS 回放 URL 格式是:http://<hosts["playback"]["hls"]>/<HubName>/<StreamTitle>[@<ProfileName>].m3u8?start=<StartUnixTimestamp>&end=<EndUnixTimestamp>
请求包:
POST /v1/streams/<StreamId>/snapshot
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
{
"name": "<SnapshotName>",
"format": "<SnapshotFormat>",
"time": <SnapAtUnixTimestamp>, // optional, default is now
"notifyUrl": "<NotifyUrl>"
}
返回包:
200 OK
Content-Type: application/json
{
"targetUrl": "<TargetUrl>",
"persistentId": "<PersistentId>"
}
请求包:
POST /v1/streams/<StreamId>/saveas
Host: pili.qiniuapi.com
Authorization: Qiniu <MacToken>
{
"name": "<VideoName>",
"notifyUrl": "<NotifyUrl>",
"start": <StartUnixTimestamp>, // 可选,默认为流最开始的数据
"end": <EndUnixTimestamp>, // 可选,默认为流最后的数据
"format": "<VideoFormat>" // http://developer.qiniu.com/docs/v6/api/reference/fop/av/avthumb.html
}
返回包:
202 Accept
Content-Type: application/json
{
"url": "<m3u8Url>",
"targetUrl": "<TargetFileUrl>",
"persistentId": <PersistentId>
}
针对如下格式的一个 HTTP 请求:
<Method> <PathWithRawQuery>
<Header1>: <Value1>
<Header2>: <Value2>
...
Host: <Host>
...
Content-Type: <ContentType>
...
Authorization: Qiniu <AK>:<Sign>
...
<Body>
对于上面这样一个请求,我们构造如下这个待签名的 <Data>
:
<Method> <PathWithRawQuery>
Host: <Host>
Content-Type: <ContentType>
[<Body>] #这里的 <Body> 只有在 <ContentType> 存在且不为 application/octet-stream 时才签进去。
有了 <Data>
,就可以计算对应的 <Sign>
,如下:
<Sign> = urlsafe_base64(hmac_sha1(<SK>, <Data>))
一个正常的待签名的 <Data>
长如下样子:
POST /v1/streams
Host: pili.qiniuapi.com
Content-Type: application/json
{
"title": 'abc',
"hub": 'doretest001',
"publishKey": 'aaaa-bbbb-cccc-dddd',
"publishSecurity": 'static'
}
Go 签名示例:
func MACToken(sk []byte, req *http.Request) ([]byte, error) {
h := hmac.New(sha1.New, sk)
u := req.URL
data := req.Method + " " + u.Path
if u.RawQuery != "" {
data += "?" + u.RawQuery
}
io.WriteString(h, data + "\nHost: " + req.Host)
ctType := req.Header.Get("Content-Type")
if ctType != "" {
io.WriteString(h, "\nContent-Type: " + ctType)
}
io.WriteString(h, "\n\n")
if req.Body != nil && ctType != "" && ctType != "application/octet-stream" {
s2, err2 := seekable.New(req)
if err2 != nil {
return nil, err2
}
h.Write(s2.Bytes())
}
return h.Sum(nil), nil
}
提问:
我生成的推流地址如下:
rtmp://pub.z1.glb.pili.qiniup.com/gouhuolive/5544ef69fb16df2e330001d7?key=e51a45450d680f32
下午 2015.5.19 13:25 完成了一次直播,但是想进行回放,用如下地址(时间戳已经计算过),并没有访问到可以回放的视频~求解
回放URL: http://hls1.z1.glb.pili.qiniuapi.com/gouhuolive/5544ef69fb16df2e330001d7.m3u8?start=1432013100&end=1432013700