API for Retrieving Live Video Clips
Updated: 2023-11-14 14:07:19
API URL
https://api.polyv.net/live/v2/channel/recordFile/{channelId}/streamRecordIndex
API Description
1. Retrieves video clips from the currently live channel.
2. The API supports the HTTPS protocol.
Supported Format
JSON
Request Method
GET or POST
Request Limit
TRUE
Request Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| appId | Yes | string | Obtained from API settings, the appId registered in the live streaming system. |
| timestamp | Yes | string | Current 13-digit millisecond timestamp, valid for 3 minutes. |
| startTime | Yes | string | Start time of the video clip, format: yyyy-MM-dd HH:mm:ss. |
| endTime | Yes | string | End time of the video clip, format: yyyy-MM-dd HH:mm:ss. |
| fileName | No | string | File name for saving to VOD. If not provided, the default name is "精彩片段". |
| cataId | No | long | Directory ID for saving to VOD. |
| sign | Yes | String | Signature, a 32-character uppercase MD5 value. The appSecret key used to generate the signature is critical for communication data security. It must not be used directly on the client side. All APIs must be called through the customer's own server to relay requests to the POLYV server for response data. See Signature Generation Rules |
Successful Response JSON Example:
{
"code": 200,
"status": "success",
"message": "",
"data": "8205ac89d3f0c634988ef97f528aa745_8"
}
Incorrect appId
{
"code": 400,
"status": "error",
"message": "application not found.",
"data": ""
}
Timestamp error
{
"code": 400,
"status": "error",
"message": "invalid timestamp.",
"data": ""
}
Signature error
{
"code": 403,
"status": "error",
"message": "invalid signature.",
"data": ""
}
Channel not found
{
"code": 400,
"status": "error",
"message": "channel not found.",
"data": ""
}
Query start time or end time is empty
{
"code": 400,
"status": "error",
"message": "startTime or endTime not found.",
"data": ""
}
Invalid start time or end time
{
"code": 400,
"status": "error",
"message": "startTime or endTime valid.",
"data": ""
}
Channel does not have this feature. Please contact customer service.
{
"code": 403,
"status": "error",
"message": "该频道暂不支持此api功能",
"data": ""
}
Save failed. Please retry. If it persists, check your POLYVO account storage and plan expiration, and contact customer service.
{
"code": 403,
"status": "error",
"message": "转存失败,请重试",
"data": ""
}
Field Description
| Parameter | Description |
|---|---|
| code | Response status code. |
| status | Request status. |
| message | Error message. |
| data | On success, returns the vid of the video saved to VOD. |
PHP Request Example
<?php
include 'config.php';
//接口需要的参数(非sign)赋值
$channelId = "108888";
$startTime = "2018-04-16 09:33:33";
$endTime = "2018-04-16 09:44:30";
$params = array(
'appId'=> $appId,
'timestamp'=> $timestamp,
'startTime'=> $startTime,
'endTime'=> $endTime,
);
//生成sign
$sign = getSign($params); //详细查看config.php文件的getSign方法
//接口请求url
$url = "https://api.polyv.net/live/v2/channel/recordFile/$channelId/streamRecordIndex?appId=$appId×tamp=$timestamp&sign=$sign&startTime=$startTime&endTime=$endTime";
//输出接口请求结果
echo file_get_contents($url);
?>
JAVA Request Example
import com.live.util.EncryptionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.*;
public class TestStreamIndex {
// 尽量把时间设置较长
private RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(15000)
.setConnectionRequestTimeout(60000).build();
private static final String APP_ID = "xxxx";
private static final String APP_SECRET = "xxxxxxxxxxxx";
private static final String STREAM_RECORD_INDEX_URL = "http://api.polyv.net/live/v2/channel/recordFile/{param}/streamRecordIndex";
public static void main(String[] args) {
TestStreamIndex demo = new TestStreamIndex();
int channelId = 183730;
String start = "2018-04-17 10:54:50";
String end = "2018-04-17 11:05:00";
String fileName = "我的直播片段";
long cataId = 1;
demo.streamRecordIndexDemo(channelId, start, end, fileName, cataId);
}
private void streamRecordIndexDemo(int channelId, String start, String end, String fileName, long cataId) {
Map<String, String> params = new HashMap<>();
params.put("appId", APP_ID);
params.put("startTime", start);
params.put("endTime", end);
params.put("timestamp", String.valueOf(System.currentTimeMillis()));
params.put("fileName", fileName);
params.put("cataId", String.valueOf(cataId));
params.put("sign", this.generateSign(params, APP_SECRET));
String result = sendHttpPost(getRealApiUrl(STREAM_RECORD_INDEX_URL, String.valueOf(channelId)), params);
System.out.println("stream record index result=" + result);
}
private String getRealApiUrl(String url, String param){
return url.replace("{param}", param);
}
public String sendHttpPost(String httpUrl, Map<String, String> maps) {
HttpPost httpPost = new HttpPost(httpUrl);
List<NameValuePair> nameValuePairs = new ArrayList<>();
for (String key : maps.keySet()) {
nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
return sendHttpPost(httpPost);
}
private String sendHttpPost(HttpPost httpPost) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpEntity entity = null;
String responseContent = null;
try {
httpClient = HttpClients.createDefault();
httpPost.setConfig(requestConfig);
response = httpClient.execute(httpPost);
entity = response.getEntity();
responseContent = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return responseContent;
}
/**
* 根据map里的参数构建加密串
* @param map
* @param secretKey
* @return
*/
protected String generateSign(Map<String, String> map, String secretKey) {
Map<String, String> params = this.paraFilter(map);
// 处理参数,计算MD5哈希值
String concatedStr = this.concatParams(params);
String plain = secretKey + concatedStr + secretKey;
String encrypted = EncryptionUtils.md5Hex(plain);
// 32位大写MD5值
return encrypted.toUpperCase();
}
/**
* 对params根据key来排序并且以key1=value1&key2=value2的形式拼接起来
* @param params
* @return
*/
private String concatParams(Map<String, String> params) {
List<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
String value = params.get(key);
sb.append(key).append(value);
}
return sb.toString();
}
/**
* 除去数组中的空值和签名参数
* @param sArray 签名参数组
* @return 去掉空值与签名参数后的新签名参数组
*/
private Map<String, String> paraFilter(Map<String, String> sArray) {
Map<String, String> result = new HashMap<String, String>();
if (sArray == null || sArray.size() <= 0) {
return result;
}
for (String key : sArray.keySet()) {
String value = sArray.get(key);
if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
|| key.equalsIgnoreCase("sign_type")) {
continue;
}
result.put(key, value);
}
return result;
}
}
