Skip to content

Commit

Permalink
fix: Adding unofficial _hlsConfig to media elements and playback core. (
Browse files Browse the repository at this point in the history
#833)

🤫 seeeecret config.
fixes #792
  • Loading branch information
cjpillsbury authored Nov 30, 2023
1 parent a5ad6ed commit b86f6e6
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 5 deletions.
5 changes: 5 additions & 0 deletions examples/nextjs-with-typescript/pages/MuxPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ function MuxPlayerPage({ location }: Props) {
theme={state.theme}
envKey={state.envKey}
metadata={state.metadata}
// Test _hlsConfig for MuxPlayer (react) (Note: This also indirectly tests <mux-player> & <mux-video>)
// _hlsConfig={{
// startLevel: 2,
// debug: true,
// }}
title={state.title}
startTime={state.startTime}
currentTime={state.currentTime}
Expand Down
5 changes: 5 additions & 0 deletions examples/nextjs-with-typescript/pages/MuxVideo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ function MuxVideoPage() {
<MuxVideo
ref={mediaElRef}
playbackId="23s11nz72DsoN657h4314PjKKjsF2JG33eBQQt6B95I"
// Test _hlsConfig for MuxVideo (react)
// _hlsConfig={{
// startLevel: 1,
// debug: true,
// }}
// metadata={{
// video_id: "video-id-12345",
// video_title: "Mad Max: Fury Road Trailer",
Expand Down
3 changes: 2 additions & 1 deletion packages/mux-audio-react/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const playerSoftwareVersion = getPlayerVersion();
const playerSoftwareName = 'mux-audio-react';

const MuxAudio = React.forwardRef<HTMLAudioElement | undefined, Partial<Props>>((props, ref) => {
const { playbackId, src: outerSrc, children, autoPlay, preload, ...restProps } = props;
const { playbackId, src: outerSrc, children, autoPlay, preload, _hlsConfig, ...restProps } = props;

const [playerInitTime] = useState(generatePlayerInitTime());
const [src, setSrc] = useState<MuxMediaProps['src']>(toMuxVideoURL(props) ?? outerSrc);
Expand Down Expand Up @@ -82,6 +82,7 @@ MuxAudio.propTypes = {
// Improve this by adding a full shape() definition for all metadata props
// metadata: PropTypes.shape({}),
metadata: PropTypes.any,
_hlsConfig: PropTypes.any,
beaconCollectionDomain: PropTypes.string,
playbackId: PropTypes.string,
playerInitTime: PropTypes.number,
Expand Down
10 changes: 10 additions & 0 deletions packages/mux-audio/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { PlaybackCore, PlaybackEngine, ExtensionMimeTypeMap } from '@mux/pl
import { getPlayerVersion } from './env';
// this must be imported after playback-core for the polyfill to be included
import { CustomAudioElement, Events as AudioEvents } from 'custom-media-element';
import { HlsConfig } from 'hls.js';

/** @TODO make the relationship between name+value smarter and more deriveable (CJP) */
type AttributeNames = {
Expand Down Expand Up @@ -60,6 +61,7 @@ class MuxAudioElement extends CustomAudioElement implements Partial<MuxMediaProp
#loadRequested?: Promise<void> | null;
#playerInitTime: number;
#metadata: Readonly<Metadata> = {};
#_hlsConfig?: Partial<HlsConfig>;

constructor() {
super();
Expand Down Expand Up @@ -294,6 +296,14 @@ class MuxAudioElement extends CustomAudioElement implements Partial<MuxMediaProp
}
}

get _hlsConfig() {
return this.#_hlsConfig;
}

set _hlsConfig(val: Readonly<Partial<HlsConfig>> | undefined) {
this.#_hlsConfig = val;
}

async #requestLoad() {
if (this.#loadRequested) return;
await (this.#loadRequested = Promise.resolve());
Expand Down
3 changes: 3 additions & 0 deletions packages/mux-player-react/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type MuxMediaPropTypes = {
// metadata: Partial<Options["data"]>;
metadata: { [k: string]: any };
extraSourceParams: Record<string, any>;
_hlsConfig: MuxPlayerElement['_hlsConfig'];
beaconCollectionDomain: string;
customDomain: string;
playbackId: string;
Expand Down Expand Up @@ -182,11 +183,13 @@ const usePlayer = (
currentTime,
themeProps,
extraSourceParams,
_hlsConfig,
...remainingProps
} = props;
useObjectPropEffect('playbackRates', playbackRates, ref);
useObjectPropEffect('metadata', metadata, ref);
useObjectPropEffect('extraSourceParams', extraSourceParams, ref);
useObjectPropEffect('_hlsConfig', _hlsConfig, ref);
useObjectPropEffect('themeProps', themeProps, ref);
useObjectPropEffect('tokens', tokens, ref);
useObjectPropEffect('playbackId', playbackId, ref);
Expand Down
23 changes: 23 additions & 0 deletions packages/mux-player/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { toNumberOrUndefined, i18n, parseJwt, containsComposedNode, camelCase, k
import * as logger from './logger';
import type { MuxTemplateProps, ErrorEvent } from './types';
import './themes/gerwig';
import { HlsConfig } from 'hls.js';
const DefaultThemeName = 'gerwig';

export { MediaError };
Expand Down Expand Up @@ -531,6 +532,7 @@ class MuxPlayerElement extends VideoApiElement implements MuxPlayerElement {
// - cues that are not at the bottom
// - line is less than -5
// - line is between 0 and 10
// @ts-ignore
if (!cue.snapToLines || cue.line < -5 || (cue.line >= 0 && cue.line < 10)) {
return;
}
Expand Down Expand Up @@ -1441,6 +1443,27 @@ class MuxPlayerElement extends VideoApiElement implements MuxPlayerElement {
this.media.metadata = { ...getMetadataFromAttrs(this), ...val };
}

/**
* Get the metadata object for Mux Data.
*/
get _hlsConfig() {
return this.media?._hlsConfig;
}

/**
* Set the metadata object for Mux Data.
*/
set _hlsConfig(val: Readonly<Partial<HlsConfig>> | undefined) {
this.#init();

// NOTE: This condition should never be met. If it is, there is a bug (CJP)
if (!this.media) {
logger.error('underlying media element missing when trying to set _hlsConfig. _hlsConfig will not be set.');
return;
}
this.media._hlsConfig = val;
}

async addCuePoints<T = any>(cuePoints: { time: number; value: T }[]) {
this.#init();

Expand Down
3 changes: 2 additions & 1 deletion packages/mux-video-react/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const playerSoftwareVersion = getPlayerVersion();
const playerSoftwareName = 'mux-video-react';

const MuxVideo = React.forwardRef<HTMLVideoElement | undefined, Partial<Props>>((props, ref) => {
const { playbackId, src: outerSrc, children, autoPlay, preload, streamType, ...restProps } = props;
const { playbackId, src: outerSrc, children, autoPlay, preload, streamType, _hlsConfig, ...restProps } = props;

const [playerInitTime] = useState(generatePlayerInitTime());
const [src, setSrc] = useState<MuxMediaProps['src']>(toMuxVideoURL(props) ?? outerSrc);
Expand Down Expand Up @@ -82,6 +82,7 @@ MuxVideo.propTypes = {
// Improve this by adding a full shape() definition for all metadata props
// metadata: PropTypes.shape({}),
metadata: PropTypes.any,
_hlsConfig: PropTypes.any,
beaconCollectionDomain: PropTypes.string,
playbackId: PropTypes.string,
playerInitTime: PropTypes.number,
Expand Down
10 changes: 10 additions & 0 deletions packages/mux-video/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { getPlayerVersion } from './env';
import 'castable-video';
import { CustomMediaMixin, Events as VideoEvents } from 'custom-media-element';
import { MediaTracksMixin } from 'media-tracks';
import type { HlsConfig } from 'hls.js';

// Must mutate so the added events are available in custom-media-element.
VideoEvents.push('castchange', 'entercast', 'leavecast');
Expand Down Expand Up @@ -86,6 +87,7 @@ class MuxVideoElement extends CustomVideoElement implements Partial<MuxMediaProp
#loadRequested?: Promise<void> | null;
#playerInitTime: number;
#metadata: Readonly<Metadata> = {};
#_hlsConfig?: Partial<HlsConfig>;
#playerSoftwareVersion?: string;
#playerSoftwareName?: string;
#errorTranslator?: (errorEvent: any) => any;
Expand Down Expand Up @@ -514,6 +516,14 @@ class MuxVideoElement extends CustomVideoElement implements Partial<MuxMediaProp
}
}

get _hlsConfig() {
return this.#_hlsConfig;
}

set _hlsConfig(val: Readonly<Partial<HlsConfig>> | undefined) {
this.#_hlsConfig = val;
}

async #requestLoad() {
if (this.#loadRequested) return;
await (this.#loadRequested = Promise.resolve());
Expand Down
8 changes: 6 additions & 2 deletions packages/playback-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,11 +424,14 @@ function useNative(

export const setupHls = (
props: Partial<
Pick<MuxMediaPropsInternal, 'debug' | 'streamType' | 'type' | 'startTime' | 'metadata' | 'preferCmcd'>
Pick<
MuxMediaPropsInternal,
'debug' | 'streamType' | 'type' | 'startTime' | 'metadata' | 'preferCmcd' | '_hlsConfig'
>
>,
mediaEl: Pick<HTMLMediaElement, 'canPlayType'>
) => {
const { debug, streamType, startTime: startPosition = -1, metadata, preferCmcd } = props;
const { debug, streamType, startTime: startPosition = -1, metadata, preferCmcd, _hlsConfig = {} } = props;
const type = getType(props);
const hlsType = type === ExtensionMimeTypeMap.M3U8;
const shouldUseNative = useNative(props, mediaEl);
Expand Down Expand Up @@ -471,6 +474,7 @@ export const setupHls = (
},
...defaultConfig,
...streamTypeConfig,
..._hlsConfig,
}) as HlsInterface;

return hls;
Expand Down
4 changes: 3 additions & 1 deletion packages/playback-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
/// <reference path="../dist/types/mux-embed.d.ts" />
import type { Options } from 'mux-embed';
import type { MediaError } from './errors';
import type { HlsInterface as Hls } from './hls';
import type { VideoTrack, AudioTrack, VideoTrackList, AudioTrackList } from 'media-tracks';
import type { HlsConfig } from 'hls.js';
import type Hls from 'hls.js';

type KeyTypes = string | number | symbol;
type Maybe<T> = T | null | undefined;
Expand Down Expand Up @@ -174,6 +175,7 @@ export type MuxMediaPropTypes = {
autoplay?: Autoplay;
preferCmcd: ValueOf<CmcdTypes> | undefined;
error?: HTMLMediaElement['error'] | MediaError;
_hlsConfig?: Partial<HlsConfig>;
};

export interface MediaTracks {
Expand Down

5 comments on commit b86f6e6

@vercel
Copy link

@vercel vercel bot commented on b86f6e6 Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

elements-demo-vue – ./examples/vue-with-typescript

elements-demo-vue-git-main-mux.vercel.app
elements-demo-vue.vercel.app
elements-demo-vue-mux.vercel.app

@vercel
Copy link

@vercel vercel bot commented on b86f6e6 Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

elements-demo-nextjs – ./examples/nextjs-with-typescript

elements-demo-nextjs-mux.vercel.app
elements-demo-nextjs-git-main-mux.vercel.app
elements-demo-nextjs.vercel.app

@vercel
Copy link

@vercel vercel bot commented on b86f6e6 Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

elements-demo-svelte-kit – ./examples/svelte-kit

elements-demo-svelte-kit.vercel.app
elements-demo-svelte-kit-git-main-mux.vercel.app
elements-demo-svelte-kit-mux.vercel.app

@vercel
Copy link

@vercel vercel bot commented on b86f6e6 Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

elements-demo-create-react-app – ./examples/create-react-app-with-typescript

elements-demo-create-react-app-mux.vercel.app
elements-demo-create-react-app-git-main-mux.vercel.app
elements-demo-create-react-app.vercel.app

@vercel
Copy link

@vercel vercel bot commented on b86f6e6 Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

elements-demo-vanilla – ./examples/vanilla-ts-esm

elements-demo-vanilla-mux.vercel.app
elements-demo-vanilla-git-main-mux.vercel.app
elements-demo-vanilla.vercel.app

Please sign in to comment.