implement video seek feature (#593)

* implement video seek feature

* rm attribute from MediaInteractions

* resolve ts warning

* use getEventTarget
This commit is contained in:
bachmanity1
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 2e0d981190
commit 6de0efa01f
4 changed files with 21 additions and 11 deletions

View File

@@ -482,17 +482,22 @@ function initMediaInteractionObserver(
blockClass: blockClass, blockClass: blockClass,
mirror: Mirror, mirror: Mirror,
): listenerHandler { ): listenerHandler {
const handler = (type: 'play' | 'pause') => (event: Event) => { const handler = (type: MediaInteractions ) => (event: Event) => {
const target = getEventTarget(event); const target = getEventTarget(event);
if (!target || isBlocked(target as Node, blockClass)) { if (!target || isBlocked(target as Node, blockClass)) {
return; return;
} }
mediaInteractionCb({ mediaInteractionCb({
type: type === 'play' ? MediaInteractions.Play : MediaInteractions.Pause, type,
id: mirror.getId(target as INode), id: mirror.getId(target as INode),
currentTime: (target as HTMLMediaElement).currentTime
}); });
}; };
const handlers = [on('play', handler('play')), on('pause', handler('pause'))]; const handlers = [
on('play', handler(MediaInteractions.Play)),
on('pause', handler(MediaInteractions.Pause)),
on('seeked', handler(MediaInteractions.Seeked))
];
return () => { return () => {
handlers.forEach((h) => h()); handlers.forEach((h) => h());
}; };

View File

@@ -906,17 +906,18 @@ export class Replayer {
} }
const mediaEl = (target as Node) as HTMLMediaElement; const mediaEl = (target as Node) as HTMLMediaElement;
try { try {
if (d.currentTime) {
mediaEl.currentTime = d.currentTime;
}
if (d.type === MediaInteractions.Pause) { if (d.type === MediaInteractions.Pause) {
mediaEl.pause(); mediaEl.pause();
} }
if (d.type === MediaInteractions.Play) { if (d.type === MediaInteractions.Play) {
if (mediaEl.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) { // remove listener for 'canplay' event because play() is async and returns a promise
mediaEl.play(); // i.e. media will evntualy start to play when data is loaded
} else { // 'canplay' event fires even when currentTime attribute changes which may lead to
mediaEl.addEventListener('canplay', () => { // unexpeted behavior
mediaEl.play(); mediaEl.play();
});
}
} }
} catch (error) { } catch (error) {
if (this.config.showWarning) { if (this.config.showWarning) {

View File

@@ -474,11 +474,13 @@ export type inputCallback = (v: inputValue & { id: number }) => void;
export const enum MediaInteractions { export const enum MediaInteractions {
Play, Play,
Pause, Pause,
Seeked,
} }
export type mediaInteractionParam = { export type mediaInteractionParam = {
type: MediaInteractions; type: MediaInteractions;
id: number; id: number;
currentTime?: number
}; };
export type mediaInteractionCallback = (p: mediaInteractionParam) => void; export type mediaInteractionCallback = (p: mediaInteractionParam) => void;

4
typings/types.d.ts vendored
View File

@@ -334,11 +334,13 @@ export declare type inputCallback = (v: inputValue & {
}) => void; }) => void;
export declare const enum MediaInteractions { export declare const enum MediaInteractions {
Play = 0, Play = 0,
Pause = 1 Pause = 1,
Seeked = 2
} }
export declare type mediaInteractionParam = { export declare type mediaInteractionParam = {
type: MediaInteractions; type: MediaInteractions;
id: number; id: number;
currentTime?: number;
}; };
export declare type mediaInteractionCallback = (p: mediaInteractionParam) => void; export declare type mediaInteractionCallback = (p: mediaInteractionParam) => void;
export declare type DocumentDimension = { export declare type DocumentDimension = {