> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sertifikasitrainer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mux (video)

> Access token, signing keys, dan playback JWT untuk video kelas.

Video pembelajaran di-host di **Mux**. API upload/manage pakai access token; playback ke browser pakai **signed JWT** (signing keys).

<Frame>
  <img src="https://www.mux.com/favicon.ico" alt="Logo Mux" width="48" />
</Frame>

**Dashboard:** [dashboard.mux.com](https://dashboard.mux.com)\
**Docs:** [mux.com/docs](https://www.mux.com/docs/core/mux-fundamentals)

## Env di project

```bash theme={null}
MUX_TOKEN_ID=...
MUX_TOKEN_SECRET=...
MUX_SIGNING_KEY_ID=...
MUX_SIGNING_KEY_PRIVATE_KEY=...          # PEM atau base64
MUX_SIGNING_KEY_PRIVATE_KEY_PKCS8=...    # format PKCS8 (dipakai signing)
```

Opsional (rotasi key): `MUX_SIGNING_KEY_ID_NEW`, `MUX_SIGNING_KEY_PRIVATE_KEY_NEW`, dll.

Kode signing: `apps/api/src/mux/mux-signing.ts`, `apps/api/src/mux/mux.service.ts`

## Setup

<Steps>
  <Step title="Buat Access Token">
    Dashboard → **Settings** → **Access Tokens** → **Generate new token**

    * Environment: **Production**
    * Permissions: **Mux Video Read** + **Mux Video Write**
    * Simpan **Token ID** + **Token Secret** (secret sekali tampil)
  </Step>

  <Step title="Buat Signing Key">
    Dashboard → **Settings** → **Signing Keys** → **Create**

    Mux mengembalikan:

    * **Key ID** → `MUX_SIGNING_KEY_ID`
    * **Private key** (base64 PEM) → `MUX_SIGNING_KEY_PRIVATE_KEY` / `_PKCS8`

    <Warning>
      Private key hanya ditampilkan sekali. Simpan di password manager sebelum tutup modal.
    </Warning>
  </Step>

  <Step title="Upload video (manual tes)">
    ```bash theme={null}
    # Setelah MUX_TOKEN_ID + MUX_TOKEN_SECRET di env
    curl https://api.mux.com/video/v1/assets \
      -u "$MUX_TOKEN_ID:$MUX_TOKEN_SECRET" \
      -H "Content-Type: application/json" \
      -d '{"input":[{"url":"https://storage.googleapis.com/muxdemofiles/mux-video-intro.mp4"}],"playback_policy":["signed"]}'
    ```

    Response berisi `playback_ids` — dipakai untuk generate JWT playback.
  </Step>

  <Step title="Playback policy">
    Asset production sebaiknya **`signed`** (bukan `public`) — user hanya bisa nonton lewat JWT dari API TrainerHub.
  </Step>

  <Step title="Push secrets">
    ```bash theme={null}
    ./thub secrets check
    ./thub secrets push
    ```
  </Step>
</Steps>

## Alur di aplikasi

```mermaid theme={null}
sequenceDiagram
  participant Web as Frontend
  participant API as API Worker
  participant Mux as Mux CDN
  Web->>API: GET playback token (lesson id)
  API->>API: Sign JWT dengan signing key
  API-->>Web: token + playback id
  Web->>Mux: stream.mux.com/...?token=JWT
```

Docs: [Secure video playback](https://www.mux.com/docs/guides/secure-video-playback) · [Signing JWTs](https://www.mux.com/docs/guides/signing-jwts)

## CLI Mux (opsional)

```bash theme={null}
npm i -g @mux/cli
mux login   # Token ID + Secret
mux signing-keys create
mux sign <playback-id>
```

## Troubleshooting

| Masalah          | Solusi                                                  |
| ---------------- | ------------------------------------------------------- |
| Video tidak play | Cek playback policy `signed` + JWT valid                |
| 401 ke Mux API   | Token ID/Secret salah atau permission kurang            |
| Key rotation     | Set `MUX_*_NEW` vars, deploy, lalu ganti primary        |
| Fitur video mati | Semua `MUX_*` opsional — kosong = tanpa video streaming |
