@glomex/vast-ima-player
Version:
Convenience wrapper for advertising video/audio content with Google IMA
96 lines (80 loc) • 2.19 kB
text/typescript
/**
* Improved version of: https://developers.google.com/interactive-media-ads/docs/sdks/html5/ad-rules#known-issues-with-mobile-safari
*/
export class CustomPlayhead {
#mediaElement?: HTMLVideoElement;
#currentTime?: number;
#enabled: boolean;
seeking: boolean;
constructor(mediaElement: HTMLVideoElement) {
this.#mediaElement = mediaElement;
this.#currentTime = 0;
this.#enabled = false;
this.seeking = false;
this._onTimeupdate = this._onTimeupdate.bind(this);
this._onSeeking = this._onSeeking.bind(this);
this._onSeeked = this._onSeeked.bind(this);
this.enable();
}
private _onSeeking() {
this.seeking = true;
}
private _onSeeked() {
this.seeking = false;
}
private _onTimeupdate() {
if (!this.seeking && !this.#mediaElement?.paused) {
this.#currentTime = this.#mediaElement?.currentTime;
}
}
get enabled() {
return this.#enabled;
}
enable() {
if (this.#enabled) return;
this.#mediaElement?.addEventListener('seeking', this._onSeeking);
this.#mediaElement?.addEventListener('seeked', this._onSeeked);
this.#mediaElement?.addEventListener('timeupdate', this._onTimeupdate);
this.#enabled = true;
}
disable() {
if (!this.#enabled) return;
this.#mediaElement?.removeEventListener('seeking', this._onSeeking);
this.#mediaElement?.removeEventListener('seeked', this._onSeeked);
this.#mediaElement?.removeEventListener('timeupdate', this._onTimeupdate);
this.#enabled = false;
}
get currentTime() {
return this.#currentTime;
}
get duration() {
return this.#mediaElement?.duration;
}
get muted() {
return this.#mediaElement?.muted;
}
get volume() {
return this.#mediaElement?.volume;
}
play() {
return new Promise((resolve) => {
resolve(this.#mediaElement?.play());
});
}
pause() {
this.#mediaElement?.pause();
}
reset() {
this.#currentTime = 0;
this.#enabled = false;
this.seeking = false;
this.enable();
}
destroy() {
this.#currentTime = 0;
this.#enabled = false;
this.seeking = false;
this.disable();
this.#mediaElement = undefined;
}
}