Skip to content

Commit

Permalink
Merge pull request #116 from bitmovin/feature/PW-21228-track-ad-trans…
Browse files Browse the repository at this point in the history
…itions-as-stalling

Include ad events in stall tracking
  • Loading branch information
wasp898 authored Nov 26, 2024
2 parents 4e8fb3d + c4a3de4 commit 2c7077b
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Fixed
- Ad-related delays not contributing to rebuffering metrics

## [5.4.0] - 2024-08-27
### Added
- Possibility to start session tracking without a `Player` instance
Expand Down
46 changes: 46 additions & 0 deletions spec/tests/ConvivaAnalyticsTracker.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PlayerEvent, PlayerEventBase } from "bitmovin-player";
import { ConvivaAnalyticsTracker } from "../../src/ts/ConvivaAnalyticsTracker";
import { MockHelper } from "../helper/MockHelper";
import * as Conviva from '@convivainc/conviva-js-coresdk';
Expand Down Expand Up @@ -75,6 +76,51 @@ describe(ConvivaAnalyticsTracker, () => {

expect(invokedTimesAfter).toBe(invokedTimesBefore);
})

describe('trackPlaybackStateChanged', () => {
let convivaAnalyticsTracker: ConvivaAnalyticsTracker;

beforeEach(() => {
convivaAnalyticsTracker = new ConvivaAnalyticsTracker('test-key');

const {playerMock} = MockHelper.createPlayerMock();
convivaAnalyticsTracker.attachPlayer(playerMock);
jest.spyOn(playerMock, 'getSource').mockImplementation(() => ({ title: 'test-title' }));
convivaAnalyticsTracker.initializeSession();
})

test.each([
PlayerEvent.Play,
PlayerEvent.Seek,
PlayerEvent.TimeShift,
PlayerEvent.AdBreakStarted,
PlayerEvent.AdFinished,
])('should start timer for stalling when reported player event is %s', (event) => {
const stallTrackingStartTimeoutSpy = jest.spyOn(convivaAnalyticsTracker['stallTrackingTimeout'], 'start');

convivaAnalyticsTracker.trackPlaybackStateChanged({ type: event } as PlayerEventBase);

expect(stallTrackingStartTimeoutSpy).toHaveBeenCalled();
})

test.each([
PlayerEvent.StallStarted,
PlayerEvent.Playing,
PlayerEvent.Paused,
PlayerEvent.Seeked,
PlayerEvent.TimeShifted,
PlayerEvent.StallEnded,
PlayerEvent.PlaybackFinished,
PlayerEvent.AdStarted,
PlayerEvent.AdBreakFinished,
])('should clear timer for stalling when reported player event is %s', (event) => {
const stallTrackingStopTimeoutSpy = jest.spyOn(convivaAnalyticsTracker['stallTrackingTimeout'], 'clear');

convivaAnalyticsTracker.trackPlaybackStateChanged({ type: event } as PlayerEventBase);

expect(stallTrackingStopTimeoutSpy).toHaveBeenCalled();
})
})
})

const getInvokedTimes = (mock: unknown) => {
Expand Down
4 changes: 4 additions & 0 deletions src/ts/ConvivaAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ export class ConvivaAnalytics {
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] adbreak started', event);
this.lastAdBreakEvent = event;
this.convivaAnalyticsTracker.trackAdBreakStarted(Conviva.Constants.AdType.CLIENT_SIDE);
this.convivaAnalyticsTracker.trackPlaybackStateChanged(event);
};

private onAdStarted = (event: AdEvent) => {
Expand All @@ -282,11 +283,13 @@ export class ConvivaAnalytics {
const bitrateKbps = event.ad.data?.bitrate;

this.convivaAnalyticsTracker.trackAdStarted(adInfo, Conviva.Constants.AdType.CLIENT_SIDE, bitrateKbps);
this.convivaAnalyticsTracker.trackPlaybackStateChanged(event);
}

private onAdFinished = (event: AdEvent) => {
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] ad finished', event);
this.convivaAnalyticsTracker.trackAdFinished();
this.convivaAnalyticsTracker.trackPlaybackStateChanged(event);
}

private onAdSkipped = (event: AdEvent) => {
Expand All @@ -298,6 +301,7 @@ export class ConvivaAnalytics {
private onAdBreakFinished = (event: AdBreakEvent) => {
this.debugLog('[ ConvivaAnalytics ] [ Player Event ] adbreak finished', event);
this.convivaAnalyticsTracker.trackAdBreakFinished();
this.convivaAnalyticsTracker.trackPlaybackStateChanged(event);
};

private onAdError = (event: ErrorEvent) => {
Expand Down
6 changes: 5 additions & 1 deletion src/ts/ConvivaAnalyticsTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,15 +621,19 @@ export class ConvivaAnalyticsTracker {
PlayerEvent.Play,
PlayerEvent.Seek,
PlayerEvent.TimeShift,
PlayerEvent.AdBreakStarted,
PlayerEvent.AdFinished,
];
const stallTrackingClearEvents = [
PlayerEvent.StallStarted,
PlayerEvent.StallStarted, // StallStarted is reported as BUFFERING immediately. Does not need the delayed timeout approach.
PlayerEvent.Playing,
PlayerEvent.Paused,
PlayerEvent.Seeked,
PlayerEvent.TimeShifted,
PlayerEvent.StallEnded,
PlayerEvent.PlaybackFinished,
PlayerEvent.AdStarted,
PlayerEvent.AdBreakFinished,
];

if (stallTrackingStartEvents.indexOf(event.type) !== -1) {
Expand Down

0 comments on commit 2c7077b

Please sign in to comment.