HLS视频加密,让您的视频内容更安全!

news2024/11/18 22:30:48

 背景介绍

HLS视频加密是一种基于HTTP Live Streaming(HLS)协议的加密技术。它的核心思想是将视频切片进行加密处理,在客户端播放时需要先获取解密密钥才能正常偶发。通过这种方式,HLS加密可以有效防止未经授权的第三方窃取视频内容,从而保障了视频内容的版权和安全。数据万象媒体处理服务提供了一套HLS视频加密方案,方便用户各个场景的需求。

 HLS加密方案

整体加密方案如下图所示:

图片

 

痛点

在我们日常的工作生活中,如果没有HLS加密,会带来以下问题:

  • 视频内容被非法下载和分享:没有加密的视频内容容易被非法下载和分享,导致付费业务受到威胁。

  • 影响用户体验:为了提高视频的安全性,可能需要采用更复杂的验证和授权机制。这可能会增加用户的操作复杂度,降低用户体验。

  • 增加服务器的负担:如果采用客户端解密的技术,服务器需要处理更多的请求和计算量,可能会对延迟和性能造成一定的不良影响。

 使用场景

  • 直播赛事:体育赛事、音乐会等大型活动需要进行直播,HLS加密可以有效防止盗版和非法传播。

  • 在线教育:在线教育平台需要保护课程内容的版权,HLS加密可以确保课程内容不被非法窃取。

  • 付费视频:电影、电视剧等付费视频内容需要进行版权保护,HLS加密可以有效防止盗版行为。

  • 企业会议:企业的重要会议、内部培训等内容需要进行保密处理,HLS加密可以确保这些内容不被泄露。

 操作指南

生成加密视频

一、模版设置

1. 开通媒体处理

进入存储桶界面,点击数据处理中的媒体处理,点击开通。

图片

2. 创建HLS转码模版

点击任务与工作流里的模版配置,点击创建转码模版

2.1 输入模版名称,封装格式选择HLS。

图片

2.2 打开视频加密开关

视频参数和音频参数根据需要填写,在高级设置里打开视频加密开关

图片

二、创建转码任务

在当前存储桶上传任意视频文件,点击任务管理里的创建任务。

1. 生成m3u8加密文件

源文件路径选择刚刚上传的视频文件,模版类型选择自定义模版,选择第二步创建的hls转码模版,记住目标路径和目标文件名,产出文件就是我们需要的加密视频文件。

图片

2. 确定产物文件

找到创建任务时填的产物路径,可看到生成后的加密文件

图片

播放加密视频

控制台媒体处理,视频加密配置模块,展示播放密钥(playKey,部署后端服务的时候会用到)

图片

拿到生成的m3u8视频文件和播放秘钥(playKey)后,就可以开始搭建服务,播放刚刚加密的m3u8视频文件。

本文前端部分以js代码为例,服务端以nodejs为例,来说明整个使用过程。

三、前端部分

1. 首先下载hls加密代码包(https://bjtest-10008930.cos.ap-shanghai.myqcloud.com/hlsCode/hls%E5%8A%A0%E5%AF%86%E4%BB%A3%E7%A0%81%E5%8C%85.zip)

2. 在页面中引入压缩包中cos_hls.js、jsencrypt.js 和 hls.js。

3. 根据播放器种类,在页面中引入压缩包中文件,目前支持三种类型(hls.js/tcplayer/video.js)。

hls.js:

<script src="./cos_hls.js"></script>
<script src="./hls.js"></script> 
<script src="./jsencrypt.js"></script>

tcplayer:


<link href="https://web.sdk.qcloud.com/player/tcplayer/release/v4.2.2/tcplayer.min.css" rel="stylesheet"/>
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.2.2/libs/hls.min.0.13.2m.js"></script>
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.2.2/tcplayer.v4.2.2.min.js"></script>
<script src="./cos_hls.js"></script>
<script src="./jsencrypt.js"></script>

video.js:


<link href="https://vjs.zencdn.net/8.11.8/video-js.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/8.11.8/video.js"></script>
<script src="./cos_hls.js"></script>
<script src="./jsencrypt.js"></script>

4. 前端使用cos_hls.js文件中封装好的cosHls对象来播放m3u8文件,用户按照如下规则传入参数,即可实现播放功能。 


<script>
    // cosHLs为cos_hls.js封装的对象,使用play方法播放视频文件
    cosHls.play({
        // video标签的id
        container: 'video',
        // 支持的播放器种类(hls.js/tcplayer/video.js)
        playerType: 'hls.js',
        // 请求m3u8接口的文件地址
        src: 'https://examplebucket-1250000000.cos.ap-beijing.myqcloud.com/hls/video.m3u8?ci-process=pm3u8',
        // 标记src里的域名是不是CDN域名(false/true)
        // useCdn: false,
        // 请求token和签名的函数
        getToken(opt, callback) {
            // 加密公钥,不需要用户填写,sdk会自动生成
            var publicKey = opt.publicKey;
            // 请求m3u8接口的文件地址,不需要用户填写,sdk会自动生成
            var src = opt.src;
            // 是否返回加密内容,与cosHls对象的ProtectContentKey参数保持一致,不需要用户填写,sdk会自动生成
            var protectContentKey = opt.ProtectContentKey;
            // 新建xhr对象,进行请求
            var xhr = new XMLHttpRequest();
            xhr.withCredentials = true;
            // /samples/hls/token为自定义请求地址,用户可自自定义
            xhr.open('POST', `/hls/token`, true);
            xhr.setRequestHeader('Content-Type', 'application/json')
            // 请求成功返回authorization 和 token
            xhr.onload = function () {
                var r = JSON.parse(xhr.responseText);
                var authorization = r.authorization
                var token = r.token
                callback(null, {authorization, token});
            };
            xhr.onerror = function () {
                callback('get token error');
            };
            // node服务所需要的参数,已从sdk获取,不需要用户填写
            var data = {
                src: src,
                publicKey: window.btoa(publicKey),
                protectContentKey: protectContentKey
            };
            xhr.send(JSON.stringify(data));
        }
    })
</script>
四、服务端部分

服务端,以 Nodejs 为例,主要代码如下:


const COS = require('cos-nodejs-sdk-v5');
const base64Url = require('base64-url');
const express = require('express');
const crypto = require('crypto');

// 配置参数
const config = {
    // 获取腾讯云密钥,建议使用限定权限的子用户的密钥 https://console.cloud.tencent.com/cam/capi
    secretId: process.env.SecretId,
    secretKey: process.env.SecretKey,
    // 播放秘钥,可在媒体处理模块获取 https://console.cloud.tencent.com/cos/bucket?bucket=xxxx-100000&region=ap-xxx&type=ci&anchorType=video
    playKey: process.env.playKey,
    // 目标存储桶名称,可在存储桶列表页获取 https://console.cloud.tencent.com/cos/bucket
    bucket: 'xxx',
    // 目标存储桶地域,可在存储桶列表页获取 https://console.cloud.tencent.com/cos/bucket
    region: 'xxx'
};

// 创建临时密钥服务和用于调试的静态服务
const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

router.post('/hls/token', (req, res, next) => {
    // 从接口拿到文件地址,加密公钥,是否返回加密内容
    const body = req.body;
    const src = body.src;
    const publicKey = body.publicKey;
    const protectContentKey = body.protectContentKey;
    
    // 如在某些特殊场景需要用HLS标准加密(例如小程序里播放/iOSWebview),可以去掉下面的限制判断并做好来源限制只允许小程序来源。
    // 代码示例只允许 protectContentKey 传 1,原因:如果允许传入 0 播放流程会走 HLS 标准加密会有风险。
    const userAgent = req.headers['user-agent'] || '';
    const uaWhiteList = ['Safari', 'wechatdevtools', 'MiniProgramEnv'];
    const isUaAllow = uaWhiteList.some(item => userAgent.includes(item));
    // 只有白名单的浏览器,才能走标准加密
    if (!protectContentKey && !isUaAllow) {
        res.status(400);
        return res.send({code: -1, message: 'protectContentKey=0 not allowed'});
    }

    // src 链接校验
    if (!src || !srcReg.test(src)) return res.send({code: -1, message: 'src format error'});
    if (!publicKey) return res.send({code: -1, message: 'publicKey empty'});

    // 解析 url
    const { bucket, region } = config;
    const { token, authorization } = getToken({publicKey, protectContentKey, bucket, region, src}, res)
    res.send({code: 0, message: 'ok', token, authorization});
});

const srcReg = /^https?:\/\/([^/]+)\/([^?]+)/;
const ciHostReg = /^[^.]+\.ci\.[^.]+\.myqcloud\.com$/;

function getToken({publicKey, protectContentKey, bucket, region, src}) {
    const m = src.match(srcReg);
    const srcHost = m[1];
    const pathKey = m[2];
    const query = {};
    const isCiHost = ciHostReg.test(srcHost);
    src.replace(/^([^?]+)(\?([^#]+))?(#.*)?$/, '$3').split('&').forEach(item => {
        const index = item.indexOf('=');
        const key = index > -1 ? item.slice(0, index) : item;
        let val = index > -1 ? item.slice(index + 1) : '';
        query[key] = decodeURIComponent(val);
    });
    let objectKey = isCiHost ? query.object : pathKey;
    const header = {
        "alg": "HS256",
        "typ": "JWT"
    }
    const appId = bucket.slice(bucket.lastIndexOf('-') + 1);
    let payload = {
        Type: "CosCiToken",
        AppId: appId,
        BucketId: bucket,
        Issuer: "client",
        IssuedTimeStamp: Math.floor((new Date().getTime() - 30 * 1000) / 1000),
        ProtectSchema: "rsa1024",
        PublicKey: publicKey,
        ProtectContentKey: protectContentKey || 0,
        UsageLimit: 50,
        Object: objectKey,
    };
    let Header = base64Url.encode(JSON.stringify(header))
    let PayLoad = base64Url.encode(JSON.stringify(payload))
    let data = Header + "." + PayLoad
    let hash = crypto.createHmac('sha256', config.playKey).update(data).digest();
    let Signature = base64Url.encode(hash);
    let token = Header + '.' + PayLoad + '.' + Signature
    let authorization = COS.getAuthorization({
        SecretId: config.secretId,
        SecretKey: config.secretKey,
        Method: 'get',
        Pathname: `/${objectKey}`,
        Query: {'ci-process': 'pm3u8'},
    });
    return {token, authorization};
}

五、效果体验

完成前后端的代码后,启动服务,即可开始播放加密视频。

图片

在线体验地址: 

https://cos.cloud.tencent.com/samples/hls/private-encrypt/

方案接入优势

  • 接入简单:支持多个开源通用播放器,定制化能力强。

  • 支持场景丰富:PC Web、Android WebView,Android/iOS移动端App

  • 不兼容的场景自动降级:因为 iOS Webview 不兼容 Media Source Extensions,会自动降级为标准加密方案。减少开发兼容成本。

总结

数据万象媒体处理新增视频加密,旨在让用户能够更加方便地使用视频加密功能,提高用户体验。同时,我们也会继续关注用户的反馈,不断优化和改进数据万象媒体处理的用户体验,为用户提供更好的服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1692361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

刷题篇--数据结构--链表

一.环形链表Ⅰ . - 力扣&#xff08;LeetCode&#xff09; 这道题可以利用快慢指针的方法来解决&#xff0c;即定义一个快指针f他的速度是一次走两步&#xff0c;慢指针s他的速度是一次走一步&#xff0c;这时我们假设链表有环&#xff0c;环的入口点为N&#xff0c;当两个指…

27寸2K显示器 - HKC G27H2

HKC G27H2是一款面向电竞市场的高性能显示器&#xff0c;以其2K分辨率和180Hz的刷新率作为主要卖点&#xff0c;旨在为玩家提供流畅而清晰的视觉体验。配备HDR 400技术和95% DCI-P3色域覆盖&#xff0c;这款显示器还支持升降旋转支架&#xff0c;为用户提供了高度的人体工程学适…

同旺科技 FLUKE ADPT 隔离版发布 ---- 说明书

所需设备&#xff1a; 1、FLUKE ADPT 隔离版 内附链接&#xff1b; 应用于&#xff1a;福禄克Fluke 12E / 15BMax / 17B Max / 101 / 106 / 107 应用于&#xff1a;福禄克Fluke 15B / 17B / 18B

酷开科技大屏营销,多元需求唤醒“客厅经济”

随着科技的发展和消费者习惯的变化&#xff0c;OTT大屏营销正逐渐成为客厅经济的新风向。OTT不仅改变了人们获取信息和娱乐的方式&#xff0c;也为品牌营销提供了新的机遇和挑战&#xff0c;OTT大屏营销已经成为客厅经济的重要组成部分。酷开科技通过其自主研发的智能电视操作系…

戴尔(Dell)服务器运行状况监控

戴尔&#xff08;Dell&#xff09;服务器因其加速的性能、增强的自动化和简化的管理而受到全球许多组织的青睐&#xff0c;许多组织将其业务关键应用程序和功能放在戴尔&#xff08;Dell&#xff09;服务器中&#xff0c;因此&#xff0c;有效的戴尔&#xff08;Dell&#xff0…

Jeecg | 完成配置后,如何启动整个项目?

前端启动步骤&#xff1a; 1. 以管理员身份打开控制台&#xff0c;切换到前端项目目录。 2. 输入 pnpm install 3. 输入 pnpm dev 4. 等待前端成功运行。 可以看到此时前端已经成功启动。 后端启动步骤&#xff1a; 1. 启动 mysql 服务器。 管理员身份打开控制台&#…

基于51单片机的多功能万年历温度计—可显示农历

基于51单片机的万年历温度计 &#xff08;仿真&#xff0b;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 本设计基于STC89C52&#xff08;与AT89S52、AT89C52通用&#xff0c;可任选&#xff09;单片机以及DS1302时钟芯片、DS18B…

Spring6 对 集成MyBatis 开发运用(附有详细的操作步骤)

详细实现操作步骤 具体实现内容&#xff1a;我们运用 Spring6 和 MyBatis 实现一个转账操作(该转账操作&#xff0c;进行一个事务上的控制&#xff0c;运用 MyBatis 执行 SQL 语句)。 第一步&#xff1a;准备数据库表 使用t_act表&#xff08;账户表&#xff09; 连接数据库的…

Scrapy框架简单介绍及Scrapy项目编写详细步骤

引言 Scrapy是一个用Python编写的开源、功能强大的网络爬虫框架&#xff0c;专为网页抓取和数据提取设计。它允许开发者高效地从网站上抓取所需的数据&#xff0c;并通过一系列可扩展和可配置的组件来处理这些数据。Scrapy框架的核心组成部分包括&#xff1a; Scrapy Engine&…

实在智能Agent保障已就位,助力商家从容应对618大促挑战

618购物狂欢节第一波“年中开门红”已开启&#xff0c;商家纷纷进入战斗状态&#xff0c;力求在这场消费盛宴中脱颖而出。面对消费者高涨的购买热情和激烈的市场竞争&#xff0c;如何在确保服务质量的同时&#xff0c;提升运营效率&#xff0c;成为每个商家必须面对的挑战。 为…

【已解决】C#设置Halcon显示区域Region的颜色

前言 在开发过程中&#xff0c;突然发现我需要显示的筛选区域的颜色是白色的&#xff0c;如下图示&#xff0c;这对我们来说不明显会导致我的二值化筛选的时候存在误差&#xff0c;因此我们需要更换成红色显示这样的话就可以更加的明显&#xff0c;二值化筛选更加的准确。 解…

云WAF与传统WAF:网络安全的双重防线

在网络安全领域&#xff0c;Web应用防火墙&#xff08;WAF&#xff09;是守护企业网络安全的重要盾牌。随着云计算技术的迅猛发展&#xff0c;云WAF作为一种新型的安全服务模式&#xff0c;正逐渐成为企业网络安全防护的新宠。本文将深入探讨云WAF与传统WAF的区别&#xff0c;分…

两篇文章讲透数据结构之堆(一)!

目录 1.堆的概念 2.堆的实现方式 3.堆的功能 4.堆的声明 5.堆的实现 5.1堆的初始化 5.2堆的插入 5.2.1向上调整算法 5.2.2堆的插入 5.3堆的删除 5.3.1向下调整算法 5.3.2堆的删除 5.4获取堆顶元素 5.5获取堆的元素个数 5.6判断堆是否为空 5.7打印堆 5.8建堆 …

【C++初阶】vector

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

全局配置路径无法识别的解决——后端

在全局配置路径reggie.path的时候&#xff0c;无法正常启动SpringBoot项目 Value("${reggie.path}")private String basePath; 查看application.yml的配置情况: 发现path没有起作用&#xff0c;推测是格式问题&#xff0c;冒号后面空格后即可

计算机网络(1

网络初识 目录 网络初识一. 网络分类1. 局域网LAN(Local Area Network):2. 广域网WAN(Wide Area Network): 二. 组建网络的基础设备1. 路由器2. 交换机 三. 标识符 协议 (protocol)一. 协议分层1. 分层的好处2. OSI七层分层3. TCP/IP五层模型(或四层) 模型(1. 物理层(可不算)(2…

全栈式数据统计:SqlAlchemy怎样连接MsSql Server获取视图列表

1.源代码 #-----------获取数据库视图列表----------------------------- # -------密码含特殊字符使用 from urllib.parse import quote_plus as urlquotefrom sqlalchemy import create_engine, MetaData, inspect# 替换为你的数据库连接字符串 DRIVER "ODBC Driver 1…

Gin与OpenAPI(Swagger)的使用

一、背景 1、swagger与openapi Swagger&#xff1a; 一种用于描述RESTFUL API的规范&#xff0c;它提供了一种简单的来描述API的请求和相应参数、错误码、返回数据类型等信息&#xff0c;是开发者可以方便了解API使用方式。 官网: https://swagger.io/ OpenAPI : 始于 …

Excel透视表:快速计算数据分析指标的利器

文章目录 概述1.数据透视表基本操作1.1准备数据&#xff1a;1.2创建透视表&#xff1a;1.3设置透视表字段&#xff1a;1.4多级分类汇总和交叉汇总的差别1.5计算汇总数据&#xff1a;1.6透视表美化&#xff1a;1.7筛选和排序&#xff1a;1.8更新透视表&#xff1a; 2.数据透视-数…

经典单链表OJ题

目录 1、轮转数组 2、返回倒数第k个节点 3、判断链表的回文结构 4、两个链表&#xff0c;找出它们的第一个公共结点 5、随机链表的复制 6、判断链表中是否有环 7、返回链表开始入环的第一个节点 1、轮转数组 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k…