视频鉴黄提供视频内容检测,识别视频中是否存在色情内容。
支持存储在七牛云 bucket(支持华东、华北和华南 bucket)或 非七牛云 bucket 中的视频进行视频鉴黄。
支持实时处理和异步处理两种方式:实时处理时,视频鉴黄结果会在识别完成后立即返回;异步处理时,会立即返回job_id,视频鉴黄结果通过job_id获得。
视频鉴黄结果会返回所有视频片段是属于色情、性感、还是正常的识别结果。同时为了让用户知道一个视频整体的分类,返回的结果会包含视频片段中出现过的分类,并显示属于这个分类的视频片段的最高的置信度。
可以通过设置请求参数,仅返回满足客户需求的视频片段(例如:用户仅需要返回色情的视频片段,以便对这部分内容做人工审核)。
支持一次调用同时请求鉴黄、鉴暴恐、敏感人物识别。请查看文档中三鉴(鉴黄、鉴暴恐和敏感人物识别)同时调用的示例。
视频片段segments:视频鉴黄是把视频截帧后,对截帧图片进行鉴黄。当连续帧推理结果一致时,表示这些帧都属于同一种类型,则把这一时段的视频认为是一个视频片段。
请求语法
POST /v1/video/
Host: ai.qiniuapi.com
Content-Type: application/json
Authorization: Qiniu :
{
"data": {
"uri": "http://www.qiniu.com/video.mp4"
},
"params": {
"async": ,
"vframe": {
"mode": ,
"interval":
},
"save": {
"bucket": ,
"prefix":
},
"hookURL": "http://yy.com/yyy"
},
"ops": [
{
"op": ,
"params": {
"labels": [
{
"label": ,
"select": ,
"score":
},
...
]
}
},
...
]
}
注意: 需要在 POST 请求的 head 部分添加七牛鉴权,以进行用户身份验证。
参数
类型
必选
说明
vid
string
是
调用者设置的视频唯一标识,异步处理的返回结果中会带上该信息
data.uri
string
是
视频地址
params.async
boolean
否
true是异步处理,false是同步处理,不填则取默认值false
params.vframe.mode
int
否
截帧逻辑,可选值为[0, 1]。0表示每隔固定时间截一帧,固定时间在vframe.interval中设定;1表示截关键帧。不填表示取默认值1。
params.vframe.interval
int
否
当params.vframe.mode取0时,用来设置每隔多长时间截一帧,单位s, 取值范围为1~60,不填则取默认值5s
params.save.bucket
string
否
保存截帧图片的Bucket名称,目前只支持华东的bucket。如何创建七牛云bucket,请参见文档。
params.save.prefix
string
否
截帧图片名称的前缀,图片名称的格式为// (图片命名格式仅供参考,业务请不要依赖此命名格式)
params.hookURL
string
否
视频检测结束后的回调地址
ops.op
string
是
视频检测执行的命令,支持多种视频检测操作。目前,视频鉴黄的命令就是pulp。
ops.op.params.labels.label
string
否
对某个命令返回label进行过滤,必须与ops.op.params.labels.select、ops.op.params.labels.score一起使用。例如,视频鉴黄的命令pulp的label有0色情, 1性感, 2正常。如果设置为label=0和select=2,则返回结果中只返回label=0的片段。注:score 越高,说明属于这一个分类(label)的概率越高。比如色情、性感、正常的label,正常这个label对应的score最高,则说明图片最有可能是正常的。
ops.op.params.labels.select
int
否
对ops.op.params.labels.label中设置的label,设置过滤条件,1表示忽略不选,2表示只选该类别。
ops.op.params.labels.score
float
否
过滤返回label结果的置信度参数,当ops.op.params.labels.select=1时表示忽略不选小于该设置的结果,当select=2时表示只选大于等于该设置的结果
响应语法
返回结果按照请求参数params.async分为两种:
params.async == false:实时处理请求,视频鉴黄完成后就返回结果
HTTP/1.1 200 OK
Content-Type: application/json
{
: {
"labels": [
{
"label": ,
"score":
},
...
],
"segments": [
{
"offset_begin": ,
"offset_end": ,
"labels": [
{
"label": ,
"score":
},
...
],
"cuts": [
{
"offset": ,
"uri": ,
"result": {}
},
...
]
},
...
]
}
}参数
类型
说明
op
string
视频检测命令
op.labels.label
string
视频维度的标签,与op.lables.score 成对返回。例如,某个视频进行视频鉴黄处理,视频片断中有若干个标签为0色情和1性感的结果,那么就表示这个视频有0色情和1性感两类标签。
op.lables.score
float
显示的是op.labels.label这类标签的置信度。这个值取的是该视频中属于这类的所有视频片断的置信度的最大值。
op.segments.offset_begin
int
视频片段起始的时间位置。
op.segments.offset_end
int
视频片段结束的时间位置。
op.segments.labels.label
string
视频片断所属的标签,一个视频片断只会有一个标签。
op.segments.labels.score
float
视频片断所属标签的置信度。这个值取的是该视频片断中所有帧的置信度的最大值。
op.segments.cuts.offset
int
视频截帧的时间位置
op.segments.cuts.uri
string
视频截帧的保存路径
op.segments.cuts.result
interface
视频截帧得到的图片的检测标签,结果与具体的命令有关。例如,视频鉴黄的命令pulp的标签有0色情, 1性感, 2正常。
params.async == true:异步处理请求,立即返回job_id
HTTP/1.1 200 OK
Content-Type: application/json
{
"job":
}参数
类型
必选
说明
job_id
string
是
服务器返回的,唯一标识该视频任务的ID。
异步处理的结果
异步处理后,获取单个视频鉴黄的结果
请求语法
GET /v1/jobs/video/ HTTP/1.1
Host: ai.qiniuapi.com
Authorization: Qiniu :
注意: 需要在请求的 head 部分添加七牛鉴权,以进行用户身份验证。
参数
类型
必选
说明
job_id
string
是
服务器返回的,唯一标识该视频任务的ID。
响应语法
{
"id": ,
"vid": ,
"request": {},
"status": ,
"result": {
: {
},
...
},
"error": ,
"created_at": ,
"updated_at":
}参数
类型
说明
id
string
服务器返回的,唯一标识该视频任务的ID
vid
string
视频唯一标识,申请任务时传入的vid
request
object
视频分析请求
status
string
任务状态,WAITING/DOING/RESCHEDULED/FAILED/FINISHED,RESCHEDULED是指等待重试中
result
object
详细解释见实时处理请求返回结果
error
string
处理视频的过程中遇到的错误,会返回相应的错误信息,详细解释见错误代码含义
created_at
string
任务创建时间,like: 2006-01-02T15:03:04
updated_at
string
任务更新时间,like: 2006-01-02T15:03:04
错误代码含义
Error Code
Error Message
Desc
400
"bad op"
输入的op值不支持
400
"invalid interval, allow mode is [0, 10]"
输入的vframe的interval值不在[0-10]的范围
400
"invalid mode, allow mode is [0, 1]"
输入的vframe的mode值不在[0-1]的范围
424
"cannot find the video"
找不到输入的视频文件
400
"cannot open the file"
打不开输入的视频文件
500
"cannot allow memory"
发生内存不足等情况
异步处理时,获取视频处理任务状态
请求语法
GET /v1/jobs/video?status= HTTP/1.1
Host: ai.qiniuapi.com
Authorization: Qiniu :
注意: 需要在请求的 head 部分添加七牛鉴权,以进行用户身份验证。
参数
类型
必选
说明
status
string
否
任务状态,WAITING/DOING/RESCHEDULED/FAILED/FINISHED,RESCHEDULED是指等待重试中
响应语法
[
{
"id": ,
"status": ,
"created_at": ,
"updated_at":
},
...
]参数
类型
说明
id
string
服务器返回的,唯一标识该视频任务的ID
status
string
任务状态,WAITING/DOING/RESCHEDULED/FAILED/FINISHED,RESCHEDULED是指等待重试中
created_at
string
任务创建时间,like: 2006-01-02T15:03:04
updated_at
string
任务更新时间,like: 2006-01-02T15:03:04
视频处理的结果回调
所有op处理结束后的结果回调CALLBACK /v1/video/result
请求语法
POST /xxxxx HTTP/1.1
Content-Type: application/json
{
"id": ,
"result": {
: {
},
...
}
}参数
类型
说明
id
string
调用者设置的视频唯一标识
result
object
详细解释见实时处理请求返回结果
请求示例
{
"data": {
"uri": "http://foo.com/foo.mp4"
},
"params": {
"vframe": {
"interval": 5
}
},
"ops": [
{
"op": "pulp",
}
]
}
返回示例
{
"pulp": {
"labels": [{
"label": "2",
"score": 0.9991879
}, {
"label": "0",
"score": 0.49774298
}],
"segments": [{
"offset_begin": 0,
"offset_end": 2233,
"labels": [{
"label": "2",
"score": 0.99896765
}],
"cuts": [{
"offset": 0,
"result": {
"label": 2,
"score": 0.99896765,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99896765
}, {
"index": 1,
"class": "sexy",
"score": 0.000120945006
}, {
"index": 0,
"class": "pulp",
"score": 0.000070455964
}]
}
}, {
"offset": 2233,
"result": {
"label": 2,
"score": 0.99812955,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99812955
}, {
"index": 0,
"class": "pulp",
"score": 0.00028895753
}, {
"index": 1,
"class": "sexy",
"score": 0.00005779577
}]
}
}]
}, {
"offset_begin": 5300,
"offset_end": 5300,
"labels": [{
"label": "0",
"score": 0.49774298
}],
"cuts": [{
"offset": 5300,
"result": {
"label": 0,
"score": 0.49774298,
"review": true,
"confidences": [{
"index": 0,
"class": "pulp",
"score": 0.49774298
}, {
"index": 2,
"class": "normal",
"score": 0.14850456
}, {
"index": 1,
"class": "sexy",
"score": 0.027909799
}]
}
}]
}, {
"offset_begin": 10800,
"offset_end": 37800,
"labels": [{
"label": "2",
"score": 0.9991879
}],
"cuts": [{
"offset": 10800,
"result": {
"label": 2,
"score": 0.9991879,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.9991879
}, {
"index": 1,
"class": "sexy",
"score": 0.00008958933
}, {
"index": 0,
"class": "pulp",
"score": 0.000060963135
}]
}
}, {
"offset": 11666,
"result": {
"label": 2,
"score": 0.99494386,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99494386
}, {
"index": 0,
"class": "pulp",
"score": 0.00061269634
}, {
"index": 1,
"class": "sexy",
"score": 0.00032472512
}]
}
}, {
"offset": 17466,
"result": {
"label": 2,
"score": 0.9978196,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.9978196
}, {
"index": 1,
"class": "sexy",
"score": 0.00024165121
}, {
"index": 0,
"class": "pulp",
"score": 0.00016254994
}]
}
}, {
"offset": 23133,
"result": {
"label": 2,
"score": 0.99635637,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99635637
}, {
"index": 1,
"class": "sexy",
"score": 0.00047670802
}, {
"index": 0,
"class": "pulp",
"score": 0.00019879821
}]
}
}, {
"offset": 26600,
"result": {
"label": 2,
"score": 0.98734176,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.98734176
}, {
"index": 1,
"class": "sexy",
"score": 0.002269196
}, {
"index": 0,
"class": "pulp",
"score": 0.00007761171
}]
}
}, {
"offset": 31999,
"result": {
"label": 2,
"score": 0.99583465,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99583465
}, {
"index": 1,
"class": "sexy",
"score": 0.00071806915
}, {
"index": 0,
"class": "pulp",
"score": 0.0000541617
}]
}
}, {
"offset": 37800,
"result": {
"label": 2,
"score": 0.99828905,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99828905
}, {
"index": 1,
"class": "sexy",
"score": 0.00028825115
}, {
"index": 0,
"class": "pulp",
"score": 0.000028989076
}]
}
}]
}]
}
}
三鉴同时调用的示例
{
"data": {
"uri": "http://os4v3rzk2.bkt.clouddn.com/20180901184507plUL4y.mp4"
},
"params": {
"vframe": {
"interval": 5
}
},
"ops": [
{
"op": "pulp"
},
{
"op": "terror"
},
{
"op": "politician"
}
]
}
三鉴同时调用的返回示例
{
"politician": {
"segments": null
},
"pulp": {
"labels": [{
"label": "2",
"score": 0.9991879
}, {
"label": "0",
"score": 0.49775043
}],
"segments": [{
"offset_begin": 0,
"offset_end": 2233,
"labels": [{
"label": "2",
"score": 0.99896765
}],
"cuts": [{
"offset": 0,
"result": {
"label": 2,
"score": 0.99896765,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99896765
}, {
"index": 1,
"class": "sexy",
"score": 0.000120948236
}, {
"index": 0,
"class": "pulp",
"score": 0.00007045435
}]
}
}, {
"offset": 2233,
"result": {
"label": 2,
"score": 0.99812955,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99812955
}, {
"index": 0,
"class": "pulp",
"score": 0.00028895302
}, {
"index": 1,
"class": "sexy",
"score": 0.000057794834
}]
}
}]
}, {
"offset_begin": 5300,
"offset_end": 5300,
"labels": [{
"label": "0",
"score": 0.49775043
}],
"cuts": [{
"offset": 5300,
"result": {
"label": 0,
"score": 0.49775043,
"review": true,
"confidences": [{
"index": 0,
"class": "pulp",
"score": 0.49775043
}, {
"index": 2,
"class": "normal",
"score": 0.14849894
}, {
"index": 1,
"class": "sexy",
"score": 0.027908035
}]
}
}]
}, {
"offset_begin": 10800,
"offset_end": 37800,
"labels": [{
"label": "2",
"score": 0.9991879
}],
"cuts": [{
"offset": 10800,
"result": {
"label": 2,
"score": 0.9991879,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.9991879
}, {
"index": 1,
"class": "sexy",
"score": 0.00008958942
}, {
"index": 0,
"class": "pulp",
"score": 0.000060963186
}]
}
}, {
"offset": 11666,
"result": {
"label": 2,
"score": 0.99494386,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99494386
}, {
"index": 0,
"class": "pulp",
"score": 0.00061269663
}, {
"index": 1,
"class": "sexy",
"score": 0.00032472447
}]
}
}, {
"offset": 17466,
"result": {
"label": 2,
"score": 0.9978196,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.9978196
}, {
"index": 1,
"class": "sexy",
"score": 0.00024165121
}, {
"index": 0,
"class": "pulp",
"score": 0.00016254994
}]
}
}, {
"offset": 23133,
"result": {
"label": 2,
"score": 0.99635637,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99635637
}, {
"index": 1,
"class": "sexy",
"score": 0.00047670802
}, {
"index": 0,
"class": "pulp",
"score": 0.00019879821
}]
}
}, {
"offset": 26600,
"result": {
"label": 2,
"score": 0.9873413,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.9873413
}, {
"index": 1,
"class": "sexy",
"score": 0.002269225
}, {
"index": 0,
"class": "pulp",
"score": 0.000077612145
}]
}
}, {
"offset": 31999,
"result": {
"label": 2,
"score": 0.99583465,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99583465
}, {
"index": 1,
"class": "sexy",
"score": 0.00071806915
}, {
"index": 0,
"class": "pulp",
"score": 0.0000541617
}]
}
}, {
"offset": 37800,
"result": {
"label": 2,
"score": 0.99828905,
"review": false,
"confidences": [{
"index": 2,
"class": "normal",
"score": 0.99828905
}, {
"index": 1,
"class": "sexy",
"score": 0.00028824853
}, {
"index": 0,
"class": "pulp",
"score": 0.00002898877
}]
}
}]
}]
},
"terror": {
"labels": [{
"label": "0",
"score": 0.99663216
}, {
"label": "1",
"score": 0.946602
}],
"segments": [{
"offset_begin": 0,
"offset_end": 0,
"labels": [{
"label": "0",
"score": 0.9935556
}],
"cuts": [{
"offset": 0,
"result": {
"label": 0,
"score": 0.9935556,
"review": false
}
}]
}, {
"offset_begin": 2233,
"offset_end": 2233,
"labels": [{
"label": "1",
"score": 0.946602
}],
"cuts": [{
"offset": 2233,
"result": {
"label": 1,
"score": 0.946602,
"review": false
}
}]
}, {
"offset_begin": 5300,
"offset_end": 37800,
"labels": [{
"label": "0",
"score": 0.99663216
}],
"cuts": [{
"offset": 5300,
"result": {
"label": 0,
"score": 0.83630264,
"review": false
}
}, {
"offset": 10800,
"result": {
"label": 0,
"score": 0.5058211,
"review": false
}
}, {
"offset": 11666,
"result": {
"label": 0,
"score": 0.99561405,
"review": false
}
}, {
"offset": 17466,
"result": {
"label": 0,
"score": 0.99663216,
"review": false
}
}, {
"offset": 23133,
"result": {
"label": 0,
"score": 0.95209014,
"review": false
}
}, {
"offset": 26600,
"result": {
"label": 0,
"score": 0.18816724,
"review": false
}
}, {
"offset": 31999,
"result": {
"label": 0,
"score": 0.86865,
"review": false
}
}, {
"offset": 37800,
"result": {
"label": 0,
"score": 0.97071385,
"review": false
}
}]
}]
}
}
价格
视频鉴黄的工作流程如下:
1)按照API里面的设置对视频进行截帧,不额外收费
2)对截帧进行图片鉴黄
所以,视频鉴黄的价格最终还是图片鉴黄的价格,具体价格请参考。
服务价格
视频鉴黄是对视频截帧后,对截帧进行图片鉴黄,所以视频鉴黄价格实际使用的是截帧图片鉴黄的价格,与图片鉴黄共用范围。
例:
某月视频文件使用视频鉴黄服务,视频截帧的数量为400万,即视频鉴黄产生的图片鉴黄量为400万;当月图片文件使用鉴黄服务,其调用量为106万。则这个月总的图片鉴黄调用量为506万,账单金额则为:
图片鉴黄:
3000000*0.155/100+2000000*0.145/100=4650+2900=7550元