前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >流媒体HLS传输协议的直播加密播放解决方案

流媒体HLS传输协议的直播加密播放解决方案

作者头像
Tinywan
发布2024-03-11 13:45:49
1380
发布2024-03-11 13:45:49
举报
文章被收录于专栏:开源技术小栈开源技术小栈

HLS

概述

HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。是苹果公司QuickTime X和iPhone软件系统的一部分。它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8)playlist文件,用于寻找可用的媒体流。

HLS采用HTTP协议传输音视频数据,HLS通过将音视频流切割成一个个小的TS切片及生成m3u8的播放列表文件,播放客户端通过HTTP协议下载播放列表文件,按照播放列表文件制定的顺序下载切片文件并播放,从而实现便下载边播放,类似于实时在线播放的效果。由于传输层只采用HTTP协议,因此其具备HTTP的网传优势,比如可以方便的透过防火墙或者代理服务器,可简单的实现媒体流的负载均衡,可以方便的结合CDN进行媒体分发等,另外HLS协议本身可实现码率自适应,通过视频转码,切片成不同码率的TS文件,从而实现播放客户端根据网络带宽情况,自由的选择码流进行播放,但是HLS在直播时延时较大。

优劣势

  • 优势:客户端支持简单,H5 video即可直接播放;网络兼容性好,可很方便的通过防火墙或代理服务器,可很简单的实现媒体流的负载均衡,CDN支持良好;自带多码率自适应机制,实现播放码率自由选择
  • 劣势:延时较高,不能用于对延时较为苛刻的场景,如互动直播领域;TS切片较多,特别是实时视频流,需要动态的生成和删除TS切片文件,为了实现高性能、低碎片化,对于文件存储的逻辑需要更加复杂的设计

直播加密实现

HSL 可播放地址

  • https://hls-auth.tinywan.com/hls/202403101/index.m3u8
  • https://hls-auth.tinywan.com/hls/202403102/index.m3u8

HTTPS密钥满足条件

  • 您需要在HTTPS服务器上安装受信任机构签署的SSL证书。
  • 密钥文件的验证域必须与第一个播放列表文件的验证域相同。最简单的方法是从HTTPS服务器提供变体播放列表文件 - 变体播放列表文件只下载一次,所以这不会造成太大的负担。其他播放列表文件可以使用HTTP提供。
  • 您必须启动自己的对话框以供用户进行身份验证,或者必须将凭据存储在客户端设备上--HTTP Live Streaming不提供用于身份验证的用户对话框。如果您正在编写自己的客户端应用程序,则可以存储凭据,无论是基于Cookie还是基于HTTP摘要,并在didReceiveAuthenticationChallenge回调中提供凭据(请参阅使用NSURLConnection和身份验证挑战和TLS链验证以了解详细信息)。您提供的凭据将被缓存并由媒体播放器重新使用。

注意:您必须获得受信任的权威机构签署的SSL证书才能使用具有HTTP Live Streaming的HTTPS服务器

RTMP 直播配置

代码语言:javascript
复制
 rtmp {
     notify_method get;

     server {
         listen 1935;
         chunk_size 4000;

         application live {
             live on;
             hls on;
             hls_path /tmp/hls;
             hls_fragment 6;

             hls_keys on;
             hls_key_path /tmp/keys;
             hls_key_url https://hls-auth.tinywan.com/keys/;
             hls_fragments_per_key 10;
             hls_playlist_length 36s;
             hls_sync 100ms;
             hls_fragment_naming system;
             hls_fragment_slicing aligned;
         }
     }
 }

推流地址:rtmp://live.tinywan.com/live_auth/123

HLS 虚拟主机配置

代码语言:javascript
复制
server {
   listen 443 ssl http2;
   server_name  live.tinywan.com;

   ssl on;
   ssl_certificate      /etc/letsencrypt/live/www.tinywan.com/fullchain.pem;
   ssl_certificate_key  /etc/letsencrypt/live/www.tinywan.com/privkey.pem;
   server_tokens off;

   location /live {
      add_header Cache-Control no-cache;
      add_header 'Access-Control-Allow-Origin' '*' always;
      add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
      add_header 'Access-Control-Allow-Headers' 'Range';

      types {
          application/vnd.apple.mpegurl m3u8;
          video/mp2t ts;
      }
      root /tmp;
   }
}

配置说明:

  1. 播放流地址:https://live.tinywan.com/live_auth/12345.m3u8
  2. m3u8 文件目录位置:/tmp/live_auth
  3. 匹配原则:location 用于匹配 url 是模糊匹配
    • 没有/时,location /abc/def 可以匹配/abc/defghi请求,也可以匹配/abc/def/ghi
    • 而有/时,location /abc/def/不能匹配/abc/defghi请求,只能匹配/abc/def/anything这样的请求
  4. 所以:location /live可以匹配地址/live_auth/12345.m3u8
  5. 最终匹配的目录:/tmp/live_auth/12345.m3u8

HLS-KEY虚拟主机配置

代码语言:javascript
复制
server {
     listen 443 ssl http2;
     server_name  hls-auth.tinywan.com;

     ssl on;
     ssl_certificate      /etc/letsencrypt/live/www.tinywan.com-0002/fullchain.pem;
     ssl_certificate_key  /etc/letsencrypt/live/www.tinywan.com-0002/privkey.pem;
     server_tokens off;

    # hls keys
    location /keys {
        add_header Cache-Control no-cache;
        add_header 'Access-Control-Allow-Origin' '*' always;
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
        add_header 'Access-Control-Allow-Headers' 'Range';
        access_by_lua_file /usr/local/openresty/nginx/conf/lua/filter_domain_ip_limit.lua;
        root /tmp;
    }
}

Lua 脚本 filter_domain_ip_limit.lua

代码语言:javascript
复制
local redis = require("resty.redis")
local var=ngx.var
local log = ngx.log
local ERR = ngx.ERR
local EXIT = ngx.exit

-- redis config
local redis_host = "127.0.0.1"
local redis_port = 6379
local redis_auth = "tinywanredisamaistream"
local redis_timeout = 1000

local red = redis:new()
red:set_timeout(redis_timeout)
local ok, err = red:connect(redis_host, redis_port)
if not ok then
    log(ERR, "connect to redis error : ", err)
end

-- client info
local client_ip = ngx.req.get_headers()['X-Real-IP']
if client_ip == nil then
   client_ip = ngx.req.get_headers()['X-Forwarded-For']
end

if client_ip == nil then
   client_ip = ngx.var.remote_addr
end

local req_origin = ngx.req.get_headers()['origin']
-- local h = ngx.req.get_headers()
-- for k, v in pairs(h) do
--     log(ERR,k.." k-----------v: "..v)
-- end
if req_origin == nil then
   red:zadd('HTTP_REQUEST_UNAUTHORIZED',ngx.time(),client_ip)
   log(ERR, 'not http request origin is nil IP::'..client_ip)
   EXIT(ngx.HTTP_UNAUTHORIZED)
end

-- redis action
if tostring(req_origin) ~= "https://www.tinywan.com" then
      red:zadd('HTTP_REQUEST_FORBIDDEN',ngx.time(),req_origin)
      log(ERR, "error : request origin is error req_origin = "..req_origin)
      EXIT(ngx.HTTP_FORBIDDEN)
end

注意:通过以上加密授权验证,只能在tinywan.com域名下进行播放,其他地方将无法播放(包括VLC也是无法播放的)

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-09,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • HLS
    • 概述
      • 优劣势
      • 直播加密实现
        • HSL 可播放地址
          • HTTPS密钥满足条件
            • RTMP 直播配置
              • HLS 虚拟主机配置
                • HLS-KEY虚拟主机配置
                  • Lua 脚本 filter_domain_ip_limit.lua
                  相关产品与服务
                  云直播
                  云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档


                  http://www.vxiaotou.com