synxed-sdk 0.1.4 → 0.1.6
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.
- package/dist/index.d.mts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +21 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +21 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -29,6 +29,9 @@ interface SynxedConfig {
|
|
|
29
29
|
serverUrl: string;
|
|
30
30
|
autoConnect?: boolean;
|
|
31
31
|
debug?: boolean;
|
|
32
|
+
/** Listening context sent on init for ad targeting (e.g. "menu", "gameplay"). */
|
|
33
|
+
gameContext?: string;
|
|
34
|
+
deviceType?: string;
|
|
32
35
|
}
|
|
33
36
|
interface PlaySongOptions {
|
|
34
37
|
catalogTrackId?: string;
|
|
@@ -71,10 +74,25 @@ interface SynxedEvents {
|
|
|
71
74
|
}) => void;
|
|
72
75
|
trackChange: (track: TrackInfo) => void;
|
|
73
76
|
queueUpdated: (tracks: TrackInfo[]) => void;
|
|
77
|
+
adStart: (ad: AdInfo) => void;
|
|
78
|
+
adEnd: (ad: AdInfo) => void;
|
|
74
79
|
error: (error: Error) => void;
|
|
75
80
|
connected: () => void;
|
|
76
81
|
disconnected: (reason: string) => void;
|
|
77
82
|
}
|
|
83
|
+
interface AdInfo {
|
|
84
|
+
adId: string;
|
|
85
|
+
campaignId: string;
|
|
86
|
+
brandName: string;
|
|
87
|
+
creativeName: string;
|
|
88
|
+
durationSeconds: number;
|
|
89
|
+
isSkippable: boolean;
|
|
90
|
+
skipAfterSeconds: number;
|
|
91
|
+
ctaType: string;
|
|
92
|
+
ctaValue: string;
|
|
93
|
+
companionBannerUrl: string;
|
|
94
|
+
campaignName: string;
|
|
95
|
+
}
|
|
78
96
|
|
|
79
97
|
declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
80
98
|
private transport;
|
|
@@ -85,6 +103,8 @@ declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
|
85
103
|
private volume;
|
|
86
104
|
private activeContentKind;
|
|
87
105
|
private heartbeatTimer;
|
|
106
|
+
private adPlaying;
|
|
107
|
+
private currentAd;
|
|
88
108
|
constructor(config: SynxedConfig);
|
|
89
109
|
get currentTrack(): TrackInfo | null;
|
|
90
110
|
/** Active playback init kind from the last `play*` call (RADIO, PLAYLIST, SONG, …). */
|
|
@@ -92,6 +112,7 @@ declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
|
92
112
|
private controlPositionMs;
|
|
93
113
|
private setupListeners;
|
|
94
114
|
private connect;
|
|
115
|
+
private buildInitExtras;
|
|
95
116
|
playSong(options: PlaySongOptions): Promise<void>;
|
|
96
117
|
playPlaylist(options: PlayPlaylistOptions): Promise<void>;
|
|
97
118
|
playRadio(options?: PlayRadioOptions): Promise<void>;
|
|
@@ -109,6 +130,9 @@ declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
|
109
130
|
private startHeartbeat;
|
|
110
131
|
private applyContentSummary;
|
|
111
132
|
private handleServerMessage;
|
|
133
|
+
private handleAdPlayback;
|
|
134
|
+
skipAd(): void;
|
|
135
|
+
clickAd(): void;
|
|
112
136
|
private handleTrackEnded;
|
|
113
137
|
private updateStatus;
|
|
114
138
|
destroy(): void;
|
|
@@ -213,6 +237,10 @@ declare class SynxedWebPlayer {
|
|
|
213
237
|
private isPlaying;
|
|
214
238
|
private currentTrack;
|
|
215
239
|
private nowPlaying;
|
|
240
|
+
private currentAd;
|
|
241
|
+
private skipBtn;
|
|
242
|
+
private avatarImgEl;
|
|
243
|
+
private avatarTextEl;
|
|
216
244
|
private avatarRing;
|
|
217
245
|
private titleEl;
|
|
218
246
|
private artistInlineEl;
|
|
@@ -242,8 +270,9 @@ declare class SynxedWebPlayer {
|
|
|
242
270
|
private stopNowPlayingPoll;
|
|
243
271
|
private displayLine;
|
|
244
272
|
private refreshLabels;
|
|
273
|
+
private updateAvatar;
|
|
245
274
|
private setPlayingVisual;
|
|
246
275
|
private togglePlay;
|
|
247
276
|
}
|
|
248
277
|
|
|
249
|
-
export { ContentKind, ErrorCode, type PlayPlaylistOptions, type PlayRadioOptions, type PlaySongOptions, type PlayerState, type RadioNowPlaying, type SynxedConfig, SynxedConnectionError, SynxedError, type SynxedEvents, SynxedPlaybackError, SynxedPlayer, SynxedProtocolError, SynxedWebPlayer, type SynxedWebPlayerMode, type SynxedWebPlayerOptions, type SynxedWebPlayerPlacement, type SynxedWebPlayerPosition, type SynxedWebPlayerSource, type SynxedWebPlayerTheme, type TrackInfo, type TransportEvents, TransportManager, buildSdkWebSocketUrl, fetchRadioNowPlaying };
|
|
278
|
+
export { type AdInfo, ContentKind, ErrorCode, type PlayPlaylistOptions, type PlayRadioOptions, type PlaySongOptions, type PlayerState, type RadioNowPlaying, type SynxedConfig, SynxedConnectionError, SynxedError, type SynxedEvents, SynxedPlaybackError, SynxedPlayer, SynxedProtocolError, SynxedWebPlayer, type SynxedWebPlayerMode, type SynxedWebPlayerOptions, type SynxedWebPlayerPlacement, type SynxedWebPlayerPosition, type SynxedWebPlayerSource, type SynxedWebPlayerTheme, type TrackInfo, type TransportEvents, TransportManager, buildSdkWebSocketUrl, fetchRadioNowPlaying };
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,9 @@ interface SynxedConfig {
|
|
|
29
29
|
serverUrl: string;
|
|
30
30
|
autoConnect?: boolean;
|
|
31
31
|
debug?: boolean;
|
|
32
|
+
/** Listening context sent on init for ad targeting (e.g. "menu", "gameplay"). */
|
|
33
|
+
gameContext?: string;
|
|
34
|
+
deviceType?: string;
|
|
32
35
|
}
|
|
33
36
|
interface PlaySongOptions {
|
|
34
37
|
catalogTrackId?: string;
|
|
@@ -71,10 +74,25 @@ interface SynxedEvents {
|
|
|
71
74
|
}) => void;
|
|
72
75
|
trackChange: (track: TrackInfo) => void;
|
|
73
76
|
queueUpdated: (tracks: TrackInfo[]) => void;
|
|
77
|
+
adStart: (ad: AdInfo) => void;
|
|
78
|
+
adEnd: (ad: AdInfo) => void;
|
|
74
79
|
error: (error: Error) => void;
|
|
75
80
|
connected: () => void;
|
|
76
81
|
disconnected: (reason: string) => void;
|
|
77
82
|
}
|
|
83
|
+
interface AdInfo {
|
|
84
|
+
adId: string;
|
|
85
|
+
campaignId: string;
|
|
86
|
+
brandName: string;
|
|
87
|
+
creativeName: string;
|
|
88
|
+
durationSeconds: number;
|
|
89
|
+
isSkippable: boolean;
|
|
90
|
+
skipAfterSeconds: number;
|
|
91
|
+
ctaType: string;
|
|
92
|
+
ctaValue: string;
|
|
93
|
+
companionBannerUrl: string;
|
|
94
|
+
campaignName: string;
|
|
95
|
+
}
|
|
78
96
|
|
|
79
97
|
declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
80
98
|
private transport;
|
|
@@ -85,6 +103,8 @@ declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
|
85
103
|
private volume;
|
|
86
104
|
private activeContentKind;
|
|
87
105
|
private heartbeatTimer;
|
|
106
|
+
private adPlaying;
|
|
107
|
+
private currentAd;
|
|
88
108
|
constructor(config: SynxedConfig);
|
|
89
109
|
get currentTrack(): TrackInfo | null;
|
|
90
110
|
/** Active playback init kind from the last `play*` call (RADIO, PLAYLIST, SONG, …). */
|
|
@@ -92,6 +112,7 @@ declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
|
92
112
|
private controlPositionMs;
|
|
93
113
|
private setupListeners;
|
|
94
114
|
private connect;
|
|
115
|
+
private buildInitExtras;
|
|
95
116
|
playSong(options: PlaySongOptions): Promise<void>;
|
|
96
117
|
playPlaylist(options: PlayPlaylistOptions): Promise<void>;
|
|
97
118
|
playRadio(options?: PlayRadioOptions): Promise<void>;
|
|
@@ -109,6 +130,9 @@ declare class SynxedPlayer extends EventEmitter<SynxedEvents> {
|
|
|
109
130
|
private startHeartbeat;
|
|
110
131
|
private applyContentSummary;
|
|
111
132
|
private handleServerMessage;
|
|
133
|
+
private handleAdPlayback;
|
|
134
|
+
skipAd(): void;
|
|
135
|
+
clickAd(): void;
|
|
112
136
|
private handleTrackEnded;
|
|
113
137
|
private updateStatus;
|
|
114
138
|
destroy(): void;
|
|
@@ -213,6 +237,10 @@ declare class SynxedWebPlayer {
|
|
|
213
237
|
private isPlaying;
|
|
214
238
|
private currentTrack;
|
|
215
239
|
private nowPlaying;
|
|
240
|
+
private currentAd;
|
|
241
|
+
private skipBtn;
|
|
242
|
+
private avatarImgEl;
|
|
243
|
+
private avatarTextEl;
|
|
216
244
|
private avatarRing;
|
|
217
245
|
private titleEl;
|
|
218
246
|
private artistInlineEl;
|
|
@@ -242,8 +270,9 @@ declare class SynxedWebPlayer {
|
|
|
242
270
|
private stopNowPlayingPoll;
|
|
243
271
|
private displayLine;
|
|
244
272
|
private refreshLabels;
|
|
273
|
+
private updateAvatar;
|
|
245
274
|
private setPlayingVisual;
|
|
246
275
|
private togglePlay;
|
|
247
276
|
}
|
|
248
277
|
|
|
249
|
-
export { ContentKind, ErrorCode, type PlayPlaylistOptions, type PlayRadioOptions, type PlaySongOptions, type PlayerState, type RadioNowPlaying, type SynxedConfig, SynxedConnectionError, SynxedError, type SynxedEvents, SynxedPlaybackError, SynxedPlayer, SynxedProtocolError, SynxedWebPlayer, type SynxedWebPlayerMode, type SynxedWebPlayerOptions, type SynxedWebPlayerPlacement, type SynxedWebPlayerPosition, type SynxedWebPlayerSource, type SynxedWebPlayerTheme, type TrackInfo, type TransportEvents, TransportManager, buildSdkWebSocketUrl, fetchRadioNowPlaying };
|
|
278
|
+
export { type AdInfo, ContentKind, ErrorCode, type PlayPlaylistOptions, type PlayRadioOptions, type PlaySongOptions, type PlayerState, type RadioNowPlaying, type SynxedConfig, SynxedConnectionError, SynxedError, type SynxedEvents, SynxedPlaybackError, SynxedPlayer, SynxedProtocolError, SynxedWebPlayer, type SynxedWebPlayerMode, type SynxedWebPlayerOptions, type SynxedWebPlayerPlacement, type SynxedWebPlayerPosition, type SynxedWebPlayerSource, type SynxedWebPlayerTheme, type TrackInfo, type TransportEvents, TransportManager, buildSdkWebSocketUrl, fetchRadioNowPlaying };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var L=require('protobufjs'),howler=require('howler');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var L__namespace=/*#__PURE__*/_interopNamespace(L);var
|
|
1
|
+
'use strict';var L=require('protobufjs'),howler=require('howler');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var L__namespace=/*#__PURE__*/_interopNamespace(L);var Q=`
|
|
2
2
|
syntax = "proto3";
|
|
3
3
|
|
|
4
4
|
enum ContentKind {
|
|
@@ -40,6 +40,7 @@ message SdkClientInit {
|
|
|
40
40
|
string countryCode = 8;
|
|
41
41
|
string region = 9;
|
|
42
42
|
string protocolVersion = 10;
|
|
43
|
+
string gameContext = 11;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
message SdkClientControl {
|
|
@@ -74,17 +75,34 @@ message SdkServerError {
|
|
|
74
75
|
string message = 2;
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
message SdkServerAdPayload {
|
|
79
|
+
string adId = 1;
|
|
80
|
+
string campaignId = 2;
|
|
81
|
+
string playbackUrl = 3;
|
|
82
|
+
bool isHls = 4;
|
|
83
|
+
uint32 durationSeconds = 5;
|
|
84
|
+
bool isSkippable = 6;
|
|
85
|
+
uint32 skipAfterSeconds = 7;
|
|
86
|
+
string ctaType = 8;
|
|
87
|
+
string ctaValue = 9;
|
|
88
|
+
string brandName = 10;
|
|
89
|
+
string creativeName = 11;
|
|
90
|
+
string companionBannerUrl = 12;
|
|
91
|
+
string campaignName = 13;
|
|
92
|
+
}
|
|
93
|
+
|
|
77
94
|
message SdkServerEnvelope {
|
|
78
95
|
oneof payload {
|
|
79
96
|
SdkServerInitAck initAck = 1;
|
|
80
97
|
SdkServerError error = 2;
|
|
98
|
+
SdkServerAdPayload ad = 3;
|
|
81
99
|
}
|
|
82
100
|
}
|
|
83
|
-
`,A=L__namespace.parse(G).root,E=A.lookupType("SdkClientEnvelope"),T=A.lookupType("SdkServerEnvelope"),v=(s=>(s[s.UNSPECIFIED=0]="UNSPECIFIED",s[s.SONG=1]="SONG",s[s.PLAYLIST=2]="PLAYLIST",s[s.CATEGORY=3]="CATEGORY",s[s.RADIO=4]="RADIO",s))(v||{}),M=(a=>(a[a.UNSPECIFIED=0]="UNSPECIFIED",a[a.UNAUTHORIZED=1]="UNAUTHORIZED",a[a.VALIDATION_ERROR=2]="VALIDATION_ERROR",a[a.NOT_FOUND=3]="NOT_FOUND",a[a.PROCESSING=4]="PROCESSING",a[a.SERVICE_UNAVAILABLE=5]="SERVICE_UNAVAILABLE",a[a.BAD_PROTOBUF=6]="BAD_PROTOBUF",a))(M||{});var u=class{static encodeClientEnvelope(e){let t=E.create(e);return E.encode(t).finish()}static decodeServerEnvelope(e){let t=T.decode(e);return T.toObject(t,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var c=class{constructor(){this.listeners=new Map;}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t);}off(e,t){let i=this.listeners.get(e);i&&i.delete(t);}once(e,t){let i=((...r)=>{t(...r),this.off(e,i);});this.on(e,i);}emit(e,...t){let i=this.listeners.get(e);i&&i.forEach(r=>r(...t));}removeAllListeners(){this.listeners.clear();}};var _=false;function U(n){_=n;}function p(...n){_&&console.debug("[Synxed]",...n);}function h(...n){console.warn("[Synxed]",...n);}function W(n,e){let i=(n.endsWith("/")?n.slice(0,-1):n).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),r=new URL(`${i}/sdk`);return r.searchParams.set("apiKey",e),r.toString()}var g=class extends c{constructor(){super(...arguments);this.ws=null;this.connectPromise=null;}connect(t,i){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;let r=W(i,t);p("Opening native WebSocket",r.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(r),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.emit("connected");},this.ws.onclose=s=>{let o=s.reason||`code ${s.code}`;this.ws=null,this.connectPromise=null,this.emit("disconnected",o);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=s=>{try{let{data:o}=s;if(!(o instanceof ArrayBuffer))return;let a=u.decodeServerEnvelope(new Uint8Array(o));this.emit("message",a);}catch(o){this.emit("error",new Error(`Failed to decode message: ${o}`));}};}async waitForConnection(){if(p("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){p("Already connected");return}if(!this.ws)throw new Error("WebSocket not initialized. Call connect() first.");return this.connectPromise?this.connectPromise:(this.connectPromise=new Promise((t,i)=>{let r=this.ws;if(r.readyState===WebSocket.OPEN){t();return}let s=()=>{p("WebSocket connected"),d(),t();},o=()=>{h("WebSocket connection error"),d(),i(new Error("WebSocket connection failed"));},a=()=>{d(),i(new Error("WebSocket closed before connection was established"));},d=()=>{r.removeEventListener("open",s),r.removeEventListener("error",o),r.removeEventListener("close",a);};r.addEventListener("open",s),r.addEventListener("error",o),r.addEventListener("close",a);}),this.connectPromise)}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null,this.connectPromise=null);}sendInit(t){if(!this.isConnected)throw new Error("WebSocket not connected");p("Sending init packet",t),this.sendBytes(u.encodeClientEnvelope({init:t}));}sendControl(t){this.isConnected&&this.sendBytes(u.encodeClientEnvelope({control:t}));}sendAnalytics(t){this.isConnected&&this.sendBytes(u.encodeClientEnvelope({analytics:t}));}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}sendBytes(t){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");this.ws.send(t);}};var x=class extends c{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;}async load(t,i){this.stop(),this.emit("loading"),p("AudioEngine loading",{url:t,isHls:i});let r=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!r)try{let{default:s}=await import('hls.js');if(s.isSupported()){p("Using Hls.js for playback");let a=new URL(t).search;this.hls=new s({xhrSetup:d=>{d.setRequestHeader("ngrok-skip-browser-warning","true");}}),this.audioEl=new Audio,this.hls.loadSource(t),this.hls.attachMedia(this.audioEl),this.audioEl.onplay=()=>{this.emit("playing"),this.startTimeUpdateLoop();},this.audioEl.onpause=()=>{this.emit("paused"),this.stopTimeUpdateLoop();},this.audioEl.onended=()=>{this.emit("ended"),this.stopTimeUpdateLoop();},this.audioEl.onerror=d=>{h("HLS audio element error",d),this.emit("error",d);},this.audioEl.onloadedmetadata=()=>{this.emit("loaded");},this.hls.on(s.Events.ERROR,(d,m)=>{m.fatal&&(h("Fatal HLS error",m),this.emit("error",m));});return}}catch{h("hls.js not available, falling back to native playback");}this.howl=new howler.Howl({src:[t],html5:true,format:i?["m3u8"]:void 0,onload:()=>{p("AudioEngine loaded"),this.emit("loaded");},onloaderror:(s,o)=>{h("AudioEngine load error",o,s),this.emit("error",o);},onplay:()=>{this.emit("playing"),this.startTimeUpdateLoop();},onpause:()=>{this.emit("paused"),this.stopTimeUpdateLoop();},onstop:()=>{this.emit("stopped"),this.stopTimeUpdateLoop();},onend:()=>{this.emit("ended"),this.stopTimeUpdateLoop();}});}play(){this.audioEl?this.audioEl.play().catch(t=>h("Play failed",t)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.hls&&(this.hls.destroy(),this.hls=null),this.audioEl&&(this.audioEl.pause(),this.audioEl.src="",this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}seek(t){this.audioEl?this.audioEl.currentTime=t/1e3:this.howl?.seek(t/1e3);}setVolume(t){this.audioEl&&(this.audioEl.volume=t),this.howl&&this.howl.volume(t);}get duration(){return this.audioEl?this.audioEl.duration*1e3:(this.howl?.duration()||0)*1e3}get currentTime(){return this.audioEl?this.audioEl.currentTime*1e3:(this.howl?.seek()||0)*1e3}startTimeUpdateLoop(){this.stopTimeUpdateLoop();let t=()=>{(this.audioEl?!this.audioEl.paused:this.howl?.playing())&&(this.emit("timeupdate",{currentTime:this.currentTime,duration:this.duration}),this.updateTimer=requestAnimationFrame(t));};this.updateTimer=requestAnimationFrame(t);}stopTimeUpdateLoop(){this.updateTimer!==null&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null);}};var b=class extends c{constructor(){super();this.queue=[];this.currentIndex=-1;}setQueue(t,i){this.queue=t,this.currentIndex=typeof i=="number"&&i>=0&&i<t.length?i:t.length>0?0:-1,this.emit("queueUpdated",this.queue),this.getCurrentTrack()&&this.emit("trackChanged",this.getCurrentTrack());}getCurrentTrack(){return this.currentIndex>=0&&this.currentIndex<this.queue.length?this.queue[this.currentIndex]:null}next(){if(this.currentIndex<this.queue.length-1){this.currentIndex++;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}previous(){if(this.currentIndex>0){this.currentIndex--;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}skipTo(t){if(t>=0&&t<this.queue.length){this.currentIndex=t;let i=this.getCurrentTrack();return this.emit("trackChanged",i),i}return null}reset(){this.queue=[],this.currentIndex=-1,this.emit("queueUpdated",[]);}get hasNext(){return this.currentIndex<this.queue.length-1}get hasPrevious(){return this.currentIndex>0}get queueSnapshot(){return [...this.queue]}get currentIndexSnapshot(){return this.currentIndex}};var y=class extends Error{constructor(t,i){super(t);this.code=i;this.name="SynxedError";}},w=class extends y{constructor(e){super(e),this.name="SynxedConnectionError";}},S=class extends y{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},K=class extends y{constructor(e){super(e),this.name="SynxedProtocolError";}};function C(n,...e){for(let t of e){let i=n[t];if(typeof i=="string"&&i.length>0)return i}}function J(n,...e){for(let t of e){let i=n[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function D(n){let e=n.initAck??n.init_ack;if(!e||typeof e!="object")return null;let t=e,i=C(t,"playbackUrl","playback_url");return i?{sessionId:C(t,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(t.isHls??t.is_hls),heartbeatIntervalMs:J(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:C(t,"contentSummary","content_summary")}:null}function X(n){if(!n||typeof n!="object")return null;let e=n,t=e.id;if(typeof t!="string"||!t.trim())return null;let i=e.kind==="internal"?"internal":"catalog",r=e.albumArt??e.album_art;return {id:t.trim(),kind:i,title:typeof e.title=="string"?e.title:void 0,artist:typeof e.artist=="string"?e.artist:void 0,duration:typeof e.duration=="number"?e.duration:void 0,albumArt:typeof r=="string"?r:void 0}}function B(n,e){if(!n?.trim())return null;let t;try{t=JSON.parse(n);}catch{return null}if(!t||typeof t!="object")return null;let i=t;if(i.type==="live_radio"||e===4)return {tracks:[{id:"synxed-radio",kind:"catalog",title:typeof i.station=="string"&&i.station.trim()?i.station.trim():"Synxed Radio",artist:""}],currentIndex:0};let s=i.tracks;if(!Array.isArray(s)||s.length===0)return null;let o=[];for(let m of s){let N=X(m);N&&o.push(N);}if(o.length===0)return null;let a=typeof i.currentIndex=="number"?i.currentIndex:typeof i.current_index=="number"?i.current_index:0,d=Math.max(0,Math.min(Math.floor(a),o.length-1));return {tracks:o,currentIndex:d}}var k=class extends c{constructor(t){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.config=t,U(!!t.debug),this.transport=new g,this.audio=new x,this.playlist=new b,this.setupListeners(),t.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}controlPositionMs(){return this.activeContentKind===4?0:this.positionMsForAnalytics()}setupListeners(){this.transport.on("connected",()=>this.emit("connected")),this.transport.on("disconnected",t=>this.emit("disconnected",t)),this.transport.on("error",t=>this.emit("error",new w(t.message))),this.transport.on("message",t=>this.handleServerMessage(t)),this.audio.on("playing",()=>this.updateStatus("playing")),this.audio.on("paused",()=>this.updateStatus("paused")),this.audio.on("stopped",()=>this.updateStatus("idle")),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",t=>this.emit("error",new S(t))),this.audio.on("timeupdate",t=>this.emit("timeUpdate",t)),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",t=>this.emit("trackChange",t)),this.playlist.on("queueUpdated",t=>this.emit("queueUpdated",t));}connect(){this.transport.connect(this.config.apiKey,this.config.serverUrl);}async playSong(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=1,this.transport.sendInit({contentKind:1,catalogTrackId:t.catalogTrackId,internalTrackId:t.internalTrackId,listenerId:t.listenerId});}async playPlaylist(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=2,this.transport.sendInit({contentKind:2,playlistCode:t.playlistCode,listenerId:t.listenerId});}async playRadio(t={}){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=4,this.transport.sendInit({contentKind:4,listenerId:t.listenerId});}pause(){this.audio.pause(),this.transport.sendControl({action:2,positionMs:this.controlPositionMs()});}resume(){this.audio.play(),this.transport.sendControl({action:1,positionMs:this.controlPositionMs()});}stop(){this.audio.stop(),this.transport.sendControl({action:3,positionMs:this.controlPositionMs()});}skip(){if(this.activeContentKind===4)return;if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:5,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.next();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}previous(){if(this.activeContentKind===4)return;if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:6,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.previous();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}skipTo(t){if(this.activeContentKind===4)return;let i=this.playlist.skipTo(t);i&&this.playSong(i.kind==="internal"?{internalTrackId:i.id}:{catalogTrackId:i.id});}seek(t){this.activeContentKind!==4&&(this.audio.seek(t),this.transport.sendControl({action:4,positionMs:t}));}setVolume(t){this.volume=Math.max(0,Math.min(1,t)),this.audio.setVolume(this.volume);}positionMsForAnalytics(t){return typeof t=="number"?Math.max(0,Math.min(4294967295,Math.floor(t))):Math.max(0,Math.min(4294967295,Math.floor(this.audio.currentTime)))}emitAnalytics(t,i,r){this.transport.sendAnalytics({eventType:t,positionMs:this.positionMsForAnalytics(i),extraJson:r?JSON.stringify(r):void 0});}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null);}startHeartbeat(t){this.clearHeartbeat();let i=Number(t);!i||i<1e3||(this.heartbeatTimer=setInterval(()=>{let r=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",r);},i));}applyContentSummary(t){let i=B(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&h("Could not parse contentSummary; queue metadata unavailable.");}async handleServerMessage(t){p("Received server message",t);let i=D(t);if(i){p("Loading playback",{url:i.playbackUrl,isHls:i.isHls}),await this.audio.load(i.playbackUrl,i.isHls),this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(i.heartbeatIntervalMs),this.applyContentSummary(i.contentSummary);return}let r=t.error;if(r&&typeof r=="object"){let s=r,o=typeof s.message=="string"?s.message:"Unknown server error",a=typeof s.code=="string"?s.code:void 0;this.emit("error",new y(o,a));}}handleTrackEnded(){this.activeContentKind!==4&&(this.playlist.hasNext?this.skip():this.updateStatus("idle"));}updateStatus(t){this.status=t,this.emit("stateChange",{status:t,currentTrack:this.playlist.getCurrentTrack(),currentTime:this.audio.currentTime,duration:this.audio.duration,volume:this.volume});}destroy(){this.clearHeartbeat(),this.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function P(n,e){let i=`${n.replace(/\/$/,"")}/radio/now-playing`;try{let r=await fetch(i,{...e,headers:{Accept:"application/json",...e?.headers}});if(!r.ok)return null;let o=(await r.json())?.data;return !o?.title||typeof o.title!="string"?null:{title:o.title,station:typeof o.station=="string"?o.station:void 0,isLive:typeof o.isLive=="boolean"?o.isLive:void 0}}catch{return null}}function l(n,e){let t=document.createElement(n);if(e?.className&&(t.className=e.className),e?.attrs)for(let[i,r]of Object.entries(e.attrs))t.setAttribute(i,r);return e?.style&&Object.assign(t.style,e.style),e?.text&&(t.textContent=e.text),e?.html&&(t.innerHTML=e.html),e?.onClick&&t.addEventListener("click",e.onClick),e?.children&&e.children.forEach(i=>t.appendChild(i)),t}function f(n,e=20){let t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("width",String(e)),t.setAttribute("height",String(e)),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","currentColor"),t.setAttribute("aria-hidden","true");let i=document.createElementNS("http://www.w3.org/2000/svg","path");return i.setAttribute("d",n),t.appendChild(i),t}var I="M8 5v14l11-7L8 5z",H="M6 5h4v14H6V5zm8 0h4v14h-4V5z",O="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",z="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function F(){let n="synxed-web-player-styles";if(document.getElementById(n))return;let e=document.createElement("style");e.id=n,e.textContent=`
|
|
101
|
+
`,M=L__namespace.parse(Q).root,I=M.lookupType("SdkClientEnvelope"),P=M.lookupType("SdkServerEnvelope"),x=(s=>(s[s.UNSPECIFIED=0]="UNSPECIFIED",s[s.SONG=1]="SONG",s[s.PLAYLIST=2]="PLAYLIST",s[s.CATEGORY=3]="CATEGORY",s[s.RADIO=4]="RADIO",s))(x||{}),_=(o=>(o[o.UNSPECIFIED=0]="UNSPECIFIED",o[o.UNAUTHORIZED=1]="UNAUTHORIZED",o[o.VALIDATION_ERROR=2]="VALIDATION_ERROR",o[o.NOT_FOUND=3]="NOT_FOUND",o[o.PROCESSING=4]="PROCESSING",o[o.SERVICE_UNAVAILABLE=5]="SERVICE_UNAVAILABLE",o[o.BAD_PROTOBUF=6]="BAD_PROTOBUF",o))(_||{});var m=class{static encodeClientEnvelope(e){let t=I.create(e);return I.encode(t).finish()}static decodeServerEnvelope(e){let t=P.decode(e);return P.toObject(t,{enums:String,longs:String,bytes:String,defaults:true,oneofs:true})}};var c=class{constructor(){this.listeners=new Map;}on(e,t){this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(t);}off(e,t){let i=this.listeners.get(e);i&&i.delete(t);}once(e,t){let i=((...r)=>{t(...r),this.off(e,i);});this.on(e,i);}emit(e,...t){let i=this.listeners.get(e);i&&i.forEach(r=>r(...t));}removeAllListeners(){this.listeners.clear();}};var U=false;function B(n){U=n;}function p(...n){U&&console.debug("[Synxed]",...n);}function u(...n){console.warn("[Synxed]",...n);}function W(n,e){let i=(n.endsWith("/")?n.slice(0,-1):n).replace(/^http:/,"ws:").replace(/^https:/,"wss:"),r=new URL(`${i}/sdk`);return r.searchParams.set("apiKey",e),r.toString()}var v=class extends c{constructor(){super(...arguments);this.ws=null;this.connectPromise=null;}connect(t,i){if(this.ws&&(this.ws.readyState===WebSocket.OPEN||this.ws.readyState===WebSocket.CONNECTING))return;let r=W(i,t);p("Opening native WebSocket",r.replace(/apiKey=[^&]+/,"apiKey=***")),this.ws=new WebSocket(r),this.ws.binaryType="arraybuffer",this.ws.onopen=()=>{this.connectPromise=null,this.emit("connected");},this.ws.onclose=s=>{let a=s.reason||`code ${s.code}`;this.ws=null,this.connectPromise=null,this.emit("disconnected",a);},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket connection error"));},this.ws.onmessage=s=>{try{let{data:a}=s;if(!(a instanceof ArrayBuffer))return;let o=m.decodeServerEnvelope(new Uint8Array(a));this.emit("message",o);}catch(a){this.emit("error",new Error(`Failed to decode message: ${a}`));}};}async waitForConnection(){if(p("Waiting for connection\u2026"),this.ws?.readyState===WebSocket.OPEN){p("Already connected");return}if(!this.ws)throw new Error("WebSocket not initialized. Call connect() first.");return this.connectPromise?this.connectPromise:(this.connectPromise=new Promise((t,i)=>{let r=this.ws;if(r.readyState===WebSocket.OPEN){t();return}let s=()=>{p("WebSocket connected"),d(),t();},a=()=>{u("WebSocket connection error"),d(),i(new Error("WebSocket connection failed"));},o=()=>{d(),i(new Error("WebSocket closed before connection was established"));},d=()=>{r.removeEventListener("open",s),r.removeEventListener("error",a),r.removeEventListener("close",o);};r.addEventListener("open",s),r.addEventListener("error",a),r.addEventListener("close",o);}),this.connectPromise)}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null,this.connectPromise=null);}sendInit(t){if(!this.isConnected)throw new Error("WebSocket not connected");p("Sending init packet",t),this.sendBytes(m.encodeClientEnvelope({init:t}));}sendControl(t){this.isConnected&&this.sendBytes(m.encodeClientEnvelope({control:t}));}sendAnalytics(t){this.isConnected&&this.sendBytes(m.encodeClientEnvelope({analytics:t}));}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}sendBytes(t){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)throw new Error("WebSocket not connected");this.ws.send(t);}};var k=class extends c{constructor(){super();this.howl=null;this.hls=null;this.audioEl=null;this.updateTimer=null;}async load(t,i){this.stop(),this.emit("loading"),p("AudioEngine loading",{url:t,isHls:i});let r=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(i&&!r)try{let{default:s}=await import('hls.js');if(s.isSupported()){p("Using Hls.js for playback");let o=new URL(t).search;this.hls=new s({xhrSetup:d=>{d.setRequestHeader("ngrok-skip-browser-warning","true");}}),this.audioEl=new Audio,this.hls.loadSource(t),this.hls.attachMedia(this.audioEl),this.audioEl.onplay=()=>{this.emit("playing"),this.startTimeUpdateLoop();},this.audioEl.onpause=()=>{this.emit("paused"),this.stopTimeUpdateLoop();},this.audioEl.onended=()=>{this.emit("ended"),this.stopTimeUpdateLoop();},this.audioEl.onerror=d=>{u("HLS audio element error",d),this.emit("error",d);},this.audioEl.onloadedmetadata=()=>{this.emit("loaded");},this.hls.on(s.Events.ERROR,(d,g)=>{g.fatal&&(u("Fatal HLS error",g),this.emit("error",g));});return}}catch{u("hls.js not available, falling back to native playback");}this.howl=new howler.Howl({src:[t],html5:true,format:i?["m3u8"]:void 0,onload:()=>{p("AudioEngine loaded"),this.emit("loaded");},onloaderror:(s,a)=>{u("AudioEngine load error",a,s),this.emit("error",a);},onplay:()=>{this.emit("playing"),this.startTimeUpdateLoop();},onpause:()=>{this.emit("paused"),this.stopTimeUpdateLoop();},onstop:()=>{this.emit("stopped"),this.stopTimeUpdateLoop();},onend:()=>{this.emit("ended"),this.stopTimeUpdateLoop();}});}play(){this.audioEl?this.audioEl.play().catch(t=>u("Play failed",t)):this.howl?.play();}pause(){this.audioEl?this.audioEl.pause():this.howl?.pause();}stop(){this.hls&&(this.hls.destroy(),this.hls=null),this.audioEl&&(this.audioEl.pause(),this.audioEl.src="",this.audioEl=null),this.howl&&(this.howl.stop(),this.howl.unload(),this.howl=null),this.stopTimeUpdateLoop();}seek(t){this.audioEl?this.audioEl.currentTime=t/1e3:this.howl?.seek(t/1e3);}setVolume(t){this.audioEl&&(this.audioEl.volume=t),this.howl&&this.howl.volume(t);}get duration(){return this.audioEl?this.audioEl.duration*1e3:(this.howl?.duration()||0)*1e3}get currentTime(){return this.audioEl?this.audioEl.currentTime*1e3:(this.howl?.seek()||0)*1e3}startTimeUpdateLoop(){this.stopTimeUpdateLoop();let t=()=>{(this.audioEl?!this.audioEl.paused:this.howl?.playing())&&(this.emit("timeupdate",{currentTime:this.currentTime,duration:this.duration}),this.updateTimer=requestAnimationFrame(t));};this.updateTimer=requestAnimationFrame(t);}stopTimeUpdateLoop(){this.updateTimer!==null&&(cancelAnimationFrame(this.updateTimer),this.updateTimer=null);}};var S=class extends c{constructor(){super();this.queue=[];this.currentIndex=-1;}setQueue(t,i){this.queue=t,this.currentIndex=typeof i=="number"&&i>=0&&i<t.length?i:t.length>0?0:-1,this.emit("queueUpdated",this.queue),this.getCurrentTrack()&&this.emit("trackChanged",this.getCurrentTrack());}getCurrentTrack(){return this.currentIndex>=0&&this.currentIndex<this.queue.length?this.queue[this.currentIndex]:null}next(){if(this.currentIndex<this.queue.length-1){this.currentIndex++;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}previous(){if(this.currentIndex>0){this.currentIndex--;let t=this.getCurrentTrack();return this.emit("trackChanged",t),t}return null}skipTo(t){if(t>=0&&t<this.queue.length){this.currentIndex=t;let i=this.getCurrentTrack();return this.emit("trackChanged",i),i}return null}reset(){this.queue=[],this.currentIndex=-1,this.emit("queueUpdated",[]);}get hasNext(){return this.currentIndex<this.queue.length-1}get hasPrevious(){return this.currentIndex>0}get queueSnapshot(){return [...this.queue]}get currentIndexSnapshot(){return this.currentIndex}};var f=class extends Error{constructor(t,i){super(t);this.code=i;this.name="SynxedError";}},w=class extends f{constructor(e){super(e),this.name="SynxedConnectionError";}},E=class extends f{constructor(e){super(typeof e=="string"?e:"Playback failed"),this.name="SynxedPlaybackError";}},K=class extends f{constructor(e){super(e),this.name="SynxedProtocolError";}};function C(n,...e){for(let t of e){let i=n[t];if(typeof i=="string"&&i.length>0)return i}}function tt(n,...e){for(let t of e){let i=n[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i!==""&&!Number.isNaN(Number(i)))return Number(i)}}function D(n){let e=n.initAck??n.init_ack;if(!e||typeof e!="object")return null;let t=e,i=C(t,"playbackUrl","playback_url");return i?{sessionId:C(t,"sessionId","session_id")??"",playbackUrl:i,isHls:!!(t.isHls??t.is_hls),heartbeatIntervalMs:tt(t,"heartbeatIntervalMs","heartbeat_interval_ms")??0,contentSummary:C(t,"contentSummary","content_summary")}:null}function et(n){if(!n||typeof n!="object")return null;let e=n,t=e.id;if(typeof t!="string"||!t.trim())return null;let i=e.kind==="internal"?"internal":"catalog",r=e.albumArt??e.album_art;return {id:t.trim(),kind:i,title:typeof e.title=="string"?e.title:void 0,artist:typeof e.artist=="string"?e.artist:void 0,duration:typeof e.duration=="number"?e.duration:void 0,albumArt:typeof r=="string"?r:void 0}}function H(n,e){if(!n?.trim())return null;let t;try{t=JSON.parse(n);}catch{return null}if(!t||typeof t!="object")return null;let i=t;if(i.type==="live_radio"||e===4)return {tracks:[{id:"synxed-radio",kind:"catalog",title:typeof i.station=="string"&&i.station.trim()?i.station.trim():"Synxed Radio",artist:""}],currentIndex:0};let s=i.tracks;if(!Array.isArray(s)||s.length===0)return null;let a=[];for(let g of s){let R=et(g);R&&a.push(R);}if(a.length===0)return null;let o=typeof i.currentIndex=="number"?i.currentIndex:typeof i.current_index=="number"?i.current_index:0,d=Math.max(0,Math.min(Math.floor(o),a.length-1));return {tracks:a,currentIndex:d}}function h(n,...e){for(let t of e){let i=n[t];if(typeof i=="string")return i}return ""}function z(n,...e){for(let t of e){let i=n[t];if(typeof i=="boolean")return i}return false}function V(n,...e){for(let t of e){let i=n[t];if(typeof i=="number"&&Number.isFinite(i))return i;if(typeof i=="string"&&i.trim()){let r=Number(i);if(Number.isFinite(r))return r}}return 0}function F(n){let e=n.ad;if(!e||typeof e!="object")return null;let t=e,i=h(t,"playbackUrl","playback_url");return i?{adId:h(t,"adId","ad_id"),campaignId:h(t,"campaignId","campaign_id"),playbackUrl:i,isHls:z(t,"isHls","is_hls")||i.includes(".m3u8"),durationSeconds:V(t,"durationSeconds","duration_seconds")||15,isSkippable:z(t,"isSkippable","is_skippable"),skipAfterSeconds:V(t,"skipAfterSeconds","skip_after_seconds"),ctaType:h(t,"ctaType","cta_type"),ctaValue:h(t,"ctaValue","cta_value"),brandName:h(t,"brandName","brand_name"),creativeName:h(t,"creativeName","creative_name"),companionBannerUrl:h(t,"companionBannerUrl","companion_banner_url"),campaignName:h(t,"campaignName","campaign_name")}:null}var T=class extends c{constructor(t){super();this.status="idle";this.volume=.8;this.activeContentKind=0;this.heartbeatTimer=null;this.adPlaying=false;this.currentAd=null;this.config=t,B(!!t.debug),this.transport=new v,this.audio=new k,this.playlist=new S,this.setupListeners(),t.autoConnect&&this.connect();}get currentTrack(){return this.playlist.getCurrentTrack()}get contentKind(){return this.activeContentKind}controlPositionMs(){return this.activeContentKind===4?0:this.positionMsForAnalytics()}setupListeners(){this.transport.on("connected",()=>this.emit("connected")),this.transport.on("disconnected",t=>this.emit("disconnected",t)),this.transport.on("error",t=>this.emit("error",new w(t.message))),this.transport.on("message",t=>this.handleServerMessage(t)),this.audio.on("playing",()=>this.updateStatus("playing")),this.audio.on("paused",()=>this.updateStatus("paused")),this.audio.on("stopped",()=>this.updateStatus("idle")),this.audio.on("loading",()=>this.updateStatus("loading")),this.audio.on("error",t=>this.emit("error",new E(t))),this.audio.on("timeupdate",t=>this.emit("timeUpdate",t)),this.audio.on("ended",()=>this.handleTrackEnded()),this.playlist.on("trackChanged",t=>this.emit("trackChange",t)),this.playlist.on("queueUpdated",t=>this.emit("queueUpdated",t));}connect(){this.transport.connect(this.config.apiKey,this.config.serverUrl);}buildInitExtras(){let t={};return this.config.gameContext?.trim()&&(t.gameContext=this.config.gameContext.trim()),this.config.deviceType?.trim()&&(t.deviceType=this.config.deviceType.trim()),t}async playSong(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=1,this.transport.sendInit({contentKind:1,catalogTrackId:t.catalogTrackId,internalTrackId:t.internalTrackId,listenerId:t.listenerId,...this.buildInitExtras()});}async playPlaylist(t){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=2,this.transport.sendInit({contentKind:2,playlistCode:t.playlistCode,listenerId:t.listenerId,...this.buildInitExtras()});}async playRadio(t={}){this.transport.isConnected||this.connect(),await this.transport.waitForConnection(),this.activeContentKind=4,this.transport.sendInit({contentKind:4,listenerId:t.listenerId,...this.buildInitExtras()});}pause(){this.audio.pause(),this.transport.sendControl({action:2,positionMs:this.controlPositionMs()});}resume(){this.audio.play(),this.transport.sendControl({action:1,positionMs:this.controlPositionMs()});}stop(){this.audio.stop(),this.transport.sendControl({action:3,positionMs:this.controlPositionMs()});}skip(){if(this.activeContentKind===4)return;if(this.adPlaying){this.skipAd();return}if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:5,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.next();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}previous(){if(this.activeContentKind===4)return;if(this.playlist.queueSnapshot.length>1){this.transport.sendControl({action:6,positionMs:this.controlPositionMs()}),this.updateStatus("loading");return}let t=this.playlist.previous();t&&this.playSong(t.kind==="internal"?{internalTrackId:t.id}:{catalogTrackId:t.id});}skipTo(t){if(this.activeContentKind===4)return;let i=this.playlist.skipTo(t);i&&this.playSong(i.kind==="internal"?{internalTrackId:i.id}:{catalogTrackId:i.id});}seek(t){this.activeContentKind===4||this.adPlaying||(this.audio.seek(t),this.transport.sendControl({action:4,positionMs:t}));}setVolume(t){this.volume=Math.max(0,Math.min(1,t)),this.audio.setVolume(this.volume);}positionMsForAnalytics(t){return typeof t=="number"?Math.max(0,Math.min(4294967295,Math.floor(t))):Math.max(0,Math.min(4294967295,Math.floor(this.audio.currentTime)))}emitAnalytics(t,i,r){this.transport.sendAnalytics({eventType:t,positionMs:this.positionMsForAnalytics(i),extraJson:r?JSON.stringify(r):void 0});}clearHeartbeat(){this.heartbeatTimer!==null&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null);}startHeartbeat(t){this.clearHeartbeat();let i=Number(t);!i||i<1e3||(this.heartbeatTimer=setInterval(()=>{let r=this.activeContentKind===4?0:this.positionMsForAnalytics();this.emitAnalytics("heartbeat",r);},i));}applyContentSummary(t){let i=H(t,this.activeContentKind);if(i){this.playlist.setQueue(i.tracks,i.currentIndex);return}t?.trim()&&u("Could not parse contentSummary; queue metadata unavailable.");}async handleServerMessage(t){p("Received server message",t);let i=F(t);if(i){await this.handleAdPlayback(i);return}let r=D(t);if(r){this.adPlaying=false,this.currentAd=null,p("Loading playback",{url:r.playbackUrl,isHls:r.isHls}),await this.audio.load(r.playbackUrl,r.isHls),this.audio.play(),this.emitAnalytics("stream_start",this.activeContentKind===4?0:void 0),this.startHeartbeat(r.heartbeatIntervalMs),this.applyContentSummary(r.contentSummary);return}let s=t.error;if(s&&typeof s=="object"){let a=s,o=typeof a.message=="string"?a.message:"Unknown server error",d=typeof a.code=="string"?a.code:void 0;this.emit("error",new f(o,d));}}async handleAdPlayback(t){this.adPlaying=true,this.currentAd={adId:t.adId,campaignId:t.campaignId,brandName:t.brandName,creativeName:t.creativeName,durationSeconds:t.durationSeconds,isSkippable:t.isSkippable,skipAfterSeconds:t.skipAfterSeconds,ctaType:t.ctaType,ctaValue:t.ctaValue,companionBannerUrl:t.companionBannerUrl,campaignName:t.campaignName},p("Loading ad playback",{url:t.playbackUrl,isHls:t.isHls}),await this.audio.load(t.playbackUrl,t.isHls),this.audio.play(),this.emit("adStart",this.currentAd);}skipAd(){if(!this.adPlaying||!this.currentAd||!this.currentAd.isSkippable)return;let t=Math.floor(this.audio.currentTime*1e3);t<this.currentAd.skipAfterSeconds*1e3||(this.emitAnalytics("ad_skip",t),this.updateStatus("loading"));}clickAd(){if(!this.adPlaying||!this.currentAd)return;let t=Math.floor(this.audio.currentTime*1e3);this.emitAnalytics("ad_cta_click",t),this.currentAd.ctaValue&&window.open(this.currentAd.ctaValue,"_blank");}handleTrackEnded(){if(this.activeContentKind!==4){if(this.adPlaying&&this.currentAd){this.emitAnalytics("ad_complete",Math.floor(this.audio.currentTime*1e3)),this.currentAd&&this.emit("adEnd",this.currentAd),this.adPlaying=false,this.currentAd=null,this.updateStatus("loading");return}if(this.playlist.queueSnapshot.length>1){this.emitAnalytics("track_complete",Math.floor(this.audio.duration*1e3)),this.updateStatus("loading");return}this.playlist.hasNext?this.skip():this.updateStatus("idle");}}updateStatus(t){this.status=t,this.emit("stateChange",{status:t,currentTrack:this.playlist.getCurrentTrack(),currentTime:this.audio.currentTime,duration:this.audio.duration,volume:this.volume});}destroy(){this.clearHeartbeat(),this.audio.stop(),this.transport.disconnect(),this.playlist.reset(),this.removeAllListeners();}};async function A(n,e){let i=`${n.replace(/\/$/,"")}/radio/now-playing`;try{let r=await fetch(i,{...e,headers:{Accept:"application/json",...e?.headers}});if(!r.ok)return null;let a=(await r.json())?.data;return !a?.title||typeof a.title!="string"?null:{title:a.title,station:typeof a.station=="string"?a.station:void 0,isLive:typeof a.isLive=="boolean"?a.isLive:void 0}}catch{return null}}function l(n,e){let t=document.createElement(n);if(e?.className&&(t.className=e.className),e?.attrs)for(let[i,r]of Object.entries(e.attrs))t.setAttribute(i,r);return e?.style&&Object.assign(t.style,e.style),e?.text&&(t.textContent=e.text),e?.html&&(t.innerHTML=e.html),e?.onClick&&t.addEventListener("click",e.onClick),e?.children&&e.children.forEach(i=>t.appendChild(i)),t}function y(n,e=20){let t=document.createElementNS("http://www.w3.org/2000/svg","svg");t.setAttribute("width",String(e)),t.setAttribute("height",String(e)),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","currentColor"),t.setAttribute("aria-hidden","true");let i=document.createElementNS("http://www.w3.org/2000/svg","path");return i.setAttribute("d",n),t.appendChild(i),t}var N="M8 5v14l11-7L8 5z",j="M6 5h4v14H6V5zm8 0h4v14h-4V5z",b="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z",q="M6 6h2v12H6V6zm11.5 12L9 12l8.5-6v12z";function $(){let n="synxed-web-player-styles";if(document.getElementById(n))return;let e=document.createElement("style");e.id=n,e.textContent=`
|
|
84
102
|
@keyframes synxed-wp-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
|
|
85
103
|
@keyframes synxed-wp-vbar {
|
|
86
104
|
0%, 100% { transform: scaleY(0.28); opacity: 0.45; }
|
|
87
105
|
50% { transform: scaleY(1); opacity: 1; }
|
|
88
106
|
}
|
|
89
|
-
`,document.head.appendChild(e);}function V(n){let e=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let t of e){let i=n.indexOf(t);if(i>0)return {title:n.slice(0,i).trim(),artist:n.slice(i+t.length).trim()}}return {title:n.trim()}}function $(n="bottom-center",e=16,t=16){let i={position:"fixed",zIndex:"50"};switch(n){case "top-left":return {...i,top:`${t}px`,left:`${e}px`};case "top-right":return {...i,top:`${t}px`,right:`${e}px`};case "bottom-left":return {...i,bottom:`${t}px`,left:`${e}px`};case "bottom-right":return {...i,bottom:`${t}px`,right:`${e}px`};default:return {...i,bottom:`${t}px`,left:"50%",transform:"translateX(-50%)"}}}function j(n={}){return {accent:n.accent??"#22c55e",accentMuted:n.accentMuted??n.accent??"#22c55e",background:n.background??"#051107",backgroundInner:n.backgroundInner??"#0a1f10",border:n.border??"rgba(34, 197, 94, 0.35)",text:n.text??"#ffffff",textMuted:n.textMuted??"rgba(255,255,255,0.35)",stationText:n.stationText??"rgba(34, 197, 94, 0.85)",liveDot:n.liveDot??"#CCFF00",glow:n.glow??"rgba(34, 197, 94, 0.35)"}}function q(n,e){n.style.setProperty("--sw-accent",e.accent),n.style.setProperty("--sw-accent-muted",e.accentMuted),n.style.setProperty("--sw-bg",e.background),n.style.setProperty("--sw-bg-inner",e.backgroundInner),n.style.setProperty("--sw-border",e.border),n.style.setProperty("--sw-text",e.text),n.style.setProperty("--sw-text-muted",e.textMuted),n.style.setProperty("--sw-station",e.stationText),n.style.setProperty("--sw-live",e.liveDot),n.style.setProperty("--sw-glow",e.glow);}var R=class n{constructor(e){this.engine=null;this.pollTimer=null;this.destroyed=false;this.isPlaying=false;this.currentTrack=null;this.nowPlaying=null;this.avatarRing=null;this.titleEl=null;this.artistInlineEl=null;this.artistBlockEl=null;this.footerEl=null;this.playBtn=null;this.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",...e},this.theme=j(this.options.theme),this.ownsRoot=!e.container,this.root=e.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),F(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(e){return new n(e)}get player(){return this.engine}get element(){return this.root}destroy(){this.destroyed||(this.destroyed=true,this.stopNowPlayingPoll(),this.engine?.destroy(),this.engine=null,this.ownsRoot&&this.root.remove());}get isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:e={},className:t,style:i}=this.options,r=e.placement??"bottom-center",s=e.offsetX??16,o=e.offsetY??(r==="bottom-center"?24:16);this.root.className=t??"",this.root.dataset.synxedWebPlayer=this.mode,q(this.root,this.theme),Object.assign(this.root.style,$(r,s,o)),i&&Object.assign(this.root.style,i),this.root.replaceChildren(),this.mode==="mini"?this.buildMini():this.mode==="large"?this.buildLarge():this.buildWide(),this.refreshLabels(),this.setPlayingVisual(this.isPlaying);}buildAvatar(e,t=false){let i=l("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=l("div",{style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"3px solid var(--sw-accent)",padding:"3px",boxShadow:"0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",background:"var(--sw-bg)",boxSizing:"border-box"}});let r=l("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden"}});return this.options.avatarUrl?r.appendChild(l("img",{attrs:{src:this.options.avatarUrl,alt:""},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)"}})):r.appendChild(l("div",{text:"S",style:{width:"100%",height:"100%",display:"flex",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(e*.28)}px`}})),this.avatarRing.appendChild(r),i.appendChild(this.avatarRing),i.appendChild(l("span",{style:{position:"absolute",...t?{top:"4px",left:"4px"}:{bottom:"6px",left:"6px"},width:t?"10px":"12px",height:t?"10px":"12px",borderRadius:"50%",background:"var(--sw-live)",border:"2px solid var(--sw-bg)",boxShadow:"0 0 8px var(--sw-live)"}})),i}buildMini(){let t=l("button",{attrs:{type:"button","aria-label":this.options.onMiniClick?"Expand player":"Live DJ"},style:{position:"relative",padding:"0",border:"none",background:"transparent",cursor:this.options.onMiniClick?"pointer":"default"},onClick:()=>this.options.onMiniClick?.()});t.appendChild(this.buildAvatar(72)),this.root.appendChild(t);}buildWide(){let t="0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)";this.root.style.width="min(calc(100vw - 20px), 560px)";let i=l("div",{style:{position:"relative",display:"flex",alignItems:"center",width:"100%"}}),r=Math.max(90*.42,40);i.appendChild(l("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${r}px`,right:"0",background:"var(--sw-bg)",border:"1px solid var(--sw-border)",borderRadius:"28px 20px 20px 28px",boxShadow:t,overflow:"hidden"},children:[l("div",{style:{position:"absolute",inset:"0",background:"linear-gradient(90deg, color-mix(in srgb, var(--sw-accent) 12%, transparent), transparent)",pointerEvents:"none"}})]}));let s=this.buildAvatar(90);Object.assign(s.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(s);let o=l("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),a=l("div",{style:{display:"flex",alignItems:"baseline",gap:"8px",overflow:"hidden"}});this.titleEl=l("h3",{style:{margin:"0",fontSize:"clamp(15px, 2.8vw, 20px)",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),a.appendChild(this.titleEl),this.artistInlineEl=l("span",{style:{fontSize:"clamp(12px, 2.4vw, 15px)",fontWeight:"300",color:"var(--sw-text-muted)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),a.appendChild(this.artistInlineEl),o.appendChild(a),this.footerEl=l("p",{style:{margin:"8px 0 0",fontSize:"9px",fontWeight:"700",color:"var(--sw-text-muted)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),o.appendChild(this.footerEl),i.appendChild(o);let d=l("div",{style:{position:"relative",zIndex:"1",flexShrink:"0",display:"flex",alignItems:"center",gap:"14px",paddingRight:"16px"}});this.playBtn=this.createPlayButton(52),d.appendChild(this.playBtn),this.isRadio||d.appendChild(l("button",{attrs:{type:"button","aria-label":"Skip"},style:{border:"none",background:"transparent",color:"var(--sw-text-muted)",display:"flex",cursor:"pointer"},onClick:()=>this.engine?.skip(),children:[f(O,22)]})),d.appendChild(this.decoLines()),i.appendChild(d),this.root.appendChild(i);}buildLarge(){this.root.style.width="min(calc(100vw - 24px), 380px)";let t=l("div",{style:{borderRadius:"24px",border:"1px solid var(--sw-border)",background:"var(--sw-bg)",boxShadow:"0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)",padding:"16px",display:"flex",flexDirection:"column",gap:"14px",fontFamily:"system-ui, -apple-system, Segoe UI, Roboto, sans-serif"}}),i=l("div",{style:{display:"flex",gap:"12px",alignItems:"center",minWidth:"0"}});i.appendChild(this.buildAvatar(96,true));let r=l("div",{style:{minWidth:"0",flex:"1"}});this.titleEl=l("h3",{style:{margin:"0",fontSize:"18px",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),r.appendChild(this.titleEl),this.artistBlockEl=l("p",{style:{margin:"6px 0 0",fontSize:"13px",fontWeight:"700",color:"var(--sw-accent-muted)",letterSpacing:"0.08em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),r.appendChild(this.artistBlockEl),this.footerEl=l("p",{style:{margin:"6px 0 0",fontSize:"10px",fontWeight:"700",color:"var(--sw-station)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),r.appendChild(this.footerEl),i.appendChild(r),t.appendChild(i),t.appendChild(this.buildVisualizer()),t.appendChild(l("p",{text:this.options.powerByLabel??"Powered by Synxed",style:{margin:"0",fontSize:"9px",fontWeight:"600",color:"var(--sw-text-muted)",letterSpacing:"0.12em",textTransform:"uppercase",textAlign:"center"}}));let s=l("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||s.appendChild(l("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[f(z,22)]})),this.playBtn=this.createPlayButton(56),s.appendChild(this.playBtn),this.isRadio||s.appendChild(l("button",{attrs:{type:"button","aria-label":"Skip"},style:this.roundControlStyle(),onClick:()=>this.engine?.skip(),children:[f(O,22)]})),t.appendChild(s),this.root.appendChild(t);}roundControlStyle(){return {width:"46px",height:"46px",borderRadius:"50%",border:"1px solid var(--sw-border)",background:"rgba(255,255,255,0.04)",color:"var(--sw-text)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"}}createPlayButton(e){return l("button",{attrs:{type:"button","aria-label":"Play"},style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"none",background:"var(--sw-accent)",color:"#0a0a0a",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",boxShadow:"0 0 18px var(--sw-glow)",flexShrink:"0"},onClick:()=>this.togglePlay(),children:[f(I,e>=56?22:20)]})}buildVisualizer(){let e=l("div",{style:{display:"flex",alignItems:"flex-end",gap:"4px",height:"52px",padding:"8px 4px",borderRadius:"14px",border:"1px solid var(--sw-border)",overflow:"hidden"}});for(let t=0;t<24;t++)e.appendChild(l("span",{style:{flex:"1",minWidth:"3px",height:"100%",borderRadius:"4px",background:"linear-gradient(180deg, var(--sw-accent), transparent)",transformOrigin:"center bottom",animation:`synxed-wp-vbar ${1+t%5*.12}s ease-in-out infinite`,animationDelay:`${t*.04}s`,opacity:"0.85"}}));return e}decoLines(){let e=l("div",{style:{display:"flex",flexDirection:"column",gap:"3px",opacity:"0.22"}});return e.appendChild(l("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)",transform:"translateX(3px)"}})),e.appendChild(l("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)"}})),e}initEngine(){let{apiKey:e,serverUrl:t,source:i}=this.options,r=new k({apiKey:e,serverUrl:t,autoConnect:true});this.engine=r;let s=a=>{this.isPlaying=a.status==="playing",a.currentTrack&&(this.currentTrack=a.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels();};r.on("stateChange",s),r.on("trackChange",a=>{this.currentTrack=a,this.refreshLabels();}),(i.type==="radio"?()=>r.playRadio():()=>r.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{});}startNowPlayingPoll(){let e=async()=>{let t=await P(this.options.serverUrl);!this.destroyed&&t&&(this.nowPlaying=t,this.refreshLabels());};e(),this.pollTimer=setInterval(e,this.options.nowPlayingPollMs??12e3);}stopNowPlayingPoll(){this.pollTimer!==null&&(clearInterval(this.pollTimer),this.pollTimer=null);}displayLine(){return this.isRadio&&this.nowPlaying?.title?V(this.nowPlaying.title):this.currentTrack?.title?{title:this.currentTrack.title,artist:this.currentTrack.artist}:{title:"Loading\u2026"}}refreshLabels(){let e=this.displayLine();if(this.titleEl&&(this.titleEl.textContent=e.title),this.artistInlineEl){let t=!!e.artist;this.artistInlineEl.style.display=t?"inline":"none",t&&(this.artistInlineEl.textContent=e.artist);}if(this.artistBlockEl){let t=!!e.artist;this.artistBlockEl.style.display=t?"block":"none",t&&(this.artistBlockEl.textContent=e.artist);}if(this.footerEl){let t=this.isRadio&&(this.nowPlaying?.station??this.currentTrack?.title??"Synxed Radio");this.footerEl.textContent=t&&this.isRadio?`${t} \xB7 ${this.options.attribution}`:this.options.attribution??"Synxed";}}setPlayingVisual(e){this.avatarRing&&(this.avatarRing.style.animation=e?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(f(e?H:I,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};exports.ContentKind=v;exports.ErrorCode=M;exports.SynxedConnectionError=w;exports.SynxedError=y;exports.SynxedPlaybackError=S;exports.SynxedPlayer=k;exports.SynxedProtocolError=K;exports.SynxedWebPlayer=R;exports.TransportManager=g;exports.buildSdkWebSocketUrl=W;exports.fetchRadioNowPlaying=P;//# sourceMappingURL=index.js.map
|
|
107
|
+
`,document.head.appendChild(e);}function G(n){let e=[" \u2014 "," \u2013 "," - "," \u2014"," \u2013"," -"];for(let t of e){let i=n.indexOf(t);if(i>0)return {title:n.slice(0,i).trim(),artist:n.slice(i+t.length).trim()}}return {title:n.trim()}}function Y(n="bottom-center",e=16,t=16){let i={position:"fixed",zIndex:"50"};switch(n){case "top-left":return {...i,top:`${t}px`,left:`${e}px`};case "top-right":return {...i,top:`${t}px`,right:`${e}px`};case "bottom-left":return {...i,bottom:`${t}px`,left:`${e}px`};case "bottom-right":return {...i,bottom:`${t}px`,right:`${e}px`};default:return {...i,bottom:`${t}px`,left:"50%",transform:"translateX(-50%)"}}}function J(n={}){return {accent:n.accent??"#22c55e",accentMuted:n.accentMuted??n.accent??"#22c55e",background:n.background??"#051107",backgroundInner:n.backgroundInner??"#0a1f10",border:n.border??"rgba(34, 197, 94, 0.35)",text:n.text??"#ffffff",textMuted:n.textMuted??"rgba(255,255,255,0.35)",stationText:n.stationText??"rgba(34, 197, 94, 0.85)",liveDot:n.liveDot??"#CCFF00",glow:n.glow??"rgba(34, 197, 94, 0.35)"}}function X(n,e){n.style.setProperty("--sw-accent",e.accent),n.style.setProperty("--sw-accent-muted",e.accentMuted),n.style.setProperty("--sw-bg",e.background),n.style.setProperty("--sw-bg-inner",e.backgroundInner),n.style.setProperty("--sw-border",e.border),n.style.setProperty("--sw-text",e.text),n.style.setProperty("--sw-text-muted",e.textMuted),n.style.setProperty("--sw-station",e.stationText),n.style.setProperty("--sw-live",e.liveDot),n.style.setProperty("--sw-glow",e.glow);}var O=class n{constructor(e){this.engine=null;this.pollTimer=null;this.destroyed=false;this.isPlaying=false;this.currentTrack=null;this.nowPlaying=null;this.currentAd=null;this.skipBtn=null;this.avatarImgEl=null;this.avatarTextEl=null;this.avatarRing=null;this.titleEl=null;this.artistInlineEl=null;this.artistBlockEl=null;this.footerEl=null;this.playBtn=null;this.options={mode:"wide",attribution:"Synxed",nowPlayingPollMs:12e3,powerByLabel:"Powered by Synxed",...e},this.theme=J(this.options.theme),this.ownsRoot=!e.container,this.root=e.container??document.createElement("div"),this.ownsRoot&&document.body.appendChild(this.root),$(),this.mountShell(),this.initEngine(),this.options.source.type==="radio"&&this.startNowPlayingPoll();}static mount(e){return new n(e)}get player(){return this.engine}get element(){return this.root}destroy(){this.destroyed||(this.destroyed=true,this.stopNowPlayingPoll(),this.engine?.destroy(),this.engine=null,this.ownsRoot&&this.root.remove());}get isRadio(){return this.options.source.type==="radio"}get mode(){return this.options.mode??"wide"}mountShell(){let{position:e={},className:t,style:i}=this.options,r=e.placement??"bottom-center",s=e.offsetX??16,a=e.offsetY??(r==="bottom-center"?24:16);this.root.className=t??"",this.root.dataset.synxedWebPlayer=this.mode,X(this.root,this.theme),Object.assign(this.root.style,Y(r,s,a)),i&&Object.assign(this.root.style,i),this.root.replaceChildren(),this.mode==="mini"?this.buildMini():this.mode==="large"?this.buildLarge():this.buildWide(),this.refreshLabels(),this.setPlayingVisual(this.isPlaying);}buildAvatar(e,t=false){let i=l("div",{style:{position:"relative",flexShrink:"0"}});this.avatarRing=l("div",{style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"3px solid var(--sw-accent)",padding:"3px",boxShadow:"0 0 24px var(--sw-glow), 0 0 48px rgba(0,0,0,0.25)",background:"var(--sw-bg)",boxSizing:"border-box"}});let r=l("div",{style:{width:"100%",height:"100%",borderRadius:"50%",background:"var(--sw-bg-inner)",overflow:"hidden"}});return this.avatarImgEl=l("img",{attrs:{src:this.options.avatarUrl||"",alt:""},style:{width:"100%",height:"100%",objectFit:"cover",objectPosition:"top",transform:this.mode==="wide"?"scale(1.15)":"scale(1.12)",display:this.options.avatarUrl?"block":"none"}}),this.avatarTextEl=l("div",{text:"S",style:{width:"100%",height:"100%",display:this.options.avatarUrl?"none":"flex",alignItems:"center",justifyContent:"center",color:"var(--sw-accent)",fontWeight:"900",fontSize:`${Math.round(e*.28)}px`}}),r.appendChild(this.avatarImgEl),r.appendChild(this.avatarTextEl),r.style.cursor="pointer",r.addEventListener("click",s=>{this.currentAd&&this.engine&&(s.stopPropagation(),this.engine.clickAd());}),this.avatarRing.appendChild(r),i.appendChild(this.avatarRing),i.appendChild(l("span",{style:{position:"absolute",...t?{top:"4px",left:"4px"}:{bottom:"6px",left:"6px"},width:t?"10px":"12px",height:t?"10px":"12px",borderRadius:"50%",background:"var(--sw-live)",border:"2px solid var(--sw-bg)",boxShadow:"0 0 8px var(--sw-live)"}})),i}buildMini(){let t=l("button",{attrs:{type:"button","aria-label":this.options.onMiniClick?"Expand player":"Live DJ"},style:{position:"relative",padding:"0",border:"none",background:"transparent",cursor:this.options.onMiniClick?"pointer":"default"},onClick:()=>this.options.onMiniClick?.()});t.appendChild(this.buildAvatar(72)),this.root.appendChild(t);}buildWide(){let t="0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)";this.root.style.width="min(calc(100vw - 20px), 560px)";let i=l("div",{style:{position:"relative",display:"flex",alignItems:"center",width:"100%"}}),r=Math.max(90*.42,40);i.appendChild(l("div",{style:{position:"absolute",top:"8px",bottom:"8px",left:`${r}px`,right:"0",background:"var(--sw-bg)",border:"1px solid var(--sw-border)",borderRadius:"28px 20px 20px 28px",boxShadow:t,overflow:"hidden"},children:[l("div",{style:{position:"absolute",inset:"0",background:"linear-gradient(90deg, color-mix(in srgb, var(--sw-accent) 12%, transparent), transparent)",pointerEvents:"none"}})]}));let s=this.buildAvatar(90);Object.assign(s.style,{position:"relative",zIndex:"1",marginLeft:"-2px"}),i.appendChild(s);let a=l("div",{style:{position:"relative",zIndex:"1",flex:"1",minWidth:"0",marginLeft:"14px",padding:"18px 8px"}}),o=l("div",{style:{display:"flex",alignItems:"baseline",gap:"8px",overflow:"hidden"}});this.titleEl=l("h3",{style:{margin:"0",fontSize:"clamp(15px, 2.8vw, 20px)",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),o.appendChild(this.titleEl),this.artistInlineEl=l("span",{style:{fontSize:"clamp(12px, 2.4vw, 15px)",fontWeight:"300",color:"var(--sw-text-muted)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),o.appendChild(this.artistInlineEl),a.appendChild(o),this.footerEl=l("p",{style:{margin:"8px 0 0",fontSize:"9px",fontWeight:"700",color:"var(--sw-text-muted)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),a.appendChild(this.footerEl),i.appendChild(a);let d=l("div",{style:{position:"relative",zIndex:"1",flexShrink:"0",display:"flex",alignItems:"center",gap:"14px",paddingRight:"16px"}});this.playBtn=this.createPlayButton(52),d.appendChild(this.playBtn),this.isRadio||(this.skipBtn=l("button",{attrs:{type:"button","aria-label":"Skip"},style:{border:"none",background:"transparent",color:"var(--sw-text-muted)",display:"flex",cursor:"pointer",fontSize:"13px",fontWeight:"bold"},onClick:()=>this.engine?.skip(),children:[y(b,22)]}),d.appendChild(this.skipBtn)),d.appendChild(this.decoLines()),i.appendChild(d),this.root.appendChild(i);}buildLarge(){this.root.style.width="min(calc(100vw - 24px), 380px)";let t=l("div",{style:{borderRadius:"24px",border:"1px solid var(--sw-border)",background:"var(--sw-bg)",boxShadow:"0 8px 40px var(--sw-glow), 0 0 0 1px var(--sw-border)",padding:"16px",display:"flex",flexDirection:"column",gap:"14px",fontFamily:"system-ui, -apple-system, Segoe UI, Roboto, sans-serif"}}),i=l("div",{style:{display:"flex",gap:"12px",alignItems:"center",minWidth:"0"}});i.appendChild(this.buildAvatar(96,true));let r=l("div",{style:{minWidth:"0",flex:"1"}});this.titleEl=l("h3",{style:{margin:"0",fontSize:"18px",fontWeight:"900",color:"var(--sw-text)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),r.appendChild(this.titleEl),this.artistBlockEl=l("p",{style:{margin:"6px 0 0",fontSize:"13px",fontWeight:"700",color:"var(--sw-accent-muted)",letterSpacing:"0.08em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",display:"none"}}),r.appendChild(this.artistBlockEl),this.footerEl=l("p",{style:{margin:"6px 0 0",fontSize:"10px",fontWeight:"700",color:"var(--sw-station)",letterSpacing:"0.18em",textTransform:"uppercase",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}),r.appendChild(this.footerEl),i.appendChild(r),t.appendChild(i),t.appendChild(this.buildVisualizer()),t.appendChild(l("p",{text:this.options.powerByLabel??"Powered by Synxed",style:{margin:"0",fontSize:"9px",fontWeight:"600",color:"var(--sw-text-muted)",letterSpacing:"0.12em",textTransform:"uppercase",textAlign:"center"}}));let s=l("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:"18px"}});this.isRadio||s.appendChild(l("button",{attrs:{type:"button","aria-label":"Previous"},style:this.roundControlStyle(),onClick:()=>this.engine?.previous(),children:[y(q,22)]})),this.playBtn=this.createPlayButton(56),s.appendChild(this.playBtn),this.isRadio||(this.skipBtn=l("button",{attrs:{type:"button","aria-label":"Skip"},style:{...this.roundControlStyle(),fontSize:"12px",fontWeight:"bold"},onClick:()=>this.engine?.skip(),children:[y(b,22)]}),s.appendChild(this.skipBtn)),t.appendChild(s),this.root.appendChild(t);}roundControlStyle(){return {width:"46px",height:"46px",borderRadius:"50%",border:"1px solid var(--sw-border)",background:"rgba(255,255,255,0.04)",color:"var(--sw-text)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"}}createPlayButton(e){return l("button",{attrs:{type:"button","aria-label":"Play"},style:{width:`${e}px`,height:`${e}px`,borderRadius:"50%",border:"none",background:"var(--sw-accent)",color:"#0a0a0a",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",boxShadow:"0 0 18px var(--sw-glow)",flexShrink:"0"},onClick:()=>this.togglePlay(),children:[y(N,e>=56?22:20)]})}buildVisualizer(){let e=l("div",{style:{display:"flex",alignItems:"flex-end",gap:"4px",height:"52px",padding:"8px 4px",borderRadius:"14px",border:"1px solid var(--sw-border)",overflow:"hidden"}});for(let t=0;t<24;t++)e.appendChild(l("span",{style:{flex:"1",minWidth:"3px",height:"100%",borderRadius:"4px",background:"linear-gradient(180deg, var(--sw-accent), transparent)",transformOrigin:"center bottom",animation:`synxed-wp-vbar ${1+t%5*.12}s ease-in-out infinite`,animationDelay:`${t*.04}s`,opacity:"0.85"}}));return e}decoLines(){let e=l("div",{style:{display:"flex",flexDirection:"column",gap:"3px",opacity:"0.22"}});return e.appendChild(l("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)",transform:"translateX(3px)"}})),e.appendChild(l("span",{style:{display:"block",width:"16px",height:"2px",borderRadius:"999px",background:"var(--sw-text)"}})),e}initEngine(){let{apiKey:e,serverUrl:t,source:i}=this.options,r=new T({apiKey:e,serverUrl:t,autoConnect:true});this.engine=r;let s=o=>{this.isPlaying=o.status==="playing",o.currentTrack&&(this.currentTrack=o.currentTrack),this.setPlayingVisual(this.isPlaying),this.refreshLabels();};r.on("stateChange",s),r.on("trackChange",o=>{this.currentTrack=o,this.refreshLabels();}),r.on("adStart",o=>{this.currentAd=o,this.refreshLabels(),this.updateAvatar();}),r.on("adEnd",()=>{this.currentAd=null,this.refreshLabels(),this.updateAvatar(),this.skipBtn&&(this.skipBtn.replaceChildren(y(b,22)),this.skipBtn.style.opacity="1",this.skipBtn.style.cursor="pointer");}),r.on("timeUpdate",o=>{if(this.currentAd&&this.currentAd.isSkippable&&this.skipBtn){let d=Math.ceil((this.currentAd.skipAfterSeconds*1e3-o.currentTime*1e3)/1e3);d>0?(this.skipBtn.textContent=`${d}s`,this.skipBtn.style.opacity="0.5",this.skipBtn.style.cursor="not-allowed"):this.skipBtn.textContent!==""&&(this.skipBtn.textContent="",this.skipBtn.replaceChildren(y(b,22)),this.skipBtn.style.opacity="1",this.skipBtn.style.cursor="pointer");}}),(i.type==="radio"?()=>r.playRadio():()=>r.playPlaylist({playlistCode:i.playlistCode}))().catch(()=>{});}startNowPlayingPoll(){let e=async()=>{let t=await A(this.options.serverUrl);!this.destroyed&&t&&(this.nowPlaying=t,this.refreshLabels());};e(),this.pollTimer=setInterval(e,this.options.nowPlayingPollMs??12e3);}stopNowPlayingPoll(){this.pollTimer!==null&&(clearInterval(this.pollTimer),this.pollTimer=null);}displayLine(){return this.currentAd?{title:this.currentAd.campaignName||"Advertisement",artist:this.currentAd.creativeName}:this.isRadio&&this.nowPlaying?.title?G(this.nowPlaying.title):this.currentTrack?.title?{title:this.currentTrack.title,artist:this.currentTrack.artist}:{title:"Loading\u2026"}}refreshLabels(){let e=this.displayLine();if(this.titleEl&&(this.titleEl.textContent=e.title),this.artistInlineEl){let t=!!e.artist;this.artistInlineEl.style.display=t?"inline":"none",t&&(this.artistInlineEl.textContent=e.artist);}if(this.artistBlockEl){let t=!!e.artist;this.artistBlockEl.style.display=t?"block":"none",t&&(this.artistBlockEl.textContent=e.artist);}if(this.footerEl)if(this.currentAd)this.footerEl.textContent="Advertisement \xB7 Synxed Player";else {let t=this.isRadio&&(this.nowPlaying?.station??this.currentTrack?.title??"Synxed Radio");this.footerEl.textContent=t&&this.isRadio?`${t} \xB7 Synxed Player`:"Synxed Player";}}updateAvatar(){let e=this.currentAd?.companionBannerUrl||this.options.avatarUrl;e?(this.avatarImgEl&&(this.avatarImgEl.src=e,this.avatarImgEl.style.display="block"),this.avatarTextEl&&(this.avatarTextEl.style.display="none")):(this.avatarImgEl&&(this.avatarImgEl.style.display="none"),this.avatarTextEl&&(this.avatarTextEl.style.display="flex"));}setPlayingVisual(e){this.avatarRing&&(this.avatarRing.style.animation=e?"synxed-wp-spin 4s linear infinite":""),this.playBtn&&(this.playBtn.replaceChildren(y(e?j:N,20)),this.playBtn.setAttribute("aria-label",e?"Pause":"Play"));}togglePlay(){this.engine&&(this.isPlaying?this.engine.pause():this.engine.resume());}};exports.ContentKind=x;exports.ErrorCode=_;exports.SynxedConnectionError=w;exports.SynxedError=f;exports.SynxedPlaybackError=E;exports.SynxedPlayer=T;exports.SynxedProtocolError=K;exports.SynxedWebPlayer=O;exports.TransportManager=v;exports.buildSdkWebSocketUrl=W;exports.fetchRadioNowPlaying=A;//# sourceMappingURL=index.js.map
|
|
90
108
|
//# sourceMappingURL=index.js.map
|