Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow triggering of events after a stream has reached the end #217

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ Does not support native HTML5 MSE controls (`<video controls>`). It works, but e

Does not support re-using the same video element.

Does not support restarting the video after end of stream has been reached.

## Usage

`npm install @eyevinn/media-event-filter`
Expand Down Expand Up @@ -316,6 +314,12 @@ A timeupdate event

Can not trigger before loaded.

### ended

The player has reached the end of a stream.

To allow restarting the stream after the end of stream has been reached set `allowResumeAfterEnded` to `true`.

## Contributing

Contributions to improve compatibility with or add support for different engines, tracking solutions, and browsers are welcome.
Expand Down
11 changes: 10 additions & 1 deletion src/media-event-filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type TFilteredMediaEventCallback = (event: FilteredMediaEvent) => void;
type TMediaEventFilterOptions = {
videoElement: HTMLVideoElement;
callback: TFilteredMediaEventCallback;
allowResumeAfterEnded?: boolean;
};

type TCallback = () => void;
Expand Down Expand Up @@ -101,6 +102,7 @@ export type TMediaEventFilter = {
export const getMediaEventFilter = ({
videoElement,
callback,
allowResumeAfterEnded = false,
}: TMediaEventFilterOptions): TMediaEventFilter => {
let ratechangeBufferTimeout: number | null = null;

Expand All @@ -114,7 +116,8 @@ export const getMediaEventFilter = ({
...initialState,
};

const isNotReady = (): boolean => state.loading || state.ended;
const isNotReady = (): boolean =>
allowResumeAfterEnded ? state.loading : state.loading || state.ended;

const onCanPlayThrough = (): void => {
if (!state.loading) {
Expand Down Expand Up @@ -153,6 +156,12 @@ export const getMediaEventFilter = ({
// playback should be ready before reacting to "seeking" event (e.g. shaka jumps)
if (isNotReady()) return;

// If stream has reached the end and an onSeeking has been triggered we want to set the ended state to false
// This can only happen if allowResumeAfterEnded is set to true (otherwise isNotReady is true)
if (state.ended) {
state.ended = false;
}

// end ongoing buffering, this enables trackers to report
// the buffer duration before starting the seek.
if (state.buffering) callback(FilteredMediaEvent.BUFFERED);
Expand Down