视频加密防下载的思路与实例参考

 视频加密防下载的思路

<div id="player"></div>
<script src="//player.polyv.net/resp/vod-player/latest/player.js"></script>
<script>
var player = polyvPlayer({
    wrap: '#player',
    width: 800,
    height: 533,
    vid: '88083abbf5bcf1356e05d39666be527a_8',   
    playsafe:'81814fed-bdd0-4506-bec1-ebc8093148c5-hfevwsfxcsbcocx', 
  //playsafeUrl:'https://myDomain.com/token', // 业务方自定义的获取播放凭证接口URL,与playsafe参数二选一
    ts:'1568131545000',
    sign:'88313661ba7ded642c7b557b0a364b4b'
});

//切换加密视频时,需要重新获取播放凭证。如果初始化播放器时使用了playsafeUrl参数,则播放器会自动获取新的凭证,无需传playsafe参数。
player.changeVid({
  vid: '88083abbf5bcf1356e05d39666be527a_9', //需要切换的视频vid
  playsafe: '81814fed-bdd0-4506-bec1-ebc8093148c6-hfevwsfxcsbcocx', //新获取的playsafe token
  sign: '88313661ba7ded642c7b557b0a364b4c', //新获取的sign和ts参数
  ts: '1568131545001'
});
</script>

1.简单介绍说明

域名黑白名单、授权播放等安全机制主要用于控制视频播放请求来源的合法性,能够有效保障用户的合法访问。但这些机制不会对视频数据本身进行加密,我们视频加密采用私有的加密算法,提供包括加密转码、安全传输、解密播放等一体化的视频安全方案。

2.流程架构

点播视频加密和解密播放的整体架构流程如下:

video-encryption

var pdiv = document.getElementById("player");
var w = pdiv.offsetWidth;
var h = pdiv.offsetWidth*0.5625;
var count = 4;
setPlayer();
function setPlayer() {
    var player = polyvPlayer({
    wrap: '#player',
    width: '100%',
    height: h,
    df:3,autoplay:'true',
    vid: 'ef03a1d2e5d2cf88211d4fdee740290d_e',   
    playsafe:'0ac40a55-d9e3-4177-8bc5-622c80e2faa2-2UIDgegc', 
    ts:'1747184314000',
    sign:'d50c69cb9701bb9a545637e0337b3c7d'
    });
}
function s2j_onPlayOver() {
    var lidnum = 1;
    var lidnextid = lidnum+1;
    if( lidnum < count){
		window.location.href='/edu/?lid='+ lidnextid;
	}  
}
function s2j_onReadyPlay(){
   document.getElementById("divplayerload").style.display = "none";
}
  • 视频加密功能采用自有知识产权的专利技术,保利威视频的加密转码、传输、解密播放全部受私有算法保护,破解难度极高。
  • 每个视频文件都有独立的私钥,能有效避免一个密钥的泄露引起大范围的安全问题。播放器和服务端使用加密协议进行密文传输,有效防止密钥被窃取。
  • 提供多套不同安全级别的加密方案,可根据自身业务场景选择。
  • 提供安全的播放器SDK,覆盖H5、iOS、Android、小程序、桌面客户端等多平台,且加密视频必须使用保利威安全播放器才能播放。
  • 云点播平台提供了完整的加密视频播放授权体系,开发者只需获取播放凭证并传入Polyv播放器即可实现加密播放,免去了凭证和密钥的管理、验证、分发等开发工作。
  • Polyv播放器提供的授权播放和防录屏跑马灯功能,进一步加强了版权保护能力。

 

3.服务端生成播放凭证

再看一下服务端生成播放凭证代码示例:

PHP 代码

// 接口中应附带自有业务的授权验证逻辑,如判断是否登录、是否购买课程等

// 以下为生成播放凭证的代码示例
function get_client_ip() {
  if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
  } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
      $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
  } else {
      $ipaddress = $_SERVER['REMOTE_ADDR'];
  }
    return $ipaddress;
}

$userId = 'your userId';       // 保利威点播账号的userId
$secretkey = 'your secretkey';     // 保利威点播账号的secretkey
$videoId = '88083abbf5bcf1356e05d39666be527a_8';  // 视频vid
$ts = time() * 1000;      // 时间戳
$viewerIp = get_client_ip();  // 观众ip
$viewerId = '12345';      // 观众id
$viewerName = 'testUser';  // 观众昵称, 若值为中文需要urlencode('张三')
$extraParams = 'HTML5';  // 自定义扩展参数
$disposable = false // true 表示 token 仅一次有效。false 则表示在有效期内可以多次验证。默认为 false。

/* 将参数 $userId、$secretkey、$videoId、$ts、$viewerIp、$viewerIp、$viewerId、$viewerName、$extraParams按照ASCKII升序 key + value + key + value ... +value 拼接
*/
$concated =  'extraParams'.$extraParams.'ts'.$ts.'userId'.$userId.'videoId'.$videoId.'viewerId'.$viewerId.'viewerIp'.$viewerIp.'viewerName'.$viewerName;
// 首尾加上secretkey值
$plain = $secretkey.$concated.$secretkey;
// 取大写MD5
$sign = strtoupper(md5($plain));

// 然后将下列参数用post请求  https://hls.videocc.net/service/v1/token 获取 token
$url = 'https://hls.videocc.net/service/v1/token';
$data = array('userId' => $userId, 'videoId' => $videoId, 'ts' => $ts, 'viewerIp' => $viewerIp, 'viewerName' => $viewerName, 'extraParams' => $extraParams, 'viewerId' => $viewerId, 'sign' => $sign);
$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded",
        'method'  => 'POST',
        'content' => http_build_query($data)
    )
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);

// 获取接口返回结果中的token值, 并传给播放器播放加密视频
$token = json_decode($result)->data->token;
echo $token;

Java SpringMvc代码

@ResponseBody
@RequestMapping("/playerSafe")
public String playerSafe(HttpServletRequest request) {
    String userId = "your userId";       // 保利威点播账号的userId
    String secretkey = "your secretkey";     // 保利威点播账号的secretkey
    String videoId = "88083abbf5bcf1356e05d39666be527a_8";  // 视频vid
    long ts = System.currentTimeMillis();      // 时间戳
    String viewerIp = getClientIp(request);  // 观众ip
    String viewerId = "12345";      // 观众id
    String viewerName = "testUser";  // 观众昵称, 若值为中文需要urlencode('张三')
    String extraParams = "HTML5";  // 自定义扩展参数
    boolean disposable = false; // true 表示 token 仅一次有效。false 则表示在有效期内可以多次验证。默认为 false。

    /* 将参数 userId、secretkey、videoId、ts、viewerIp、viewerIp、viewerId、viewerName、extraParams按照ASCKII升序 key + value + key + value ... +value 拼接
     */
    String concated = "extraParams" + extraParams + "ts" + ts + "userId" + userId + "videoId" + videoId + "viewerId" + viewerId + "viewerIp" + viewerIp + "viewerName" + viewerName;
    // 首尾加上secretkey值
    String plain = secretkey + concated + secretkey;
    // 取大写MD5,可自行选择md5库
    String sign = md5Hex(plain).toUpperCase();

    // 然后将下列参数用post请求  https://hls.videocc.net/service/v1/token 获取 token
    String url = "https://hls.videocc.net/service/v1/token";

    Map<String, String> params = new HashMap<>();
    params.put("userId", userId);
    params.put("videoId", videoId);
    params.put("ts", String.valueOf(ts));
    params.put("viewerIp", viewerIp);
    params.put("viewerName", viewerName);
    params.put("extraParams", extraParams);
    params.put("viewerId", viewerId);
    params.put("sign", sign);
    // 可自行选择http客户端
    String response = HttpClientUtil.getInstance().sendHttpPost(url, params);

    try {
        //解析json
        ObjectMapper objectMapper = new ObjectMapper();
        TokenResponse tokenResponse = objectMapper.readValue(response, TokenResponse.class);
        // 响应代码,200为成功,403为ts过期或签名错误,400为参数错误(例如缺少 userId 或 videoId)
        if (tokenResponse.getCode() == 200) {
            Map data = (Map) tokenResponse.getData();
            return data.get("token").toString();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "";
}
static class TokenResponse {
    int code;
    String status;
    String message;
    Object data;
    //省略getter、setter...
}
public String getClientIp(HttpServletRequest request) {
    String ip = request.getHeader("x-forwarded-for");
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        ip = request.getRemoteAddr();
    }
    return ip;
}

如果播放器使用playsafeUrl参数的方式,则需输出json格式:

PHP 代码

// 已省略获取token的代码...
$token = json_decode($result)->data->token;
$code = json_decode($result)->code; // 响应代码,200为成功,403为ts过期或签名错误,400为参数错误(例如缺少 userId 或 videoId)
$message=json_decode($result)->message;
$status=json_decode($result)->status;
if($code == 200){
    $array = Array("code"=>$code,'status'=>$status,'message'=>$message,"data"=>$token);
}else{
    $array = Array("code"=>$code,'status'=>$status,'message'=>$message,"data"=>json_decode($result)->data);
}
$Json = json_encode($array);
echo $Json; //输出json

4.实例效果图截图

我的推荐原创内容

视频应用类

谷歌Chrome浏览器 

视频安全视频加密

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值