@zezosoft/react-player 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,7 @@ A React video player by Zezosoft supporting HLS, MP4, DASH, preview thumbnails,
10
10
  - 💬 **Subtitles** — WebVTT with customizable styling
11
11
  - ⏭️ **Intro skip** — Skip intro button with configurable time range
12
12
  - 📺 **Episodes** — Next episode auto-play and playlist
13
- - 📢 **Ads** — Pre-roll, mid-roll, post-roll video ads
13
+ - 📢 **Ads** — Pre-roll, mid-roll, post-roll (custom MP4 + Google IMA)
14
14
  - 📚 **Watch history** — Resume playback, progress tracking
15
15
 
16
16
  ## 📦 Installation
@@ -105,8 +105,16 @@ The player accepts four props: `video` (required), `style`, `events`, and `featu
105
105
 
106
106
  ### Ads (`AdConfig`)
107
107
 
108
+ Custom MP4 ads and **Google IMA** (VAST/VMAP) can be used together. See **[docs/IMA_INTEGRATION.md](./docs/IMA_INTEGRATION.md)** for IMA setup, sample tags, and hybrid usage.
109
+
108
110
  ```typescript
109
111
  {
112
+ ima?: {
113
+ adTagUrl: string;
114
+ preRoll?: boolean;
115
+ postRoll?: boolean;
116
+ midRollCuePoints?: number[];
117
+ };
110
118
  preRoll?: AdBreak;
111
119
  midRoll?: AdBreak[];
112
120
  postRoll?: AdBreak;
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import { IPlayerConfig } from "../../types";
3
+ interface AdOverlayChromeProps {
4
+ config?: IPlayerConfig;
5
+ showControls: boolean;
6
+ progressPercent: number;
7
+ skipable?: boolean;
8
+ canSkipAd?: boolean;
9
+ skipCountdown?: number;
10
+ onSkip?: () => void;
11
+ sponsoredUrl?: string;
12
+ fadeClassName?: string;
13
+ }
14
+ declare const AdOverlayChrome: React.FC<AdOverlayChromeProps>;
15
+ export default AdOverlayChrome;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { AdBreak } from "../types/AdTypes";
3
+ import { IPlayerConfig } from "../../types";
4
+ interface ImaAdOverlayProps {
5
+ adBreak: AdBreak;
6
+ config?: IPlayerConfig;
7
+ }
8
+ declare const ImaAdOverlay: React.FC<ImaAdOverlayProps>;
9
+ export default ImaAdOverlay;
@@ -6,5 +6,6 @@ export { useIntroSkip } from "./useIntroSkip";
6
6
  export { useEpisodes } from "./useEpisodes";
7
7
  export { useVideoEvents } from "./useVideoEvents";
8
8
  export { useAdManager } from "./useAdManager";
9
+ export { useImaAds } from "./useImaAds";
9
10
  export { usePrimaryVideoLifecycle } from "./usePrimaryVideoLifecycle";
10
11
  export { useVideoError } from "./useVideoError";
@@ -1,8 +1,8 @@
1
- import { AdConfig, AdBreak, AdType } from "../types/AdTypes";
1
+ import { AdConfig, AdBreak } from "../types/AdTypes";
2
2
  export declare const useAdManager: (adConfig?: AdConfig) => {
3
3
  isAdPlaying: boolean;
4
4
  currentAd: AdBreak | null;
5
- adType: AdType | null;
5
+ adType: import("../..").AdType | null;
6
6
  skipAd: () => void;
7
7
  endAd: () => void;
8
8
  };
@@ -0,0 +1,8 @@
1
+ import { AdConfig } from "../types/AdTypes";
2
+ export declare const useImaAds: (adConfig?: AdConfig) => {
3
+ hasIma: boolean;
4
+ hasImaPreRoll: boolean;
5
+ imaPreRollNeedsGesture: boolean;
6
+ initializeIma: () => boolean;
7
+ startImaPreRoll: () => void;
8
+ };
@@ -0,0 +1,6 @@
1
+ export declare const useOverlayAutoHide: () => {
2
+ showControls: boolean;
3
+ onMouseEnter: () => void;
4
+ onMouseLeave: () => void;
5
+ onMouseMove: () => void;
6
+ };
@@ -1,6 +1,7 @@
1
1
  import { VideoState } from "../../store/types/StoreTypes";
2
2
  interface UsePrimaryVideoLifecycleParams {
3
3
  hasPreRoll: boolean;
4
+ hasImaPreRoll?: boolean;
4
5
  trackSrc: string;
5
6
  }
6
7
  interface PrimaryVideoLifecycleResult {
@@ -13,5 +14,5 @@ interface PrimaryVideoLifecycleResult {
13
14
  shouldCoverMainVideo: boolean;
14
15
  shouldShowPlaceholder: boolean;
15
16
  }
16
- export declare const usePrimaryVideoLifecycle: ({ hasPreRoll, trackSrc, }: UsePrimaryVideoLifecycleParams) => PrimaryVideoLifecycleResult;
17
+ export declare const usePrimaryVideoLifecycle: ({ hasPreRoll, hasImaPreRoll, trackSrc, }: UsePrimaryVideoLifecycleParams) => PrimaryVideoLifecycleResult;
17
18
  export {};
@@ -0,0 +1,2 @@
1
+ /** Appends a fresh correlator so each ad request is unique (required by many GAM tags). */
2
+ export declare const buildAdTagUrl: (adTagUrl: string) => string;
@@ -0,0 +1,5 @@
1
+ import { AdBreak, AdType } from "../types/AdTypes";
2
+ /**
3
+ * Synthetic ad break used for IMA callbacks and UI state (no direct MP4 URL).
4
+ */
5
+ export declare const createImaAdBreak: (type: AdType, id?: string) => AdBreak;
@@ -0,0 +1 @@
1
+ export declare const createImaRenderingSettings: () => google.ima.AdsRenderingSettings;
@@ -0,0 +1,4 @@
1
+ export declare const getImaSlotDimensions: (video: HTMLVideoElement, wrapper: HTMLDivElement | null) => {
2
+ width: number;
3
+ height: number;
4
+ };
@@ -0,0 +1,3 @@
1
+ import { ImaConfig } from "../types/AdTypes";
2
+ /** Detect VMAP / ad-rule tags that require a single persistent IMA session. */
3
+ export declare const isVmapAdTag: (adTagUrl: string, imaConfig?: Pick<ImaConfig, "adTagFormat">) => boolean;
@@ -0,0 +1,10 @@
1
+ export declare const IMA_SDK_URL = "https://imasdk.googleapis.com/js/sdkloader/ima3.js";
2
+ export declare const isImaSdkLoaded: () => boolean;
3
+ /**
4
+ * Loads the Google IMA HTML5 SDK once per URL per page.
5
+ */
6
+ export declare const loadImaSdk: (sdkUrl?: string) => Promise<void>;
7
+ /**
8
+ * Fire-and-forget IMA SDK preload. Safe to call before the player mounts.
9
+ */
10
+ export declare const preloadImaSdk: (sdkUrl?: string) => void;
@@ -0,0 +1,3 @@
1
+ export declare const suppressImaUi: (roots: HTMLElement[]) => void;
2
+ export declare const getImaUiRoots: (container: HTMLElement | null, wrapper: HTMLElement | null) => HTMLElement[];
3
+ export declare const watchImaUi: (roots: HTMLElement[]) => (() => void);
@@ -0,0 +1,5 @@
1
+ import type { VideoState } from "../../store/types/StoreTypes";
2
+ type ImaAdUiSetters = Pick<VideoState, "setAdCurrentTime" | "setCanSkipAd" | "setSkipCountdown" | "setImaSkipEnabled">;
3
+ /** Syncs ad progress + skip countdown from the active IMA AdsManager. */
4
+ export declare const syncImaAdUi: (manager: google.ima.AdsManager, currentAd: google.ima.Ad | null, adDurationSeconds: number, setters: ImaAdUiSetters) => void;
5
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare const findNativeSkip: (root: ParentNode) => HTMLElement | null;
2
+ /** Clears hide styles so IMA's skip handler receives a real activation. */
3
+ export declare const activateNativeSkip: (element: HTMLElement) => void;
4
+ export type ImaSkipResult = "native" | "api" | "stop" | "failed";
5
+ /** Skips the current ad when skippable. */
6
+ export declare const triggerImaSkip: (manager: google.ima.AdsManager | null, roots: HTMLElement[]) => ImaSkipResult;
@@ -1,15 +1,50 @@
1
1
  export type AdType = "pre-roll" | "mid-roll" | "post-roll" | "overlay";
2
+ /** How the ad break is rendered: direct MP4 (`custom`) or Google IMA (`ima`). */
3
+ export type AdProvider = "custom" | "ima";
4
+ export interface ImaConfig {
5
+ /** VAST/VMAP ad tag URL from Google Ad Manager or compatible ad server. */
6
+ adTagUrl: string;
7
+ /**
8
+ * Tag format. Auto-detected from URL when omitted (`output=vmap` or `ad_rule=1` → VMAP).
9
+ * VMAP uses one IMA session for pre/mid/post breaks; VAST requests ads per break.
10
+ */
11
+ adTagFormat?: "vmap" | "vast";
12
+ /**
13
+ * Request a pre-roll from the ad tag when content is ready.
14
+ * @default true
15
+ */
16
+ preRoll?: boolean;
17
+ /**
18
+ * Call `contentComplete()` when main content ends (enables post-roll in VMAP tags).
19
+ * @default true
20
+ */
21
+ postRoll?: boolean;
22
+ /**
23
+ * Content time offsets (seconds) for additional mid-roll ad requests.
24
+ * Use when your tag is not a full VMAP or you need explicit cue points.
25
+ */
26
+ midRollCuePoints?: number[];
27
+ /** Optional content metadata for ad targeting. */
28
+ contentTitle?: string;
29
+ contentDuration?: number;
30
+ /** Custom URL for the IMA SDK script (defaults to Google's CDN). */
31
+ sdkUrl?: string;
32
+ }
2
33
  export interface AdBreak {
3
34
  id: string;
4
35
  type: AdType;
5
36
  time: number;
37
+ /** Direct media URL for `custom` ads; empty for synthetic IMA breaks. */
6
38
  adUrl: string;
39
+ provider?: AdProvider;
7
40
  skipable?: boolean;
8
41
  skipAfter?: number;
9
42
  duration?: number;
10
43
  sponsoredUrl?: string;
11
44
  }
12
45
  export interface AdConfig {
46
+ /** Google IMA (VAST/VMAP). Works alongside custom MP4 `preRoll` / `midRoll` / `postRoll`. */
47
+ ima?: ImaConfig;
13
48
  preRoll?: AdBreak;
14
49
  midRoll?: AdBreak[];
15
50
  postRoll?: AdBreak;
@@ -31,3 +66,15 @@ export interface AdConfig {
31
66
  onAdSkip?: (adBreak: AdBreak) => void;
32
67
  onAdError?: (adBreak: AdBreak, error: Error) => void;
33
68
  }
69
+ /** Runtime API exposed by the IMA integration for player controls. */
70
+ export interface ImaPlaybackApi {
71
+ pause: () => void;
72
+ resume: () => void;
73
+ setVolume: (volume: number) => void;
74
+ getVolume: () => number;
75
+ /** Returns true if AdsManager.skip() was invoked. */
76
+ skip: () => boolean;
77
+ isSkippable: () => boolean;
78
+ getRemainingTime: () => number;
79
+ getDuration: () => number;
80
+ }
@@ -10,6 +10,7 @@ export declare const timeFormat: (seconds: number) => string;
10
10
  * @returns
11
11
  */
12
12
  export declare const secondsToMilliseconds: (seconds: number) => number;
13
+ export declare const getSeekableLiveEdge: (video: HTMLVideoElement) => number | null;
13
14
  /**
14
15
  * @description
15
16
  * @param url
@@ -5,6 +5,8 @@ interface PopoverProps {
5
5
  closeOnButtonClick?: boolean;
6
6
  className?: string;
7
7
  align?: "left" | "center" | "right";
8
+ onOpenChange?: (open: boolean) => void;
9
+ triggerAriaLabel?: string;
8
10
  }
9
11
  declare const Popover: React.FC<PopoverProps>;
10
12
  export default Popover;
package/dist/index.d.ts CHANGED
@@ -4,4 +4,5 @@ export { useVideoStore } from "./store/VideoState";
4
4
  export type { VideoPlayerProps, Episode, SubtitleTrack, IntroConfig, NextEpisodeConfig, WatchHistoryData, } from "./VideoPlayer/types/VideoPlayerTypes";
5
5
  export type { SubtitleStyleConfig } from "./VideoPlayer/hooks/useSubtitleStyling";
6
6
  export type { VideoQualityConfig, SeekBarConfig, PlayPauseButtonConfig, } from "./VideoPlayer/types/VideoPlayerTypes";
7
+ export type { AdConfig, AdBreak, AdType, AdProvider, ImaConfig, ImaPlaybackApi, } from "./VideoPlayer/types/AdTypes";
7
8
  export type { VideoState, VideoRefsState, VideoPlaybackState, VideoTimingState, VideoControlsState, VideoQualityState, SubtitlesState, EpisodesState, IntroState, } from "./store/types/StoreTypes";