SDK开发说明
V3版本SDK对点播服务提供的所有API进行了封装,您可以通过点播API Explorer调试接口。同时在代码示例处,会生成各种语言的demo供您参考。您也可以使用“SDK代码示例调试”,直接调试代码。
在使用SDK V3版本过程中,如您有进一步疑问和建议,欢迎您提交工单进行交流反馈。
媒资上传
当您需要使用服务端SDK上传本地媒资时,可参考《视频点播 API参考》中的应用示例1或应用示例2进行操作。其中,应用示例中对应的“创建媒资:上传方式”和“确认媒资上传”步骤,可参考SDK中的创建媒资:上传方式和确认媒资上传方法。在PUT媒资文件时,您可以使用HTTP PUT方式,将媒资文件PUT到对应的URL中即可。
生成鉴权URL
若您使用SDK时需要生成鉴权URL,可在点播控制台中使用Key防盗链算法生成,也可以参考以下Demo生成。
package AuthUrlDemo; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.StringUtils; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; class AuthUrlDemo { // url是未带加密信息的原始播放url, key是在点播控制台配置的Key值 // 加密算法A public static String createAuthInfoUrlByAlgorithmA(String url, String key) { try { checkParam(url, key); long timestamp = Instant.now().getEpochSecond(); String randUid = UUID.randomUUID().toString().replaceAll("-", ""); String uid = "0"; String tmpRandKey = timestamp + "-" + randUid + "-" + uid; URL originUrl = new URL(url); String string2Md5 = originUrl.getPath() + "-" + tmpRandKey + "-" + key; String md5Hash = DigestUtils.md5Hex(string2Md5.getBytes(StandardCharsets.UTF_8)); String authInfo = "auth_key=" + tmpRandKey + "-" + md5Hash; return StringUtils.isEmpty(originUrl.getQuery()) ? url + "?" + authInfo : url + "&" + authInfo; } catch (Exception e) { e.printStackTrace(); } return null; } // 加密算法B public static String createAuthInfoUrlByAlgorithmB(String url, String key) { try { checkParam(url, key); URL originUrl = new URL(url); String filePath = originUrl.getPath(); String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")); String str2Md5 = key + dateStr + filePath; String md5sum = DigestUtils.md5Hex(str2Md5.getBytes(StandardCharsets.UTF_8)); return originUrl.getProtocol() + "://" + originUrl.getHost() + "/" + dateStr + "/" + md5sum + originUrl.getFile(); } catch (Exception e) { e.printStackTrace(); } return null; } // 加密算法C public static String createAuthInfoUrlByAlgorithmC(String url, String key) { try { checkParam(url, key); URL originUrl = new URL(url); String filePath = originUrl.getPath(); String hexTime = Long.toHexString(Instant.now().getEpochSecond()).toUpperCase(Locale.ENGLISH); String str2Md5 = key + filePath + hexTime; String md5Hash = DigestUtils.md5Hex(str2Md5.getBytes(StandardCharsets.UTF_8)); return originUrl.getProtocol() + "://" + originUrl.getHost() + "/" + md5Hash + "/" + hexTime + originUrl.getFile(); } catch (Exception e) { e.printStackTrace(); } return null; } // 加密算法D public static String createAuthInfoUrlByAlgorithmD(String url, String key) { try { checkParam(url, key); URL originUrl = new URL(url); String urlPath = originUrl.getPath(); String pathInUrl = urlPath.substring(0, urlPath.lastIndexOf("/") + 1); String data = encodeUrl(pathInUrl) + "$" + getUtcTime("yyyyMMddHHmmss"); String encryptInfo = aesCbcEncrypt(data, key, true); String authInfoStr = "auth_info=" + URLEncoder.encode(encryptInfo, "UTF-8"); return urlPath + "?" + authInfoStr; } catch (Exception e) { e.printStackTrace(); } return null; } private static void checkParam(String url, String key) { if (StringUtils.isAnyEmpty(url, key)) { throw new IllegalArgumentException("url or key is illegal"); } } private static String aesCbcEncrypt(String data, String key, boolean hasPoint) throws Exception { checkParam(data, key); byte[] realKey = get128BitKey(key); SecureRandom secureRand = new SecureRandom(); byte[] ivBytes = new byte[16]; secureRand.nextBytes(ivBytes); if (hasPoint) { return aesCbcEncrypt(data, ivBytes, realKey) + "." + bytesToHexString(ivBytes); } else { return aesCbcEncrypt(data, ivBytes, realKey) + bytesToHexString(ivBytes); } } private static String aesCbcEncrypt(String data, byte[] ivBytes, byte[] key) throws Exception { SecretKeySpec sk = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); if (ivBytes != null) { cipher.init(Cipher.ENCRYPT_MODE, sk, new IvParameterSpec(ivBytes)); } else { cipher.init(Cipher.ENCRYPT_MODE, sk); } return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes("UTF-8"))); } private static byte[] get128BitKey(String key) { byte[] result = null; if (key != null) { result = new byte[16]; byte[] origin = key.getBytes(); if (origin.length > 16) { System.arraycopy(origin, 0, result, 0, 16); } else { System.arraycopy(origin, 0, result, 0, origin.length); } } return result; } private static String encodeUrl(String str) { try { if (StringUtils.isNotEmpty(str)) { StringBuilder encodeStr = new StringBuilder(32); String[] tmpArray = str.split("/"); for (int i = 0; i < tmpArray.length; i++) { encodeStr.append(URLEncoder.encode(tmpArray[i], "UTF8")).append("/"); } return encodeStr.toString(); } } catch (Exception e) { throw new RuntimeException(String.format("Encode fail %s", e.getMessage())); } return str; } private static String getUtcTime(String dateTimePattern) { SimpleDateFormat foo = new SimpleDateFormat(dateTimePattern); java.util.Calendar cal = java.util.Calendar.getInstance(); int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET); int dstOffset = cal.get(java.util.Calendar.DST_OFFSET); cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset)); String time = foo.format(new Date(cal.getTimeInMillis())); return time; } private static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(""); if ((src == null) || (src.length <= 0)) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } }