@amplitude/analytics-core 2.44.1 → 2.44.2-SR-3115.0

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.
@@ -0,0 +1,25 @@
1
+ import type { VideoEvent, MuxEmbeddedPlayer, MuxElement } from '../video-analytics/types';
2
+ type PlaybackState = 'playing' | 'paused' | 'ended' | 'error';
3
+ type Vendor = 'mux';
4
+ type State = {
5
+ playbackState: PlaybackState;
6
+ errorMessage?: string;
7
+ lastEvent?: VideoEvent;
8
+ };
9
+ type VideoObserverParams = {
10
+ videoEl: HTMLVideoElement | MuxEmbeddedPlayer | MuxElement;
11
+ onStateChange: (previousState: State, nextState: State) => void;
12
+ vendor?: Vendor;
13
+ isEmbedded?: boolean;
14
+ };
15
+ export declare class VideoObserver {
16
+ private state;
17
+ private untrack;
18
+ private onStateChange;
19
+ private handler;
20
+ constructor({ videoEl, onStateChange, vendor, isEmbedded }: VideoObserverParams);
21
+ private updateState;
22
+ destroy(): void;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=video.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../../src/observers/video.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAExG,KAAK,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,KAAK,MAAM,GAAG,KAAK,CAAC;AAEpB,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,UAAU,CAAC;IAC3D,aAAa,EAAE,CAAC,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,KAAK,IAAI,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAEX;IAEF,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,aAAa,CAAmD;IACxE,OAAO,CAAC,OAAO,CAab;gBAEU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,mBAAmB;IAU/E,OAAO,CAAC,WAAW;IAcnB,OAAO;CAGR"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VideoObserver = void 0;
4
+ var track_video_1 = require("../video-analytics/track-video");
5
+ var VideoObserver = /** @class */ (function () {
6
+ function VideoObserver(_a) {
7
+ var videoEl = _a.videoEl, onStateChange = _a.onStateChange, vendor = _a.vendor, isEmbedded = _a.isEmbedded;
8
+ var _this = this;
9
+ this.state = {
10
+ playbackState: 'paused',
11
+ };
12
+ this.handler = {
13
+ onPlay: function (evt) {
14
+ _this.updateState('playing', evt);
15
+ },
16
+ onPause: function (evt) {
17
+ _this.updateState('paused', evt);
18
+ },
19
+ onEnded: function (evt) {
20
+ _this.updateState('ended', evt);
21
+ },
22
+ onError: function () {
23
+ _this.updateState('error');
24
+ },
25
+ };
26
+ this.onStateChange = onStateChange;
27
+ if (isEmbedded) {
28
+ // TODO: support embedded iFrame video with no Vendor
29
+ this.untrack = (0, track_video_1.trackMuxEmbeddedVideo)(videoEl, this.handler);
30
+ }
31
+ else {
32
+ this.untrack = (0, track_video_1.trackHtmlVideo)(videoEl, this.handler, vendor);
33
+ }
34
+ }
35
+ VideoObserver.prototype.updateState = function (playbackState, event) {
36
+ var previousState = this.state;
37
+ var nextState = {
38
+ playbackState: playbackState,
39
+ lastEvent: event,
40
+ };
41
+ this.state = nextState;
42
+ try {
43
+ this.onStateChange(previousState, nextState);
44
+ }
45
+ catch (_error) {
46
+ // Swallow callback errors to keep observer state consistent.
47
+ }
48
+ };
49
+ VideoObserver.prototype.destroy = function () {
50
+ this.untrack();
51
+ };
52
+ return VideoObserver;
53
+ }());
54
+ exports.VideoObserver = VideoObserver;
55
+ //# sourceMappingURL=video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["../../../src/observers/video.ts"],"names":[],"mappings":";;;AAAA,8DAAuF;AAoBvF;IAsBE,uBAAY,EAAmE;YAAjE,OAAO,aAAA,EAAE,aAAa,mBAAA,EAAE,MAAM,YAAA,EAAE,UAAU,gBAAA;QAAxD,iBAQC;QA7BO,UAAK,GAAU;YACrB,aAAa,EAAE,QAAQ;SACxB,CAAC;QAIM,YAAO,GAAiB;YAC9B,MAAM,EAAE,UAAC,GAAe;gBACtB,KAAI,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,EAAE,UAAC,GAAe;gBACvB,KAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,EAAE,UAAC,GAAe;gBACvB,KAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,EAAE;gBACP,KAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC;SACF,CAAC;QAGA,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,UAAU,EAAE;YACd,qDAAqD;YACrD,IAAI,CAAC,OAAO,GAAG,IAAA,mCAAqB,EAAC,OAA4B,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;SAClF;aAAM;YACL,IAAI,CAAC,OAAO,GAAG,IAAA,4BAAc,EAAC,OAA2B,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;SAClF;IACH,CAAC;IAEO,mCAAW,GAAnB,UAAoB,aAA4B,EAAE,KAAkB;QAClE,IAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAM,SAAS,GAAU;YACvB,aAAa,eAAA;YACb,SAAS,EAAE,KAAK;SACjB,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI;YACF,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;SAC9C;QAAC,OAAO,MAAM,EAAE;YACf,6DAA6D;SAC9D;IACH,CAAC;IAED,+BAAO,GAAP;QACE,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IACH,oBAAC;AAAD,CAAC,AAjDD,IAiDC;AAjDY,sCAAa","sourcesContent":["import { trackHtmlVideo, trackMuxEmbeddedVideo } from '../video-analytics/track-video';\nimport type { VideoHandler, VideoEvent, MuxEmbeddedPlayer, MuxElement } from '../video-analytics/types';\n\ntype PlaybackState = 'playing' | 'paused' | 'ended' | 'error';\n\ntype Vendor = 'mux'; // | 'vimeo' | 'youtube' | 'other'\n\ntype State = {\n playbackState: PlaybackState;\n errorMessage?: string;\n lastEvent?: VideoEvent;\n};\n\ntype VideoObserverParams = {\n videoEl: HTMLVideoElement | MuxEmbeddedPlayer | MuxElement;\n onStateChange: (previousState: State, nextState: State) => void;\n vendor?: Vendor;\n isEmbedded?: boolean;\n};\n\nexport class VideoObserver {\n private state: State = {\n playbackState: 'paused',\n };\n\n private untrack: () => void;\n private onStateChange: (previousState: State, nextState: State) => void;\n private handler: VideoHandler = {\n onPlay: (evt: VideoEvent) => {\n this.updateState('playing', evt);\n },\n onPause: (evt: VideoEvent) => {\n this.updateState('paused', evt);\n },\n onEnded: (evt: VideoEvent) => {\n this.updateState('ended', evt);\n },\n onError: () => {\n this.updateState('error');\n },\n };\n\n constructor({ videoEl, onStateChange, vendor, isEmbedded }: VideoObserverParams) {\n this.onStateChange = onStateChange;\n if (isEmbedded) {\n // TODO: support embedded iFrame video with no Vendor\n this.untrack = trackMuxEmbeddedVideo(videoEl as MuxEmbeddedPlayer, this.handler);\n } else {\n this.untrack = trackHtmlVideo(videoEl as HTMLVideoElement, this.handler, vendor);\n }\n }\n\n private updateState(playbackState: PlaybackState, event?: VideoEvent) {\n const previousState = this.state;\n const nextState: State = {\n playbackState,\n lastEvent: event,\n };\n this.state = nextState;\n try {\n this.onStateChange(previousState, nextState);\n } catch (_error) {\n // Swallow callback errors to keep observer state consistent.\n }\n }\n\n destroy() {\n this.untrack();\n }\n}\n"]}
@@ -4,20 +4,18 @@ import { VideoHandler, MuxEmbeddedPlayer, MuxElement } from './types';
4
4
  *
5
5
  * @param videoEl - The HTML video element to track.
6
6
  * @param handlers - The video handlers to call when on video lifecycle events.
7
- * @param customMetadata - Custom metadata to add to all the video events.
8
7
  * @returns A function to untrack the video.
9
8
  */
10
- export declare function trackHtmlVideo(videoEl: HTMLVideoElement | MuxElement, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>, vendor?: 'mux'): () => void;
9
+ export declare function trackHtmlVideo(videoEl: HTMLVideoElement | MuxElement, handlers: VideoHandler, vendor?: 'mux'): () => void;
11
10
  /**
12
11
  * Track a Mux HTML video element.
13
12
  *
14
13
  * @param videoEl - The HTML Mux video element to track.
15
14
  * @param handlers - The video handlers to call when on video lifecycle events.
16
- * @param customMetadata - Custom metadata to add to all the video events.
17
15
  * @returns A function to untrack the video.
18
16
  */
19
- export declare function trackMuxHtmlVideo(videoEl: MuxElement, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>): () => void;
20
- export declare function trackMuxEmbeddedVideo(player: MuxEmbeddedPlayer, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>): () => void;
17
+ export declare function trackMuxHtmlVideo(videoEl: MuxElement, handlers: VideoHandler): () => void;
18
+ export declare function trackMuxEmbeddedVideo(player: MuxEmbeddedPlayer, handlers: VideoHandler): () => void;
21
19
  export declare function trackYoutubeEmbeddedVideo(): void;
22
20
  export declare function trackVimeoEmbeddedVideo(): void;
23
21
  //# sourceMappingURL=track-video.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"track-video.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAIZ,iBAAiB,EACjB,UAAU,EACX,MAAM,SAAS,CAAC;AA4CjB;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,GAAG,UAAU,EACtC,QAAQ,EAAE,YAAY,EACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACzD,MAAM,CAAC,EAAE,KAAK,cAqCf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,YAAY,EACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,cAG1D;AA8BD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,YAAY,EACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,cA2D1D;AAED,wBAAgB,yBAAyB,SAExC;AAED,wBAAgB,uBAAuB,SAEtC"}
1
+ {"version":3,"file":"track-video.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAc,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA4ClF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,GAAG,UAAU,EACtC,QAAQ,EAAE,YAAY,EACtB,MAAM,CAAC,EAAE,KAAK,cAkCf;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,cAE5E;AA8BD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,cAuDtF;AAED,wBAAgB,yBAAyB,SAExC;AAED,wBAAgB,uBAAuB,SAEtC"}
@@ -37,22 +37,21 @@ function getMuxMetadata(videoEl) {
37
37
  *
38
38
  * @param videoEl - The HTML video element to track.
39
39
  * @param handlers - The video handlers to call when on video lifecycle events.
40
- * @param customMetadata - Custom metadata to add to all the video events.
41
40
  * @returns A function to untrack the video.
42
41
  */
43
- function trackHtmlVideo(videoEl, handlers, customMetadata, vendor) {
42
+ function trackHtmlVideo(videoEl, handlers, vendor) {
44
43
  var playHandler = function () {
45
- var startEvent = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, getPlayData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
44
+ var startEvent = tslib_1.__assign(tslib_1.__assign({}, getPlayData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {}));
46
45
  handlers.onPlay(startEvent);
47
46
  };
48
47
  videoEl.addEventListener('play', playHandler);
49
48
  var pauseHandler = function () {
50
- var pauseEvent = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, getPauseData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
49
+ var pauseEvent = tslib_1.__assign(tslib_1.__assign({}, getPauseData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {}));
51
50
  handlers.onPause(pauseEvent);
52
51
  };
53
52
  videoEl.addEventListener('pause', pauseHandler);
54
53
  var endedHandler = function () {
55
- var endedEvent = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, getEndData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
54
+ var endedEvent = tslib_1.__assign(tslib_1.__assign({}, getEndData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {}));
56
55
  handlers.onEnded(endedEvent);
57
56
  };
58
57
  videoEl.addEventListener('ended', endedHandler);
@@ -68,11 +67,10 @@ exports.trackHtmlVideo = trackHtmlVideo;
68
67
  *
69
68
  * @param videoEl - The HTML Mux video element to track.
70
69
  * @param handlers - The video handlers to call when on video lifecycle events.
71
- * @param customMetadata - Custom metadata to add to all the video events.
72
70
  * @returns A function to untrack the video.
73
71
  */
74
- function trackMuxHtmlVideo(videoEl, handlers, customMetadata) {
75
- return trackHtmlVideo(videoEl, handlers, customMetadata, 'mux');
72
+ function trackMuxHtmlVideo(videoEl, handlers) {
73
+ return trackHtmlVideo(videoEl, handlers, 'mux');
76
74
  }
77
75
  exports.trackMuxHtmlVideo = trackMuxHtmlVideo;
78
76
  function getMuxIframeMetadata(player, elem) {
@@ -108,14 +106,14 @@ function getMuxIframeMetadata(player, elem) {
108
106
  });
109
107
  });
110
108
  }
111
- function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
109
+ function trackMuxEmbeddedVideo(player, handlers) {
112
110
  var onUnsubscribe = [];
113
111
  var readyHandler = function () {
114
112
  var elem = player.elem;
115
113
  var playHandler = function () {
116
114
  getMuxIframeMetadata(player, elem)
117
115
  .then(function (playerState) {
118
- var startEvent = tslib_1.__assign(tslib_1.__assign({}, playerState), customMetadata);
116
+ var startEvent = tslib_1.__assign({}, playerState);
119
117
  handlers.onPlay(startEvent);
120
118
  })
121
119
  .catch(function (error) {
@@ -127,7 +125,7 @@ function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
127
125
  var pauseHandler = function () {
128
126
  getMuxIframeMetadata(player, elem)
129
127
  .then(function (playerState) {
130
- var pauseEvent = tslib_1.__assign(tslib_1.__assign({}, playerState), customMetadata);
128
+ var pauseEvent = tslib_1.__assign({}, playerState);
131
129
  handlers.onPause(pauseEvent);
132
130
  })
133
131
  .catch(function (error) {
@@ -139,7 +137,7 @@ function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
139
137
  var endedHandler = function () {
140
138
  getMuxIframeMetadata(player, elem)
141
139
  .then(function (playerState) {
142
- var endedEvent = tslib_1.__assign(tslib_1.__assign({}, playerState), customMetadata);
140
+ var endedEvent = tslib_1.__assign({}, playerState);
143
141
  handlers.onEnded(endedEvent);
144
142
  })
145
143
  .catch(function (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"track-video.js","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n VideoHandler,\n StartVideoEvent,\n PauseVideoEvent,\n EndedVideoEvent,\n MuxEmbeddedPlayer,\n MuxElement,\n} from './types';\n\nfunction getPlayData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n program_duration: videoEl.duration,\n };\n}\n\nfunction calculatePercentCompleted(currentTime: number, duration: number) {\n let percentCompleted = 0;\n if (Number.isFinite(currentTime) && Number.isFinite(duration) && duration > 0) {\n const rawPercent = (currentTime / duration) * 100;\n // Clamp to [0, 100] to avoid invalid analytics values.\n percentCompleted = Math.min(100, Math.max(0, rawPercent));\n }\n return percentCompleted;\n}\n\nfunction getPauseData(videoEl: HTMLVideoElement | MuxElement) {\n const currentTime = videoEl.currentTime;\n const duration = videoEl.duration;\n\n return {\n ...getPlayData(videoEl),\n last_position: currentTime,\n percent_completed: calculatePercentCompleted(currentTime, duration),\n };\n}\n\nfunction getEndData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n ...getPauseData(videoEl),\n };\n}\n\nfunction getMuxMetadata(videoEl: MuxElement) {\n return {\n mux_playback_id: videoEl.getAttribute('playback-id'),\n mux_video_id: videoEl.getAttribute('metadata-video-id'),\n mux_video_title: videoEl.getAttribute('metadata-video-title'),\n mux_session_id: videoEl.getAttribute('session-id'),\n };\n}\n\n/**\n * Track a standard HTML video element.\n *\n * @param videoEl - The HTML video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @param customMetadata - Custom metadata to add to all the video events.\n * @returns A function to untrack the video.\n */\nexport function trackHtmlVideo(\n videoEl: HTMLVideoElement | MuxElement,\n handlers: VideoHandler,\n customMetadata: Record<string, string | number | boolean>,\n vendor?: 'mux', // if new vendors add them to this\n) {\n const playHandler = () => {\n const startEvent: StartVideoEvent = {\n ...getPlayData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n ...customMetadata,\n };\n handlers.onPlay(startEvent);\n };\n videoEl.addEventListener('play', playHandler);\n\n const pauseHandler = () => {\n const pauseEvent: PauseVideoEvent = {\n ...getPauseData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n ...customMetadata,\n };\n handlers.onPause(pauseEvent);\n };\n videoEl.addEventListener('pause', pauseHandler);\n\n const endedHandler = () => {\n const endedEvent: EndedVideoEvent = {\n ...getEndData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n ...customMetadata,\n };\n handlers.onEnded(endedEvent);\n };\n videoEl.addEventListener('ended', endedHandler);\n\n return () => {\n videoEl.removeEventListener('play', playHandler);\n videoEl.removeEventListener('pause', pauseHandler);\n videoEl.removeEventListener('ended', endedHandler);\n };\n}\n\n/**\n * Track a Mux HTML video element.\n *\n * @param videoEl - The HTML Mux video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @param customMetadata - Custom metadata to add to all the video events.\n * @returns A function to untrack the video.\n */\nexport function trackMuxHtmlVideo(\n videoEl: MuxElement,\n handlers: VideoHandler,\n customMetadata: Record<string, string | number | boolean>,\n) {\n return trackHtmlVideo(videoEl, handlers, customMetadata, 'mux');\n}\n\nasync function getMuxIframeMetadata(player: MuxEmbeddedPlayer, elem: HTMLIFrameElement) {\n const [duration, currentTime] = await Promise.all([\n new Promise<number>((resolve) => player.getDuration(resolve)),\n new Promise<number>((resolve) => player.getCurrentTime(resolve)),\n ]);\n\n let url,\n metadataVideoTitle = null,\n metadataVideoId = null,\n playerId = null;\n try {\n url = new URL(elem.getAttribute('src') as string);\n metadataVideoTitle = url.searchParams.get('metadata-video-title');\n metadataVideoId = url.searchParams.get('metadata-video-id');\n playerId = url.pathname.split('/').pop();\n } catch (error) {\n // invalid or no src url, skip the header metadata\n }\n return {\n percent_completed: calculatePercentCompleted(currentTime, duration),\n program_duration: duration,\n last_position: currentTime,\n mux_video_title: metadataVideoTitle,\n mux_video_id: metadataVideoId,\n mux_playback_id: playerId,\n };\n}\n\nexport function trackMuxEmbeddedVideo(\n player: MuxEmbeddedPlayer,\n handlers: VideoHandler,\n customMetadata: Record<string, string | number | boolean>,\n) {\n const onUnsubscribe: (() => void)[] = [];\n const readyHandler = () => {\n const { elem } = player;\n const playHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const startEvent: StartVideoEvent = {\n ...playerState,\n ...customMetadata,\n };\n handlers.onPlay(startEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'play' handler: ${error as string}`);\n });\n };\n player.on('play', playHandler);\n onUnsubscribe.push(() => player.off('play', playHandler));\n\n const pauseHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const pauseEvent: PauseVideoEvent = {\n ...playerState,\n ...customMetadata,\n };\n handlers.onPause(pauseEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'pause' handler: ${error as string}`);\n });\n };\n player.on('pause', pauseHandler);\n onUnsubscribe.push(() => player.off('pause', pauseHandler));\n\n const endedHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const endedEvent: EndedVideoEvent = {\n ...playerState,\n ...customMetadata,\n };\n handlers.onEnded(endedEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'ended' handler: ${error as string}`);\n });\n };\n player.on('ended', endedHandler);\n onUnsubscribe.push(() => player.off('ended', endedHandler));\n };\n player.on('ready', readyHandler);\n\n return () => {\n player.off('ready', readyHandler);\n onUnsubscribe.forEach((unsubscribe) => unsubscribe());\n };\n}\n\nexport function trackYoutubeEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n\nexport function trackVimeoEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n"]}
1
+ {"version":3,"file":"track-video.js","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"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","sourcesContent":["import { VideoHandler, VideoEvent, MuxEmbeddedPlayer, MuxElement } from './types';\n\nfunction getPlayData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n program_duration: videoEl.duration,\n };\n}\n\nfunction calculatePercentCompleted(currentTime: number, duration: number) {\n let percentCompleted = 0;\n if (Number.isFinite(currentTime) && Number.isFinite(duration) && duration > 0) {\n const rawPercent = (currentTime / duration) * 100;\n // Clamp to [0, 100] to avoid invalid analytics values.\n percentCompleted = Math.min(100, Math.max(0, rawPercent));\n }\n return percentCompleted;\n}\n\nfunction getPauseData(videoEl: HTMLVideoElement | MuxElement) {\n const currentTime = videoEl.currentTime;\n const duration = videoEl.duration;\n\n return {\n ...getPlayData(videoEl),\n last_position: currentTime,\n percent_completed: calculatePercentCompleted(currentTime, duration),\n };\n}\n\nfunction getEndData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n ...getPauseData(videoEl),\n };\n}\n\nfunction getMuxMetadata(videoEl: MuxElement) {\n return {\n mux_playback_id: videoEl.getAttribute('playback-id'),\n mux_video_id: videoEl.getAttribute('metadata-video-id'),\n mux_video_title: videoEl.getAttribute('metadata-video-title'),\n mux_session_id: videoEl.getAttribute('session-id'),\n };\n}\n\n/**\n * Track a standard HTML video element.\n *\n * @param videoEl - The HTML video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @returns A function to untrack the video.\n */\nexport function trackHtmlVideo(\n videoEl: HTMLVideoElement | MuxElement,\n handlers: VideoHandler,\n vendor?: 'mux', // if new vendors add them to this as enum\n) {\n const playHandler = () => {\n const startEvent: VideoEvent = {\n ...getPlayData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n };\n handlers.onPlay(startEvent);\n };\n videoEl.addEventListener('play', playHandler);\n\n const pauseHandler = () => {\n const pauseEvent: VideoEvent = {\n ...getPauseData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n };\n handlers.onPause(pauseEvent);\n };\n videoEl.addEventListener('pause', pauseHandler);\n\n const endedHandler = () => {\n const endedEvent: VideoEvent = {\n ...getEndData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n };\n handlers.onEnded(endedEvent);\n };\n videoEl.addEventListener('ended', endedHandler);\n\n return () => {\n videoEl.removeEventListener('play', playHandler);\n videoEl.removeEventListener('pause', pauseHandler);\n videoEl.removeEventListener('ended', endedHandler);\n };\n}\n\n/**\n * Track a Mux HTML video element.\n *\n * @param videoEl - The HTML Mux video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @returns A function to untrack the video.\n */\nexport function trackMuxHtmlVideo(videoEl: MuxElement, handlers: VideoHandler) {\n return trackHtmlVideo(videoEl, handlers, 'mux');\n}\n\nasync function getMuxIframeMetadata(player: MuxEmbeddedPlayer, elem: HTMLIFrameElement) {\n const [duration, currentTime] = await Promise.all([\n new Promise<number>((resolve) => player.getDuration(resolve)),\n new Promise<number>((resolve) => player.getCurrentTime(resolve)),\n ]);\n\n let url,\n metadataVideoTitle = null,\n metadataVideoId = null,\n playerId = null;\n try {\n url = new URL(elem.getAttribute('src') as string);\n metadataVideoTitle = url.searchParams.get('metadata-video-title');\n metadataVideoId = url.searchParams.get('metadata-video-id');\n playerId = url.pathname.split('/').pop();\n } catch (error) {\n // invalid or no src url, skip the header metadata\n }\n return {\n percent_completed: calculatePercentCompleted(currentTime, duration),\n program_duration: duration,\n last_position: currentTime,\n mux_video_title: metadataVideoTitle,\n mux_video_id: metadataVideoId,\n mux_playback_id: playerId,\n };\n}\n\nexport function trackMuxEmbeddedVideo(player: MuxEmbeddedPlayer, handlers: VideoHandler) {\n const onUnsubscribe: (() => void)[] = [];\n const readyHandler = () => {\n const { elem } = player;\n const playHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const startEvent: VideoEvent = {\n ...playerState,\n };\n handlers.onPlay(startEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'play' handler: ${error as string}`);\n });\n };\n player.on('play', playHandler);\n onUnsubscribe.push(() => player.off('play', playHandler));\n\n const pauseHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const pauseEvent: VideoEvent = {\n ...playerState,\n };\n handlers.onPause(pauseEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'pause' handler: ${error as string}`);\n });\n };\n player.on('pause', pauseHandler);\n onUnsubscribe.push(() => player.off('pause', pauseHandler));\n\n const endedHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const endedEvent: VideoEvent = {\n ...playerState,\n };\n handlers.onEnded(endedEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'ended' handler: ${error as string}`);\n });\n };\n player.on('ended', endedHandler);\n onUnsubscribe.push(() => player.off('ended', endedHandler));\n };\n player.on('ready', readyHandler);\n\n return () => {\n player.off('ready', readyHandler);\n onUnsubscribe.forEach((unsubscribe) => unsubscribe());\n };\n}\n\nexport function trackYoutubeEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n\nexport function trackVimeoEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n"]}
@@ -1,10 +1,10 @@
1
- type VideoHandler = {
2
- onPlay: (startEvent: StartVideoEvent) => void;
3
- onPause: (pauseEvent: PauseVideoEvent) => void;
4
- onEnded: (endedEvent: EndedVideoEvent) => void;
1
+ export type VideoHandler = {
2
+ onPlay: (startEvent: VideoEvent) => void;
3
+ onPause: (pauseEvent: VideoEvent) => void;
4
+ onEnded: (endedEvent: VideoEvent) => void;
5
5
  onError: (error: string) => void;
6
6
  };
7
- type BaseVideoEvent = {
7
+ export type VideoEvent = {
8
8
  program_duration: number;
9
9
  playback_id?: string | undefined;
10
10
  video_id?: string | undefined;
@@ -12,18 +12,12 @@ type BaseVideoEvent = {
12
12
  content_id?: string | undefined;
13
13
  content_type?: string | undefined;
14
14
  session_id?: string | undefined;
15
- [key: string]: string | number | boolean | undefined | null;
16
- };
17
- type MuxVideoMetadata = {
18
15
  mux_playback_id?: string | undefined | null;
19
16
  mux_video_id?: string | undefined | null;
20
17
  mux_video_title?: string | undefined | null;
21
18
  mux_session_id?: string | undefined | null;
22
- };
23
- type StartVideoEvent = BaseVideoEvent & MuxVideoMetadata;
24
- type PauseVideoEvent = BaseVideoEvent & MuxVideoMetadata & {
25
19
  last_position?: number | undefined | null;
26
- percent_completed: number;
20
+ percent_completed?: number;
27
21
  };
28
22
  type MuxEmbeddedPlayer = {
29
23
  getCurrentTime: (cb: (time: number) => void) => void;
@@ -32,12 +26,11 @@ type MuxEmbeddedPlayer = {
32
26
  off: (event: string, callback: () => void) => void;
33
27
  elem: HTMLIFrameElement;
34
28
  };
35
- type EndedVideoEvent = PauseVideoEvent;
36
29
  type MuxElement = EventTarget & Element & {
37
30
  duration: number;
38
31
  currentTime: number;
39
32
  play?: () => Promise<unknown>;
40
33
  pause?: () => void;
41
34
  };
42
- export { VideoHandler, BaseVideoEvent, MuxVideoMetadata, StartVideoEvent, PauseVideoEvent, EndedVideoEvent, MuxElement, MuxEmbeddedPlayer, };
35
+ export { MuxElement, MuxEmbeddedPlayer };
43
36
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;CAC7D,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF,KAAK,eAAe,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEzD,KAAK,eAAe,GAAG,cAAc,GACnC,gBAAgB,GAAG;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEJ,KAAK,iBAAiB,GAAG;IACvB,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACtD,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAClD,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACnD,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC;AAEF,KAAK,eAAe,GAAG,eAAe,CAAC;AAEvC,KAAK,UAAU,GAAG,WAAW,GAC3B,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAEzG,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,eAAe,EACf,UAAU,EACV,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACtD,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAClD,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACnD,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC;AAEF,KAAK,UAAU,GAAG,WAAW,GAC3B,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAEzG,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"","sourcesContent":["type VideoHandler = {\n onPlay: (startEvent: StartVideoEvent) => void;\n onPause: (pauseEvent: PauseVideoEvent) => void;\n onEnded: (endedEvent: EndedVideoEvent) => void;\n onError: (error: string) => void;\n};\n\ntype BaseVideoEvent = {\n program_duration: number;\n playback_id?: string | undefined;\n video_id?: string | undefined;\n video_title?: string | undefined;\n content_id?: string | undefined;\n content_type?: string | undefined;\n session_id?: string | undefined;\n [key: string]: string | number | boolean | undefined | null;\n};\n\ntype MuxVideoMetadata = {\n mux_playback_id?: string | undefined | null;\n mux_video_id?: string | undefined | null;\n mux_video_title?: string | undefined | null;\n mux_session_id?: string | undefined | null;\n};\n\ntype StartVideoEvent = BaseVideoEvent & MuxVideoMetadata;\n\ntype PauseVideoEvent = BaseVideoEvent &\n MuxVideoMetadata & {\n last_position?: number | undefined | null;\n percent_completed: number;\n };\n\ntype MuxEmbeddedPlayer = {\n getCurrentTime: (cb: (time: number) => void) => void;\n getDuration: (cb: (duration: number) => void) => void;\n on: (event: string, callback: () => void) => void;\n off: (event: string, callback: () => void) => void;\n elem: HTMLIFrameElement;\n};\n\ntype EndedVideoEvent = PauseVideoEvent; // & { ... }\n\ntype MuxElement = EventTarget &\n Element & { duration: number; currentTime: number; play?: () => Promise<unknown>; pause?: () => void };\n\nexport {\n VideoHandler,\n BaseVideoEvent,\n MuxVideoMetadata,\n StartVideoEvent,\n PauseVideoEvent,\n EndedVideoEvent,\n MuxElement,\n MuxEmbeddedPlayer,\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"","sourcesContent":["export type VideoHandler = {\n onPlay: (startEvent: VideoEvent) => void;\n onPause: (pauseEvent: VideoEvent) => void;\n onEnded: (endedEvent: VideoEvent) => void;\n onError: (error: string) => void;\n};\n\nexport type VideoEvent = {\n program_duration: number;\n playback_id?: string | undefined;\n video_id?: string | undefined;\n video_title?: string | undefined;\n content_id?: string | undefined;\n content_type?: string | undefined;\n session_id?: string | undefined;\n mux_playback_id?: string | undefined | null;\n mux_video_id?: string | undefined | null;\n mux_video_title?: string | undefined | null;\n mux_session_id?: string | undefined | null;\n last_position?: number | undefined | null;\n percent_completed?: number;\n};\n\ntype MuxEmbeddedPlayer = {\n getCurrentTime: (cb: (time: number) => void) => void;\n getDuration: (cb: (duration: number) => void) => void;\n on: (event: string, callback: () => void) => void;\n off: (event: string, callback: () => void) => void;\n elem: HTMLIFrameElement;\n};\n\ntype MuxElement = EventTarget &\n Element & { duration: number; currentTime: number; play?: () => Promise<unknown>; pause?: () => void };\n\nexport { MuxElement, MuxEmbeddedPlayer };\n"]}
@@ -0,0 +1,25 @@
1
+ import type { VideoEvent, MuxEmbeddedPlayer, MuxElement } from '../video-analytics/types';
2
+ type PlaybackState = 'playing' | 'paused' | 'ended' | 'error';
3
+ type Vendor = 'mux';
4
+ type State = {
5
+ playbackState: PlaybackState;
6
+ errorMessage?: string;
7
+ lastEvent?: VideoEvent;
8
+ };
9
+ type VideoObserverParams = {
10
+ videoEl: HTMLVideoElement | MuxEmbeddedPlayer | MuxElement;
11
+ onStateChange: (previousState: State, nextState: State) => void;
12
+ vendor?: Vendor;
13
+ isEmbedded?: boolean;
14
+ };
15
+ export declare class VideoObserver {
16
+ private state;
17
+ private untrack;
18
+ private onStateChange;
19
+ private handler;
20
+ constructor({ videoEl, onStateChange, vendor, isEmbedded }: VideoObserverParams);
21
+ private updateState;
22
+ destroy(): void;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=video.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../../src/observers/video.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAExG,KAAK,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,KAAK,MAAM,GAAG,KAAK,CAAC;AAEpB,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,UAAU,CAAC;CACxB,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,GAAG,UAAU,CAAC;IAC3D,aAAa,EAAE,CAAC,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,KAAK,IAAI,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAEX;IAEF,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,aAAa,CAAmD;IACxE,OAAO,CAAC,OAAO,CAab;gBAEU,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,mBAAmB;IAU/E,OAAO,CAAC,WAAW;IAcnB,OAAO;CAGR"}
@@ -0,0 +1,52 @@
1
+ import { trackHtmlVideo, trackMuxEmbeddedVideo } from '../video-analytics/track-video';
2
+ var VideoObserver = /** @class */ (function () {
3
+ function VideoObserver(_a) {
4
+ var videoEl = _a.videoEl, onStateChange = _a.onStateChange, vendor = _a.vendor, isEmbedded = _a.isEmbedded;
5
+ var _this = this;
6
+ this.state = {
7
+ playbackState: 'paused',
8
+ };
9
+ this.handler = {
10
+ onPlay: function (evt) {
11
+ _this.updateState('playing', evt);
12
+ },
13
+ onPause: function (evt) {
14
+ _this.updateState('paused', evt);
15
+ },
16
+ onEnded: function (evt) {
17
+ _this.updateState('ended', evt);
18
+ },
19
+ onError: function () {
20
+ _this.updateState('error');
21
+ },
22
+ };
23
+ this.onStateChange = onStateChange;
24
+ if (isEmbedded) {
25
+ // TODO: support embedded iFrame video with no Vendor
26
+ this.untrack = trackMuxEmbeddedVideo(videoEl, this.handler);
27
+ }
28
+ else {
29
+ this.untrack = trackHtmlVideo(videoEl, this.handler, vendor);
30
+ }
31
+ }
32
+ VideoObserver.prototype.updateState = function (playbackState, event) {
33
+ var previousState = this.state;
34
+ var nextState = {
35
+ playbackState: playbackState,
36
+ lastEvent: event,
37
+ };
38
+ this.state = nextState;
39
+ try {
40
+ this.onStateChange(previousState, nextState);
41
+ }
42
+ catch (_error) {
43
+ // Swallow callback errors to keep observer state consistent.
44
+ }
45
+ };
46
+ VideoObserver.prototype.destroy = function () {
47
+ this.untrack();
48
+ };
49
+ return VideoObserver;
50
+ }());
51
+ export { VideoObserver };
52
+ //# sourceMappingURL=video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["../../../src/observers/video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAoBvF;IAsBE,uBAAY,EAAmE;YAAjE,OAAO,aAAA,EAAE,aAAa,mBAAA,EAAE,MAAM,YAAA,EAAE,UAAU,gBAAA;QAAxD,iBAQC;QA7BO,UAAK,GAAU;YACrB,aAAa,EAAE,QAAQ;SACxB,CAAC;QAIM,YAAO,GAAiB;YAC9B,MAAM,EAAE,UAAC,GAAe;gBACtB,KAAI,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,EAAE,UAAC,GAAe;gBACvB,KAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAClC,CAAC;YACD,OAAO,EAAE,UAAC,GAAe;gBACvB,KAAI,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACjC,CAAC;YACD,OAAO,EAAE;gBACP,KAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC;SACF,CAAC;QAGA,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,UAAU,EAAE;YACd,qDAAqD;YACrD,IAAI,CAAC,OAAO,GAAG,qBAAqB,CAAC,OAA4B,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;SAClF;aAAM;YACL,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC,OAA2B,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;SAClF;IACH,CAAC;IAEO,mCAAW,GAAnB,UAAoB,aAA4B,EAAE,KAAkB;QAClE,IAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAM,SAAS,GAAU;YACvB,aAAa,eAAA;YACb,SAAS,EAAE,KAAK;SACjB,CAAC;QACF,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI;YACF,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;SAC9C;QAAC,OAAO,MAAM,EAAE;YACf,6DAA6D;SAC9D;IACH,CAAC;IAED,+BAAO,GAAP;QACE,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IACH,oBAAC;AAAD,CAAC,AAjDD,IAiDC","sourcesContent":["import { trackHtmlVideo, trackMuxEmbeddedVideo } from '../video-analytics/track-video';\nimport type { VideoHandler, VideoEvent, MuxEmbeddedPlayer, MuxElement } from '../video-analytics/types';\n\ntype PlaybackState = 'playing' | 'paused' | 'ended' | 'error';\n\ntype Vendor = 'mux'; // | 'vimeo' | 'youtube' | 'other'\n\ntype State = {\n playbackState: PlaybackState;\n errorMessage?: string;\n lastEvent?: VideoEvent;\n};\n\ntype VideoObserverParams = {\n videoEl: HTMLVideoElement | MuxEmbeddedPlayer | MuxElement;\n onStateChange: (previousState: State, nextState: State) => void;\n vendor?: Vendor;\n isEmbedded?: boolean;\n};\n\nexport class VideoObserver {\n private state: State = {\n playbackState: 'paused',\n };\n\n private untrack: () => void;\n private onStateChange: (previousState: State, nextState: State) => void;\n private handler: VideoHandler = {\n onPlay: (evt: VideoEvent) => {\n this.updateState('playing', evt);\n },\n onPause: (evt: VideoEvent) => {\n this.updateState('paused', evt);\n },\n onEnded: (evt: VideoEvent) => {\n this.updateState('ended', evt);\n },\n onError: () => {\n this.updateState('error');\n },\n };\n\n constructor({ videoEl, onStateChange, vendor, isEmbedded }: VideoObserverParams) {\n this.onStateChange = onStateChange;\n if (isEmbedded) {\n // TODO: support embedded iFrame video with no Vendor\n this.untrack = trackMuxEmbeddedVideo(videoEl as MuxEmbeddedPlayer, this.handler);\n } else {\n this.untrack = trackHtmlVideo(videoEl as HTMLVideoElement, this.handler, vendor);\n }\n }\n\n private updateState(playbackState: PlaybackState, event?: VideoEvent) {\n const previousState = this.state;\n const nextState: State = {\n playbackState,\n lastEvent: event,\n };\n this.state = nextState;\n try {\n this.onStateChange(previousState, nextState);\n } catch (_error) {\n // Swallow callback errors to keep observer state consistent.\n }\n }\n\n destroy() {\n this.untrack();\n }\n}\n"]}
@@ -4,20 +4,18 @@ import { VideoHandler, MuxEmbeddedPlayer, MuxElement } from './types';
4
4
  *
5
5
  * @param videoEl - The HTML video element to track.
6
6
  * @param handlers - The video handlers to call when on video lifecycle events.
7
- * @param customMetadata - Custom metadata to add to all the video events.
8
7
  * @returns A function to untrack the video.
9
8
  */
10
- export declare function trackHtmlVideo(videoEl: HTMLVideoElement | MuxElement, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>, vendor?: 'mux'): () => void;
9
+ export declare function trackHtmlVideo(videoEl: HTMLVideoElement | MuxElement, handlers: VideoHandler, vendor?: 'mux'): () => void;
11
10
  /**
12
11
  * Track a Mux HTML video element.
13
12
  *
14
13
  * @param videoEl - The HTML Mux video element to track.
15
14
  * @param handlers - The video handlers to call when on video lifecycle events.
16
- * @param customMetadata - Custom metadata to add to all the video events.
17
15
  * @returns A function to untrack the video.
18
16
  */
19
- export declare function trackMuxHtmlVideo(videoEl: MuxElement, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>): () => void;
20
- export declare function trackMuxEmbeddedVideo(player: MuxEmbeddedPlayer, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>): () => void;
17
+ export declare function trackMuxHtmlVideo(videoEl: MuxElement, handlers: VideoHandler): () => void;
18
+ export declare function trackMuxEmbeddedVideo(player: MuxEmbeddedPlayer, handlers: VideoHandler): () => void;
21
19
  export declare function trackYoutubeEmbeddedVideo(): void;
22
20
  export declare function trackVimeoEmbeddedVideo(): void;
23
21
  //# sourceMappingURL=track-video.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"track-video.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAIZ,iBAAiB,EACjB,UAAU,EACX,MAAM,SAAS,CAAC;AA4CjB;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,GAAG,UAAU,EACtC,QAAQ,EAAE,YAAY,EACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACzD,MAAM,CAAC,EAAE,KAAK,cAqCf;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,YAAY,EACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,cAG1D;AA8BD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,YAAY,EACtB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,cA2D1D;AAED,wBAAgB,yBAAyB,SAExC;AAED,wBAAgB,uBAAuB,SAEtC"}
1
+ {"version":3,"file":"track-video.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAc,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AA4ClF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,gBAAgB,GAAG,UAAU,EACtC,QAAQ,EAAE,YAAY,EACtB,MAAM,CAAC,EAAE,KAAK,cAkCf;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,cAE5E;AA8BD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,cAuDtF;AAED,wBAAgB,yBAAyB,SAExC;AAED,wBAAgB,uBAAuB,SAEtC"}
@@ -34,22 +34,21 @@ function getMuxMetadata(videoEl) {
34
34
  *
35
35
  * @param videoEl - The HTML video element to track.
36
36
  * @param handlers - The video handlers to call when on video lifecycle events.
37
- * @param customMetadata - Custom metadata to add to all the video events.
38
37
  * @returns A function to untrack the video.
39
38
  */
40
- export function trackHtmlVideo(videoEl, handlers, customMetadata, vendor) {
39
+ export function trackHtmlVideo(videoEl, handlers, vendor) {
41
40
  var playHandler = function () {
42
- var startEvent = __assign(__assign(__assign({}, getPlayData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
41
+ var startEvent = __assign(__assign({}, getPlayData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {}));
43
42
  handlers.onPlay(startEvent);
44
43
  };
45
44
  videoEl.addEventListener('play', playHandler);
46
45
  var pauseHandler = function () {
47
- var pauseEvent = __assign(__assign(__assign({}, getPauseData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
46
+ var pauseEvent = __assign(__assign({}, getPauseData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {}));
48
47
  handlers.onPause(pauseEvent);
49
48
  };
50
49
  videoEl.addEventListener('pause', pauseHandler);
51
50
  var endedHandler = function () {
52
- var endedEvent = __assign(__assign(__assign({}, getEndData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
51
+ var endedEvent = __assign(__assign({}, getEndData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {}));
53
52
  handlers.onEnded(endedEvent);
54
53
  };
55
54
  videoEl.addEventListener('ended', endedHandler);
@@ -64,11 +63,10 @@ export function trackHtmlVideo(videoEl, handlers, customMetadata, vendor) {
64
63
  *
65
64
  * @param videoEl - The HTML Mux video element to track.
66
65
  * @param handlers - The video handlers to call when on video lifecycle events.
67
- * @param customMetadata - Custom metadata to add to all the video events.
68
66
  * @returns A function to untrack the video.
69
67
  */
70
- export function trackMuxHtmlVideo(videoEl, handlers, customMetadata) {
71
- return trackHtmlVideo(videoEl, handlers, customMetadata, 'mux');
68
+ export function trackMuxHtmlVideo(videoEl, handlers) {
69
+ return trackHtmlVideo(videoEl, handlers, 'mux');
72
70
  }
73
71
  function getMuxIframeMetadata(player, elem) {
74
72
  return __awaiter(this, void 0, void 0, function () {
@@ -103,14 +101,14 @@ function getMuxIframeMetadata(player, elem) {
103
101
  });
104
102
  });
105
103
  }
106
- export function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
104
+ export function trackMuxEmbeddedVideo(player, handlers) {
107
105
  var onUnsubscribe = [];
108
106
  var readyHandler = function () {
109
107
  var elem = player.elem;
110
108
  var playHandler = function () {
111
109
  getMuxIframeMetadata(player, elem)
112
110
  .then(function (playerState) {
113
- var startEvent = __assign(__assign({}, playerState), customMetadata);
111
+ var startEvent = __assign({}, playerState);
114
112
  handlers.onPlay(startEvent);
115
113
  })
116
114
  .catch(function (error) {
@@ -122,7 +120,7 @@ export function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
122
120
  var pauseHandler = function () {
123
121
  getMuxIframeMetadata(player, elem)
124
122
  .then(function (playerState) {
125
- var pauseEvent = __assign(__assign({}, playerState), customMetadata);
123
+ var pauseEvent = __assign({}, playerState);
126
124
  handlers.onPause(pauseEvent);
127
125
  })
128
126
  .catch(function (error) {
@@ -134,7 +132,7 @@ export function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
134
132
  var endedHandler = function () {
135
133
  getMuxIframeMetadata(player, elem)
136
134
  .then(function (playerState) {
137
- var endedEvent = __assign(__assign({}, playerState), customMetadata);
135
+ var endedEvent = __assign({}, playerState);
138
136
  handlers.onEnded(endedEvent);
139
137
  })
140
138
  .catch(function (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"track-video.js","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n VideoHandler,\n StartVideoEvent,\n PauseVideoEvent,\n EndedVideoEvent,\n MuxEmbeddedPlayer,\n MuxElement,\n} from './types';\n\nfunction getPlayData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n program_duration: videoEl.duration,\n };\n}\n\nfunction calculatePercentCompleted(currentTime: number, duration: number) {\n let percentCompleted = 0;\n if (Number.isFinite(currentTime) && Number.isFinite(duration) && duration > 0) {\n const rawPercent = (currentTime / duration) * 100;\n // Clamp to [0, 100] to avoid invalid analytics values.\n percentCompleted = Math.min(100, Math.max(0, rawPercent));\n }\n return percentCompleted;\n}\n\nfunction getPauseData(videoEl: HTMLVideoElement | MuxElement) {\n const currentTime = videoEl.currentTime;\n const duration = videoEl.duration;\n\n return {\n ...getPlayData(videoEl),\n last_position: currentTime,\n percent_completed: calculatePercentCompleted(currentTime, duration),\n };\n}\n\nfunction getEndData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n ...getPauseData(videoEl),\n };\n}\n\nfunction getMuxMetadata(videoEl: MuxElement) {\n return {\n mux_playback_id: videoEl.getAttribute('playback-id'),\n mux_video_id: videoEl.getAttribute('metadata-video-id'),\n mux_video_title: videoEl.getAttribute('metadata-video-title'),\n mux_session_id: videoEl.getAttribute('session-id'),\n };\n}\n\n/**\n * Track a standard HTML video element.\n *\n * @param videoEl - The HTML video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @param customMetadata - Custom metadata to add to all the video events.\n * @returns A function to untrack the video.\n */\nexport function trackHtmlVideo(\n videoEl: HTMLVideoElement | MuxElement,\n handlers: VideoHandler,\n customMetadata: Record<string, string | number | boolean>,\n vendor?: 'mux', // if new vendors add them to this\n) {\n const playHandler = () => {\n const startEvent: StartVideoEvent = {\n ...getPlayData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n ...customMetadata,\n };\n handlers.onPlay(startEvent);\n };\n videoEl.addEventListener('play', playHandler);\n\n const pauseHandler = () => {\n const pauseEvent: PauseVideoEvent = {\n ...getPauseData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n ...customMetadata,\n };\n handlers.onPause(pauseEvent);\n };\n videoEl.addEventListener('pause', pauseHandler);\n\n const endedHandler = () => {\n const endedEvent: EndedVideoEvent = {\n ...getEndData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n ...customMetadata,\n };\n handlers.onEnded(endedEvent);\n };\n videoEl.addEventListener('ended', endedHandler);\n\n return () => {\n videoEl.removeEventListener('play', playHandler);\n videoEl.removeEventListener('pause', pauseHandler);\n videoEl.removeEventListener('ended', endedHandler);\n };\n}\n\n/**\n * Track a Mux HTML video element.\n *\n * @param videoEl - The HTML Mux video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @param customMetadata - Custom metadata to add to all the video events.\n * @returns A function to untrack the video.\n */\nexport function trackMuxHtmlVideo(\n videoEl: MuxElement,\n handlers: VideoHandler,\n customMetadata: Record<string, string | number | boolean>,\n) {\n return trackHtmlVideo(videoEl, handlers, customMetadata, 'mux');\n}\n\nasync function getMuxIframeMetadata(player: MuxEmbeddedPlayer, elem: HTMLIFrameElement) {\n const [duration, currentTime] = await Promise.all([\n new Promise<number>((resolve) => player.getDuration(resolve)),\n new Promise<number>((resolve) => player.getCurrentTime(resolve)),\n ]);\n\n let url,\n metadataVideoTitle = null,\n metadataVideoId = null,\n playerId = null;\n try {\n url = new URL(elem.getAttribute('src') as string);\n metadataVideoTitle = url.searchParams.get('metadata-video-title');\n metadataVideoId = url.searchParams.get('metadata-video-id');\n playerId = url.pathname.split('/').pop();\n } catch (error) {\n // invalid or no src url, skip the header metadata\n }\n return {\n percent_completed: calculatePercentCompleted(currentTime, duration),\n program_duration: duration,\n last_position: currentTime,\n mux_video_title: metadataVideoTitle,\n mux_video_id: metadataVideoId,\n mux_playback_id: playerId,\n };\n}\n\nexport function trackMuxEmbeddedVideo(\n player: MuxEmbeddedPlayer,\n handlers: VideoHandler,\n customMetadata: Record<string, string | number | boolean>,\n) {\n const onUnsubscribe: (() => void)[] = [];\n const readyHandler = () => {\n const { elem } = player;\n const playHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const startEvent: StartVideoEvent = {\n ...playerState,\n ...customMetadata,\n };\n handlers.onPlay(startEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'play' handler: ${error as string}`);\n });\n };\n player.on('play', playHandler);\n onUnsubscribe.push(() => player.off('play', playHandler));\n\n const pauseHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const pauseEvent: PauseVideoEvent = {\n ...playerState,\n ...customMetadata,\n };\n handlers.onPause(pauseEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'pause' handler: ${error as string}`);\n });\n };\n player.on('pause', pauseHandler);\n onUnsubscribe.push(() => player.off('pause', pauseHandler));\n\n const endedHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const endedEvent: EndedVideoEvent = {\n ...playerState,\n ...customMetadata,\n };\n handlers.onEnded(endedEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'ended' handler: ${error as string}`);\n });\n };\n player.on('ended', endedHandler);\n onUnsubscribe.push(() => player.off('ended', endedHandler));\n };\n player.on('ready', readyHandler);\n\n return () => {\n player.off('ready', readyHandler);\n onUnsubscribe.forEach((unsubscribe) => unsubscribe());\n };\n}\n\nexport function trackYoutubeEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n\nexport function trackVimeoEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n"]}
1
+ {"version":3,"file":"track-video.js","sourceRoot":"","sources":["../../../src/video-analytics/track-video.ts"],"names":[],"mappings":"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","sourcesContent":["import { VideoHandler, VideoEvent, MuxEmbeddedPlayer, MuxElement } from './types';\n\nfunction getPlayData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n program_duration: videoEl.duration,\n };\n}\n\nfunction calculatePercentCompleted(currentTime: number, duration: number) {\n let percentCompleted = 0;\n if (Number.isFinite(currentTime) && Number.isFinite(duration) && duration > 0) {\n const rawPercent = (currentTime / duration) * 100;\n // Clamp to [0, 100] to avoid invalid analytics values.\n percentCompleted = Math.min(100, Math.max(0, rawPercent));\n }\n return percentCompleted;\n}\n\nfunction getPauseData(videoEl: HTMLVideoElement | MuxElement) {\n const currentTime = videoEl.currentTime;\n const duration = videoEl.duration;\n\n return {\n ...getPlayData(videoEl),\n last_position: currentTime,\n percent_completed: calculatePercentCompleted(currentTime, duration),\n };\n}\n\nfunction getEndData(videoEl: HTMLVideoElement | MuxElement) {\n return {\n ...getPauseData(videoEl),\n };\n}\n\nfunction getMuxMetadata(videoEl: MuxElement) {\n return {\n mux_playback_id: videoEl.getAttribute('playback-id'),\n mux_video_id: videoEl.getAttribute('metadata-video-id'),\n mux_video_title: videoEl.getAttribute('metadata-video-title'),\n mux_session_id: videoEl.getAttribute('session-id'),\n };\n}\n\n/**\n * Track a standard HTML video element.\n *\n * @param videoEl - The HTML video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @returns A function to untrack the video.\n */\nexport function trackHtmlVideo(\n videoEl: HTMLVideoElement | MuxElement,\n handlers: VideoHandler,\n vendor?: 'mux', // if new vendors add them to this as enum\n) {\n const playHandler = () => {\n const startEvent: VideoEvent = {\n ...getPlayData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n };\n handlers.onPlay(startEvent);\n };\n videoEl.addEventListener('play', playHandler);\n\n const pauseHandler = () => {\n const pauseEvent: VideoEvent = {\n ...getPauseData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n };\n handlers.onPause(pauseEvent);\n };\n videoEl.addEventListener('pause', pauseHandler);\n\n const endedHandler = () => {\n const endedEvent: VideoEvent = {\n ...getEndData(videoEl),\n ...(vendor === 'mux' ? getMuxMetadata(videoEl) : {}),\n };\n handlers.onEnded(endedEvent);\n };\n videoEl.addEventListener('ended', endedHandler);\n\n return () => {\n videoEl.removeEventListener('play', playHandler);\n videoEl.removeEventListener('pause', pauseHandler);\n videoEl.removeEventListener('ended', endedHandler);\n };\n}\n\n/**\n * Track a Mux HTML video element.\n *\n * @param videoEl - The HTML Mux video element to track.\n * @param handlers - The video handlers to call when on video lifecycle events.\n * @returns A function to untrack the video.\n */\nexport function trackMuxHtmlVideo(videoEl: MuxElement, handlers: VideoHandler) {\n return trackHtmlVideo(videoEl, handlers, 'mux');\n}\n\nasync function getMuxIframeMetadata(player: MuxEmbeddedPlayer, elem: HTMLIFrameElement) {\n const [duration, currentTime] = await Promise.all([\n new Promise<number>((resolve) => player.getDuration(resolve)),\n new Promise<number>((resolve) => player.getCurrentTime(resolve)),\n ]);\n\n let url,\n metadataVideoTitle = null,\n metadataVideoId = null,\n playerId = null;\n try {\n url = new URL(elem.getAttribute('src') as string);\n metadataVideoTitle = url.searchParams.get('metadata-video-title');\n metadataVideoId = url.searchParams.get('metadata-video-id');\n playerId = url.pathname.split('/').pop();\n } catch (error) {\n // invalid or no src url, skip the header metadata\n }\n return {\n percent_completed: calculatePercentCompleted(currentTime, duration),\n program_duration: duration,\n last_position: currentTime,\n mux_video_title: metadataVideoTitle,\n mux_video_id: metadataVideoId,\n mux_playback_id: playerId,\n };\n}\n\nexport function trackMuxEmbeddedVideo(player: MuxEmbeddedPlayer, handlers: VideoHandler) {\n const onUnsubscribe: (() => void)[] = [];\n const readyHandler = () => {\n const { elem } = player;\n const playHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const startEvent: VideoEvent = {\n ...playerState,\n };\n handlers.onPlay(startEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'play' handler: ${error as string}`);\n });\n };\n player.on('play', playHandler);\n onUnsubscribe.push(() => player.off('play', playHandler));\n\n const pauseHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const pauseEvent: VideoEvent = {\n ...playerState,\n };\n handlers.onPause(pauseEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'pause' handler: ${error as string}`);\n });\n };\n player.on('pause', pauseHandler);\n onUnsubscribe.push(() => player.off('pause', pauseHandler));\n\n const endedHandler = () => {\n getMuxIframeMetadata(player, elem)\n .then((playerState) => {\n const endedEvent: VideoEvent = {\n ...playerState,\n };\n handlers.onEnded(endedEvent);\n })\n .catch((error) => {\n handlers.onError(`Error getting Mux iframe metadata from 'ended' handler: ${error as string}`);\n });\n };\n player.on('ended', endedHandler);\n onUnsubscribe.push(() => player.off('ended', endedHandler));\n };\n player.on('ready', readyHandler);\n\n return () => {\n player.off('ready', readyHandler);\n onUnsubscribe.forEach((unsubscribe) => unsubscribe());\n };\n}\n\nexport function trackYoutubeEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n\nexport function trackVimeoEmbeddedVideo() {\n throw new Error('Not implemented');\n}\n"]}
@@ -1,10 +1,10 @@
1
- type VideoHandler = {
2
- onPlay: (startEvent: StartVideoEvent) => void;
3
- onPause: (pauseEvent: PauseVideoEvent) => void;
4
- onEnded: (endedEvent: EndedVideoEvent) => void;
1
+ export type VideoHandler = {
2
+ onPlay: (startEvent: VideoEvent) => void;
3
+ onPause: (pauseEvent: VideoEvent) => void;
4
+ onEnded: (endedEvent: VideoEvent) => void;
5
5
  onError: (error: string) => void;
6
6
  };
7
- type BaseVideoEvent = {
7
+ export type VideoEvent = {
8
8
  program_duration: number;
9
9
  playback_id?: string | undefined;
10
10
  video_id?: string | undefined;
@@ -12,18 +12,12 @@ type BaseVideoEvent = {
12
12
  content_id?: string | undefined;
13
13
  content_type?: string | undefined;
14
14
  session_id?: string | undefined;
15
- [key: string]: string | number | boolean | undefined | null;
16
- };
17
- type MuxVideoMetadata = {
18
15
  mux_playback_id?: string | undefined | null;
19
16
  mux_video_id?: string | undefined | null;
20
17
  mux_video_title?: string | undefined | null;
21
18
  mux_session_id?: string | undefined | null;
22
- };
23
- type StartVideoEvent = BaseVideoEvent & MuxVideoMetadata;
24
- type PauseVideoEvent = BaseVideoEvent & MuxVideoMetadata & {
25
19
  last_position?: number | undefined | null;
26
- percent_completed: number;
20
+ percent_completed?: number;
27
21
  };
28
22
  type MuxEmbeddedPlayer = {
29
23
  getCurrentTime: (cb: (time: number) => void) => void;
@@ -32,12 +26,11 @@ type MuxEmbeddedPlayer = {
32
26
  off: (event: string, callback: () => void) => void;
33
27
  elem: HTMLIFrameElement;
34
28
  };
35
- type EndedVideoEvent = PauseVideoEvent;
36
29
  type MuxElement = EventTarget & Element & {
37
30
  duration: number;
38
31
  currentTime: number;
39
32
  play?: () => Promise<unknown>;
40
33
  pause?: () => void;
41
34
  };
42
- export { VideoHandler, BaseVideoEvent, MuxVideoMetadata, StartVideoEvent, PauseVideoEvent, EndedVideoEvent, MuxElement, MuxEmbeddedPlayer, };
35
+ export { MuxElement, MuxEmbeddedPlayer };
43
36
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;CAC7D,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CAC5C,CAAC;AAEF,KAAK,eAAe,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEzD,KAAK,eAAe,GAAG,cAAc,GACnC,gBAAgB,GAAG;IACjB,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEJ,KAAK,iBAAiB,GAAG;IACvB,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACtD,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAClD,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACnD,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC;AAEF,KAAK,eAAe,GAAG,eAAe,CAAC;AAEvC,KAAK,UAAU,GAAG,WAAW,GAC3B,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAEzG,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,eAAe,EACf,UAAU,EACV,iBAAiB,GAClB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IACzC,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3C,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,cAAc,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;IACtD,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAClD,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACnD,IAAI,EAAE,iBAAiB,CAAC;CACzB,CAAC;AAEF,KAAK,UAAU,GAAG,WAAW,GAC3B,OAAO,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAEzG,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"","sourcesContent":["type VideoHandler = {\n onPlay: (startEvent: StartVideoEvent) => void;\n onPause: (pauseEvent: PauseVideoEvent) => void;\n onEnded: (endedEvent: EndedVideoEvent) => void;\n onError: (error: string) => void;\n};\n\ntype BaseVideoEvent = {\n program_duration: number;\n playback_id?: string | undefined;\n video_id?: string | undefined;\n video_title?: string | undefined;\n content_id?: string | undefined;\n content_type?: string | undefined;\n session_id?: string | undefined;\n [key: string]: string | number | boolean | undefined | null;\n};\n\ntype MuxVideoMetadata = {\n mux_playback_id?: string | undefined | null;\n mux_video_id?: string | undefined | null;\n mux_video_title?: string | undefined | null;\n mux_session_id?: string | undefined | null;\n};\n\ntype StartVideoEvent = BaseVideoEvent & MuxVideoMetadata;\n\ntype PauseVideoEvent = BaseVideoEvent &\n MuxVideoMetadata & {\n last_position?: number | undefined | null;\n percent_completed: number;\n };\n\ntype MuxEmbeddedPlayer = {\n getCurrentTime: (cb: (time: number) => void) => void;\n getDuration: (cb: (duration: number) => void) => void;\n on: (event: string, callback: () => void) => void;\n off: (event: string, callback: () => void) => void;\n elem: HTMLIFrameElement;\n};\n\ntype EndedVideoEvent = PauseVideoEvent; // & { ... }\n\ntype MuxElement = EventTarget &\n Element & { duration: number; currentTime: number; play?: () => Promise<unknown>; pause?: () => void };\n\nexport {\n VideoHandler,\n BaseVideoEvent,\n MuxVideoMetadata,\n StartVideoEvent,\n PauseVideoEvent,\n EndedVideoEvent,\n MuxElement,\n MuxEmbeddedPlayer,\n};\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/video-analytics/types.ts"],"names":[],"mappings":"","sourcesContent":["export type VideoHandler = {\n onPlay: (startEvent: VideoEvent) => void;\n onPause: (pauseEvent: VideoEvent) => void;\n onEnded: (endedEvent: VideoEvent) => void;\n onError: (error: string) => void;\n};\n\nexport type VideoEvent = {\n program_duration: number;\n playback_id?: string | undefined;\n video_id?: string | undefined;\n video_title?: string | undefined;\n content_id?: string | undefined;\n content_type?: string | undefined;\n session_id?: string | undefined;\n mux_playback_id?: string | undefined | null;\n mux_video_id?: string | undefined | null;\n mux_video_title?: string | undefined | null;\n mux_session_id?: string | undefined | null;\n last_position?: number | undefined | null;\n percent_completed?: number;\n};\n\ntype MuxEmbeddedPlayer = {\n getCurrentTime: (cb: (time: number) => void) => void;\n getDuration: (cb: (duration: number) => void) => void;\n on: (event: string, callback: () => void) => void;\n off: (event: string, callback: () => void) => void;\n elem: HTMLIFrameElement;\n};\n\ntype MuxElement = EventTarget &\n Element & { duration: number; currentTime: number; play?: () => Promise<unknown>; pause?: () => void };\n\nexport { MuxElement, MuxEmbeddedPlayer };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amplitude/analytics-core",
3
- "version": "2.44.1",
3
+ "version": "2.44.2-SR-3115.0",
4
4
  "description": "",
5
5
  "author": "Amplitude Inc",
6
6
  "homepage": "https://github.com/amplitude/Amplitude-TypeScript",