hls.js 播放音视频切片鉴权问题 | laravel china 社区-金年会app官方网

<template>
  <div>
    <audio ref="audioplayer" controls />
    <button @click="playaudio">播放音频</button>
  </div>
</template>
<script setup lang="ts">
import hls from 'hls.js';
import { ref, onmounted, onbeforeunmount } from 'vue';
const audioplayer = ref<htmlaudioelement | null>(null);
const audiourl = 'https://pep-file.oss-cn-beijing.aliyuncs.com/zjoutresource/xxx/6101/8_b1_16/8_b1_16.m3u8?auth_key=xx';
const playaudio = () => {
  if (audioplayer.value) {
    if (hls.issupported()) {
      const hls = new hls();
      hls.loadsource(audiourl);
      hls.attachmedia(audioplayer.value);
      hls.on(hls.events.manifest_parsed, () => {
        audioplayer.value?.play(); 
      });
    } else {
      audioplayer.value.src = audiourl; 
      audioplayer.value.addeventlistener('loadedmetadata', () => {
        audioplayer.value?.play(); 
      });
    }
  }
}
onmounted(() => {
  audioplayer.value?.load();
})
onbeforeunmount(() => {
  if (audioplayer.value) {
    audioplayer.value.src = ''; 
  }
})
</script>
<style scoped>
</style>

问题:
音频路径audiourl需要鉴权才能访问,但是m3u8里面的hls.key和.ts文件如何实现自动鉴权

#extm3u
#ext-x-version:3
#ext-x-targetduration:8
#ext-x-media-sequence:0
#ext-x-playlist-type:vod
#ext-x-key:method=aes-128,uri="hls.key",iv=0x6b75eb391048f9416d3a475499489390
#extinf:7.274833,
part_0000.ts
#ext-x-endlist
本作品采用《cc 协议》,转载必须注明作者和本文链接
从零开发一个电商项目,功能包括电商后台、商品 & sku 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
以构建论坛项目 larabbs 为线索,展开对 laravel 框架的全面学习。应用程序架构思路贴近 laravel 框架的设计哲学。
讨论数量: 10

一般都是后端创建一个限时url返回前台,比如限时一天有效期

3周前
shine-x (楼主) 3周前

我之前是用nginx的internal限制的

写个video.php的处理脚本


/**
 * 访问 /video.php 则实际访问的是 /videos/test.mp4.
 *
 * 由此,可以在 php 里实现复杂的认证逻辑比如播放次数、ip、登录权限、用户身份等等。
 */
//todo 做一些判断和限制
//最后跳转到资源
header("x-accel-redirect: /videos/test.mp4");

nginx 收到调整资源/videos/test.mp4的请求

location /videos {
     internal; 
     root /nas/videos;
}

前端直接src读video.php,video.php怎么加参数都可以

2周前
xiucai 1周前
唐章明

如果你的意思是指文件不能公开访问(比如对象存储储存桶私有),生成了m3u8文件的签名链接,但是m3u8文件里面指向的ts切片却没有携带签名。

  • 方案1:公有云自带处理方案。
    比如阿里云,使用hls/sign签名边转边播,oss对音视频数据的访问提供了动态签名机制,即只需在首次访问m3u8文件时在url中添加x-oss-process=hls/sign,live_1, oss将对返回的播放列表中的所有ts地址自动按照与m3u8完全相同的方式进行签名

    原始m3u8内容

    #extm3u
    #ext-x-version:3
    #ext-x-targetduration:10
    #ext-x-media-sequence:0
    #ext-x-playlist-type:vod
    #extinf:10.0,
    media-c14709808479b31566b50f2f8b93fe1a-0.ts
    #extinf:10.0,
    media-c14709808479b31566b50f2f8b93fe1a-1.ts
    #extinf:10.0,
    media-c14709808479b31566b50f2f8b93fe1a-2.ts
    #extinf:10.0,
    media-c14709808479b31566b50f2f8b93fe1a-3.ts
    #ext-x-endlist

    使用hls/sign签名后返回的内容

    #extm3u
    #ext-x-version:3
    #ext-x-targetduration:10
    #ext-x-media-sequence:0
    #ext-x-playlist-type:vod
    #extinf:10.000,
    media-c14709808479b31566b50f2f8b93fe1a-0.ts?x-oss-process=if_status_eq_404{hls/ts,from_b3v0chv0l21lzglhlm0zdtg}&x-oss-expires=1710457284&x-oss-signature-version=oss2&x-oss-access-key-id=****feaub****&x-oss-signature=****vr3gy****
    #extinf:10.000,
    media-c14709808479b31566b50f2f8b93fe1a-1.ts?x-oss-process=if_status_eq_404{hls/ts,from_b3v0chv0l21lzglhlm0zdtg}&x-oss-expires=1710457284&x-oss-signature-version=oss2&x-oss-access-key-id=****feaub****&x-oss-signature=****vr3gy****
    #extinf:10.000,
    media-c14709808479b31566b50f2f8b93fe1a-2.ts?x-oss-process=if_status_eq_404{hls/ts,from_b3v0chv0l21lzglhlm0zdtg}&x-oss-expires=1710457284&x-oss-signature-version=oss2&x-oss-access-key-id=****feaub****&x-oss-signature=****vr3gy****
    #extinf:10.000,
    media-c14709808479b31566b50f2f8b93fe1a-3.ts?x-oss-process=if_status_eq_404{hls/ts,from_b3v0chv0l21lzglhlm0zdtg}&x-oss-expires=1710457284&x-oss-signature-version=oss2&x-oss-access-key-id=****feaub****&x-oss-signature=****vr3gy****
    #ext-x-endlist

    其他云自行查阅文档,部分公有云的对象存储是没有这个功能的

  • 方案2:自行处理
    我刚好有使用这个功能,仅供参考

<?php
$s3 = new aws\s3\s3client([
    'version' => 'latest',
    'region' => 'us-east-1',
    'endpoint' => 'xxxxx',
    'credentials' => [
        'key'    => '',
        'secret' => '',
    ]
]);
try {
    $file = $s3->getobject([
        'bucket' => 'wodevideo',
        'key' => 'ddd2/index.m3u8',
    ]);
    $body = $file->get('body');
    $body->rewind();
    $content = $body->getcontents();
} catch (exception $exception) {
    echo "failed to download  from  with error: " . $exception->getmessage();
    exit("please fix error with file downloading before continuing.");
}
// m3u8处理
$m3u8texts = explode("\n", $content);
$m3u8text = '';
foreach ($m3u8texts as $line => $linetext) {
    if( str_starts_with($linetext, '#') ){
        $m3u8text .= $linetext . "\n";
        continue;
    }
    try {
        // 把m3u8的每个ts切片转换为签名链接
        $request = $s3->createpresignedrequest($bucket, $linetext, ' 10 minutes');
        $m3u8text .= $request->geturi() . "\n";
    } catch (\exception $e) {
        // echo $e->getmessage();exit;
    }
}
// 作为m3u8文件输出
header("access-control-allow-origin:*");
header("access-control-allow-headers:*");
header("access-control-allow-methods:*");
 header('access-control-allow-headers:authorization,lpy');
header('content-type: application/vnd.apple.mpegurl');
header('content-disposition: attachment; filename="playlist.m3u8"');
echo $m3u8text;
2周前
唐章明 (作者) 2周前
shine-x (楼主) 2周前
唐章明 (作者) 2周前
唐章明 (作者) 2周前

之前用七牛的两种方案是:

  1. 联系七牛云忽略ts切片的鉴权
  2. 将m3u8获取方式改成通过api获取 api解析m3u8 给每个ts切片做鉴权处理
2周前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图