@amplitude/analytics-core 2.44.0-SR-3115.0 → 2.44.1
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/lib/cjs/video-analytics/track-video.d.ts +23 -0
- package/lib/cjs/video-analytics/track-video.d.ts.map +1 -0
- package/lib/cjs/video-analytics/track-video.js +167 -0
- package/lib/cjs/video-analytics/track-video.js.map +1 -0
- package/lib/cjs/video-analytics/types.d.ts +43 -0
- package/lib/cjs/video-analytics/types.d.ts.map +1 -0
- package/lib/cjs/video-analytics/types.js +3 -0
- package/lib/cjs/video-analytics/types.js.map +1 -0
- package/lib/esm/video-analytics/track-video.d.ts +23 -0
- package/lib/esm/video-analytics/track-video.d.ts.map +1 -0
- package/lib/esm/video-analytics/track-video.js +159 -0
- package/lib/esm/video-analytics/track-video.js.map +1 -0
- package/lib/esm/video-analytics/types.d.ts +43 -0
- package/lib/esm/video-analytics/types.d.ts.map +1 -0
- package/lib/esm/video-analytics/types.js +2 -0
- package/lib/esm/video-analytics/types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VideoHandler, MuxEmbeddedPlayer, MuxElement } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Track a standard HTML video element.
|
|
4
|
+
*
|
|
5
|
+
* @param videoEl - The HTML video element to track.
|
|
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
|
+
* @returns A function to untrack the video.
|
|
9
|
+
*/
|
|
10
|
+
export declare function trackHtmlVideo(videoEl: HTMLVideoElement | MuxElement, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>, vendor?: 'mux'): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Track a Mux HTML video element.
|
|
13
|
+
*
|
|
14
|
+
* @param videoEl - The HTML Mux video element to track.
|
|
15
|
+
* @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
|
+
* @returns A function to untrack the video.
|
|
18
|
+
*/
|
|
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;
|
|
21
|
+
export declare function trackYoutubeEmbeddedVideo(): void;
|
|
22
|
+
export declare function trackVimeoEmbeddedVideo(): void;
|
|
23
|
+
//# sourceMappingURL=track-video.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.trackVimeoEmbeddedVideo = exports.trackYoutubeEmbeddedVideo = exports.trackMuxEmbeddedVideo = exports.trackMuxHtmlVideo = exports.trackHtmlVideo = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
function getPlayData(videoEl) {
|
|
6
|
+
return {
|
|
7
|
+
program_duration: videoEl.duration,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function calculatePercentCompleted(currentTime, duration) {
|
|
11
|
+
var percentCompleted = 0;
|
|
12
|
+
if (Number.isFinite(currentTime) && Number.isFinite(duration) && duration > 0) {
|
|
13
|
+
var rawPercent = (currentTime / duration) * 100;
|
|
14
|
+
// Clamp to [0, 100] to avoid invalid analytics values.
|
|
15
|
+
percentCompleted = Math.min(100, Math.max(0, rawPercent));
|
|
16
|
+
}
|
|
17
|
+
return percentCompleted;
|
|
18
|
+
}
|
|
19
|
+
function getPauseData(videoEl) {
|
|
20
|
+
var currentTime = videoEl.currentTime;
|
|
21
|
+
var duration = videoEl.duration;
|
|
22
|
+
return tslib_1.__assign(tslib_1.__assign({}, getPlayData(videoEl)), { last_position: currentTime, percent_completed: calculatePercentCompleted(currentTime, duration) });
|
|
23
|
+
}
|
|
24
|
+
function getEndData(videoEl) {
|
|
25
|
+
return tslib_1.__assign({}, getPauseData(videoEl));
|
|
26
|
+
}
|
|
27
|
+
function getMuxMetadata(videoEl) {
|
|
28
|
+
return {
|
|
29
|
+
mux_playback_id: videoEl.getAttribute('playback-id'),
|
|
30
|
+
mux_video_id: videoEl.getAttribute('metadata-video-id'),
|
|
31
|
+
mux_video_title: videoEl.getAttribute('metadata-video-title'),
|
|
32
|
+
mux_session_id: videoEl.getAttribute('session-id'),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Track a standard HTML video element.
|
|
37
|
+
*
|
|
38
|
+
* @param videoEl - The HTML video element to track.
|
|
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
|
+
* @returns A function to untrack the video.
|
|
42
|
+
*/
|
|
43
|
+
function trackHtmlVideo(videoEl, handlers, customMetadata, vendor) {
|
|
44
|
+
var playHandler = function () {
|
|
45
|
+
var startEvent = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, getPlayData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
|
|
46
|
+
handlers.onPlay(startEvent);
|
|
47
|
+
};
|
|
48
|
+
videoEl.addEventListener('play', playHandler);
|
|
49
|
+
var pauseHandler = function () {
|
|
50
|
+
var pauseEvent = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, getPauseData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
|
|
51
|
+
handlers.onPause(pauseEvent);
|
|
52
|
+
};
|
|
53
|
+
videoEl.addEventListener('pause', pauseHandler);
|
|
54
|
+
var endedHandler = function () {
|
|
55
|
+
var endedEvent = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, getEndData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
|
|
56
|
+
handlers.onEnded(endedEvent);
|
|
57
|
+
};
|
|
58
|
+
videoEl.addEventListener('ended', endedHandler);
|
|
59
|
+
return function () {
|
|
60
|
+
videoEl.removeEventListener('play', playHandler);
|
|
61
|
+
videoEl.removeEventListener('pause', pauseHandler);
|
|
62
|
+
videoEl.removeEventListener('ended', endedHandler);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
exports.trackHtmlVideo = trackHtmlVideo;
|
|
66
|
+
/**
|
|
67
|
+
* Track a Mux HTML video element.
|
|
68
|
+
*
|
|
69
|
+
* @param videoEl - The HTML Mux video element to track.
|
|
70
|
+
* @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
|
+
* @returns A function to untrack the video.
|
|
73
|
+
*/
|
|
74
|
+
function trackMuxHtmlVideo(videoEl, handlers, customMetadata) {
|
|
75
|
+
return trackHtmlVideo(videoEl, handlers, customMetadata, 'mux');
|
|
76
|
+
}
|
|
77
|
+
exports.trackMuxHtmlVideo = trackMuxHtmlVideo;
|
|
78
|
+
function getMuxIframeMetadata(player, elem) {
|
|
79
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
80
|
+
var _a, duration, currentTime, url, metadataVideoTitle, metadataVideoId, playerId;
|
|
81
|
+
return tslib_1.__generator(this, function (_b) {
|
|
82
|
+
switch (_b.label) {
|
|
83
|
+
case 0: return [4 /*yield*/, Promise.all([
|
|
84
|
+
new Promise(function (resolve) { return player.getDuration(resolve); }),
|
|
85
|
+
new Promise(function (resolve) { return player.getCurrentTime(resolve); }),
|
|
86
|
+
])];
|
|
87
|
+
case 1:
|
|
88
|
+
_a = tslib_1.__read.apply(void 0, [_b.sent(), 2]), duration = _a[0], currentTime = _a[1];
|
|
89
|
+
metadataVideoTitle = null, metadataVideoId = null, playerId = null;
|
|
90
|
+
try {
|
|
91
|
+
url = new URL(elem.getAttribute('src'));
|
|
92
|
+
metadataVideoTitle = url.searchParams.get('metadata-video-title');
|
|
93
|
+
metadataVideoId = url.searchParams.get('metadata-video-id');
|
|
94
|
+
playerId = url.pathname.split('/').pop();
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
// invalid or no src url, skip the header metadata
|
|
98
|
+
}
|
|
99
|
+
return [2 /*return*/, {
|
|
100
|
+
percent_completed: calculatePercentCompleted(currentTime, duration),
|
|
101
|
+
program_duration: duration,
|
|
102
|
+
last_position: currentTime,
|
|
103
|
+
mux_video_title: metadataVideoTitle,
|
|
104
|
+
mux_video_id: metadataVideoId,
|
|
105
|
+
mux_playback_id: playerId,
|
|
106
|
+
}];
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
|
|
112
|
+
var onUnsubscribe = [];
|
|
113
|
+
var readyHandler = function () {
|
|
114
|
+
var elem = player.elem;
|
|
115
|
+
var playHandler = function () {
|
|
116
|
+
getMuxIframeMetadata(player, elem)
|
|
117
|
+
.then(function (playerState) {
|
|
118
|
+
var startEvent = tslib_1.__assign(tslib_1.__assign({}, playerState), customMetadata);
|
|
119
|
+
handlers.onPlay(startEvent);
|
|
120
|
+
})
|
|
121
|
+
.catch(function (error) {
|
|
122
|
+
handlers.onError("Error getting Mux iframe metadata from 'play' handler: ".concat(error));
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
player.on('play', playHandler);
|
|
126
|
+
onUnsubscribe.push(function () { return player.off('play', playHandler); });
|
|
127
|
+
var pauseHandler = function () {
|
|
128
|
+
getMuxIframeMetadata(player, elem)
|
|
129
|
+
.then(function (playerState) {
|
|
130
|
+
var pauseEvent = tslib_1.__assign(tslib_1.__assign({}, playerState), customMetadata);
|
|
131
|
+
handlers.onPause(pauseEvent);
|
|
132
|
+
})
|
|
133
|
+
.catch(function (error) {
|
|
134
|
+
handlers.onError("Error getting Mux iframe metadata from 'pause' handler: ".concat(error));
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
player.on('pause', pauseHandler);
|
|
138
|
+
onUnsubscribe.push(function () { return player.off('pause', pauseHandler); });
|
|
139
|
+
var endedHandler = function () {
|
|
140
|
+
getMuxIframeMetadata(player, elem)
|
|
141
|
+
.then(function (playerState) {
|
|
142
|
+
var endedEvent = tslib_1.__assign(tslib_1.__assign({}, playerState), customMetadata);
|
|
143
|
+
handlers.onEnded(endedEvent);
|
|
144
|
+
})
|
|
145
|
+
.catch(function (error) {
|
|
146
|
+
handlers.onError("Error getting Mux iframe metadata from 'ended' handler: ".concat(error));
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
player.on('ended', endedHandler);
|
|
150
|
+
onUnsubscribe.push(function () { return player.off('ended', endedHandler); });
|
|
151
|
+
};
|
|
152
|
+
player.on('ready', readyHandler);
|
|
153
|
+
return function () {
|
|
154
|
+
player.off('ready', readyHandler);
|
|
155
|
+
onUnsubscribe.forEach(function (unsubscribe) { return unsubscribe(); });
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
exports.trackMuxEmbeddedVideo = trackMuxEmbeddedVideo;
|
|
159
|
+
function trackYoutubeEmbeddedVideo() {
|
|
160
|
+
throw new Error('Not implemented');
|
|
161
|
+
}
|
|
162
|
+
exports.trackYoutubeEmbeddedVideo = trackYoutubeEmbeddedVideo;
|
|
163
|
+
function trackVimeoEmbeddedVideo() {
|
|
164
|
+
throw new Error('Not implemented');
|
|
165
|
+
}
|
|
166
|
+
exports.trackVimeoEmbeddedVideo = trackVimeoEmbeddedVideo;
|
|
167
|
+
//# sourceMappingURL=track-video.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
type VideoHandler = {
|
|
2
|
+
onPlay: (startEvent: StartVideoEvent) => void;
|
|
3
|
+
onPause: (pauseEvent: PauseVideoEvent) => void;
|
|
4
|
+
onEnded: (endedEvent: EndedVideoEvent) => void;
|
|
5
|
+
onError: (error: string) => void;
|
|
6
|
+
};
|
|
7
|
+
type BaseVideoEvent = {
|
|
8
|
+
program_duration: number;
|
|
9
|
+
playback_id?: string | undefined;
|
|
10
|
+
video_id?: string | undefined;
|
|
11
|
+
video_title?: string | undefined;
|
|
12
|
+
content_id?: string | undefined;
|
|
13
|
+
content_type?: string | undefined;
|
|
14
|
+
session_id?: string | undefined;
|
|
15
|
+
[key: string]: string | number | boolean | undefined | null;
|
|
16
|
+
};
|
|
17
|
+
type MuxVideoMetadata = {
|
|
18
|
+
mux_playback_id?: string | undefined | null;
|
|
19
|
+
mux_video_id?: string | undefined | null;
|
|
20
|
+
mux_video_title?: string | undefined | null;
|
|
21
|
+
mux_session_id?: string | undefined | null;
|
|
22
|
+
};
|
|
23
|
+
type StartVideoEvent = BaseVideoEvent & MuxVideoMetadata;
|
|
24
|
+
type PauseVideoEvent = BaseVideoEvent & MuxVideoMetadata & {
|
|
25
|
+
last_position?: number | undefined | null;
|
|
26
|
+
percent_completed: number;
|
|
27
|
+
};
|
|
28
|
+
type MuxEmbeddedPlayer = {
|
|
29
|
+
getCurrentTime: (cb: (time: number) => void) => void;
|
|
30
|
+
getDuration: (cb: (duration: number) => void) => void;
|
|
31
|
+
on: (event: string, callback: () => void) => void;
|
|
32
|
+
off: (event: string, callback: () => void) => void;
|
|
33
|
+
elem: HTMLIFrameElement;
|
|
34
|
+
};
|
|
35
|
+
type EndedVideoEvent = PauseVideoEvent;
|
|
36
|
+
type MuxElement = EventTarget & Element & {
|
|
37
|
+
duration: number;
|
|
38
|
+
currentTime: number;
|
|
39
|
+
play?: () => Promise<unknown>;
|
|
40
|
+
pause?: () => void;
|
|
41
|
+
};
|
|
42
|
+
export { VideoHandler, BaseVideoEvent, MuxVideoMetadata, StartVideoEvent, PauseVideoEvent, EndedVideoEvent, MuxElement, MuxEmbeddedPlayer, };
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VideoHandler, MuxEmbeddedPlayer, MuxElement } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Track a standard HTML video element.
|
|
4
|
+
*
|
|
5
|
+
* @param videoEl - The HTML video element to track.
|
|
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
|
+
* @returns A function to untrack the video.
|
|
9
|
+
*/
|
|
10
|
+
export declare function trackHtmlVideo(videoEl: HTMLVideoElement | MuxElement, handlers: VideoHandler, customMetadata: Record<string, string | number | boolean>, vendor?: 'mux'): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Track a Mux HTML video element.
|
|
13
|
+
*
|
|
14
|
+
* @param videoEl - The HTML Mux video element to track.
|
|
15
|
+
* @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
|
+
* @returns A function to untrack the video.
|
|
18
|
+
*/
|
|
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;
|
|
21
|
+
export declare function trackYoutubeEmbeddedVideo(): void;
|
|
22
|
+
export declare function trackVimeoEmbeddedVideo(): void;
|
|
23
|
+
//# sourceMappingURL=track-video.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { __assign, __awaiter, __generator, __read } from "tslib";
|
|
2
|
+
function getPlayData(videoEl) {
|
|
3
|
+
return {
|
|
4
|
+
program_duration: videoEl.duration,
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
function calculatePercentCompleted(currentTime, duration) {
|
|
8
|
+
var percentCompleted = 0;
|
|
9
|
+
if (Number.isFinite(currentTime) && Number.isFinite(duration) && duration > 0) {
|
|
10
|
+
var rawPercent = (currentTime / duration) * 100;
|
|
11
|
+
// Clamp to [0, 100] to avoid invalid analytics values.
|
|
12
|
+
percentCompleted = Math.min(100, Math.max(0, rawPercent));
|
|
13
|
+
}
|
|
14
|
+
return percentCompleted;
|
|
15
|
+
}
|
|
16
|
+
function getPauseData(videoEl) {
|
|
17
|
+
var currentTime = videoEl.currentTime;
|
|
18
|
+
var duration = videoEl.duration;
|
|
19
|
+
return __assign(__assign({}, getPlayData(videoEl)), { last_position: currentTime, percent_completed: calculatePercentCompleted(currentTime, duration) });
|
|
20
|
+
}
|
|
21
|
+
function getEndData(videoEl) {
|
|
22
|
+
return __assign({}, getPauseData(videoEl));
|
|
23
|
+
}
|
|
24
|
+
function getMuxMetadata(videoEl) {
|
|
25
|
+
return {
|
|
26
|
+
mux_playback_id: videoEl.getAttribute('playback-id'),
|
|
27
|
+
mux_video_id: videoEl.getAttribute('metadata-video-id'),
|
|
28
|
+
mux_video_title: videoEl.getAttribute('metadata-video-title'),
|
|
29
|
+
mux_session_id: videoEl.getAttribute('session-id'),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Track a standard HTML video element.
|
|
34
|
+
*
|
|
35
|
+
* @param videoEl - The HTML video element to track.
|
|
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
|
+
* @returns A function to untrack the video.
|
|
39
|
+
*/
|
|
40
|
+
export function trackHtmlVideo(videoEl, handlers, customMetadata, vendor) {
|
|
41
|
+
var playHandler = function () {
|
|
42
|
+
var startEvent = __assign(__assign(__assign({}, getPlayData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
|
|
43
|
+
handlers.onPlay(startEvent);
|
|
44
|
+
};
|
|
45
|
+
videoEl.addEventListener('play', playHandler);
|
|
46
|
+
var pauseHandler = function () {
|
|
47
|
+
var pauseEvent = __assign(__assign(__assign({}, getPauseData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
|
|
48
|
+
handlers.onPause(pauseEvent);
|
|
49
|
+
};
|
|
50
|
+
videoEl.addEventListener('pause', pauseHandler);
|
|
51
|
+
var endedHandler = function () {
|
|
52
|
+
var endedEvent = __assign(__assign(__assign({}, getEndData(videoEl)), (vendor === 'mux' ? getMuxMetadata(videoEl) : {})), customMetadata);
|
|
53
|
+
handlers.onEnded(endedEvent);
|
|
54
|
+
};
|
|
55
|
+
videoEl.addEventListener('ended', endedHandler);
|
|
56
|
+
return function () {
|
|
57
|
+
videoEl.removeEventListener('play', playHandler);
|
|
58
|
+
videoEl.removeEventListener('pause', pauseHandler);
|
|
59
|
+
videoEl.removeEventListener('ended', endedHandler);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Track a Mux HTML video element.
|
|
64
|
+
*
|
|
65
|
+
* @param videoEl - The HTML Mux video element to track.
|
|
66
|
+
* @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
|
+
* @returns A function to untrack the video.
|
|
69
|
+
*/
|
|
70
|
+
export function trackMuxHtmlVideo(videoEl, handlers, customMetadata) {
|
|
71
|
+
return trackHtmlVideo(videoEl, handlers, customMetadata, 'mux');
|
|
72
|
+
}
|
|
73
|
+
function getMuxIframeMetadata(player, elem) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
75
|
+
var _a, duration, currentTime, url, metadataVideoTitle, metadataVideoId, playerId;
|
|
76
|
+
return __generator(this, function (_b) {
|
|
77
|
+
switch (_b.label) {
|
|
78
|
+
case 0: return [4 /*yield*/, Promise.all([
|
|
79
|
+
new Promise(function (resolve) { return player.getDuration(resolve); }),
|
|
80
|
+
new Promise(function (resolve) { return player.getCurrentTime(resolve); }),
|
|
81
|
+
])];
|
|
82
|
+
case 1:
|
|
83
|
+
_a = __read.apply(void 0, [_b.sent(), 2]), duration = _a[0], currentTime = _a[1];
|
|
84
|
+
metadataVideoTitle = null, metadataVideoId = null, playerId = null;
|
|
85
|
+
try {
|
|
86
|
+
url = new URL(elem.getAttribute('src'));
|
|
87
|
+
metadataVideoTitle = url.searchParams.get('metadata-video-title');
|
|
88
|
+
metadataVideoId = url.searchParams.get('metadata-video-id');
|
|
89
|
+
playerId = url.pathname.split('/').pop();
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
// invalid or no src url, skip the header metadata
|
|
93
|
+
}
|
|
94
|
+
return [2 /*return*/, {
|
|
95
|
+
percent_completed: calculatePercentCompleted(currentTime, duration),
|
|
96
|
+
program_duration: duration,
|
|
97
|
+
last_position: currentTime,
|
|
98
|
+
mux_video_title: metadataVideoTitle,
|
|
99
|
+
mux_video_id: metadataVideoId,
|
|
100
|
+
mux_playback_id: playerId,
|
|
101
|
+
}];
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
export function trackMuxEmbeddedVideo(player, handlers, customMetadata) {
|
|
107
|
+
var onUnsubscribe = [];
|
|
108
|
+
var readyHandler = function () {
|
|
109
|
+
var elem = player.elem;
|
|
110
|
+
var playHandler = function () {
|
|
111
|
+
getMuxIframeMetadata(player, elem)
|
|
112
|
+
.then(function (playerState) {
|
|
113
|
+
var startEvent = __assign(__assign({}, playerState), customMetadata);
|
|
114
|
+
handlers.onPlay(startEvent);
|
|
115
|
+
})
|
|
116
|
+
.catch(function (error) {
|
|
117
|
+
handlers.onError("Error getting Mux iframe metadata from 'play' handler: ".concat(error));
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
player.on('play', playHandler);
|
|
121
|
+
onUnsubscribe.push(function () { return player.off('play', playHandler); });
|
|
122
|
+
var pauseHandler = function () {
|
|
123
|
+
getMuxIframeMetadata(player, elem)
|
|
124
|
+
.then(function (playerState) {
|
|
125
|
+
var pauseEvent = __assign(__assign({}, playerState), customMetadata);
|
|
126
|
+
handlers.onPause(pauseEvent);
|
|
127
|
+
})
|
|
128
|
+
.catch(function (error) {
|
|
129
|
+
handlers.onError("Error getting Mux iframe metadata from 'pause' handler: ".concat(error));
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
player.on('pause', pauseHandler);
|
|
133
|
+
onUnsubscribe.push(function () { return player.off('pause', pauseHandler); });
|
|
134
|
+
var endedHandler = function () {
|
|
135
|
+
getMuxIframeMetadata(player, elem)
|
|
136
|
+
.then(function (playerState) {
|
|
137
|
+
var endedEvent = __assign(__assign({}, playerState), customMetadata);
|
|
138
|
+
handlers.onEnded(endedEvent);
|
|
139
|
+
})
|
|
140
|
+
.catch(function (error) {
|
|
141
|
+
handlers.onError("Error getting Mux iframe metadata from 'ended' handler: ".concat(error));
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
player.on('ended', endedHandler);
|
|
145
|
+
onUnsubscribe.push(function () { return player.off('ended', endedHandler); });
|
|
146
|
+
};
|
|
147
|
+
player.on('ready', readyHandler);
|
|
148
|
+
return function () {
|
|
149
|
+
player.off('ready', readyHandler);
|
|
150
|
+
onUnsubscribe.forEach(function (unsubscribe) { return unsubscribe(); });
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export function trackYoutubeEmbeddedVideo() {
|
|
154
|
+
throw new Error('Not implemented');
|
|
155
|
+
}
|
|
156
|
+
export function trackVimeoEmbeddedVideo() {
|
|
157
|
+
throw new Error('Not implemented');
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=track-video.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
type VideoHandler = {
|
|
2
|
+
onPlay: (startEvent: StartVideoEvent) => void;
|
|
3
|
+
onPause: (pauseEvent: PauseVideoEvent) => void;
|
|
4
|
+
onEnded: (endedEvent: EndedVideoEvent) => void;
|
|
5
|
+
onError: (error: string) => void;
|
|
6
|
+
};
|
|
7
|
+
type BaseVideoEvent = {
|
|
8
|
+
program_duration: number;
|
|
9
|
+
playback_id?: string | undefined;
|
|
10
|
+
video_id?: string | undefined;
|
|
11
|
+
video_title?: string | undefined;
|
|
12
|
+
content_id?: string | undefined;
|
|
13
|
+
content_type?: string | undefined;
|
|
14
|
+
session_id?: string | undefined;
|
|
15
|
+
[key: string]: string | number | boolean | undefined | null;
|
|
16
|
+
};
|
|
17
|
+
type MuxVideoMetadata = {
|
|
18
|
+
mux_playback_id?: string | undefined | null;
|
|
19
|
+
mux_video_id?: string | undefined | null;
|
|
20
|
+
mux_video_title?: string | undefined | null;
|
|
21
|
+
mux_session_id?: string | undefined | null;
|
|
22
|
+
};
|
|
23
|
+
type StartVideoEvent = BaseVideoEvent & MuxVideoMetadata;
|
|
24
|
+
type PauseVideoEvent = BaseVideoEvent & MuxVideoMetadata & {
|
|
25
|
+
last_position?: number | undefined | null;
|
|
26
|
+
percent_completed: number;
|
|
27
|
+
};
|
|
28
|
+
type MuxEmbeddedPlayer = {
|
|
29
|
+
getCurrentTime: (cb: (time: number) => void) => void;
|
|
30
|
+
getDuration: (cb: (duration: number) => void) => void;
|
|
31
|
+
on: (event: string, callback: () => void) => void;
|
|
32
|
+
off: (event: string, callback: () => void) => void;
|
|
33
|
+
elem: HTMLIFrameElement;
|
|
34
|
+
};
|
|
35
|
+
type EndedVideoEvent = PauseVideoEvent;
|
|
36
|
+
type MuxElement = EventTarget & Element & {
|
|
37
|
+
duration: number;
|
|
38
|
+
currentTime: number;
|
|
39
|
+
play?: () => Promise<unknown>;
|
|
40
|
+
pause?: () => void;
|
|
41
|
+
};
|
|
42
|
+
export { VideoHandler, BaseVideoEvent, MuxVideoMetadata, StartVideoEvent, PauseVideoEvent, EndedVideoEvent, MuxElement, MuxEmbeddedPlayer, };
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +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"]}
|