From b7c2ab201a13f264f34918da596fa821725f4e47 Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Tue, 3 Dec 2024 17:12:55 +0100 Subject: [PATCH 01/10] Add missing issuer for pause and mute --- src/ts/BitmovinYospacePlayer.ts | 4 ++-- src/ts/InternalBitmovinYospacePlayer.ts | 12 ++---------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/ts/BitmovinYospacePlayer.ts b/src/ts/BitmovinYospacePlayer.ts index de46ba7..267c389 100644 --- a/src/ts/BitmovinYospacePlayer.ts +++ b/src/ts/BitmovinYospacePlayer.ts @@ -483,11 +483,11 @@ export class BitmovinYospacePlayer implements BitmovinYospacePlayerAPI { } mute(issuer?: string): void { - return this.player.mute(); + return this.player.mute(issuer); } pause(issuer?: string): void { - return this.player.pause(); + return this.player.pause(issuer); } play(issuer?: string): Promise { diff --git a/src/ts/InternalBitmovinYospacePlayer.ts b/src/ts/InternalBitmovinYospacePlayer.ts index 54999ea..371e87d 100644 --- a/src/ts/InternalBitmovinYospacePlayer.ts +++ b/src/ts/InternalBitmovinYospacePlayer.ts @@ -387,19 +387,11 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { } pause(issuer?: string): void { - if (this.playerPolicy.canPause()) { - this.player.pause(); - } else { - this.handleYospacePolicyEvent(YospacePolicyErrorCode.PAUSE_NOT_ALLOWED); - } + this.playerPolicy.canPause() ? this.player.pause(issuer) : this.handleYospacePolicyEvent(YospacePolicyErrorCode.PAUSE_NOT_ALLOWED); } mute(issuer?: string): void { - if (this.playerPolicy.canMute()) { - this.player.mute(); - } else { - this.handleYospacePolicyEvent(YospacePolicyErrorCode.MUTE_NOT_ALLOWED); - } + this.playerPolicy.canMute() ? this.player.mute(issuer) : this.handleYospacePolicyEvent(YospacePolicyErrorCode.MUTE_NOT_ALLOWED); } /** From aed22b199ec9d3a9ae20c6ecfb5f05577df993f5 Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Tue, 3 Dec 2024 17:17:06 +0100 Subject: [PATCH 02/10] Only import types where needed --- src/ts/YospaceListenerAdapter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ts/YospaceListenerAdapter.ts b/src/ts/YospaceListenerAdapter.ts index f015fff..72e0972 100644 --- a/src/ts/YospaceListenerAdapter.ts +++ b/src/ts/YospaceListenerAdapter.ts @@ -1,6 +1,7 @@ -import { AdBreak, Advert } from '@yospace/admanagement-sdk'; import { ArrayUtils } from 'bitmovin-player-ui/dist/js/framework/arrayutils'; import { Logger } from './Logger'; +import type { AdBreak, Advert, Session, SessionErrorCode } from '@yospace/admanagement-sdk'; +import type { TrackingError } from '@yospace/admanagement-sdk/types/Public/TrackingError'; /** BYS -> BitmovinYospace */ export enum BYSListenerEvent { From c3918a6d285f389f60f966600435eb7a5495796c Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Tue, 3 Dec 2024 17:19:18 +0100 Subject: [PATCH 03/10] Add parameters and types for yospace observers --- src/ts/YospaceListenerAdapter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/YospaceListenerAdapter.ts b/src/ts/YospaceListenerAdapter.ts index 72e0972..f00c4a0 100644 --- a/src/ts/YospaceListenerAdapter.ts +++ b/src/ts/YospaceListenerAdapter.ts @@ -116,11 +116,11 @@ export class YospaceAdListenerAdapter { Logger.warn('[BYP][listener] onAdvertBreakEarlyReturn not implemented'); } - onSessionError() { + onSessionError(errorCode: SessionErrorCode) { Logger.warn('[BYP][listener] onSessionError not implemented'); } - onTrackingError() { + onTrackingError(trackingError: TrackingError) { Logger.warn('[BYP][listener] onTrackingError not implemented'); } From b2cf81f465b425de35515dd749719faa80ae770a Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Tue, 3 Dec 2024 17:28:41 +0100 Subject: [PATCH 04/10] Pull yospace ad data when the source was loaded, and delay SourceLoaded event until this was successfully done --- src/ts/InternalBitmovinYospacePlayer.ts | 29 ++++++++++++++++++++++++- src/ts/YospaceListenerAdapter.ts | 5 ++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/ts/InternalBitmovinYospacePlayer.ts b/src/ts/InternalBitmovinYospacePlayer.ts index 371e87d..7bd2b62 100644 --- a/src/ts/InternalBitmovinYospacePlayer.ts +++ b/src/ts/InternalBitmovinYospacePlayer.ts @@ -286,7 +286,11 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { } Logger.log('Loading Source: ' + stringify(clonedSource)); - this.player.load(clonedSource, forceTechnology, disableSeeking).then(resolve).catch(reject); + this.player + .load(clonedSource, forceTechnology, disableSeeking) + .then(() => this.pullYospaceAdDataForLive()) + .then(() => resolve()) + .catch(reject); } else { session.shutdown(); this.session = null; @@ -386,6 +390,29 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { return this.player.play(issuer); } + private pullYospaceAdDataForLive(): Promise { + if ( + (this.yospaceSourceConfig.assetType !== YospaceAssetType.DVRLIVE && this.yospaceSourceConfig.assetType !== YospaceAssetType.LINEAR) || + this.startSent + ) { + // Manually triggering the Yospace ad data update is only needed for Live and DVRLive sessions, and only the first time the stream is started. + return Promise.resolve(); + } + + const adBreakUpdatePromise = new Promise((resolve, reject) => { + const onAnalyticUpdate = () => { + this.yospaceListenerAdapter.removeListener(BYSListenerEvent.ANALYTIC_UPDATED, onAnalyticUpdate); + resolve(); + }; + + this.yospaceListenerAdapter.addListener(BYSListenerEvent.ANALYTIC_UPDATED, onAnalyticUpdate); + }); + + this.session.onPlayerEvent(YsPlayerEvent.PLAYBACK_READY, 0); + + return adBreakUpdatePromise; + } + pause(issuer?: string): void { this.playerPolicy.canPause() ? this.player.pause(issuer) : this.handleYospacePolicyEvent(YospacePolicyErrorCode.PAUSE_NOT_ALLOWED); } diff --git a/src/ts/YospaceListenerAdapter.ts b/src/ts/YospaceListenerAdapter.ts index f00c4a0..9986fb2 100644 --- a/src/ts/YospaceListenerAdapter.ts +++ b/src/ts/YospaceListenerAdapter.ts @@ -10,6 +10,7 @@ export enum BYSListenerEvent { ADVERT_END = 'advert_end', AD_BREAK_END = 'ad_break_end', ANALYTICS_FIRED = 'analytics_fired', + ANALYTIC_UPDATED = 'analytics_updated', } export type BYSTrackingEventType = @@ -95,7 +96,9 @@ export class YospaceAdListenerAdapter { } onAnalyticUpdate() { - // No op + this.emitEvent({ + type: BYSListenerEvent.ANALYTIC_UPDATED, + } as BYSListenerEventBase); } onTrackingEvent(type: BYSTrackingEventType) { From e989c9d06d4be1f582bb7bb5f36979705fae1716 Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Tue, 3 Dec 2024 17:33:55 +0100 Subject: [PATCH 05/10] Add missing issuer for unmute --- src/ts/BitmovinYospacePlayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/BitmovinYospacePlayer.ts b/src/ts/BitmovinYospacePlayer.ts index 267c389..a7b242e 100644 --- a/src/ts/BitmovinYospacePlayer.ts +++ b/src/ts/BitmovinYospacePlayer.ts @@ -559,7 +559,7 @@ export class BitmovinYospacePlayer implements BitmovinYospacePlayerAPI { } unmute(issuer?: string): void { - return this.player.unmute(); + return this.player.unmute(issuer); } setAspectRatio(aspectratio: string | number): void { From 94e4a1466fdc0caca87c854ec3081a0fa6a39291 Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Tue, 3 Dec 2024 17:34:40 +0100 Subject: [PATCH 06/10] Add changelog event for missing issuer --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02bbe86..69db41f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed + +- Missing `issuer` in `Muted`, `Unmuted` and `Paused` events + ## [2.8.0] - 2024-10-30 ### Added From 433f2c6cf64227234f33ca516bfec7e11a202d49 Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Tue, 3 Dec 2024 17:35:16 +0100 Subject: [PATCH 07/10] Add changelog event for changed startup behavior --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69db41f..5fdc853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Changed + +- Improve startup behavior for `LINEAR` and `DVRLIVE` streams according to https://developer.yospace.com/sdk-documentation/javascript/userguide/yosdk/latest/en/optimising-user-experience-at-video-start.html + ### Fixed - Missing `issuer` in `Muted`, `Unmuted` and `Paused` events From dcf40cdbdcb7ae04b158b649adfbc95ee98629d7 Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Thu, 5 Dec 2024 09:43:34 +0100 Subject: [PATCH 08/10] Update src/ts/InternalBitmovinYospacePlayer.ts Co-authored-by: David Steinacher --- src/ts/InternalBitmovinYospacePlayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/InternalBitmovinYospacePlayer.ts b/src/ts/InternalBitmovinYospacePlayer.ts index 7bd2b62..be8a46a 100644 --- a/src/ts/InternalBitmovinYospacePlayer.ts +++ b/src/ts/InternalBitmovinYospacePlayer.ts @@ -399,7 +399,7 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { return Promise.resolve(); } - const adBreakUpdatePromise = new Promise((resolve, reject) => { + const adDataUpdatedPromise = new Promise((resolve, reject) => { const onAnalyticUpdate = () => { this.yospaceListenerAdapter.removeListener(BYSListenerEvent.ANALYTIC_UPDATED, onAnalyticUpdate); resolve(); From e1029a1d0524290bdaef68fa03e571b475ee4d63 Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Thu, 5 Dec 2024 09:44:01 +0100 Subject: [PATCH 09/10] Update src/ts/InternalBitmovinYospacePlayer.ts Co-authored-by: David Steinacher --- src/ts/InternalBitmovinYospacePlayer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/InternalBitmovinYospacePlayer.ts b/src/ts/InternalBitmovinYospacePlayer.ts index be8a46a..65fb5c5 100644 --- a/src/ts/InternalBitmovinYospacePlayer.ts +++ b/src/ts/InternalBitmovinYospacePlayer.ts @@ -288,8 +288,8 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { Logger.log('Loading Source: ' + stringify(clonedSource)); this.player .load(clonedSource, forceTechnology, disableSeeking) - .then(() => this.pullYospaceAdDataForLive()) - .then(() => resolve()) + .then(this.pullYospaceAdDataForLive) + .then(resolve) .catch(reject); } else { session.shutdown(); From 6ea259e826a861c3fcdbfdc4495a2cbb3c47a8fd Mon Sep 17 00:00:00 2001 From: Daniel Weinberger Date: Thu, 5 Dec 2024 09:46:41 +0100 Subject: [PATCH 10/10] Change pullYospaceAdDataForLive to an arrow function --- src/ts/InternalBitmovinYospacePlayer.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ts/InternalBitmovinYospacePlayer.ts b/src/ts/InternalBitmovinYospacePlayer.ts index 65fb5c5..9970d7d 100644 --- a/src/ts/InternalBitmovinYospacePlayer.ts +++ b/src/ts/InternalBitmovinYospacePlayer.ts @@ -286,11 +286,7 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { } Logger.log('Loading Source: ' + stringify(clonedSource)); - this.player - .load(clonedSource, forceTechnology, disableSeeking) - .then(this.pullYospaceAdDataForLive) - .then(resolve) - .catch(reject); + this.player.load(clonedSource, forceTechnology, disableSeeking).then(this.pullYospaceAdDataForLive).then(resolve).catch(reject); } else { session.shutdown(); this.session = null; @@ -390,7 +386,7 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { return this.player.play(issuer); } - private pullYospaceAdDataForLive(): Promise { + private pullYospaceAdDataForLive = (): Promise => { if ( (this.yospaceSourceConfig.assetType !== YospaceAssetType.DVRLIVE && this.yospaceSourceConfig.assetType !== YospaceAssetType.LINEAR) || this.startSent @@ -410,8 +406,8 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { this.session.onPlayerEvent(YsPlayerEvent.PLAYBACK_READY, 0); - return adBreakUpdatePromise; - } + return adDataUpdatedPromise; + }; pause(issuer?: string): void { this.playerPolicy.canPause() ? this.player.pause(issuer) : this.handleYospacePolicyEvent(YospacePolicyErrorCode.PAUSE_NOT_ALLOWED);