Skip to content

Commit

Permalink
Handle Infinity and NaN durations in Html Media Tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
greg-el committed Jun 17, 2024
1 parent e9b9d48 commit fca793d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@snowplow/browser-plugin-media-tracking",
"comment": "Handle Infinity/NaN durations in Media Tracking",
"type": "none"
}
],
"packageName": "@snowplow/browser-plugin-media-tracking"
}
3 changes: 2 additions & 1 deletion plugins/browser-plugin-media-tracking/src/buildMediaEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { eventNames, NETWORK_STATE, READY_STATE } from './constants';
import { MediaElement, MediaPlayer, MediaPlayerEvent, VideoElement } from './contexts';
import {
dataUrlHandler,
getDuration,
getUriFileExtension,
isElementFullScreen,
textTrackListToJson,
Expand Down Expand Up @@ -29,7 +30,7 @@ export function buildMediaEvent(
function getMediaPlayerEntities(el: HTMLAudioElement | HTMLVideoElement, detail?: EventDetail): MediaEntities {
const data: MediaPlayer = {
currentTime: el.currentTime || 0,
duration: el.duration || 0,
duration: getDuration(el),
ended: el.ended,
loop: el.loop,
muted: el.muted,
Expand Down
10 changes: 10 additions & 0 deletions plugins/browser-plugin-media-tracking/src/helperFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,13 @@ export function dataUrlHandler(url: string): string {
}
return url;
}

export function getDuration(el: HTMLAudioElement | HTMLVideoElement): number | null {
const duration = el.duration;
// A NaN value is returned if duration is not available, or Infinity if the media resource is streaming.
if (isNaN(duration) || duration === Infinity) {
return null;
}

return duration;
}
67 changes: 67 additions & 0 deletions plugins/browser-plugin-media-tracking/test/media.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { findMediaElem } from '../src/findMediaElement';
import {
boundaryErrorHandling,
dataUrlHandler,
getDuration,
getUriFileExtension,
trackingOptionsParser,
} from '../src/helperFunctions';
Expand Down Expand Up @@ -239,3 +240,69 @@ describe('getUriFileExtension', () => {
expect(output).toBe(null);
});
});

describe('getDuration of a ', () => {
describe('video element', () => {
it('returns the duration if valid', () => {
const video = { duration: 10 } as HTMLVideoElement;
const output = getDuration(video);
expect(output).toBe(10);
});

it('returns null if the duration is Infinity', () => {
const video = { duration: Infinity } as HTMLVideoElement;
const output = getDuration(video);
expect(output).toBe(null);
});

it('returns null if the duration is +Infinity', () => {
const video = { duration: +Infinity } as HTMLVideoElement;
const output = getDuration(video);
expect(output).toBe(null);
});

it('returns null if the duration is NaN', () => {
const video = { duration: NaN } as HTMLVideoElement;
const output = getDuration(video);
expect(output).toBe(null);
});

it('returns null if the duration is not available', () => {
const video = {} as HTMLVideoElement;
const output = getDuration(video);
expect(output).toBe(null);
});
});

describe('audio element', () => {
it('returns the duration if valid', () => {
const audio = { duration: 10 } as HTMLAudioElement;
const output = getDuration(audio);
expect(output).toBe(10);
});

it('returns null if the duration is Infinity', () => {
const audio = { duration: Infinity } as HTMLAudioElement;
const output = getDuration(audio);
expect(output).toBe(null);
});

it('returns null if the duration is +Infinity', () => {
const audio = { duration: +Infinity } as HTMLAudioElement;
const output = getDuration(audio);
expect(output).toBe(null);
});

it('returns null if the duration is NaN', () => {
const audio = { duration: NaN } as HTMLAudioElement;
const output = getDuration(audio);
expect(output).toBe(null);
});

it('returns null if the duration is not available', () => {
const audio = {} as HTMLAudioElement;
const output = getDuration(audio);
expect(output).toBe(null);
});
});
});

0 comments on commit fca793d

Please sign in to comment.