diff --git a/examples/nextjs-with-typescript/pages/MuxPlayer.tsx b/examples/nextjs-with-typescript/pages/MuxPlayer.tsx index 9fa9879b..769ac0ce 100644 --- a/examples/nextjs-with-typescript/pages/MuxPlayer.tsx +++ b/examples/nextjs-with-typescript/pages/MuxPlayer.tsx @@ -1,10 +1,11 @@ import Head from 'next/head'; import MuxPlayer, { MuxPlayerProps, MaxResolution, MinResolution, RenditionOrder } from '@mux/mux-player-react'; +import type MuxPlayerElement from '@mux/mux-player'; import '@mux/mux-player/themes/classic'; import '@mux/mux-player/themes/minimal'; import '@mux/mux-player/themes/microvideo'; import '@mux/mux-player/themes/gerwig'; -import { useReducer, useState } from 'react'; +import { useReducer, useRef, useState } from 'react'; import mediaAssetsJSON from '@mux/assets/media-assets.json'; import type { NextParsedUrlQuery } from 'next/dist/server/request-meta'; import { @@ -250,7 +251,8 @@ export const getServerSideProps = getLocationServerSideProps; type Props = LocationProps; function MuxPlayerPage({ location }: Props) { - // const mediaElRef = useRef(null); + const mediaElRef = useRef(null); + const [playerSoftwareInfo, setPlayerSoftwareInfo] = useState<{ name?: string; version?: string }>({}); const [mediaAssets, _setMediaAssets] = useState(mediaAssetsJSON); const [selectedAsset, setSelectedAsset] = useState(undefined); /** @TODO fix typing complexities here (CJP) */ @@ -262,15 +264,22 @@ function MuxPlayerPage({ location }: Props) { const [stylesState, dispatchStyles] = useReducer(reducer, DEFAULT_INITIAL_STYLES_STATE); const genericOnStyleChange = (obj) => dispatchStyles(updateProps(obj)); + console.log('playerSoftwareInfo', playerSoftwareInfo); + return ( <> <MuxPlayer/> Demo
+ {(playerSoftwareInfo.name || playerSoftwareInfo.version) && ( +
+ {playerSoftwareInfo.name ?? 'N/A'}@{playerSoftwareInfo.version ?? 'N/A'} +
+ )}
console.log("ready!")} preferCmcd={state.preferCmcd} preferPlayback={state.preferPlayback} debug={state.debug} @@ -338,6 +346,10 @@ function MuxPlayerPage({ location }: Props) { proudlyDisplayMuxBadge={state.proudlyDisplayMuxBadge} onPlay={(evt: Event) => { onPlay(evt); + setPlayerSoftwareInfo({ + name: mediaElRef.current?.playerSoftwareName, + version: mediaElRef.current?.playerSoftwareVersion, + }); // dispatch(updateProps({ paused: false })); }} onPause={(evt: Event) => { diff --git a/examples/nextjs-with-typescript/pages/api/storyboard-proxy.ts b/examples/nextjs-with-typescript/pages/api/storyboard-proxy.ts new file mode 100644 index 00000000..dfea3651 --- /dev/null +++ b/examples/nextjs-with-typescript/pages/api/storyboard-proxy.ts @@ -0,0 +1,27 @@ +import type { NextApiRequest, NextApiResponse } from 'next'; + +export default async function handler(req: NextApiRequest, res: NextApiResponse) { + const { url, delay } = req.query; + + if (!url || typeof url !== 'string') { + return res.status(400).json({ error: 'Missing required "url" query parameter' }); + } + + const delayMs = parseInt(typeof delay === 'string' ? delay : '0', 10) || 0; + + if (delayMs > 0) { + await new Promise((resolve) => setTimeout(resolve, delayMs)); + } + + const upstream = await fetch(url); + + if (!upstream.ok) { + return res.status(upstream.status).json({ error: `Upstream error: ${upstream.statusText}` }); + } + + const body = await upstream.text(); + + res.setHeader('Content-Type', upstream.headers.get('content-type') ?? 'text/vtt'); + res.setHeader('Cache-Control', 'no-store'); + res.status(200).send(body); +}