Skip to content

Commit

Permalink
feat: configurable uploads and import from Mux (#350)
Browse files Browse the repository at this point in the history
* feat: starting to configure asset upload

* feat: new Next-based example

Sets the stage for using the new backend handler

* refactor: adapt styles & versions to new Sanity UI styles

* docs: documentation of new options

* feat: configurable options for URL uploads

* Converted Uploader to functional component

* chore(prettier): 🤖 ✨

* refactor: minor type adjustments

* feat: ability to import existing videos from Mux

* fix: configuration UI improvements & fixes

* fix: remove custom caption dropzone

---------

Co-authored-by: Evan Kirkiles <[email protected]>
Co-authored-by: hdoro <[email protected]>
  • Loading branch information
3 people authored Apr 8, 2024
1 parent a62d893 commit 0492fab
Show file tree
Hide file tree
Showing 73 changed files with 10,478 additions and 53,609 deletions.
164 changes: 148 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,125 @@ Having the ID be non-root ensures that only editors are able to see it.
The Mux plugin will find its access tokens by fetching this document.
# Playing videos in the frontend
## Fetching playback IDs and understanding the data structure
When a Mux video is uploaded/chosen in a document via this plugin, it gets stored as a reference to the video document:
```json
// example document
{
"_type": "exampleSchemaWithVideo",
// Example video field
"myVideoField": {
"_type": "mux.video",
"asset": {
"_type": "reference",
"_weak": true,
"_ref": "4e37284e-cec2-406d-973c-fdf9ab1e5598" // 👈 ID of the document holding the video's Mux data
}
}
}
```
Before you can display videos in your frontend, you need to follow these references to fetch the asset's playback ID, which will be used to create a player. Here's an example GROQ query to expand the video reference in the example data above:
```groq
// Example for fetching data above
*[ _type == "exampleSchemaWithVideo" ] {
myVideoField {
asset-> {
playbackId,
assetId,
filename,
}
}
}
```
💡 For more information on querying references, refer to the documentation on [Writing GROQ queries for references](https://www.sanity.io/docs/reference-type#96b949753900) or on [Sanity's GraphQL API](https://www.sanity.io/docs/graphql).
For reference, here's an example `mux.videoAsset` document:
```json
{
"_id": "4e37284e-cec2-406d-973c-fdf9ab1e5598",
"_type": "mux.videoAsset",
"assetId": "7ovyI76F92n02H00mWP7lOCZMIU00N4iysDiQDNppX026HY",
"filename": "mux-example-video.mp4",
"status": "ready",
"playbackId": "YA02HBpY02fKWHDRMNilo301pdH02LY3k9HTcK43ItGJLWA",
// Full Mux asset data:
"data": {
"encoding_tier": "smart",
"max_resolution_tier": "1080p",
"aspect_ratio": "16:9",
"created_at": "1706645034",
"duration": 25.492133,
"status": "ready",
"master_access": "none",
"max_stored_frame_rate": 29.97,
"playback_ids": [
{
"id": "YA02HBpY02fKWHDRMNilo301pdH02LY3k9HTcK43ItGJLWA",
"policy": "signed"
}
],
"resolution_tier": "1080p",
"ingest_type": "on_demand_url",
"max_stored_resolution": "HD",
"tracks": [
{
"max_channel_layout": "stereo",
"max_channels": 2,
"id": "00MKMC73SYimw1YTh0102lPJJp9w2R5rHddpNX1N9opAMk",
"type": "audio",
"primary": true,
"duration": 25.45
},
{
"max_frame_rate": 29.97,
"max_height": 1080,
"id": "g1wEph3CVvbJL01YNKzAWMyH8N1SxW00WeECGjqwEHW9g",
"type": "video",
"duration": 25.4254,
"max_width": 1920
}
],
"id": "7ovyI76F92n02H00mWP7lOCZMIU00N4iysDiQDNppX026HY",
"mp4_support": "none"
}
}
```
We recommend using [Mux Player](https://www.mux.com/player), try the [Codesandbox example](https://codesandbox.io/s/github/sanity-io/sanity-plugin-mux-input/tree/main/example).
## Playing videos in the frontend
# Enabling Signed URLs
We recommend using [Mux Player](https://www.mux.com/player) to properly display your videos, through packages like `@mux/mux-player` and `@mux/mux-player-react`. Here's an example of how you can use the Mux Player to display a video in a React component:
```tsx
'use client'

import MuxPlayer from '@mux/mux-player-react'

export default function MuxVideo({playbackId, title}: {playbackId?: string; title?: string}) {
if (!playbackId) return null

return <MuxPlayer playbackId={playbackId} metadata={title ? {video_title: title} : undefined} />
}
```
💡 You can try these recommendations through the [Codesandbox example](https://codesandbox.io/s/github/sanity-io/sanity-plugin-mux-input/tree/main/example).
## Configuring Mux video uploads
### Signed URLs (private playbacks)
To enable [signed urls](https://docs.mux.com/docs/security-signed-urls) with content uploaded to Mux, you will need to check the "Enable Signed Urls" option in the Mux Plugin configuration. Assuming that the API Access Token and Secret Key are set (as per the [Quick start](#quick-start) section).
More information for this feature of the plugin can be found on Mux's [documentation](https://docs.mux.com/docs/headless-cms-sanity#advanced-signed-urls)
# Enabling MP4 support
### Encoding tier
### MP4 support (downloadable videos)
To enable [static MP4 renditions](https://docs.mux.com/guides/video/enable-static-mp4-renditions), add `mp4_support: 'standard'` to the `options` of your `mux.video` schema type.
Expand All @@ -95,9 +203,37 @@ export default defineConfig({
})
```
Currently, `mp4_support` is the only supported MUX option and this supports a value of either `standard` or `none` (the default).
If MP4 support is enabled in the plugin's configuration, editors can still choose to enable MP4 renditions on a per-video basis when uploading new assets.
### Video resolution (max_resolution_tier)
# Contributing
To edit [max_resolution_tier](https://docs.mux.com/api-reference#video/operation/create-direct-upload) to support other resolutions other than 1080p, add `max_resolution_tier: '1080p' | '1440p' | '2160p'` to the `options` of your `mux.video` schema type. Defaults to `1080p`.
```js
import {muxInput} from 'sanity-plugin-mux-input'

export default defineConfig({
plugins: [muxInput({max_resolution_tier: '2160p'})],
})
```
When uploading new assets, editors can still choose a lower resolution for each video than configured globally.
### Encoding tier (smart or baseline)
The [encoding tier](https://docs.mux.com/guides/use-encoding-tiers) informs the cost, quality, and available platform features for the asset. You can choose between `smart` and `baseline` at the plugin configuration. Defaults to `smart`.
```js
import {muxInput} from 'sanity-plugin-mux-input'

export default defineConfig({
plugins: [muxInput({encoding_tier: 'baseline'})],
})
```
If `encoding_tier: 'smart'`, editors can still choose to use the `baseline` encoding tier on a per-video basis when uploading new assets.
## Contributing
Issues are actively monitored and PRs are welcome. When developing this plugin the easiest setup is:
Expand All @@ -111,7 +247,7 @@ Issues are actively monitored and PRs are welcome. When developing this plugin t
1. Edit `schemas/post.js` and add follow the plugin documentation to add a `mux.video` type field.
1. Your studio should reload, and now when you edit the plugin code it should reload the studio, when you're done creating a branch, put in a PR and a maintainer will review it. Thank you!
# Publishing
### Publishing
Run the ["CI" workflow](https://github.com/sanity-io/sanity-plugin-mux-input/actions/workflows/ci.yml).
Make sure to select the main branch and check "Release new version".
Expand All @@ -133,15 +269,7 @@ On the [main](/tree/main) branch this will result in:
After Studio v3 turns stable this behavior will change. The v2 version will then be available on the `studio-v2` dist-tag, and `studio-v3` is upgraded to live on `latest`.
# Test

`npm test`

## License

MIT-licensed. See LICENSE.

## Develop & test
### Develop & test
This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
with default configuration for build & watch scripts.
Expand All @@ -155,3 +283,7 @@ Run ["CI & Release" workflow](https://github.com/sanity-io/sanity-plugin-mux-inp
Make sure to select the main branch and check "Release new version".
Semantic release will only release on configured branches, so it is safe to run release on any branch.
## License
MIT-licensed. See LICENSE.
3 changes: 3 additions & 0 deletions example/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NEXT_PUBLIC_SANITY_PROJECT_ID=""
NEXT_PUBLIC_SANITY_DATASET="production"
NEXT_PUBLIC_SANITY_API_VERSION="2024-01-30"
21 changes: 17 additions & 4 deletions example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,33 @@
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
36 changes: 36 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
6 changes: 0 additions & 6 deletions example/ignored-build-step.sh

This file was deleted.

4 changes: 4 additions & 0 deletions example/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}

export default nextConfig
Loading

0 comments on commit 0492fab

Please sign in to comment.