Skip to content

Commit

Permalink
feat: support slotted poster img (e.g. next/image) (#189)
Browse files Browse the repository at this point in the history
* feat: support slotted poster img (e.g. next/image)
#146

* docs: add slotted poster image element
  • Loading branch information
luwes authored Feb 23, 2024
1 parent 72dcc92 commit 3673bf0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ You can add a custom poster and blurDataURL to the video by passing them as prop
```tsx
import Video from 'next-video';
import awesomeVideo from '/videos/awesome-video.mp4';
import awesomePoster from '/images/awesome-poster.jpg';
import awesomePoster from '../public/images/awesome-poster.jpg';

export default function Page() {
return <Video
Expand All @@ -199,6 +199,43 @@ export default function Page() {
}
```

This is a good solution but it will not provide the same level of optimization
as the automatic poster and blurDataURL by the default provider.

To get the same level of optimization you can use a slotted poster element.


### Slotted poster image element

Add a slotted poster image element
(like [`next/image`](https://nextjs.org/docs/app/api-reference/components/image))
to the video by passing it as a child with a `slot="poster"` attribute.

Now your image will get all the benefits of the used image component
and it will be nicely placed behind the video player controls.


```tsx
import Image from 'next/image';
import Video from 'next-video';
import awesomeVideo from '/videos/awesome-video.mp4';
import awesomePoster from '../public/images/awesome-poster.jpg';

export default function Page() {
return (
<Video src={awesomeVideo}>
<Image
slot="poster"
src={awesomePoster}
placeholder="blur"
alt="Some peeps doing something awesome"
/>
</Video>
);
}
```


### Custom Player

You can customize the player by passing a custom player component to the `as` prop.
Expand Down
12 changes: 11 additions & 1 deletion src/components/default-player.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { forwardRef, Suspense, lazy } from 'react';
import { forwardRef, Suspense, lazy, Children, isValidElement } from 'react';
import { getPlaybackId, getPosterURLFromPlaybackId } from '../providers/mux/transformer.js';

import type { MuxPlayerProps, MuxPlayerRefAttributes } from '@mux/mux-player-react';
Expand All @@ -21,6 +21,16 @@ export const DefaultPlayer = forwardRef<DefaultPlayerRefAttributes | null, Defau
...rest
} = allProps;

const slottedPoster = Children.toArray(children).find((child) => {
return typeof child === 'object' && 'type' in child && child.props.slot === 'poster';
});

// If there's a slotted poster image (e.g. next/image) remove the default player poster and blurDataURL.
if (isValidElement(slottedPoster)) {
poster = '';
blurDataURL = undefined;
}

const props: MuxPlayerProps = rest;
const imgStyleProps: React.CSSProperties = {};
const playbackId = asset ? getPlaybackId(asset) : undefined;
Expand Down

0 comments on commit 3673bf0

Please sign in to comment.