Skip to content

Commit fca793d

Browse files
committed
Handle Infinity and NaN durations in Html Media Tracking
1 parent e9b9d48 commit fca793d

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@snowplow/browser-plugin-media-tracking",
5+
"comment": "Handle Infinity/NaN durations in Media Tracking",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@snowplow/browser-plugin-media-tracking"
10+
}

plugins/browser-plugin-media-tracking/src/buildMediaEvent.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { eventNames, NETWORK_STATE, READY_STATE } from './constants';
22
import { MediaElement, MediaPlayer, MediaPlayerEvent, VideoElement } from './contexts';
33
import {
44
dataUrlHandler,
5+
getDuration,
56
getUriFileExtension,
67
isElementFullScreen,
78
textTrackListToJson,
@@ -29,7 +30,7 @@ export function buildMediaEvent(
2930
function getMediaPlayerEntities(el: HTMLAudioElement | HTMLVideoElement, detail?: EventDetail): MediaEntities {
3031
const data: MediaPlayer = {
3132
currentTime: el.currentTime || 0,
32-
duration: el.duration || 0,
33+
duration: getDuration(el),
3334
ended: el.ended,
3435
loop: el.loop,
3536
muted: el.muted,

plugins/browser-plugin-media-tracking/src/helperFunctions.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,13 @@ export function dataUrlHandler(url: string): string {
113113
}
114114
return url;
115115
}
116+
117+
export function getDuration(el: HTMLAudioElement | HTMLVideoElement): number | null {
118+
const duration = el.duration;
119+
// A NaN value is returned if duration is not available, or Infinity if the media resource is streaming.
120+
if (isNaN(duration) || duration === Infinity) {
121+
return null;
122+
}
123+
124+
return duration;
125+
}

plugins/browser-plugin-media-tracking/test/media.test.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { findMediaElem } from '../src/findMediaElement';
3333
import {
3434
boundaryErrorHandling,
3535
dataUrlHandler,
36+
getDuration,
3637
getUriFileExtension,
3738
trackingOptionsParser,
3839
} from '../src/helperFunctions';
@@ -239,3 +240,69 @@ describe('getUriFileExtension', () => {
239240
expect(output).toBe(null);
240241
});
241242
});
243+
244+
describe('getDuration of a ', () => {
245+
describe('video element', () => {
246+
it('returns the duration if valid', () => {
247+
const video = { duration: 10 } as HTMLVideoElement;
248+
const output = getDuration(video);
249+
expect(output).toBe(10);
250+
});
251+
252+
it('returns null if the duration is Infinity', () => {
253+
const video = { duration: Infinity } as HTMLVideoElement;
254+
const output = getDuration(video);
255+
expect(output).toBe(null);
256+
});
257+
258+
it('returns null if the duration is +Infinity', () => {
259+
const video = { duration: +Infinity } as HTMLVideoElement;
260+
const output = getDuration(video);
261+
expect(output).toBe(null);
262+
});
263+
264+
it('returns null if the duration is NaN', () => {
265+
const video = { duration: NaN } as HTMLVideoElement;
266+
const output = getDuration(video);
267+
expect(output).toBe(null);
268+
});
269+
270+
it('returns null if the duration is not available', () => {
271+
const video = {} as HTMLVideoElement;
272+
const output = getDuration(video);
273+
expect(output).toBe(null);
274+
});
275+
});
276+
277+
describe('audio element', () => {
278+
it('returns the duration if valid', () => {
279+
const audio = { duration: 10 } as HTMLAudioElement;
280+
const output = getDuration(audio);
281+
expect(output).toBe(10);
282+
});
283+
284+
it('returns null if the duration is Infinity', () => {
285+
const audio = { duration: Infinity } as HTMLAudioElement;
286+
const output = getDuration(audio);
287+
expect(output).toBe(null);
288+
});
289+
290+
it('returns null if the duration is +Infinity', () => {
291+
const audio = { duration: +Infinity } as HTMLAudioElement;
292+
const output = getDuration(audio);
293+
expect(output).toBe(null);
294+
});
295+
296+
it('returns null if the duration is NaN', () => {
297+
const audio = { duration: NaN } as HTMLAudioElement;
298+
const output = getDuration(audio);
299+
expect(output).toBe(null);
300+
});
301+
302+
it('returns null if the duration is not available', () => {
303+
const audio = {} as HTMLAudioElement;
304+
const output = getDuration(audio);
305+
expect(output).toBe(null);
306+
});
307+
});
308+
});

0 commit comments

Comments
 (0)