vaersaagod/muxmate

Mux 关于流媒体的内容,伙伴们!

安装: 115

依赖项: 0

建议者: 0

安全: 0

星星: 3

关注者: 3

分支: 3

开放问题: 0

类型:craft-plugin

3.0.1 2024-08-22 09:42 UTC

This package is auto-updated.

Last update: 2024-09-22 09:54:06 UTC


README

Mux 关于流媒体的内容,伙伴们!

Logo

描述

MuxMate 将 Mux 集成到 Craft CMS 中。

要求

此插件需要 Craft CMS 5.2.0 或更高版本,以及 PHP 8.2 或更高版本。

免责声明

这是一个 私有插件,为 Værsågod 及其朋友制作。

入门指南

1. 创建 Mux 环境

https://www.mux.com 上注册一个 Mux 账户,并添加一个环境。为每个 Craft 环境创建单独的 Mux 环境是个不错的想法。

2. 创建 Mux 访问令牌

为适当的 Mux 环境创建一个 Mux 访问令牌。令牌只需要 "Mux 视频" 权限。
复制访问令牌 ID 和密钥。

3. 配置 MuxMate

在您的存储库中创建一个文件 config/_muxmate.php,并添加 Mux 访问令牌 ID 和密钥

<?php

use craft\helpers\App;

return [
    'muxAccessTokenId' => App::env('MUX_ACCESS_TOKEN_ID'),
    'muxSecretKey' => App::env('MUX_SECRET_KEY'),
];

...还有很多配置设置(见 下面 了解所有设置),但这两项是您绝对需要的。

4. 将 MuxMate webhook 端点添加到 Mux 环境

没有工作的 Mux webhook,您将难以进行操作,所以不要跳过此步骤!

在您的 Mux 账户中,转到设置 -> Webhooks,选择适当的环境,并使用此 URL 创建一个新的 webhook

https://your-site.com/muxmate/webhook

如果这是一个本地环境(或无法从外部访问),您可以使用 Ngrok 或类似工具创建一个公开可用的 Webhook 端点 URL。

5. 创建 MuxMate 字段并将其添加到卷

MuxMate 随附一个自定义的 "MuxMate" 字段类型。创建一个具有此字段类型的字段(名称或处理程序不重要),并将其添加到计划上传视频的任何卷的字段布局中。

6. 上传视频到 Craft,并等待它

当包含 MuxMate 字段(在其字段布局中)的视频在 Craft 中保存时,其 URL 会自动 POST 到 Mux 的 assets/create 端点。假设视频的 URL 是公开可用的,Mux 然后下载视频并为它创建一个 Mux 资产。

Mux 端的流程是完全异步的,但遵循预定的顺序

  1. 创建 Mux 资产,包含基本元数据
  2. 创建 HLS 流;当准备好时,Mux 资产状态将变为 "ready"。
  3. 创建静态渲染(即转译的 MP4 资产);当完成时,Mux 资产元数据将包含一个键 static_renditions

假设 MuxMate webhook URL 已添加到 Mux(并且是公开可用的),Craft 中的资产 Mux 元数据将自动更新上述每个步骤。

7. 在前端渲染 Mux 视频

要渲染在 Mux 中创建的视频,只需在资产上调用 getMuxVideo() 方法以渲染一个自定义的 <mux-video> 网络组件实例

{{ video.getMuxVideo()|attr({ controls: true }) }}

本地测试

在本地环境中,Mux 通常无法访问您的视频。为确保它可以,请执行以下操作之一

使用云存储(S3、DO Spaces)文件系统来存储您的视频资产

一个简单的解决方案是使用某种云存储文件系统来存储视频的卷。您甚至可以设置一个仅本地使用的云存储文件系统,通过使用环境变量来设置卷的“资产文件系统”设置。

在本地环境中使用远程隧道覆盖卷的文件系统基本URL

如果您已经为webhook设置了类似Ngrok隧道,您也可以使用相同的隧道来确保Mux可以访问您的视频资产。这里有一些方法可以做到这一点

使用MuxMate覆盖文件系统的Base URL

您可以通过使用MuxMate的volumes配置设置来配置MuxMate以覆盖特定卷中资产的Base URL。

假设您的视频存储在名为videos的卷中(该卷使用的是Base URL设置为@web/uploads/videos的文件系统),以下是您可以如何覆盖该Base URL的示例

在您的.env文件中

VIDEO_VOLUME_BASE_URL=https://2d13-51-175-241-107.ngrok-free.app/uploads/videos

在您的config/_muxmate.php文件中

<?php

use craft\helpers\App;

return [
    'muxAccessTokenId' => App::env('MUX_ACCESS_TOKEN_ID'),
    'muxSecretKey' => App::env('MUX_SECRET_KEY'),
    'volumes' => [
        'videos' => [
            'baseUrl' => App::env('VIDEO_VOLUME_BASE_URL'),
        ],
    ],
];

将文件系统的Base URL设置为自定义别名

另一个选项是添加一个自定义Yii别名,例如@videosBaseUrl,并将您的卷的文件系统的“Base URL”设置为此别名(例如,@videosBaseUrl/uploads/videos)。然后,使用Craft的aliases配置设置来定义自定义的@videosBaseUrl别名

在您的.env文件中

VIDEOS_BASE_URL=https://2d13-51-175-241-107.ngrok-free.app

在您的config/general.php文件中

'aliases' => [
    '@videosBaseUrl' => App::env('VIDEOS_ALIAS') ?? App::env('PRIMARY_SITE_URL')
],

为现有的Craft视频资产创建(或更新)Mux资产

MuxMate资产在视频上传到Craft时创建,仅将MuxMate字段添加到卷中并不会对现有视频资产产生影响。如果您想MuxMate为现有Craft视频资产创建(或更新)Mux资产,有一些选项

重新保存资产(手动,通过控制面板)

MuxMate不会在Craft资产通过程序重新保存时创建或更新Mux资产(这是故意的)。但是,手动通过控制面板重新保存资产将会做到这一点。

在资产编辑页面点击“创建Mux资产”按钮。

与手动重新保存资产不同,这不会更新资产的dateUpdated属性。

使用_muxmate/create CLI命令

_muxmate/create CLI命令可以用来创建Mux资产,无论是批量(即整个卷)还是单个资产

_muxmate/create - 为所有视频资产创建Mux资产。通过传递--update=1来重新创建任何现有Mux资产。
_muxmate/create --volume=videos - 为卷videos中的所有视频资产创建Mux资产。通过传递--update=1来重新创建任何现有Mux资产。
_muxmate/create --assetId=1234 - 为ID为1234的视频资产创建Mux资产。通过传递--update=1来重新创建现有Mux资产。

视频的渲染和播放

Mux视频

渲染Mux视频最简单的方法是使用对所有资产都适用的getMuxVideo()方法。

{{ video.getMuxVideo() }}

上述代码将渲染一个<mux-video>网络组件,这是对原生<video>元素的近似直接替换。
<mux-video>的好处是它自动填充HLS(如果用户的浏览器不支持),并且它自动与Mux Data集成。

设置<mux-video>属性

可以使用|attr() Twig过滤器来设置<mux-video>组件的属性。

{{ video.getMuxVideo()|attr({
    id: 'my-video',
    class: 'border-2 border-black',
    controls: true
}) }}

内联视频(播放内联/循环视频)

要渲染内联视频(即视频循环),可以将参数inline: true传递给getMuxVideo()方法。

{{ video.getMuxVideo({ inline: true }) }}

以上自动为<mux-video>组件设置以下属性

autoplay: 'muted',
loop: true,
muted: true,
playsinline: true,
disablePictureInPicture: true

或者,当然,您可以使用|attr() Twig过滤器自己设置这些属性

{{ video.getMuxVideo()|attr({
    autoplay: 'muted',
    loop: true,
    muted: true,
    playsinline: true,
    disablePictureInPicture: true
}) }}

对象适配Mux视频

<mux-video>的样式通常很简单。唯一例外是对象适配,因为需要将object-fit应用于实际的<video>元素——由于它在Web组件的shadow DOM中嵌套,因此无法访问。

默认情况下,Mux视频使用object-fit: contain进行对象适配。要更改对象适配的值,可以使用以下CSS变量:

--media-object-fit
--media-object-position

使用object-fit: cover;的示例

{{ video.getMuxVideo({ inline: true })|attr({
    style: {
        '--media-object-fit': 'cover',
        '--media-object-position': '25% 10%'
    }
}) }}

使用JS控制Mux视频播放

通常,<mux-video>与原生的<video>元素工作方式相同,即具有相同的方法(如.play().pause()等),并触发相同的事件(如timeupdate等)。

然而,在尝试以编程方式与Mux视频交互之前,您应该确保自定义的<mux-video> Web组件已加载,可以使用customElements API

window.customElements.whenDefined('mux-video')
    .then(() => {
        const video = document.getElementById('video');
        video.addEventListener('canplay', () => {
            video.play();
            console.log('ready!');
        });
    })
    .catch(error => {
        console.error(error);
    });

延迟加载<mux-video> Web组件

<mux-video> Web组件体积较大(约150K压缩后),因此延迟加载它可能是有意义的——即在<mux-video>元素实际进入视口之前不加载它。

要自动在所有地方延迟加载<mux-video> Web组件,只需将lazyloadMuxVideo配置设置设置为true

<?php

return [
    'lazyloadMuxVideo' => true,
];
实现自己的延迟加载策略

对于更复杂的使用情况,您可以通过将muxVideoUrl配置设置设置为false来防止MuxMate自动加载<mux-video> Web组件。

<?php

return [
    'muxVideoUrl' => false,
];

在此之后,您可以根据自己的喜好以任何延迟方式自行加载Web组件。例如

const video = document.getElementById('video');
let hasLoadedMuxVideoJs = false;
const observer = new IntersectionObserver(([{ isIntersecting }]) => {
    if (isIntersecting && !hasLoadedMuxVideoJs) {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = true;
        script.src = 'https://cdn.jsdelivr.net.cn/npm/@mux/mux-video@0';
        document.body.appendChild(script);
    }
});
内容安全策略(CSP)

如果您正在实施CSP(好主意!),您可能需要将nonce设置为MuxMate创建的脚本标签。为此,请使用scriptSrcNonce配置设置。以下是一个使用ToolMate插件创建nonce的示例

<?php

use \vaersaagod\toolmate\ToolMate;

return [
    'scriptSrcNonce' => ToolMate::getInstance()->csp->createNonce('script-src'),
];

此功能即使在启用模板缓存的情况下也能正常工作 🔥

从视频中获取图像和动画GIF

从视频中获取图像

getMuxImageUrl()资产方法支持与Mux文档中描述的所有相同参数:https://docs.mux.com/guides/video/get-images-from-a-video

示例

{% set imageUrl = video.getMuxImageUrl({ width: 1080, height: 720 }) %}
<img src="{{ imageUrl }}" />

从视频中获取动画GIF

getMuxGifUrl()资产方法支持与Mux文档中描述的所有相同参数:https://docs.mux.com/guides/video/get-images-from-a-video#get-an-animated-gif-from-a-video

示例

{% set gifUrl = video.getMuxGifUrl({ start: 10, end: 20, width: 300, height: 150 }) %}
<img src="{{ gifUrl }}" />

签名URL

为了保护您的Mux资产,对Mux URL进行签名可能是一个好主意。

创建签名密钥

要开始使用Mux签名URL,首先需要创建一个Mux签名密钥

  1. 在您的Mux账户中,转到设置 -> 签名密钥
  2. 选择适当的环境,然后单击“生成新密钥”
  3. 复制签名密钥ID和Base64编码的私钥(不要将其作为.pem文件下载)
  4. 配置MuxMate以使用签名密钥
<?php
return [
    ...
    'muxSigningKey' => [
        'id' => App::env('MUX_SIGNING_KEY_ID'),
        'privateKey' => App::env('MUX_SIGNING_PRIVATE_KEY'),
    ],
],

选择播放策略

MuxMate为您所有的资产创建公共和签名播放ID,因此使用签名ID只需选择正确的策略。

默认情况下,MuxMate使用所有资产的公共播放ID。要默认使用签名播放ID,配置MuxMate的defaultPolicy配置设置

<?php
return [
    ...
    'defaultPolicy' => 'signed',
];

创建视频流、静态版本URL或图像/GIF时,也可以通过传递参数signed来选择特定的策略。
一些示例

签名Mux图像URL

{% set imageUrl = video.getMuxImageUrl({ width: 1080, height: 720 }, 'signed') %}
<img src="{{ imageUrl }}" />

签名Mux GIF URL

{% set gifUrl = video.getMuxGifUrl({ start: 10, end: 20, width: 300, height: 150 }, 'signed') %}
<img src="{{ gifUrl }}" />

签名<mux-video>标签

{{ video.getMuxVideo({ inline: true }, null, 'signed') }}

查看Mux资产方法和属性,以获取支持signed参数的方法的完整概述。

基于Mux数据查询资产

可以通过使用MuxMate字段的handle来执行基于Mux元数据的资产子查询,例如

{% set videos = entry.videos.muxMateFieldHandle({ status: 'ready' }).all() %}

此外,还支持:empty::notempty:指令,可以确保返回的资产在MuxMate字段中具有Mux数据

{% set videos = entry.videos.muxMateFieldHandle(':notempty:').all() %}

配置

MuxMate通过将文件config/_muxmate.php添加到您的仓库中进行配置。

配置设置

muxAccessTokenId [字符串|null]

默认: null

Mux访问令牌ID

muxSecretKey [字符串|null]

默认: null

Mux访问令牌密钥

muxSigningKey [数组|null]

默认 null

用于签名URL的签名密钥ID和私钥

'muxSigningKey' => [
    'id' => App::env('MUX_SIGNING_KEY_ID'),
    'privateKey' => App::env('MUX_SIGNING_PRIVATE_KEY'),
    'minExpirationTime' => 'PT5M',
],

defaultPolicy [字符串|null]

默认 null (默认为'public')

在生成Mux URL时使用的默认播放策略。应设置为'public'(默认)或'signed'

defaultMp4Quality [字符串|null]

默认 null (默认为'high')

用于静态版本的默认质量。需要是'high'(默认)、'medium''low'之一。

defaultMaxResolution [字符串|null]

默认 null

用于HLS流的默认max_resolution参数。需要是'720p''1080p''1440p''2160p'之一。

maxResolutionTier [字符串|null]

默认 null (默认为'1080p')

在创建新的Mux资产时使用的默认max_resolution_tier参数。需要是'1080p''1440p''2160p'之一。

muxVideoUrl [字符串|bool|null]

默认: 'https://cdn.jsdelivr.net.cn/npm/@mux/mux-video@0'

<mux-video> JS库的URL。如果要使用不同的分发,请将其设置为不同的URL(支持别名和环境变量),或者将其设置为false以完全自行处理库的加载(例如,用于自定义延迟加载或其他类似用途)。

lazyloadMuxVideo [bool]

默认: false

设置为true以使MuxMate延迟加载<mux-video>库。即,MuxMate不会在页面加载时自动加载(尽管是异步的),而是在<mux-video>组件进入视口时创建IntersectionObserver并加载脚本。

scriptSrcNonce [字符串|null]

默认 null

volumes [数组|null]

默认: null 每卷配置设置。目前仅支持baseUrl设置,请参阅上面的“在本地环境中覆盖您的卷文件系统Base URL”。

Mux资产方法和属性

MuxMate向资产模型添加了一些方法和属性

isMuxVideo() [bool]

如果资产具有Mux资产ID,则返回true

isMuxVideoReady() [bool]

如果资产具有Mux资产ID且具有“就绪”状态,即已准备好播放,则返回true

getMuxVideo(array|null options = null, array|null params = null, string|null policy = null) [Markup|string]

@options 选项数组;inlinelazyload
@params Mux参数数组
@policy 'public''signed'之一

如果资产有Mux播放ID,则返回一个<mux-video>网页组件。

options数组可以包含以下设置

inline: true # Automatically sets all the required attributes for videos that should play inline.
lazyload: true # Lazyloads the `<mux-video>` web component. Defaults to the `lazyloadMuxVideo` config setting

params数组可以包含Mux视频参数(例如“播放修改器”),如max_resolution参数

{{ asset.getMuxVideo(null, { max_resolution: '720p' }) }}

getMuxStreamUrl(array|null params = null, string|null policy = null) [string|null]

@params Mux参数数组
@policy 'public''signed'之一

如果资产有Mux播放ID,则返回HLS流URL。与getMuxVideo()方法的@params数组相同。

getMuxMp4Url(string|null quality = null, string|null policy = null) [string|null]

@quality 可选值为'high''medium''low'
@policy 'public''signed'之一

如果资产有Mux播放ID和静态渲染版本,则返回MP4文件的URL。
如果quality参数为null或设置为不可用的质量,则返回最高可用质量。

getMuxImageUrl(array|null params = null, string|null policy) [string|null]

@params 数组为Mux参数,请参阅https://docs.mux.com/guides/video/get-images-from-a-video#thumbnail-query-string-parameters
@policy 'public''signed'之一

如果资产有Mux播放ID,则返回视频静态帧的URL。

getMuxGifUrl(array|null params = null, string|null policy) [string|null]

@params array 参数数组,请参阅https://docs.mux.com/guides/video/get-images-from-a-video#animated-gif-query-string-parameters
@policy 'public''signed'之一

如果资产有Mux播放ID,则返回视频的动画GIF。

getMuxVideoDuration() [float|null]

返回视频时长,单位为秒

getStaticRenditions() [array|null]

返回视频可用静态渲染版本的数组。数组按质量('high''medium''low')索引。

getMuxAssetId() [string|null]

返回Mux资产ID。

getMuxPlaybackId(string|null policy) [string|null]

@policy 'public''signed'之一
返回给定策略的Mux播放ID。

getMuxData() [array|null]

返回整个Mux资产元数据负载。请参阅https://docs.mux.com/api-reference#video/operation/get-asset

getMuxStatus() [string|null]

返回Mux资产状态。如果显示为ready,则表示可以继续。

getMuxAspectRatio() [float|int|null]

返回视频的宽高比