接口URL
http://api.polyv.net/live/v3/channel/basic/create
接口说明
1、接口用于创建频道并进行相关设置
2、接口支持https
支持格式
JSON
请求方式
POST
请求数限制
TRUE
请求参数
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
appId | 是 | string | 从API设置中获取,在直播系统登记的appId |
timestamp | 是 | long | 13位当前时间戳 |
sign | 是 | string | 签名值 |
basicSetting | 是 | json | 基础设置 |
authSettings | 否 | json | 观看条件设置 |
注:这里的appId,timestamp,sign必须通过url传参,json数据通过请求体传参,如:
http://api.polyv.net/live/v3/channel/basic/create?appId={{appId}}×tamp={{timestamp}}&sign={{sign}}
请求体json示例
{
"basicSetting": {
"name": "测试",
"channelPasswd": "10086",
"maxViewer": 20,
"startTime": 1557888134000
},
"authSettings": [
{
"rank": 1,
"enabled": "Y",
"authType": "external",
"externalKey": "L0EjokKI4O",
"externalUri": "http://demo.polyv.net/chenwb/live-validate.php"
}
]
}
basicSetting详细说明
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
name | 是 | string | 频道名称 |
channelPasswd | 是 | string | 频道密码,长度不能超过16位 |
autoPlay | 否 | int | 是否自动播放,0/1,默认1 |
playerColor | 否 | string | 播放器控制栏颜色,默认:#666666 |
scene | 否 | string | 直播场景: alone 活动拍摄 ppt 三分屏 topclass 大班课 |
categoryId | 否 | int | 新建频道的所属分类,如果不提交,则为默认分类(分类ID可通过“获取直播分类”接口得到) |
maxViewer | 否 | int | 最大同时在线人数 |
startTime | 否 | long | 直播开始时间,13位时间戳 |
desc | 否 | string | 直播介绍的内容 |
publisher | 否 | string | 主持人 |
authSettings详细说明
详细的数据参数,参考 更新观看条件 的请求参数部分
响应成功JSON示例:
{
"code": 200,
"status": "success",
"message": "",
"data": {
"channelId": 323158,
"userId": "b0f7041324",
"name": "测试",
"publisher": null,
"description": "",
"url": "rtmp://push-c1.videocc.net/recordf/b0f704132420190515115309303",
"stream": "b0f704132420190515115309303",
"logoImage": "",
"logoOpacity": 1,
"logoPosition": "tr",
"logoHref": "",
"coverImage": "",
"coverHref": "",
"waitImage": "",
"waitHref": "",
"cutoffImage": "",
"cutoffHref": "",
"advertType": "NONE",
"advertDuration": 0,
"advertWidth": 0,
"advertHeight": 0,
"advertImage": "",
"advertHref": "",
"advertFlvVid": "",
"advertFlvUrl": "",
"playerColor": "#FFFFFF",
"autoPlay": false,
"warmUpFlv": "",
"passwdRestrict": false,
"passwdEncrypted": "",
"isOnlyAudio": "N",
"isLowLatency": "N",
"m3u8Url": "http://pull-c1.videocc.net/recordf/b0f704132420190515115309303.m3u8?auth_key=1557892389-0-0-d1cab3b24dc910dc22e3ab60915f682b",
"m3u8Url1": "",
"m3u8Url2": "",
"m3u8Url3": "",
"channelLogoImage": null,
"scene": "topclass",
"currentTimeMillis": 1557892389591
}
}
响应字段说明
参数名 | 类型 | 说明 |
---|---|---|
status | string | 状态值 |
result | object | 响应的结果 |
channelId | string | 直播频道ID |
userId | string | 直播用户ID |
name | string | 直播频道名称 |
description | string | 直播频道描述 |
url | string | 直播推流地址 |
stream | string | 直播流名称 |
logoImage | string | 播放器logo |
logoOpacity | float | Logo不透明度,1表示完全不透明 |
logoPosition | string | Logo位置 |
logoHref | string | Logo的跳转链接 |
coverImage | string | 播放前显示的封面图 |
coverHref | string | 封面图的跳转链接 |
waitImage | string | 等待推流时的显示图片 |
waitHref | string | 等待推流时显示图片的跳转链接 |
cutoffImage | string | 切断流时的显示图片 |
cutoffHref | string | 切断流时显示图片的跳转链接 |
advertType | string | 广告类型 |
advertDuration | string | 广告时长 |
advertWidth | string | 广告区域宽度 |
advertHeight | string | 广告区域高度 |
advertImage | string | 图片广告 |
advertHref | string | 广告的跳转链接 |
advertFlvVid | string | 视频广告ID |
advertFlvUrl | string | 视频广告链接 |
playerColor | string | 播放器控制栏颜色 |
autoPlay | boolean | 自动播放 |
warmUpFlv | string | 一开始的暖场视频 |
passwdRestrict | boolean | 观看密码限制,需要输入观看密码才能播放流 |
passwdEncrypted | string | 观看密码加密后的密文 |
isOnlyAudio | string | 仅推音频流 |
isLowLatency | string | 低延迟 |
m3u8Url | string | 直播拉流(播放)m3u8地址 |
m3u8Url1 | string | 直播拉流(播放)m3u8地址1 |
m3u8Url2 | string | 直播拉流(播放)m3u8地址2 |
m3u8Url3 | string | 直播拉流(播放)m3u8地址3 |
currentTimeMillis | timestamp | 服务器返回的时间戳(毫秒) |
响应失败JSON示例:
参数错误
{
"code": 400,
"status": "error",
"message": "param validate error",
"data": 400
}
未输入appId
{
"code": 400,
"status": "error",
"message": "appId is required.",
"data": ""
}
appId不正确
{
"code": 400,
"status": "error",
"message": "application not found.",
"data": ""
}
时间戳错误
{
"code": 400,
"status": "error",
"message": "invalid timestamp.",
"data": ""
}
签名错误
{
"code": 403,
"status": "error",
"message": "invalid signature.",
"data": ""
}
Json格式错误或字段类型不对
{
"code": 400,
"status": "error",
"message": "json format error",
"data": 400
}
字段说明
参数名 | 说明 |
---|---|
code | 状态码,成功为200,签名失败为403,参数错误为400,服务端错误为500 |
status | 成功为success,错误时为error |
message | 成功为"",错误时为错误描述信息 |
data | 成功时为true,错误时为"" |
php请求示例
<?php
//引用config.php
include '/srv/http/live/config.php';
$params = array(
'appId' => $appId,
'timestamp' => $timestamp
);
//生成sign
$sign = getSign($params); //详细查看config.php文件的getSign方法
$json = '{"basicSetting":{"name":"测试","channelPasswd":"10086","maxViewer":20},"authSettings":[{"rank":1,"enabled":"Y","authType":"external","externalKey":"L0EjokKI4O","externalUri":"http://demo.polyv.net/chenwb/live-validate.php"}]}';
$params["sign"] = $sign;
$url="http://api.polyv.net/live/v3/channel/basic/create?".http_build_query($params);
function post($url, $post_data = '', $timeout = 5){
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POST, 1);
if($post_data != ''){
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
}
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($post_data)));
$file_contents = curl_exec($ch);
curl_close($ch);
return $file_contents;
}
echo post($url,$json);
?>
Java请求示例
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.live.util.EncryptionUtils;
public class Demo {
private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(15000).setConnectTimeout(15000)
.setConnectionRequestTimeout(15000).build();
public static void main(String[] args) {
String url = "http://api.polyv.net/live/v3/channel/basic/create";
String appId = "appId";
String key = "appSecret";
Map<String, String> map = new HashMap<>();
String timestamp = Long.toString(System.currentTimeMillis());
map.put("appId", appId);
map.put("timestamp", timestamp);
String sign = getSign(map, key);
map.put("sign", sign);
String body = "{\"basicSetting\":{\"name\":\"测试\",\"channelPasswd\":\"10086\",\"maxViewer\":20," +
"\"startTime\":\"1\"},\"authSettings\":[{\"rank\":1,\"enabled\":\"Y\",\"authType\":\"external\"," +
"\"externalKey\":\"L0EjokKI4O\",\"externalUri\":\"http://demo.polyv.net/chenwb/live-validate.php\"}]}";
String content = sendHttpPost(url, map, body);
System.out.println(content);
}
/**
* 发送 post请求
* @param httpUrl 地址
* @param maps 参数
*/
public static String sendHttpPost(String httpUrl, Map<String, String> maps, String body) {
StringBuilder url = new StringBuilder();
url.append(httpUrl).append("?");
for (Map.Entry<String, String> map : maps.entrySet()) {
url.append(map.getKey()).append("=").append(map.getValue()).append("&");
}
String urlStr = url.toString().substring(0, url.length() - 1);
System.out.println(urlStr);
// 创建httpPost
HttpPost httpPost = new HttpPost(urlStr);
try {
StringEntity entity = new StringEntity(body, Charset.forName("UTF-8"));
httpPost.setEntity(entity);
} catch (Exception e) {
// ...
}
return sendHttpPost(httpPost);
}
/**
* 发送Post请求
* @param httpPost
* @return
*/
private static String sendHttpPost(HttpPost httpPost) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpEntity entity;
String responseContent = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
httpPost.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpPost);
entity = response.getEntity();
responseContent = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
// ...
} finally {
try {
// 关闭连接,释放资源
if (response != null) {
response.close();
}
if (null != httpPost) {
httpPost.releaseConnection();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
// ...
}
}
return responseContent;
}
/**
* 根据map里的参数构建加密串
* @param map
* @param secretKey
* @return
*/
protected static String getSign(Map<String, String> map, String secretKey) {
Map<String, String> params = paraFilter(map);
// 处理参数,计算MD5哈希值
String concatedStr = 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 static String concatParams(Map<String, String> params) {
List<String> keys = new ArrayList<>(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 static Map<String, String> paraFilter(Map<String, String> sArray) {
Map<String, String> result = new HashMap<>();
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;
}
}