Skip to main content

Hooks

React hooks provided by @elcto/player for advanced video control.

useVideoPosition

Manage saved video playback positions for resume functionality.

import { useVideoPosition } from "@elcto/player/hooks";

function VideoPage() {
const { position, clearPosition, savePosition, isEnabled } = useVideoPosition("video-123");

if (!isEnabled) {
// User hasn't consented to functional cookies
return <p>Enable functional cookies to resume playback</p>;
}

return (
<div>
{position && <p>Resume from {Math.floor(position.time)}s</p>}
<button onClick={clearPosition}>Clear saved position</button>
</div>
);
}

Parameters

ParameterTypeDescription
videoIdstringUnique identifier for the video

Returns

PropertyTypeDescription
positionStoredPosition | nullSaved position data
savePosition(time: number, duration: number) => voidSave current position
clearPosition() => voidClear saved position
isEnabledbooleanWhether storage is allowed (functional cookies consented)

StoredPosition Type

interface StoredPosition {
time: number; // Saved position in seconds
duration: number; // Total video duration
updatedAt: number; // Timestamp when saved
}

Storage Details

  • Key Format: elcto-player:${videoId}
  • Storage: localStorage
  • Expiry: Positions older than 30 days are automatically cleared
  • Consent: Requires functional cookie category consent via @elcto/cookies-consent

The hook automatically checks if the user has consented to functional cookies:

import { useVideoPosition } from "@elcto/player/hooks";
import { useCookieStatus } from "@elcto/cookies-consent";

function VideoWithConsent() {
const { isEnabled } = useVideoPosition("my-video");
const { openPreferences } = useCookieStatus();

if (!isEnabled) {
return (
<div>
<p>Resume playback requires functional cookies.</p>
<button onClick={openPreferences}>Update preferences</button>
</div>
);
}

return <VideoPlayer src={videoUrl} videoId="my-video" rememberPosition />;
}

Manual Position Control

For custom player implementations:

function CustomPlayer({ videoId, videoRef }) {
const { position, savePosition, clearPosition } = useVideoPosition(videoId);

// Restore position on load
useEffect(() => {
if (position && videoRef.current) {
videoRef.current.currentTime = position.time;
}
}, [position]);

// Save position periodically
useEffect(() => {
const interval = setInterval(() => {
if (videoRef.current) {
savePosition(
videoRef.current.currentTime,
videoRef.current.duration
);
}
}, 5000);

return () => clearInterval(interval);
}, [savePosition]);

// Clear when video ends
const handleEnded = () => {
clearPosition();
};

return <video ref={videoRef} onEnded={handleEnded} />;
}