@mux/mux-player-astro 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,238 @@
1
+ <p align="center">
2
+ <h1 align="center">&lt;MuxPlayer/&gt;</h1>
3
+ <a href="https://npmcharts.com/compare/@mux/mux-player-astro?interval=30"><img src="https://img.shields.io/npm/dm/@mux/mux-player-astro.svg?sanitize=true" alt="Downloads"></a>
4
+ <a href="https://www.npmjs.com/package/@mux/mux-player-astro"><img src="https://img.shields.io/npm/v/@mux/mux-player-astro.svg?sanitize=true" alt="Version"></a>
5
+ <a href="https://www.npmjs.com/package/@mux/mux-player-astro"><img src="https://img.shields.io/npm/l/@mux/mux-player-astro.svg?sanitize=true" alt="License"></a>
6
+ </p>
7
+
8
+ # Introduction
9
+
10
+ `<MuxPlayer />` is a Mux-flavored Astro video player component, built on top of our [mux-player web component](../mux-player) and [Media Chrome](https://media-chrome.org).
11
+
12
+ # Installation
13
+
14
+ ```shell
15
+ npm install @mux/mux-player-astro
16
+ ```
17
+
18
+ or
19
+
20
+ ```shell
21
+ yarn add @mux/mux-player-astro
22
+ ```
23
+
24
+ # Usage
25
+
26
+ ## Basic Usage
27
+
28
+ ```astro
29
+ ---
30
+ import { MuxPlayer } from '@mux/mux-player-astro';
31
+ ---
32
+
33
+ <MuxPlayer
34
+ playbackId="DS00Spx1CV902MCtPj5WknGlR102V5HFkDe"
35
+ metadata={{
36
+ video_title: 'Big Buck Bunny',
37
+ viewer_user_id: 'user-id-1234',
38
+ }}
39
+ />
40
+ ```
41
+
42
+ ## With Styling
43
+
44
+ ```astro
45
+ ---
46
+ import { MuxPlayer } from '@mux/mux-player-astro';
47
+ ---
48
+
49
+ <MuxPlayer
50
+ playbackId="DS00Spx1CV902MCtPj5WknGlR102V5HFkDe"
51
+ style={{
52
+ display: 'block',
53
+ aspectRatio: '16/9',
54
+ backgroundColor: '#000',
55
+ }}
56
+ autoplay
57
+ muted
58
+ streamType="on-demand"
59
+ proudlyDisplayMuxBadge
60
+ />
61
+ ```
62
+
63
+ ## With Themes
64
+
65
+ You can use one of the built-in themes by passing the theme name as a string to the `theme` prop:
66
+
67
+ ```astro
68
+ ---
69
+ import { MuxPlayer } from '@mux/mux-player-astro';
70
+ ---
71
+
72
+ <MuxPlayer
73
+ playbackId="DS00Spx1CV902MCtPj5WknGlR102V5HFkDe"
74
+ theme="classic"
75
+ style={{
76
+ display: 'block',
77
+ aspectRatio: '16/9',
78
+ }}
79
+ />
80
+ ```
81
+
82
+ Available themes:
83
+ - `classic` - Classic player theme
84
+ - `minimal` - Minimal player theme
85
+ - `microvideo` - Microvideo theme for short-form content
86
+ - `gerwig` - P, pretty, I, intelligent, N, never sad, K, cool
87
+ - `news` - News theme
88
+
89
+ Alternatively you can use a [Media Chrome theme](https://www.mux.com/docs/guides/player-themes#media-chrome-themes) by passing the theme name as a string and including the theme `<template>` element with that ID in your page:
90
+
91
+ ```astro
92
+ ---
93
+ import { MuxPlayer } from '@mux/mux-player-astro';
94
+ ---
95
+ <template id="tiny-theme">
96
+ <media-controller>
97
+ <slot name="media" slot="media"></slot>
98
+ <media-control-bar>
99
+ <media-play-button></media-play-button>
100
+ </media-control-bar>
101
+ </media-controller>
102
+ </template>
103
+ <MuxPlayer
104
+ playbackId="DS00Spx1CV902MCtPj5WknGlR102V5HFkDe"
105
+ theme="tiny-theme"
106
+ />
107
+ ```
108
+
109
+ ## With Event Handling
110
+
111
+ To add event listeners to the component you can use [a client-side script](https://docs.astro.build/en/guides/client-side-scripts/). You can get the correct types for the player element by importing `MuxPlayerElement` from `@mux/mux-player-astro` and casting the element to that type.
112
+
113
+ ```astro
114
+ ---
115
+ import { MuxPlayer } from '@mux/mux-player-astro';
116
+ ---
117
+
118
+ <MuxPlayer
119
+ id="my-player"
120
+ playbackId="DS00Spx1CV902MCtPj5WknGlR102V5HFkDe"
121
+ />
122
+
123
+ <script>
124
+ import type { MuxPlayerElement } from '@mux/mux-player-astro';
125
+
126
+ const player = document.getElementById('my-player') as MuxPlayerElement;
127
+
128
+ player.addEventListener('play', (event) => {
129
+ console.log('Player started playing!');
130
+ });
131
+
132
+ player.addEventListener('pause', (event) => {
133
+ console.log('Player paused!');
134
+ });
135
+
136
+ player.addEventListener('timeupdate', (event) => {
137
+ console.log('Current time: ', player.currentTime);
138
+ });
139
+
140
+ player.addEventListener('ended', (event) => {
141
+ console.log('Video ended!');
142
+ });
143
+ </script>
144
+ ```
145
+
146
+ ## Audio Content
147
+
148
+ ```astro
149
+ ---
150
+ import { MuxPlayer } from '@mux/mux-player-astro';
151
+ ---
152
+
153
+ <MuxPlayer
154
+ playbackId="your-audio-playback-id"
155
+ audio
156
+ metadata={{
157
+ video_title: 'My Podcast Episode',
158
+ }}
159
+ />
160
+ ```
161
+
162
+ ## Live Streams
163
+
164
+ ```astro
165
+ ---
166
+ import { MuxPlayer } from '@mux/mux-player-astro';
167
+ ---
168
+
169
+ <MuxPlayer
170
+ playbackId="your-live-playback-id"
171
+ streamType="live"
172
+ targetLiveWindow={Infinity}
173
+ title="Live Stream"
174
+ />
175
+ ```
176
+
177
+ ## Custom Colors
178
+
179
+ ```astro
180
+ ---
181
+ import { MuxPlayer } from '@mux/mux-player-astro';
182
+ ---
183
+
184
+ <MuxPlayer
185
+ playbackId="DS00Spx1CV902MCtPj5WknGlR102V5HFkDe"
186
+ primaryColor="#ff6b35"
187
+ secondaryColor="#ffffff"
188
+ accentColor="#0066cc"
189
+ />
190
+ ```
191
+
192
+ # Props
193
+
194
+ All props from the underlying `mux-player` web component are supported, including:
195
+
196
+ ## Core Props
197
+ - `playbackId` - Mux playback ID for the video
198
+ - `src` - Direct video URL (alternative to playbackId)
199
+ - `poster` - Poster image URL
200
+ - `audio` - Enable audio-only mode
201
+
202
+ ## Playback Props
203
+ - `autoplay` - Auto-start playback
204
+ - `muted` - Start muted
205
+ - `loop` - Loop the video
206
+ - `playsInline` - Play inline on mobile
207
+ - `currentTime` - Set initial playback position
208
+ - `playbackRate` - Playback speed (1.0 = normal)
209
+
210
+ ## Stream Props
211
+ - `streamType` - Type of stream ('on-demand', 'live', 'll-live')
212
+ - `targetLiveWindow` - Live stream window duration
213
+
214
+ ## Metadata Props
215
+ - `metadata` - Object with video_id, video_title, viewer_user_id
216
+ - `envKey` - Environment key for Mux Data
217
+ - `customDomain` - Custom domain for video delivery
218
+
219
+ ## UI Props
220
+ - `theme` - Player theme component
221
+ - `primaryColor` - Primary UI color
222
+ - `secondaryColor` - Secondary UI color
223
+ - `accentColor` - Accent UI color
224
+ - `proudlyDisplayMuxBadge` - Show Mux badge
225
+
226
+ ## Advanced Props
227
+ - `tokens` - Signed tokens for private videos
228
+ - `storyboardSrc` - Custom storyboard/thumbnail track
229
+ - `chapters` - Chapter markers
230
+ - `renditionOrder` - Quality selection ordering
231
+ - `maxResolution` - Maximum playback resolution
232
+ - `minResolution` - Minimum playback resolution
233
+
234
+ # Docs
235
+
236
+ Docs and guides live on [docs.mux.com](https://docs.mux.com/guides/video/mux-player?utm_source=github-mux-player).
237
+
238
+ API reference lives [on Github](../mux-player/REFERENCE.md).
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@mux/mux-player-astro",
3
+ "version": "0.0.1",
4
+ "description": "An open source Mux player for Astro that Just Works™",
5
+ "homepage": "https://mux.com/player",
6
+ "keywords": [
7
+ "video",
8
+ "mux",
9
+ "player",
10
+ "hls",
11
+ "astro",
12
+ "astro-component"
13
+ ],
14
+ "type": "module",
15
+ "files": [
16
+ "src"
17
+ ],
18
+ "exports": {
19
+ ".": "./src/index.ts",
20
+ "./ads": "./src/ads/index.ts"
21
+ },
22
+ "peerDependencies": {
23
+ "astro": "^4.0.0 || ^5.0.0"
24
+ },
25
+ "dependencies": {
26
+ "@mux/mux-player": "3.5.1",
27
+ "@mux/playback-core": "0.30.1"
28
+ },
29
+ "devDependencies": {
30
+ "astro": "^5.11.0",
31
+ "vite": "^6.0.0"
32
+ }
33
+ }
@@ -0,0 +1,13 @@
1
+ ---
2
+ import type { MuxPlayerProps } from './types';
3
+ import { getThemeObject, toNativeAttributes } from './utils';
4
+ type Props = MuxPlayerProps;
5
+ const { theme, ...props } = Astro.props;
6
+ const { component: Theme, name: themeName } = await getThemeObject(theme);
7
+ ---
8
+
9
+ <mux-player {...toNativeAttributes(props)} theme={themeName}><slot /></mux-player>
10
+ {Theme && <Theme />}
11
+ <script>
12
+ import '@mux/mux-player';
13
+ </script>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import type { MuxPlayerAdsProps } from '../types';
3
+ import { getThemeObject, toNativeAttributes } from '../utils';
4
+ type Props = MuxPlayerAdsProps;
5
+ const { theme, ...props } = Astro.props;
6
+ const { component: Theme, name: themeName } = await getThemeObject(theme);
7
+ ---
8
+
9
+ <mux-player {...toNativeAttributes(props)} theme={themeName}><slot /></mux-player>
10
+ {Theme && <Theme />}
11
+ <script>
12
+ import '@mux/mux-player/ads';
13
+ </script>
@@ -0,0 +1,3 @@
1
+ export { default as MuxPlayer } from './MuxPlayer.astro';
2
+ export type { default as MuxPlayerElement } from '@mux/mux-player';
3
+ export type { MuxVideoTheme } from '../types';
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { default as MuxPlayer } from './MuxPlayer.astro';
2
+ export type { default as MuxPlayerElement } from '@mux/mux-player';
3
+ export type { MuxVideoTheme } from './types';
@@ -0,0 +1,3 @@
1
+ <script>
2
+ import '@mux/mux-player/themes/classic';
3
+ </script>
@@ -0,0 +1,6 @@
1
+ import type { MuxVideoTheme } from '../../types';
2
+ import component from './classic.astro';
3
+ export default {
4
+ component,
5
+ name: 'classic',
6
+ } satisfies MuxVideoTheme;
@@ -0,0 +1,3 @@
1
+ <script>
2
+ import '@mux/mux-player/themes/gerwig';
3
+ </script>
@@ -0,0 +1,6 @@
1
+ import type { MuxVideoTheme } from '../../types';
2
+ import component from './gerwig.astro';
3
+ export default {
4
+ component,
5
+ name: 'gerwig',
6
+ } satisfies MuxVideoTheme;
@@ -0,0 +1,6 @@
1
+ import type { MuxVideoTheme } from '../../types';
2
+ import component from './microvideo.astro';
3
+ export default {
4
+ component,
5
+ name: 'microvideo',
6
+ } satisfies MuxVideoTheme;
@@ -0,0 +1,3 @@
1
+ <script>
2
+ import '@mux/mux-player/themes/microvideo';
3
+ </script>
@@ -0,0 +1,6 @@
1
+ import type { MuxVideoTheme } from '../../types';
2
+ import component from './minimal.astro';
3
+ export default {
4
+ component,
5
+ name: 'minimal',
6
+ } satisfies MuxVideoTheme;
@@ -0,0 +1,3 @@
1
+ <script>
2
+ import '@mux/mux-player/themes/minimal';
3
+ </script>
@@ -0,0 +1,6 @@
1
+ import type { MuxVideoTheme } from '../../types';
2
+ import component from './news.astro';
3
+ export default {
4
+ component,
5
+ name: 'news',
6
+ } satisfies MuxVideoTheme;
@@ -0,0 +1,3 @@
1
+ <script>
2
+ import '@mux/mux-player/themes/news';
3
+ </script>
package/src/types.ts ADDED
@@ -0,0 +1,95 @@
1
+ import type {
2
+ CmcdTypes,
3
+ MaxResolutionValue,
4
+ MinResolutionValue,
5
+ PlaybackTypes,
6
+ RenditionOrderValue,
7
+ StreamTypes,
8
+ } from '@mux/playback-core';
9
+ import type { Tokens } from '@mux/mux-player';
10
+ import type { AstroComponentFactory } from 'astro/runtime/server/index.js';
11
+
12
+ type ValueOf<T> = T[keyof T];
13
+
14
+ export type MuxVideoTheme = {
15
+ component?: AstroComponentFactory;
16
+ name?: string;
17
+ };
18
+
19
+ export type BuiltinTheme = 'classic' | 'gerwig' | 'microvideo' | 'minimal' | 'news';
20
+
21
+ export type MuxPlayerProps = {
22
+ theme?: MuxVideoTheme | BuiltinTheme | (string & {});
23
+ hotkeys?: string;
24
+ nohotkeys?: boolean;
25
+ castReceiver?: string | undefined;
26
+ castCustomData?: Record<string, any> | undefined;
27
+ defaultHiddenCaptions?: boolean;
28
+ playerSoftwareVersion?: string;
29
+ playerSoftwareName?: string;
30
+ playerInitTime?: number;
31
+ forwardSeekOffset?: number;
32
+ backwardSeekOffset?: number;
33
+ maxResolution?: MaxResolutionValue;
34
+ minResolution?: MinResolutionValue;
35
+ renditionOrder?: RenditionOrderValue;
36
+ programStartTime?: number;
37
+ programEndTime?: number;
38
+ proudlyDisplayMuxBadge?: boolean;
39
+ assetStartTime?: number;
40
+ assetEndTime?: number;
41
+ metadataVideoId?: string;
42
+ metadataVideoTitle?: string;
43
+ metadataViewerUserId?: string;
44
+ metadata?: {
45
+ video_id?: string;
46
+ video_title?: string;
47
+ viewer_user_id?: string;
48
+ };
49
+ primaryColor?: string;
50
+ secondaryColor?: string;
51
+ accentColor?: string;
52
+ placeholder?: string;
53
+ playbackRates?: number[];
54
+ defaultShowRemainingTime?: boolean;
55
+ defaultDuration?: number;
56
+ noVolumePref?: boolean;
57
+ thumbnailTime?: number;
58
+ title?: string;
59
+ videoTitle?: string;
60
+ tokens?: Tokens;
61
+ currentTime?: number;
62
+ volume?: number;
63
+ paused?: boolean;
64
+ src?: string | null;
65
+ poster?: string;
66
+ playbackRate?: number;
67
+ playsInline?: boolean;
68
+ preload?: string;
69
+ crossorigin?: string;
70
+ autoplay?: boolean | string;
71
+ loop?: boolean;
72
+ muted?: boolean;
73
+ audio?: boolean;
74
+ envKey?: string;
75
+ debug?: boolean;
76
+ disableTracking?: boolean;
77
+ disableCookies?: boolean;
78
+ disablePictureInPicture?: boolean;
79
+ extraSourceParams?: Record<string, any>;
80
+ beaconCollectionDomain?: string;
81
+ customDomain?: string;
82
+ playbackId?: string;
83
+ preferPlayback?: ValueOf<PlaybackTypes> | undefined;
84
+ streamType?: ValueOf<StreamTypes>;
85
+ defaultStreamType?: ValueOf<StreamTypes>;
86
+ targetLiveWindow?: number;
87
+ startTime?: number;
88
+ storyboardSrc?: string;
89
+ preferCmcd?: ValueOf<CmcdTypes> | undefined;
90
+ } & astroHTML.JSX.HTMLAttributes;
91
+
92
+ export type MuxPlayerAdsProps = MuxPlayerProps & {
93
+ allowAdBlocker?: boolean;
94
+ adTagUrl?: string;
95
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,68 @@
1
+ /// <reference types="vite/client" />
2
+ import type { MuxVideoTheme } from './types';
3
+
4
+ const toKebabCase = (string: string) =>
5
+ string.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`).replaceAll('_', '-');
6
+
7
+ const FLATTEN_PROPS = new Set(['metadata', 'tokens', 'castCustomData']);
8
+
9
+ export const themes = import.meta.glob<{ default: MuxVideoTheme }>('./themes/*/index.ts');
10
+
11
+ function stringifyValue(value: any): string {
12
+ if (Array.isArray(value)) {
13
+ return value.join(' ');
14
+ }
15
+ if (typeof value === 'object' && value !== null) {
16
+ return JSON.stringify(value);
17
+ }
18
+ if (value === true) {
19
+ return '';
20
+ }
21
+ return String(value);
22
+ }
23
+
24
+ export async function getThemeObject(theme: string | MuxVideoTheme | undefined): Promise<MuxVideoTheme> {
25
+ if (!theme) {
26
+ return {};
27
+ }
28
+ if (typeof theme !== 'string') {
29
+ return theme;
30
+ }
31
+ const themeModule = themes[`./themes/${theme}/index.ts`];
32
+ if (!themeModule) {
33
+ return {
34
+ name: theme,
35
+ };
36
+ }
37
+ return (await themeModule()).default;
38
+ }
39
+
40
+ export const toNativeAttributes = (props: { [key: string]: any } = {}): Record<string, string> => {
41
+ return Object.entries(props).reduce<Record<string, string>>((transformedProps, [propName, propValue]) => {
42
+ if (typeof propValue === 'undefined' || propValue === null || propValue === false) {
43
+ return transformedProps;
44
+ }
45
+ if (propName === 'style') {
46
+ transformedProps.style = propValue;
47
+ return transformedProps;
48
+ }
49
+
50
+ const attrName = toKebabCase(propName);
51
+
52
+ if (FLATTEN_PROPS.has(propName)) {
53
+ if (typeof propValue === 'object' && !Array.isArray(propValue)) {
54
+ Object.entries(propValue).forEach(([key, value]) => {
55
+ const kebabKey = toKebabCase(`${attrName}-${key}`);
56
+ if (typeof propValue !== 'undefined' && propValue !== null && !props.hasOwnProperty(kebabKey)) {
57
+ transformedProps[kebabKey] = stringifyValue(value);
58
+ }
59
+ });
60
+ }
61
+ } else {
62
+ const attrValue = stringifyValue(propValue);
63
+ transformedProps[attrName] = attrValue;
64
+ }
65
+
66
+ return transformedProps;
67
+ }, {});
68
+ };