动作活体检测API和H5
<p>[TOC]</p>
<h2>接口描述</h2>
<ul>
<li>拍摄一段视频,按照指示做相应动作来识别是否为活⼈</li>
<li>动作活体⽀持眨眼、张嘴、左右摇头、上下点头四个动作</li>
<li>视频时长3秒左右,大小建议不超过10M,常用视频格式都支持【注意:webm也支持】</li>
<li>本文档适用于API、H5两种方式接入</li>
</ul>
<h2>API方式</h2>
<h3>请求说明</h3>
<h4>请求地址</h4>
<p><code>https://api.jumdata.com/lifecheck</code></p>
<h4>请求方式</h4>
<ul>
<li>POST</li>
</ul>
<h4>请求格式</h4>
<ul>
<li>form-data</li>
</ul>
<h4>请求参数</h4>
<table>
<thead>
<tr>
<th>名称</th>
<th>类型</th>
<th>必须</th>
<th><div style="width:420px">说明</div></th>
</tr>
</thead>
<tbody>
<tr>
<td>appId</td>
<td>String</td>
<td>是</td>
<td>聚美智数分配的商户唯一标识</td>
</tr>
<tr>
<td>timestamp</td>
<td>long</td>
<td>是</td>
<td>当前时间戳</td>
</tr>
<tr>
<td>sign</td>
<td>String</td>
<td>是</td>
<td>签名,<a href='#sign'>见签名算法说明</a></td>
</tr>
<tr>
<td>file</td>
<td>file</td>
<td>否</td>
<td>视频文件,适合本地文件上传,file和url二选一</td>
</tr>
<tr>
<td>url</td>
<td>String</td>
<td>否</td>
<td>视频文件地址,下载限时10秒,file和url二选一</td>
</tr>
<tr>
<td>motions</td>
<td>String</td>
<td>是</td>
<td>用户动作序列,BLINK - 眨眼;MOUTH - 张嘴; NOD - 点头;YAW - 摇头</td>
</tr>
</tbody>
</table>
<p><a name="sign"></a></p>
<h4>签名算法</h4>
<pre><code class="language-java">sign = sha256(appId + appSecret + timestamp)</code></pre>
<p>用聚美智数分配的 <strong>appId</strong>和 <strong>appSecret</strong>,当前时间戳 <strong>timestamp</strong>,按上述顺序拼接成字符串,再进行 <strong>sha256</strong> 哈希得到。如下:</p>
<pre><code class="language-java">String appId = &quot;xyzxy2121zxyz&quot;;
String timestamp = &quot;1555378976238&quot;;
String appSecret = &quot;efcefcef1121cefcefc1212121&quot;;
String str = appId + appSecret + timestamp;
String sign = sha256(str);</code></pre>
<h3>返回说明</h3>
<h4>通过返回样例</h4>
<pre><code class="language-json">{
&quot;code&quot;: 200,
&quot;message&quot;: &quot;成功&quot;,
&quot;charge&quot;: true,
&quot;taskNo&quot;: &quot;69564903663951243279&quot;,
&quot;data&quot;:{
&quot;passed&quot;: true,
&quot;face_image_url&quot;: &quot;https://xxxx&quot;,
&quot;hack_score&quot;: 0.7475364208221436,
&quot;motions&quot;:{
&quot;score&quot;: 0.4667766656564324,
&quot;motion&quot;: &quot;BLINK&quot;,
&quot;passed&quot;: true
}
}
}</code></pre>
<h4>不通过返回样例</h4>
<pre><code class="language-json">{
&quot;code&quot;: 200,
&quot;message&quot;: &quot;成功&quot;,
&quot;charge&quot;: true,
&quot;taskNo&quot;: &quot;69564903663951243279&quot;,
&quot;data&quot;:{
&quot;desc&quot;: &quot;检测不通过&quot;,
&quot;passed&quot;: false,
&quot;hack_score&quot;: 0.9975364208221436,
&quot;motions&quot;:{
&quot;score&quot;: 0.1667766656504324,
&quot;motion&quot;: &quot;BLINK&quot;,
&quot;passed&quot;: false
}
}
}</code></pre>
<h4>错误返回样例</h4>
<pre><code>{
&quot;msg&quot;: &quot;参数错误&quot;,
&quot;code&quot;: 400
}</code></pre>
<h4>返回字段说明</h4>
<table>
<thead>
<tr>
<th>字段名</th>
<th><div style="width:420px">说明</div></th>
</tr>
</thead>
<tbody>
<tr>
<td>code</td>
<td>返回码,详见code返回码说明(非http返回状态码)</td>
</tr>
<tr>
<td>msg</td>
<td>code对应的描述</td>
</tr>
<tr>
<td>charge</td>
<td>计费标志</td>
</tr>
<tr>
<td>taskNo</td>
<td>本次请求号</td>
</tr>
<tr>
<td>data</td>
<td>返回具体结果,object类型,详见data返回字段描述</td>
</tr>
</tbody>
</table>
<h4>data返回字段说明</h4>
<table>
<thead>
<tr>
<th>字段名</th>
<th><div style="width:420px">说明</div></th>
</tr>
</thead>
<tbody>
<tr>
<td>passed</td>
<td>总体检测结果,true - 通过,false - 未通过</td>
</tr>
<tr>
<td>desc</td>
<td>passed为false 活体检查失败的原因</td>
</tr>
<tr>
<td>face_image_url</td>
<td>活体成功之后,抓取的人脸照片</td>
</tr>
<tr>
<td>hack_score</td>
<td>防hack检测分数,hack_score阈值为0.98,由行业大数据训练得到,大于0.98是hack行为,小于等于0.98是正常活人</td>
</tr>
<tr>
<td>motions</td>
<td>单个行为检测结果,详见motions返回字段说明</td>
</tr>
</tbody>
</table>
<h4>motions返回字段说明</h4>
<table>
<thead>
<tr>
<th>字段名</th>
<th><div style="width:420px">说明</div></th>
</tr>
</thead>
<tbody>
<tr>
<td>motion</td>
<td>用户动作序列</td>
</tr>
<tr>
<td>passed</td>
<td>单个动作检测结果</td>
</tr>
<tr>
<td>score</td>
<td>单个动作分值 > 0.2表示通过,<= 0.2表示不通过</td>
</tr>
</tbody>
</table>
<h4>code 说明</h4>
<table>
<thead>
<tr>
<th>code</th>
<th><div style="width:420px">说明</div></th>
</tr>
</thead>
<tbody>
<tr>
<td>200</td>
<td>成功(计费)</td>
</tr>
<tr>
<td>400</td>
<td>参数错误</td>
</tr>
<tr>
<td>404</td>
<td>接口地址不正确</td>
</tr>
<tr>
<td>500</td>
<td>服务商维护,请稍候再试</td>
</tr>
<tr>
<td>601</td>
<td>接口未开通</td>
</tr>
<tr>
<td>602</td>
<td>账号停用</td>
</tr>
<tr>
<td>603</td>
<td>余额不足请充值</td>
</tr>
<tr>
<td>604</td>
<td>接口停用</td>
</tr>
<tr>
<td>606</td>
<td>调用超限,请稍候再试</td>
</tr>
<tr>
<td>607</td>
<td>ip不在白名单</td>
</tr>
<tr>
<td>609</td>
<td>请求过于频繁,请稍候再试</td>
</tr>
<tr>
<td>610</td>
<td>请求超时</td>
</tr>
<tr>
<td>999</td>
<td>其他,以实际返回为准</td>
</tr>
</tbody>
</table>
<h2>H5方式</h2>
<h3>概述</h3>
<ul>
<li>嵌入聚美智数提供的活体检测H5页面,可打开摄像头,根据指示拍摄视频并提交</li>
<li>聚美智数检测完成之后在页面上直接返回结果,也可以通过回调通知方式将结果发送给商家</li>
<li>视频时长2秒左右,大小建议不超过10M</li>
</ul>
<h3>体验</h3>
<p><a href="https://api-h5.jumdata.com/lifecheck?appId=kSOnzJEi78tV8xvS&title=%E6%B4%BB%E4%BD%93%E6%A3%80%E6%B5%8BH5%E7%89%88-%E8%81%9A%E7%BE%8E%E6%99%BA%E6%95%B0">https://api-h5.jumdata.com/lifecheck?appId=kSOnzJEi78tV8xvS&title=%E6%B4%BB%E4%BD%93%E6%A3%80%E6%B5%8BH5%E7%89%88-%E8%81%9A%E7%BE%8E%E6%99%BA%E6%95%B0</a></p>
<h3>请求说明</h3>
<h4>H5页面地址</h4>
<ul>
<li>嵌入以下地址即可
<code>https://api-h5.jumdata.com/lifecheck?appId=&amp;timestamp=&amp;sign=&amp;notifyUrl=&amp;taskId=&amp;returnUrl=&amp;title=&amp;motions=&amp;complexity=</code></li>
</ul>
<h4>参数说明</h4>
<table>
<thead>
<tr>
<th>名称</th>
<th>必须</th>
<th><div style="width:420px">说明</div></th>
</tr>
</thead>
<tbody>
<tr>
<td>appId</td>
<td>是</td>
<td>聚美智数分配的唯一标识</td>
</tr>
<tr>
<td>timestamp</td>
<td>是</td>
<td>当前时间的毫秒数</td>
</tr>
<tr>
<td>sign</td>
<td>是</td>
<td>签名,见签名算法说明</td>
</tr>
<tr>
<td>motions</td>
<td>否</td>
<td>用户动作,BLINK - 眨眼;MOUTH - 张嘴; NOD - 点头;YAW - 摇头。如不传则动作随机</td>
</tr>
<tr>
<td>title</td>
<td>否</td>
<td>活体检测h5页面标题</td>
</tr>
<tr>
<td>notifyUrl</td>
<td>否</td>
<td>商家服务端接收活体检测结果地址 ,详见接收检测结果说明</td>
</tr>
<tr>
<td>taskId</td>
<td>否</td>
<td>商家调用时生成一个唯一id,嵌入h5的时候传入该参数,聚美智数通知结果时原文返回,便于商家关联业务数据。当notifyUrl不为空时,taskId也不能为空</td>
</tr>
<tr>
<td>successUrl</td>
<td>否</td>
<td>活体检测成功跳转到该页面 ,详见接收检测结果说明</td>
</tr>
<tr>
<td>failUrl</td>
<td>否</td>
<td>活体检测失败跳转到该页面 ,详见接收检测结果说明</td>
</tr>
<tr>
<td>returnUrl</td>
<td>否</td>
<td>活体检测后跳转到该页面,当提供了successUrl或failUrl时,该参数无效</td>
</tr>
</tbody>
</table>
<h3>接收检测结果说明</h3>
<ul>
<li>商家的前端和服务端都可以接收检测结果</li>
</ul>
<h4>服务端接收检测结果</h4>
<ul>
<li>如果商家需要在服务端接收检测结果,需要提供接收检测结果接口,聚美智数会在检测之后将检测结果通知到<code>notifyUrl</code> 参数指定的接口地址</li>
</ul>
<h5>请求方式</h5>
<ul>
<li>POST</li>
</ul>
<h5>请求格式</h5>
<ul>
<li>formdata</li>
</ul>
<h5>参数说明</h5>
<table>
<thead>
<tr>
<th>名称</th>
<th><div style="width:420px">说明</div></th>
</tr>
</thead>
<tbody>
<tr>
<td>taskId</td>
<td>返回打开h5页面时传入的taskId</td>
</tr>
<tr>
<td>passed</td>
<td>true 通过;false 未通过</td>
</tr>
<tr>
<td>face_image_url</td>
<td>活体成功之后,抓取的人脸照片</td>
</tr>
<tr>
<td>hack_score</td>
<td>防hack检测分数,hack_score阈值为0.98,由行业大数据训练得到,大于0.98是hack行为,小于等于0.98是正常活人</td>
</tr>
<tr>
<td>motion</td>
<td>用户动作序列</td>
</tr>
<tr>
<td>motions_passed</td>
<td>单个动作检测结果</td>
</tr>
<tr>
<td>motions_score</td>
<td>单个动作行为检测分数</td>
</tr>
<tr>
<td>sign</td>
<td>结果参数签名,详见结果签名算法</td>
</tr>
<tr>
<td>timestamp</td>
<td>当前时间戳</td>
</tr>
</tbody>
</table>
<h5>签名算法</h5>
<pre><code>sha256(appId + appSecret + passed + motions_score + hack_score + face_image_url + timestamp + taskId)</code></pre>
<ul>
<li>将结果参数和appId按顺序:appId,appSecret,passed,motions_score,hack_score,face_image_url,timestamp,taskId 接成字符串,再对拼接后的字符串进行sha256摘要得到</li>
<li>如果passed=false,则face_image_url不返回,生成sign时需要忽略</li>
</ul>
<h5>返回接收结果</h5>
<ul>
<li>商家接收到活体检测结果,在进行自己的业务处理后,需要将处理结果返回给聚美智数,格式如下:</li>
</ul>
<pre><code class="language-json">{
&quot;success&quot;: true,
&quot;msg&quot;: &quot;&quot; // 失败时返回msg,成功时无需返回
}</code></pre>
<ul>
<li>如果是接收失败,聚美智数会再次推送,最多推送5次</li>
</ul>
<h4>前端接收检测结果</h4>
<ul>
<li>
<p>如果商家需要在前端接收检测结果,需要提供接收检测结果页面,聚美智数会在检测之后跳转到<code>successUrl</code> 参数或<code>failUrl</code>参数指定的页面地址,并将检测结果作为url参数带入,如下所示
<code>successUrl?sign=12121312sdsda&amp;taskId=1212121313123123123&amp;passed=true&amp;face_image_url=https://xxx=&amp;hack_score=0.8969539999961853&amp;motion=NOD&amp;motions_passed=true&amp;motions_score=0.23534825444221497</code></p>
</li>
<li>详细参数和服务端结果参数相同 </li>
</ul>
<h2>注意点</h2>
<ul>
<li>摇头和点头,动作幅度不能过大,动作不能太快,否则会检测不到人脸继而失败</li>
</ul>