Skip to content

Commit

Permalink
fix: start-time for live streams
Browse files Browse the repository at this point in the history
  • Loading branch information
luwes committed Dec 13, 2023
1 parent c30b7d5 commit 4f6435f
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 57 deletions.
3 changes: 2 additions & 1 deletion packages/mux-player/src/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ export const content = (props: MuxTemplateProps) => html`
defaultstreamtype="${props.defaultStreamType ?? false}"
hotkeys="${getHotKeys(props) || false}"
nohotkeys="${props.noHotKeys || !props.hasSrc || props.isDialogOpen || false}"
noautoseektolive="${!!props.streamType?.includes(StreamTypes.LIVE) && props.targetLiveWindow !== 0}"
noautoseektolive="${props.startTime != null ||
(!!props.streamType?.includes(StreamTypes.LIVE) && props.targetLiveWindow !== 0)}"
novolumepref="${props.novolumepref || false}"
disabled="${!props.hasSrc || props.isDialogOpen}"
audio="${props.audio ?? false}"
Expand Down
53 changes: 1 addition & 52 deletions packages/playback-core/src/autoplay.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { addEventListenerWithTeardown } from './util';
import { ValueOf, Autoplay, AutoplayTypes, PlaybackEngine } from './types';

Check warning on line 2 in packages/playback-core/src/autoplay.ts

View workflow job for this annotation

GitHub Actions / lint

'PlaybackEngine' is defined but never used
import Hls from './hls';

const AutoplayTypeValues = Object.values(AutoplayTypes);
export const isAutoplayValue = (value: unknown): value is Autoplay => {
Expand All @@ -16,13 +15,8 @@ export const isAutoplayValue = (value: unknown): value is Autoplay => {
// It works with both the native video element or hls.js.
// This returns a method UpdateAutoplay, that allows the user to change
// the value of the autoplay attribute and it will react appropriately.
export const setupAutoplay = (
{ autoplay: maybeAutoplay }: { autoplay?: Autoplay },
mediaEl: HTMLMediaElement,
hls?: PlaybackEngine
) => {
export const setupAutoplay = ({ autoplay: maybeAutoplay }: { autoplay?: Autoplay }, mediaEl: HTMLMediaElement) => {
let hasPlayed = false;
let isLive = false;
let autoplay: Autoplay = isAutoplayValue(maybeAutoplay) ? maybeAutoplay : !!maybeAutoplay;

const updateHasPlayed = () => {
Expand Down Expand Up @@ -61,56 +55,11 @@ export const setupAutoplay = (
mediaEl,
'loadstart',
() => {
// only update isLive here if we're using native playback
if (!hls) {
isLive = !Number.isFinite(mediaEl.duration);
}
handleAutoplay(mediaEl, autoplay);
},
{ once: true }
);

// determine if we're live for hls.js
if (hls) {
hls.once(Hls.Events.LEVEL_LOADED, (e: any, data: any) => {
isLive = data.details.live ?? false;
});
}

// When we are not auto-playing, we should seek to the live sync position
// This will seek first play event of *any* live video including event-type,
// which probably shouldn't seek
if (!autoplay) {
const handleSeek = () => {
// don't seek if we're not live
if (!isLive) {
return;
}
// seek to either hls.js's liveSyncPosition or the native seekable end
if (hls?.liveSyncPosition) {
mediaEl.currentTime = hls.liveSyncPosition;
} else {
if (Number.isFinite(mediaEl.seekable.end(0))) {
mediaEl.currentTime = mediaEl.seekable.end(0);
}
}
};
if (hls) {
addEventListenerWithTeardown(
mediaEl,
'play',
() => {
if (mediaEl.preload === 'metadata') {
hls.once(Hls.Events.LEVEL_UPDATED, handleSeek);
} else {
handleSeek();
}
},
{ once: true }
);
}
}

// this method allows us to update the value of autoplay
// and try autoplaying appropriately.
const updateAutoplay = (newAutoplay?: Autoplay) => {
Expand Down
17 changes: 13 additions & 4 deletions packages/playback-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export const initialize = (props: Partial<MuxMediaPropsInternal>, mediaEl: HTMLM
setupMux(props, mediaEl, nextHlsInstance);
loadMedia(props, mediaEl, nextHlsInstance);
setupCuePoints(mediaEl);
const setAutoplay = setupAutoplay(props as Pick<MuxMediaProps, 'autoplay'>, mediaEl, nextHlsInstance);
const setAutoplay = setupAutoplay(props as Pick<MuxMediaProps, 'autoplay'>, mediaEl);
const setPreload = setupPreload(props as Pick<MuxMediaProps, 'preload' | 'src'>, mediaEl, nextHlsInstance);

return {
Expand Down Expand Up @@ -614,8 +614,10 @@ export const loadMedia = (
) => {
const shouldUseNative = useNative(props, mediaEl);
const { src } = props;

if (mediaEl && shouldUseNative) {
const type = getType(props);

if (typeof src === 'string') {
if (mediaEl.preload === 'none') {
addEventListenerWithTeardown(mediaEl, 'loadstart', () => updateStreamInfoFromSrc(src, mediaEl, type));
Expand All @@ -624,7 +626,8 @@ export const loadMedia = (
}

mediaEl.setAttribute('src', src);
if (props.startTime) {

if (props.startTime != null) {
(muxMediaState.get(mediaEl) ?? {}).startTime = props.startTime;
// seekable is set to the range of the entire video once durationchange fires
mediaEl.addEventListener('durationchange', seekInSeekableRange, { once: true });
Expand Down Expand Up @@ -722,8 +725,8 @@ export const loadMedia = (

function seekInSeekableRange(event: Event) {
const mediaEl = event.target as HTMLMediaElement;
const startTime = muxMediaState.get(mediaEl)?.startTime;
if (!startTime) return;
let startTime = muxMediaState.get(mediaEl)?.startTime;
if (startTime == null) return;

Check warning on line 729 in packages/playback-core/src/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback-core/src/index.ts#L728-L729

Added lines #L728 - L729 were not covered by tests

if (inSeekableRange(mediaEl.seekable, mediaEl.duration, startTime)) {
// Setting preload to `none` from `auto` was required on iOS to fix a bug
Expand All @@ -733,6 +736,12 @@ function seekInSeekableRange(event: Event) {
mediaEl.preload = 'none';
}

// If live and startTime is 0 we need to increase it by a small amount
// otherwise native HLS will still jump to the live edge.
if (mediaEl.duration === Infinity && startTime == 0) {
startTime += 0.001;
}

Check warning on line 744 in packages/playback-core/src/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/playback-core/src/index.ts#L739-L744

Added lines #L739 - L744 were not covered by tests
mediaEl.currentTime = startTime;

if (wasAuto) {
Expand Down

0 comments on commit 4f6435f

Please sign in to comment.