@dolby-optiview/ads-sdk-adapter-theoplayer 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { PlayerAdapter, PlayerAdapterEvent, PlayerAdapterEventHandler, VideoQuality } from '@dolby-optiview/ads-sdk-core';
|
|
1
|
+
import type { ExternalPlaybackState, PlayerAdapter, PlayerAdapterEvent, PlayerAdapterEventHandler, VideoQuality } from '@dolby-optiview/ads-sdk-core';
|
|
2
2
|
import { type THEONetworkLike } from './dashPtsOffset';
|
|
3
|
+
import { type THEOCastLike } from './theoExternalPlayback';
|
|
3
4
|
/** Minimal surface of a THEOplayer metadata `TextTrackCue`. */
|
|
4
5
|
export interface THEOTextTrackCueLike {
|
|
5
6
|
startTime?: number;
|
|
@@ -137,6 +138,8 @@ export interface THEOplayerLike {
|
|
|
137
138
|
/** The start of the seekable range at index, in seconds, when supported. */
|
|
138
139
|
start?(index: number): number;
|
|
139
140
|
};
|
|
141
|
+
/** Casting facilities; `cast.airplay` reports AirPlay state. Optional. */
|
|
142
|
+
readonly cast?: THEOCastLike;
|
|
140
143
|
/** Video rendition ladder; absent on builds or sources without selectable qualities. */
|
|
141
144
|
readonly videoTracks?: ArrayLike<THEOMediaTrackLike>;
|
|
142
145
|
/** Playback rate, `1` being normal. THEOplayer's latency manager drives this itself. */
|
|
@@ -224,6 +227,8 @@ export declare class THEOplayerAdapter implements PlayerAdapter {
|
|
|
224
227
|
private cueEnters;
|
|
225
228
|
private seenCues;
|
|
226
229
|
private readonly dashPtsOffsets;
|
|
230
|
+
private readonly externalPlayback;
|
|
231
|
+
private readonly externalPlaybackGate;
|
|
227
232
|
/**
|
|
228
233
|
* @param player The THEOplayer instance (a `ChromelessPlayer` or anything satisfying {@link THEOplayerLike}).
|
|
229
234
|
* @param container The element the player was created in; the SDK locates the `<video>` inside it.
|
|
@@ -373,6 +378,8 @@ export declare class THEOplayerAdapter implements PlayerAdapter {
|
|
|
373
378
|
}): Promise<void>;
|
|
374
379
|
on(event: PlayerAdapterEvent, handler: PlayerAdapterEventHandler): void;
|
|
375
380
|
off(event: PlayerAdapterEvent, handler: PlayerAdapterEventHandler): void;
|
|
381
|
+
get externalPlaybackState(): ExternalPlaybackState | undefined;
|
|
382
|
+
setExternalPlaybackAllowed(allowed: boolean): void;
|
|
376
383
|
destroy(): void;
|
|
377
384
|
private emit;
|
|
378
385
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toMediaErrorPayload as e}from"./theoErrorToMediaError";import{decodeGeobData as t,toUint8Array as r}from"./cueBytes";import{DashPtsOffsetTracker as s}from"./dashPtsOffset";export function inferSourceType(e){const t=e.split(/[?#]/,1)[0].toLowerCase();return t.endsWith(".mp4")||t.endsWith(".m4v")?"video/mp4":t.endsWith(".webm")?"video/webm":"application/x-mpegurl"}export function withLiveOffset(e,t){const r=e.sources,s=e=>"object"==typeof e&&null!==e&&Object.getPrototypeOf(e)===Object.prototype;return s(e)&&Array.isArray(r)&&0!==r.length&&void 0===e.liveOffset&&r.every(e=>s(e)&&void 0===e.liveOffset)?{...e,sources:r.map(e=>({...e,liveOffset:t}))}:null}export class THEOplayerAdapter{constructor(e,t){this.endedSuppressedUntilStart=!1,this.pendingSeekTime=null,this.liveRemapCleanup=null,this.eventListeners=new Map,this.boundHandlers=new Map,this.pinnedTrack=null,this.cueTracks=[],this.liveStartOffset=null,this.frameLoaded=!1,this.rewrittenSource=null,this.cueEnters=[],this.seenCues=new WeakSet,this.player=e,this.container=t,this.dashPtsOffsets=new s(e.network),this.setupNativeListeners(),this.setupMetadataListener()}get seekableEnd(){const e=this.player.seekable;if(!e||0===e.length)return null;const t=e.end(e.length-1);return"number"==typeof t&&Number.isFinite(t)?t:null}get seekableStart(){const e=this.player.seekable;if(!e?.length)return null;const t=e.start?.(e.length-1);return"number"==typeof t&&Number.isFinite(t)?t:null}get liveEdge(){const e=this.seekableEnd;if(null===e)return null;const t=this.player.source,r=t?.sources?.[0]?.liveOffset??t?.liveOffset;return"number"==typeof r&&Number.isFinite(r)&&r>=0?e+r:e}requestLiveStartOffset(e,t){const r=null!==e&&null!==t?e*t:NaN;return!Number.isFinite(r)||r<=0?(this.liveStartOffset=null,!1):(this.liveStartOffset=r,this.rewriteSourceForLiveStart(),!this.frameLoaded)}rewriteSourceForLiveStart(){const e=this.liveStartOffset,t=this.player.source;if(null===e||this.frameLoaded||!t||t===this.rewrittenSource)return;const r=withLiveOffset(t,e);if(!r)return;this.rewrittenSource=r;const s=!this.player.paused;this.player.source=r,s&&this.player.play()}get playbackRate(){return this.player.playbackRate??1}set playbackRate(e){this.player.playbackRate=e}setVideoQuality(e){if(null===e){const e=this.pinnedTrack;if(!e)return!1;const t=this.targetQualityBeforePin;try{return e.targetQuality=t,e.targetQuality!==t?!1:(this.pinnedTrack=null,this.targetQualityBeforePin=void 0,!0)}catch{return!1}}const t=this.player.videoTracks;if(!t||0===t.length)return!1;const r=t[0],s=r?.qualities;if(!r||!s||0===s.length)return!1;const i=[];for(let e=0;e<s.length;e++){const t=s[e];if(!t||!1===t.available||!1===t.enabled)continue;const r=t.bandwidth;"number"==typeof r&&Number.isFinite(r)&&r>0&&i.push(t)}if(i.length<2)return!1;let n=i[0];for(let e=1;e<i.length;e++)i[e].bandwidth<n.bandwidth&&(n=i[e]);const a=!this.pinnedTrack;let l;a&&(this.pinnedTrack=r,this.targetQualityBeforePin=r.targetQuality);try{r.targetQuality=n,l=r.targetQuality===n}catch{l=!1}return!!l||(a&&(this.pinnedTrack=null,this.targetQualityBeforePin=void 0),!1)}get maxLiveSeekPosition(){const e=this.player.latencyManager;if(!e?.monitoringLivePlayback)return null;const t=e.currentLatency,r=e.currentConfiguration?.minimumOffset;if("number"!=typeof t||!Number.isFinite(t))return null;if("number"!=typeof r||!Number.isFinite(r))return null;const s=this.player.currentTime+t-r;return Number.isFinite(s)?s:null}get currentTime(){return this.player.currentTime}set currentTime(e){this.player.currentTime=e}get duration(){return this.player.duration}get isLive(){const e=this.player.duration;return"number"==typeof e?!Number.isFinite(e):null}get paused(){return this.player.paused}get playbackReady(){const e=this.videoElement;return!0!==this.player.seeking&&!!e&&e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!e.seeking}get muted(){return this.player.muted}set muted(e){this.player.muted=e}get volume(){return this.player.volume}set volume(e){this.player.volume=e}get videoElement(){return this.container.querySelector("video")}get programDateTime(){return this.player.currentProgramDateTime}pause(){this.player.pause()}play(){return this.player.play(),Promise.resolve()}seek(e){!0!==this.player.seeking?(this.pendingSeekTime=null,this.player.currentTime=e):this.pendingSeekTime=e}get sourceUrl(){return this.player.source?.sources?.[0]?.src??null}load(e){return this.pendingSeekTime=null,this.player.source={sources:[{src:e,type:inferSourceType(e)}]},this.endedSuppressedUntilStart=!0,Promise.resolve()}async releaseMediaElement(){this.player.pause(),this.player.source=null;const e=this.videoElement;e&&await new Promise(t=>{let r=!1;const s=()=>{r||(r=!0,e.removeEventListener("emptied",s),clearTimeout(i),t())},i=setTimeout(s,250);e.addEventListener("emptied",s,{once:!0})})}async unload(){this.pendingSeekTime=null,await this.releaseMediaElement()}async recreateMediaPipeline(e){const{startTime:t}=e,r=this.player.source;if(!r?.sources?.length)throw new Error("THEOplayer pipeline recreate: no source description");const s=!0===this.isLive,i=this.player.currentProgramDateTime,n=this.player.currentTime,a=i&&Number.isFinite(i.getTime())?i.getTime()+1e3*(t-n):null,l=this.seekableEnd,o=s&&null!==l?Math.max(0,l-t):null;if(await this.releaseMediaElement(),this.endedSuppressedUntilStart=!0,this.player.source=r,this.player.currentTime=t,s){const e=()=>{this.player.removeEventListener("loadedmetadata",t),this.player.removeEventListener("error",e),this.liveRemapCleanup=null},t=()=>{e();const t=this.player.currentProgramDateTime;let r=null;null!==a&&t&&Number.isFinite(t.getTime())?r=this.player.currentTime+(a-t.getTime())/1e3:null!==o&&null!==this.seekableEnd&&(r=this.seekableEnd-o),null!==r&&Math.abs(r-this.player.currentTime)>.5&&(this.player.currentTime=r)};this.liveRemapCleanup=e,this.player.addEventListener("loadedmetadata",t),this.player.addEventListener("error",e)}}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t)}off(e,t){this.eventListeners.get(e)?.delete(t)}destroy(){this.pendingSeekTime=null,this.liveRemapCleanup?.(),this.liveRemapCleanup=null,this.teardownNativeListeners(),this.teardownMetadataListener(),this.dashPtsOffsets.destroy(),this.eventListeners.clear(),this.player.destroy()}emit(e,t){const r=this.eventListeners.get(e);if(r)for(const e of r)e(t)}setupMetadataListener(){const e=this.player.textTracks;if(!e)return;const t=e=>{e.track&&this.subscribeMetadataTrack(e.track)};this.addTrackHandler=t,this.metadataTrackList=e,e.addEventListener("addtrack",t);for(let t=0;t<(e.length??0);t++){const r=e[t];r&&this.subscribeMetadataTrack(r)}}deferMetadataCue(e){"function"==typeof queueMicrotask?queueMicrotask(e):Promise.resolve().then(e)}subscribeMetadataTrack(e){if("metadata"!==(e.kind??e.type))return;if(this.cueTracks.some(({track:t})=>t===e))return;let t=!1;const r=s=>{if(!this.cueTracks.some(({track:t})=>t===e))return;if(t)return void this.deferMetadataCue(()=>r(s));const i=s.cue;if(i&&!this.seenCues.has(i)&&(this.seenCues.add(i),this.emit("timedmetadata",{...this.toCue(i),phase:"parsed"}),"function"==typeof i.addEventListener)){const e=()=>{this.emit("timedmetadata",{...this.toCue(i),phase:"presented"})};i.addEventListener("enter",e),this.cueEnters.push({cue:i,handler:e})}},s="disabled"===e.mode;this.cueTracks.push({track:e,handler:r,enabledByAdapter:s}),e.addEventListener("addcue",r),s&&(t=!0,e.mode="hidden",t=!1);const i=e.cues;if(i&&i.length>0){const t=()=>{if(this.cueTracks.some(({track:t})=>t===e))for(let e=0;e<i.length;e++){const t=i[e];t&&r({cue:t})}};this.deferMetadataCue(t)}}teardownMetadataListener(){this.addTrackHandler&&this.metadataTrackList&&this.metadataTrackList.removeEventListener("addtrack",this.addTrackHandler),this.addTrackHandler=void 0,this.metadataTrackList=void 0;for(const{track:e,handler:t,enabledByAdapter:r}of this.cueTracks)e.removeEventListener("addcue",t),r&&"hidden"===e.mode&&(e.mode="disabled");this.cueTracks=[];for(const{cue:e,handler:t}of this.cueEnters)e.removeEventListener?.("enter",t);this.cueEnters=[],this.seenCues=new WeakSet}toCue(e){if("string"==typeof e.schemeIDURI){const t={type:"emsg",startTime:e.startTime??0,endTime:e.endTime,schemeIdUri:e.schemeIDURI},s=this.dashPtsOffsets.offsetAt(t.startTime);void 0!==s&&(t.ptsOffset=s);const i=r(e.content);return i?(t.raw=i,t.messageData=new TextDecoder("utf-8").decode(i)):"string"==typeof e.content&&(t.messageData=e.content),t}const s={type:"id3",startTime:e.startTime??0,endTime:e.endTime},i=e.content;if(i&&"object"==typeof i){const e=i.id;if("GEOB"===e||"GEO"===e){"string"==typeof i.description&&(s.description=i.description),"string"==typeof i.mimeType&&(s.mimeType=i.mimeType);const e=t(i.data);return void 0!==e&&(s.messageData=e),s}const r=i.text??i.data??i.description;e&&void 0!==r?s.frames={[e]:String(r)}:s.messageData=JSON.stringify(i)}else"string"==typeof i&&(s.messageData=i);return s}setupNativeListeners(){const t=["timeupdate","ended","error","seeked","volumechange","waiting","playing","pause"];for(const r of t){const t=t=>{if("ended"===r&&this.endedSuppressedUntilStart)return;"playing"===r&&!1===this.player.paused&&(this.endedSuppressedUntilStart=!1);const s=this.eventListeners.get(r);if(s)for(const i of s)"error"===r?i(e(t,this.videoElement)):i();if("seeked"===r&&null!==this.pendingSeekTime){const e=this.pendingSeekTime;this.pendingSeekTime=null,this.player.currentTime=e}};this.boundHandlers.set(r,t),this.player.addEventListener(r,t)}const r=()=>{this.frameLoaded=!1,setTimeout(()=>this.rewriteSourceForLiveStart(),0)},s=()=>{this.frameLoaded=!0};this.boundHandlers.set("sourcechange",r),this.player.addEventListener("sourcechange",r),this.boundHandlers.set("loadeddata",s),this.player.addEventListener("loadeddata",s)}teardownNativeListeners(){for(const[e,t]of this.boundHandlers)this.player.removeEventListener(e,t);this.boundHandlers.clear()}}
|
|
1
|
+
import{toMediaErrorPayload as e}from"./theoErrorToMediaError";import{decodeGeobData as t,toUint8Array as r}from"./cueBytes";import{DashPtsOffsetTracker as s}from"./dashPtsOffset";import{ExternalPlaybackGate as i,observeTheoExternalPlayback as n}from"./theoExternalPlayback";export function inferSourceType(e){const t=e.split(/[?#]/,1)[0].toLowerCase();return t.endsWith(".mp4")||t.endsWith(".m4v")?"video/mp4":t.endsWith(".webm")?"video/webm":"application/x-mpegurl"}export function withLiveOffset(e,t){const r=e.sources,s=e=>"object"==typeof e&&null!==e&&Object.getPrototypeOf(e)===Object.prototype;return s(e)&&Array.isArray(r)&&0!==r.length&&void 0===e.liveOffset&&r.every(e=>s(e)&&void 0===e.liveOffset)?{...e,sources:r.map(e=>({...e,liveOffset:t}))}:null}export class THEOplayerAdapter{constructor(e,t){this.endedSuppressedUntilStart=!1,this.pendingSeekTime=null,this.liveRemapCleanup=null,this.eventListeners=new Map,this.boundHandlers=new Map,this.pinnedTrack=null,this.cueTracks=[],this.liveStartOffset=null,this.frameLoaded=!1,this.rewrittenSource=null,this.cueEnters=[],this.seenCues=new WeakSet,this.externalPlaybackGate=new i(()=>this.videoElement),this.player=e,this.container=t,this.dashPtsOffsets=new s(e.network),this.externalPlayback=n(e.cast?.airplay,this.videoElement,e=>this.emit("externalplaybackchange",e)),this.setupNativeListeners(),this.setupMetadataListener()}get seekableEnd(){const e=this.player.seekable;if(!e||0===e.length)return null;const t=e.end(e.length-1);return"number"==typeof t&&Number.isFinite(t)?t:null}get seekableStart(){const e=this.player.seekable;if(!e?.length)return null;const t=e.start?.(e.length-1);return"number"==typeof t&&Number.isFinite(t)?t:null}get liveEdge(){const e=this.seekableEnd;if(null===e)return null;const t=this.player.source,r=t?.sources?.[0]?.liveOffset??t?.liveOffset;return"number"==typeof r&&Number.isFinite(r)&&r>=0?e+r:e}requestLiveStartOffset(e,t){const r=null!==e&&null!==t?e*t:NaN;return!Number.isFinite(r)||r<=0?(this.liveStartOffset=null,!1):(this.liveStartOffset=r,this.rewriteSourceForLiveStart(),!this.frameLoaded)}rewriteSourceForLiveStart(){const e=this.liveStartOffset,t=this.player.source;if(null===e||this.frameLoaded||!t||t===this.rewrittenSource)return;const r=withLiveOffset(t,e);if(!r)return;this.rewrittenSource=r;const s=!this.player.paused;this.player.source=r,s&&this.player.play()}get playbackRate(){return this.player.playbackRate??1}set playbackRate(e){this.player.playbackRate=e}setVideoQuality(e){if(null===e){const e=this.pinnedTrack;if(!e)return!1;const t=this.targetQualityBeforePin;try{return e.targetQuality=t,e.targetQuality!==t?!1:(this.pinnedTrack=null,this.targetQualityBeforePin=void 0,!0)}catch{return!1}}const t=this.player.videoTracks;if(!t||0===t.length)return!1;const r=t[0],s=r?.qualities;if(!r||!s||0===s.length)return!1;const i=[];for(let e=0;e<s.length;e++){const t=s[e];if(!t||!1===t.available||!1===t.enabled)continue;const r=t.bandwidth;"number"==typeof r&&Number.isFinite(r)&&r>0&&i.push(t)}if(i.length<2)return!1;let n=i[0];for(let e=1;e<i.length;e++)i[e].bandwidth<n.bandwidth&&(n=i[e]);const a=!this.pinnedTrack;let l;a&&(this.pinnedTrack=r,this.targetQualityBeforePin=r.targetQuality);try{r.targetQuality=n,l=r.targetQuality===n}catch{l=!1}return!!l||(a&&(this.pinnedTrack=null,this.targetQualityBeforePin=void 0),!1)}get maxLiveSeekPosition(){const e=this.player.latencyManager;if(!e?.monitoringLivePlayback)return null;const t=e.currentLatency,r=e.currentConfiguration?.minimumOffset;if("number"!=typeof t||!Number.isFinite(t))return null;if("number"!=typeof r||!Number.isFinite(r))return null;const s=this.player.currentTime+t-r;return Number.isFinite(s)?s:null}get currentTime(){return this.player.currentTime}set currentTime(e){this.player.currentTime=e}get duration(){return this.player.duration}get isLive(){const e=this.player.duration;return"number"==typeof e?!Number.isFinite(e):null}get paused(){return this.player.paused}get playbackReady(){const e=this.videoElement;return!0!==this.player.seeking&&!!e&&e.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA&&!e.seeking}get muted(){return this.player.muted}set muted(e){this.player.muted=e}get volume(){return this.player.volume}set volume(e){this.player.volume=e}get videoElement(){return this.container.querySelector("video")}get programDateTime(){return this.player.currentProgramDateTime}pause(){this.player.pause()}play(){return this.player.play(),Promise.resolve()}seek(e){!0!==this.player.seeking?(this.pendingSeekTime=null,this.player.currentTime=e):this.pendingSeekTime=e}get sourceUrl(){return this.player.source?.sources?.[0]?.src??null}load(e){return this.pendingSeekTime=null,this.player.source={sources:[{src:e,type:inferSourceType(e)}]},this.externalPlaybackGate.reapply(),this.endedSuppressedUntilStart=!0,Promise.resolve()}async releaseMediaElement(){this.player.pause(),this.player.source=null;const e=this.videoElement;e&&await new Promise(t=>{let r=!1;const s=()=>{r||(r=!0,e.removeEventListener("emptied",s),clearTimeout(i),t())},i=setTimeout(s,250);e.addEventListener("emptied",s,{once:!0})})}async unload(){this.pendingSeekTime=null,await this.releaseMediaElement()}async recreateMediaPipeline(e){const{startTime:t}=e,r=this.player.source;if(!r?.sources?.length)throw new Error("THEOplayer pipeline recreate: no source description");const s=!0===this.isLive,i=this.player.currentProgramDateTime,n=this.player.currentTime,a=i&&Number.isFinite(i.getTime())?i.getTime()+1e3*(t-n):null,l=this.seekableEnd,o=s&&null!==l?Math.max(0,l-t):null;if(await this.releaseMediaElement(),this.endedSuppressedUntilStart=!0,this.player.source=r,this.player.currentTime=t,s){const e=()=>{this.player.removeEventListener("loadedmetadata",t),this.player.removeEventListener("error",e),this.liveRemapCleanup=null},t=()=>{e();const t=this.player.currentProgramDateTime;let r=null;null!==a&&t&&Number.isFinite(t.getTime())?r=this.player.currentTime+(a-t.getTime())/1e3:null!==o&&null!==this.seekableEnd&&(r=this.seekableEnd-o),null!==r&&Math.abs(r-this.player.currentTime)>.5&&(this.player.currentTime=r)};this.liveRemapCleanup=e,this.player.addEventListener("loadedmetadata",t),this.player.addEventListener("error",e)}}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set),this.eventListeners.get(e).add(t)}off(e,t){this.eventListeners.get(e)?.delete(t)}get externalPlaybackState(){return this.externalPlayback?.state}setExternalPlaybackAllowed(e){this.externalPlaybackGate.set(e)}destroy(){this.externalPlayback?.dispose(),this.pendingSeekTime=null,this.liveRemapCleanup?.(),this.liveRemapCleanup=null,this.teardownNativeListeners(),this.teardownMetadataListener(),this.dashPtsOffsets.destroy(),this.eventListeners.clear(),this.player.destroy()}emit(e,t){const r=this.eventListeners.get(e);if(r)for(const e of r)e(t)}setupMetadataListener(){const e=this.player.textTracks;if(!e)return;const t=e=>{e.track&&this.subscribeMetadataTrack(e.track)};this.addTrackHandler=t,this.metadataTrackList=e,e.addEventListener("addtrack",t);for(let t=0;t<(e.length??0);t++){const r=e[t];r&&this.subscribeMetadataTrack(r)}}deferMetadataCue(e){"function"==typeof queueMicrotask?queueMicrotask(e):Promise.resolve().then(e)}subscribeMetadataTrack(e){if("metadata"!==(e.kind??e.type))return;if(this.cueTracks.some(({track:t})=>t===e))return;let t=!1;const r=s=>{if(!this.cueTracks.some(({track:t})=>t===e))return;if(t)return void this.deferMetadataCue(()=>r(s));const i=s.cue;if(i&&!this.seenCues.has(i)&&(this.seenCues.add(i),this.emit("timedmetadata",{...this.toCue(i),phase:"parsed"}),"function"==typeof i.addEventListener)){const e=()=>{this.emit("timedmetadata",{...this.toCue(i),phase:"presented"})};i.addEventListener("enter",e),this.cueEnters.push({cue:i,handler:e})}},s="disabled"===e.mode;this.cueTracks.push({track:e,handler:r,enabledByAdapter:s}),e.addEventListener("addcue",r),s&&(t=!0,e.mode="hidden",t=!1);const i=e.cues;if(i&&i.length>0){const t=()=>{if(this.cueTracks.some(({track:t})=>t===e))for(let e=0;e<i.length;e++){const t=i[e];t&&r({cue:t})}};this.deferMetadataCue(t)}}teardownMetadataListener(){this.addTrackHandler&&this.metadataTrackList&&this.metadataTrackList.removeEventListener("addtrack",this.addTrackHandler),this.addTrackHandler=void 0,this.metadataTrackList=void 0;for(const{track:e,handler:t,enabledByAdapter:r}of this.cueTracks)e.removeEventListener("addcue",t),r&&"hidden"===e.mode&&(e.mode="disabled");this.cueTracks=[];for(const{cue:e,handler:t}of this.cueEnters)e.removeEventListener?.("enter",t);this.cueEnters=[],this.seenCues=new WeakSet}toCue(e){if("string"==typeof e.schemeIDURI){const t={type:"emsg",startTime:e.startTime??0,endTime:e.endTime,schemeIdUri:e.schemeIDURI},s=this.dashPtsOffsets.offsetAt(t.startTime);void 0!==s&&(t.ptsOffset=s);const i=r(e.content);return i?(t.raw=i,t.messageData=new TextDecoder("utf-8").decode(i)):"string"==typeof e.content&&(t.messageData=e.content),t}const s={type:"id3",startTime:e.startTime??0,endTime:e.endTime},i=e.content;if(i&&"object"==typeof i){const e=i.id;if("GEOB"===e||"GEO"===e){"string"==typeof i.description&&(s.description=i.description),"string"==typeof i.mimeType&&(s.mimeType=i.mimeType);const e=t(i.data);return void 0!==e&&(s.messageData=e),s}const r=i.text??i.data??i.description;e&&void 0!==r?s.frames={[e]:String(r)}:s.messageData=JSON.stringify(i)}else"string"==typeof i&&(s.messageData=i);return s}setupNativeListeners(){const t=["timeupdate","ended","error","seeked","volumechange","waiting","playing","pause"];for(const r of t){const t=t=>{if("ended"===r&&this.endedSuppressedUntilStart)return;"playing"===r&&!1===this.player.paused&&(this.endedSuppressedUntilStart=!1);const s=this.eventListeners.get(r);if(s)for(const i of s)"error"===r?i(e(t,this.videoElement)):i();if("seeked"===r&&null!==this.pendingSeekTime){const e=this.pendingSeekTime;this.pendingSeekTime=null,this.player.currentTime=e}};this.boundHandlers.set(r,t),this.player.addEventListener(r,t)}const r=()=>{this.frameLoaded=!1,this.externalPlaybackGate.reapply(),setTimeout(()=>this.rewriteSourceForLiveStart(),0)},s=()=>{this.frameLoaded=!0};this.boundHandlers.set("sourcechange",r),this.player.addEventListener("sourcechange",r),this.boundHandlers.set("loadeddata",s),this.player.addEventListener("loadeddata",s)}teardownNativeListeners(){for(const[e,t]of this.boundHandlers)this.player.removeEventListener(e,t);this.boundHandlers.clear()}}
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ExternalPlaybackChange } from '@dolby-optiview/ads-sdk-core';
|
|
2
|
+
import { type ExternalPlaybackObserver } from '@dolby-optiview/ads-sdk-core/external-playback';
|
|
3
|
+
/** The part of THEOplayer's `cast.airplay` the adapter reads. @category Player Integration */
|
|
4
|
+
export interface THEOAirPlayLike {
|
|
5
|
+
/** `unavailable`, `available`, `connecting` or `connected`. */
|
|
6
|
+
readonly state: 'unavailable' | 'available' | 'connecting' | 'connected';
|
|
7
|
+
/** Subscribe to AirPlay state changes. */
|
|
8
|
+
addEventListener(type: 'statechange', listener: () => void): void;
|
|
9
|
+
/** Remove a `statechange` listener. */
|
|
10
|
+
removeEventListener(type: 'statechange', listener: () => void): void;
|
|
11
|
+
}
|
|
12
|
+
/** Prefers THEOplayer's own AirPlay API, falling back to the `<video>` element's signals. */
|
|
13
|
+
export declare function observeTheoExternalPlayback(airplay: THEOAirPlayLike | undefined, video: HTMLVideoElement | null, emit: (change: ExternalPlaybackChange) => void): ExternalPlaybackObserver | null;
|
|
14
|
+
/** Remembers the requested gate and re-applies it to the live `<video>`, which THEOplayer may create or replace later. */
|
|
15
|
+
export declare class ExternalPlaybackGate {
|
|
16
|
+
private readonly getVideo;
|
|
17
|
+
private allowed;
|
|
18
|
+
constructor(getVideo: () => HTMLVideoElement | null);
|
|
19
|
+
set(allowed: boolean): void;
|
|
20
|
+
reapply(): void;
|
|
21
|
+
}
|
|
22
|
+
/** The part of THEOplayer's `cast` namespace the adapter reads. @category Player Integration */
|
|
23
|
+
export interface THEOCastLike {
|
|
24
|
+
/** AirPlay state and events; absent on builds without AirPlay. */
|
|
25
|
+
readonly airplay?: THEOAirPlayLike;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createReconnectHold as e,observeExternalPlayback as t,setExternalPlaybackAllowed as n}from"@dolby-optiview/ads-sdk-core/external-playback";const i={unavailable:"inactive",available:"inactive",connecting:"connecting",connected:"active"},a="webkitcurrentplaybacktargetiswirelesschanged";export function observeTheoExternalPlayback(n,c,l){return n?function(t,n,c){let l=i[t.state];const r=e=>{e!==l&&(l=e,c({state:l,target:"airplay"}))},s=e(()=>r("inactive")),o=()=>{switch(t.state){case"connected":return s.cancel(),void r("active");case"connecting":return void(s.holding?s.extend():r("connecting"));default:if(s.holding&&s.sawConnecting)s.cancel(),r("inactive");else{if(s.holding)return;"active"===l?s.begin():r("inactive")}}};t.addEventListener("statechange",o);const d=n,g=()=>{!0===d?.webkitCurrentPlaybackTargetIsWireless?s.holding&&s.cancel():"active"!==l||"connected"===t.state||s.holding||s.begin()},v=()=>{s.holding&&s.extend()},h=null!==n&&"webkitCurrentPlaybackTargetIsWireless"in n,u=d?.remote;return h&&n.addEventListener(a,g),u?.addEventListener("connecting",v),{get state(){return l},dispose:()=>{s.dispose(),t.removeEventListener("statechange",o),h&&n.removeEventListener(a,g),u?.removeEventListener("connecting",v)}}}(n,c,l):c?t(c,l):null}export class ExternalPlaybackGate{constructor(e){this.getVideo=e,this.allowed=null}set(e){this.allowed=e,this.reapply()}reapply(){const e=this.getVideo();e&&null!==this.allowed&&n(e,this.allowed)}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dolby-optiview/ads-sdk-adapter-theoplayer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "THEOplayer adapter for OptiView Ads SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"sideEffects": false,
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@dolby-optiview/ads-sdk-core": "^1.
|
|
40
|
+
"@dolby-optiview/ads-sdk-core": "^1.3.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"theoplayer": ">=9.0.0"
|