diff --git a/CHANGELOG.md b/CHANGELOG.md index 02bbe86..5fdc853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ 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 + ## [2.8.0] - 2024-10-30 ### Added diff --git a/src/ts/BitmovinYospacePlayer.ts b/src/ts/BitmovinYospacePlayer.ts index de46ba7..a7b242e 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 { @@ -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 { diff --git a/src/ts/InternalBitmovinYospacePlayer.ts b/src/ts/InternalBitmovinYospacePlayer.ts index 54999ea..9970d7d 100644 --- a/src/ts/InternalBitmovinYospacePlayer.ts +++ b/src/ts/InternalBitmovinYospacePlayer.ts @@ -286,7 +286,7 @@ 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,20 +386,35 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { return this.player.play(issuer); } - pause(issuer?: string): void { - if (this.playerPolicy.canPause()) { - this.player.pause(); - } else { - this.handleYospacePolicyEvent(YospacePolicyErrorCode.PAUSE_NOT_ALLOWED); + 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 adDataUpdatedPromise = 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 adDataUpdatedPromise; + }; + + pause(issuer?: string): void { + 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); } /** diff --git a/src/ts/YospaceListenerAdapter.ts b/src/ts/YospaceListenerAdapter.ts index f015fff..9986fb2 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 { @@ -9,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 = @@ -94,7 +96,9 @@ export class YospaceAdListenerAdapter { } onAnalyticUpdate() { - // No op + this.emitEvent({ + type: BYSListenerEvent.ANALYTIC_UPDATED, + } as BYSListenerEventBase); } onTrackingEvent(type: BYSTrackingEventType) { @@ -115,11 +119,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'); }