@tylermcrobert/sanity-videoplayer-mux
v0.2.0
Published
Sanity media plugin with a video field. Host studios must provide muxInput() from sanity-plugin-mux-input.
Readme
@tylermcrobert/sanity-videoplayer-mux
An intelligent and ergonomic Sanity video player schema plugin with TypeScript helpers.
Bring your own video component. This package does not ship a player — no <mux-video>, <video>, or framework wrapper. You get schema, a GROQ projection, and typed props; you render them with whatever player you already use.
- Drop in a
videoPlayerfield. Mux asset, playback, and poster are already modeled. - Content Editor Ergonomics - Easy UX makes use of hidden fields to keep the editing experience as simple or as robust as needed.
- Flexible - An editor can simply choose "Controls" or "Autoplay", or control each video playback prop.
- One GROQ projection in, native video props out: Mux stream
src, numeric aspect ratio, sized poster (custom image or Mux thumbnail), andtrue | undefinedplayback attributes you can spread onto your own<mux-video>,<video>, or other player.
Getting started
Configuring Sanity Studio to use the videoPlayer
Start by installing install and registering muxInput() from sanity-plugin-mux-input Followed by videoPlayer() from @tylermcrobert/sanity-videoplayer-mux/plugin
import { muxInput } from "sanity-plugin-mux-input";
import { videoPlayer } from "@tylermcrobert/sanity-videoplayer-mux/plugin";
export default defineConfig({
plugins: [muxInput(), videoPlayer()],
// Or hide Custom... : videoPlayer({ showCustom: false })
});To use the player in your schema, call the videoPlayer
defineField({
name: "video",
type: "videoPlayer",
});Using in your app
You bring the player. This package only turns the Sanity field into props you can spread onto it.
import { VIDEO_PLAYER_PROJECTION } from "@tylermcrobert/sanity-videoplayer-mux";
const MY_QUERY = defineQuery(`
headerVideo: { ${VIDEO_PLAYER_PROJECTION} }
`);Map the projection to props, then pass them to your own component (example with @mux/mux-video):
<script>
import { getParsedVideoProps } from "@tylermcrobert/sanity-videoplayer-mux";
import "@mux/mux-video";
let { videoProjection } = $props();
const { aspect, videoProps } = $derived(getParsedVideoProps(videoProjection));
</script>
<mux-video
style:aspect-ratio={aspect}
{...videoProps}
></mux-video>getParsedVideoProps converts playback presets to boolean video attributes, uses your Sanity poster when set, or falls back to Mux’s start-frame thumbnail — sized to the video aspect ratio.
Ease of life
Use video thumbnail and filename in previews
Use selectVideo / prepareVideo from the plugin entry to show the Mux thumbnail (or custom poster) and filename in list previews:
import { prepareVideo, selectVideo } from "@tylermcrobert/sanity-videoplayer-mux/plugin";
preview: {
select: {
title: "title",
...selectVideo("video"), // path to the videoPlayer field; omit for root
},
prepare(selection) {
return {
title: selection.title,
...prepareVideo(selection),
};
},
},Using typescript helpers to map to native html (framework-agnostic)
Query
"video": {
"playbackId": video.muxAsset.asset->playbackId,
"aspect": video.muxAsset.asset->data.aspect_ratio,
"poster": video.poster.asset->url,
"playbackSettings": video.playbackSettings,
"customPlaybackSettings": select(
video.playbackSettings == "custom" => video.customPlaybackSettings
),
}