@hopeplayer/core 1.0.14 → 1.0.16

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.
Files changed (73) hide show
  1. package/dist/HopePlayerElement.d.ts +57 -0
  2. package/dist/HopePlayerElement.d.ts.map +1 -1
  3. package/dist/chunks/{index-BTBAxNjr.js → index-BXSND_xN.js} +2 -2
  4. package/dist/chunks/{index-BTBAxNjr.js.map → index-BXSND_xN.js.map} +1 -1
  5. package/dist/chunks/index-BbRYOSvk.js +261 -0
  6. package/dist/chunks/index-BbRYOSvk.js.map +1 -0
  7. package/dist/chunks/{index-Dy0Th0is.js → index-C3BQGcT3.js} +2 -2
  8. package/dist/chunks/{index-Dy0Th0is.js.map → index-C3BQGcT3.js.map} +1 -1
  9. package/dist/chunks/{index-C2c71cGP.js → index-CBX7bn-G.js} +2 -2
  10. package/dist/chunks/{index-C2c71cGP.js.map → index-CBX7bn-G.js.map} +1 -1
  11. package/dist/chunks/{index-CaMVTgh0.js → index-CDPrkLq0.js} +55 -68
  12. package/dist/chunks/index-CDPrkLq0.js.map +1 -0
  13. package/dist/chunks/index-CWLyz1fp.js +415 -0
  14. package/dist/chunks/index-CWLyz1fp.js.map +1 -0
  15. package/dist/chunks/index-Ch3ep-eJ.js +245 -0
  16. package/dist/chunks/index-Ch3ep-eJ.js.map +1 -0
  17. package/dist/chunks/{index-DtqNHU7Y.js → index-D3Z7ZDLJ.js} +2 -2
  18. package/dist/chunks/{index-DtqNHU7Y.js.map → index-D3Z7ZDLJ.js.map} +1 -1
  19. package/dist/chunks/{index-Dz0E1YPE.js → index-DEv3YqLg.js} +1374 -908
  20. package/dist/chunks/index-DEv3YqLg.js.map +1 -0
  21. package/dist/chunks/{index-BCMVXNL0.js → index-DITXYcHx.js} +68 -96
  22. package/dist/chunks/index-DITXYcHx.js.map +1 -0
  23. package/dist/chunks/index-Miba3PD_.js +387 -0
  24. package/dist/chunks/index-Miba3PD_.js.map +1 -0
  25. package/dist/chunks/{index-DcVUXkXo.js → index-e00_M05B.js} +2 -2
  26. package/dist/chunks/{index-DcVUXkXo.js.map → index-e00_M05B.js.map} +1 -1
  27. package/dist/chunks/loadGpt-CmiAy366.js +18 -0
  28. package/dist/chunks/loadGpt-CmiAy366.js.map +1 -0
  29. package/dist/controls/SettingsMenu.d.ts +4 -0
  30. package/dist/controls/SettingsMenu.d.ts.map +1 -1
  31. package/dist/hls/SourceManager.d.ts +10 -0
  32. package/dist/hls/SourceManager.d.ts.map +1 -1
  33. package/dist/hls/sourceGroups.d.ts +19 -0
  34. package/dist/hls/sourceGroups.d.ts.map +1 -0
  35. package/dist/hope-player.js +1 -1
  36. package/dist/i18n/locales/en.d.ts.map +1 -1
  37. package/dist/i18n/locales/tr.d.ts.map +1 -1
  38. package/dist/i18n/types.d.ts +22 -0
  39. package/dist/i18n/types.d.ts.map +1 -1
  40. package/dist/index.d.ts +1 -1
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/plugins/ad-triggers/AdTriggers.d.ts +99 -0
  43. package/dist/plugins/ad-triggers/AdTriggers.d.ts.map +1 -0
  44. package/dist/plugins/ad-triggers/index.d.ts +7 -0
  45. package/dist/plugins/ad-triggers/index.d.ts.map +1 -0
  46. package/dist/plugins/ads/AdsController.d.ts +8 -0
  47. package/dist/plugins/ads/AdsController.d.ts.map +1 -1
  48. package/dist/plugins/cast/CastController.d.ts +107 -0
  49. package/dist/plugins/cast/CastController.d.ts.map +1 -0
  50. package/dist/plugins/cast/RemoteMediaProxy.d.ts +41 -0
  51. package/dist/plugins/cast/RemoteMediaProxy.d.ts.map +1 -0
  52. package/dist/plugins/cast/castSdk.d.ts +160 -0
  53. package/dist/plugins/cast/castSdk.d.ts.map +1 -0
  54. package/dist/plugins/cast/index.d.ts +7 -0
  55. package/dist/plugins/cast/index.d.ts.map +1 -0
  56. package/dist/plugins/pause-ad/loadGpt.d.ts +2 -0
  57. package/dist/plugins/pause-ad/loadGpt.d.ts.map +1 -1
  58. package/dist/plugins/rewarded/RewardedUnlock.d.ts +68 -0
  59. package/dist/plugins/rewarded/RewardedUnlock.d.ts.map +1 -0
  60. package/dist/plugins/rewarded/gpt.d.ts +12 -0
  61. package/dist/plugins/rewarded/gpt.d.ts.map +1 -0
  62. package/dist/plugins/rewarded/index.d.ts +7 -0
  63. package/dist/plugins/rewarded/index.d.ts.map +1 -0
  64. package/dist/plugins/sponsorship/SponsorshipLayer.d.ts +73 -0
  65. package/dist/plugins/sponsorship/SponsorshipLayer.d.ts.map +1 -0
  66. package/dist/plugins/sponsorship/index.d.ts +7 -0
  67. package/dist/plugins/sponsorship/index.d.ts.map +1 -0
  68. package/dist/types/index.d.ts +375 -1
  69. package/dist/types/index.d.ts.map +1 -1
  70. package/package.json +1 -1
  71. package/dist/chunks/index-BCMVXNL0.js.map +0 -1
  72. package/dist/chunks/index-CaMVTgh0.js.map +0 -1
  73. package/dist/chunks/index-Dz0E1YPE.js.map +0 -1
@@ -0,0 +1,387 @@
1
+ var k = Object.defineProperty;
2
+ var x = (l, t, e) => t in l ? k(l, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : l[t] = e;
3
+ var r = (l, t, e) => x(l, typeof t != "symbol" ? t + "" : t, e);
4
+ import { s as E } from "./index-DEv3YqLg.js";
5
+ const T = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1", C = 1e4;
6
+ let g = null;
7
+ function b() {
8
+ var t, e;
9
+ const l = window;
10
+ return (t = l.cast) != null && t.framework && ((e = l.chrome) != null && e.cast) ? { framework: l.cast.framework, chrome: l.chrome.cast } : null;
11
+ }
12
+ function w() {
13
+ if (g) return g;
14
+ const l = window;
15
+ return b() ? g = Promise.resolve(b()) : !l.chrome || !window.isSecureContext ? g = Promise.resolve(null) : (g = new Promise((t) => {
16
+ const e = l.__onGCastApiAvailable, s = setTimeout(() => t(null), C);
17
+ if (l.__onGCastApiAvailable = (i, a) => {
18
+ e == null || e(i, a), clearTimeout(s), t(i ? b() : null);
19
+ }, !document.querySelector('script[src*="cast_sender.js"]')) {
20
+ const i = document.createElement("script");
21
+ i.async = !0, i.src = T, i.onerror = () => {
22
+ clearTimeout(s), g = null, t(null);
23
+ }, document.head.appendChild(i);
24
+ }
25
+ }), g);
26
+ }
27
+ const I = ["paused", "currentTime", "duration", "ended", "volume", "muted", "readyState", "seeking", "buffered", "play", "pause"], M = {
28
+ length: 0,
29
+ start: () => {
30
+ throw new DOMException("Index out of range", "IndexSizeError");
31
+ },
32
+ end: () => {
33
+ throw new DOMException("Index out of range", "IndexSizeError");
34
+ }
35
+ }, P = 150;
36
+ function A(l, t) {
37
+ return Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, t).get.call(l);
38
+ }
39
+ class N {
40
+ constructor(t, e, s) {
41
+ r(this, "state");
42
+ r(this, "pendingSeek", null);
43
+ r(this, "seekTimer", null);
44
+ r(this, "installed", !1);
45
+ this.video = t, this.commands = e, this.state = { ...s };
46
+ }
47
+ get current() {
48
+ return this.state;
49
+ }
50
+ install() {
51
+ if (this.installed) return;
52
+ this.installed = !0;
53
+ const t = this.video, e = () => this.state, s = (i, a) => {
54
+ Object.defineProperty(t, i, { configurable: !0, enumerable: !1, ...a });
55
+ };
56
+ s("paused", { get: () => e().paused }), s("ended", { get: () => e().ended }), s("duration", { get: () => e().duration }), s("readyState", { get: () => 4 }), s("seeking", { get: () => this.pendingSeek !== null }), s("buffered", { get: () => M }), s("currentTime", {
57
+ get: () => this.pendingSeek ?? e().currentTime,
58
+ set: (i) => this.seek(i)
59
+ }), s("volume", {
60
+ get: () => e().volume,
61
+ set: (i) => {
62
+ const a = Math.min(1, Math.max(0, Number(i) || 0));
63
+ this.state.volume = a, this.commands.setVolume(a), this.fire("volumechange");
64
+ }
65
+ }), s("muted", {
66
+ get: () => e().muted,
67
+ set: (i) => {
68
+ this.state.muted = !!i, this.commands.setMuted(!!i), this.fire("volumechange");
69
+ }
70
+ }), s("play", {
71
+ value: () => (this.state.ended && this.seek(0), this.commands.play(), Promise.resolve())
72
+ }), s("pause", { value: () => this.commands.pause() });
73
+ }
74
+ uninstall() {
75
+ if (this.installed) {
76
+ this.installed = !1, this.seekTimer && clearTimeout(this.seekTimer), this.seekTimer = null, this.pendingSeek = null;
77
+ for (const t of I) delete this.video[t];
78
+ }
79
+ }
80
+ /** TV'den gelen durum — değişen alanlar için olay yayar. */
81
+ update(t) {
82
+ const e = this.state;
83
+ this.state = { ...e, ...t };
84
+ const s = this.state;
85
+ t.duration !== void 0 && t.duration !== e.duration && this.fire("durationchange"), t.currentTime !== void 0 && t.currentTime !== e.currentTime && this.pendingSeek === null && this.fire("timeupdate"), (t.volume !== void 0 || t.muted !== void 0) && (s.volume !== e.volume || s.muted !== e.muted) && this.fire("volumechange"), t.paused !== void 0 && t.paused !== e.paused && (s.paused ? this.fire("pause") : (this.fire("play"), this.fire("playing"))), t.ended && !e.ended && this.fire("ended");
86
+ }
87
+ seek(t) {
88
+ const e = Math.max(0, Number(t) || 0), s = this.pendingSeek === null;
89
+ this.pendingSeek = e, s && this.fire("seeking"), this.fire("timeupdate"), this.seekTimer && clearTimeout(this.seekTimer), this.seekTimer = setTimeout(() => {
90
+ this.seekTimer = null;
91
+ const i = this.pendingSeek ?? e;
92
+ this.commands.seek(i), this.state = { ...this.state, currentTime: i, ended: !1 }, this.pendingSeek = null, this.fire("seeked"), this.fire("timeupdate");
93
+ }, P);
94
+ }
95
+ fire(t) {
96
+ this.video.dispatchEvent(new Event(t));
97
+ }
98
+ }
99
+ let y = null, m = null;
100
+ const B = 20, _ = 5;
101
+ class L {
102
+ constructor(t, e) {
103
+ r(this, "options");
104
+ r(this, "api", null);
105
+ r(this, "context", null);
106
+ r(this, "session", null);
107
+ r(this, "player", null);
108
+ r(this, "controller", null);
109
+ r(this, "proxy", null);
110
+ r(this, "castBtn", null);
111
+ r(this, "castIcon", null);
112
+ r(this, "airplayBtn", null);
113
+ r(this, "remoteBtn", null);
114
+ r(this, "overlay", null);
115
+ r(this, "loadedSrc", "");
116
+ r(this, "loadedContent", "");
117
+ r(this, "savedAutoplay", !1);
118
+ r(this, "airplayActive", !1);
119
+ r(this, "destroyed", !1);
120
+ r(this, "remoteWatchId", null);
121
+ r(this, "onCastState", (t) => {
122
+ var s;
123
+ const e = t.castState ?? "NO_DEVICES_AVAILABLE";
124
+ this.castBtn && (this.castBtn.hidden = e === "NO_DEVICES_AVAILABLE"), (s = this.castBtn) == null || s.toggleAttribute("data-connecting", e === "CONNECTING"), this.proxy || this.emit(e === "NO_DEVICES_AVAILABLE" ? "unavailable" : e === "CONNECTING" ? "connecting" : "available", "chromecast");
125
+ });
126
+ r(this, "onSessionState", (t) => {
127
+ const e = t.sessionState;
128
+ (e === "SESSION_STARTED" || e === "SESSION_RESUMED") && t.session ? y === this ? (y = null, this.attach(t.session, !0)) : e === "SESSION_RESUMED" && !m && this.tryResume(t.session) : (e === "SESSION_ENDED" || e === "SESSION_START_FAILED") && (y === this && (y = null), m === this && this.detach());
129
+ });
130
+ r(this, "onRemoteChange", (t) => {
131
+ var i;
132
+ const e = this.player, s = this.proxy;
133
+ if (!(!e || !s))
134
+ switch (t.field) {
135
+ case "isPaused":
136
+ s.update({ paused: !!t.value });
137
+ break;
138
+ case "currentTime":
139
+ s.update({ currentTime: Number(t.value) || 0 });
140
+ break;
141
+ case "duration":
142
+ s.update({ duration: Number(t.value) > 0 ? Number(t.value) : s.current.duration });
143
+ break;
144
+ case "volumeLevel":
145
+ s.update({ volume: Number(t.value) });
146
+ break;
147
+ case "isMuted":
148
+ s.update({ muted: !!t.value });
149
+ break;
150
+ case "playerState":
151
+ t.value === "IDLE" && e.isMediaLoaded === !1 && s.current.currentTime > 0 ? s.update({ ended: !0, paused: !0 }) : t.value === "PLAYING" && s.update({ ended: !1, paused: !1 });
152
+ break;
153
+ case "isPlayingBreak":
154
+ (i = this.overlay) == null || i.toggleAttribute("data-break", !!t.value);
155
+ break;
156
+ case "isConnected":
157
+ !t.value && m === this && this.detach();
158
+ break;
159
+ }
160
+ });
161
+ /** Cast sırasında player başka bir kaynağa geçti (playlist sonraki öğe, kalite, yedek kaynak) → TV'ye de gönder. */
162
+ r(this, "onLocalSourceChange", () => {
163
+ if (!this.proxy) return;
164
+ HTMLMediaElement.prototype.pause.call(this.ctx.videoEl);
165
+ const t = this.ctx.getMedia();
166
+ if (!t || t.src === this.loadedSrc) return;
167
+ const e = this.ctx.contentKey() === this.loadedContent;
168
+ this.loadMedia(e ? this.proxy.current.currentTime : 0, !0);
169
+ });
170
+ this.ctx = t, this.options = e, e.chromecast && this.initChromecast(), e.airplay && this.initAirPlay(), e.remotePlayback && this.initRemotePlayback();
171
+ }
172
+ update(t) {
173
+ const e = this.options;
174
+ this.options = t, t.chromecast && !e.chromecast && this.initChromecast(), t.airplay && !e.airplay && this.initAirPlay(), t.remotePlayback && !e.remotePlayback && this.initRemotePlayback(), this.castBtn && (this.castBtn.hidden = !t.chromecast || this.castBtn.hidden), this.airplayBtn && !t.airplay && (this.airplayBtn.hidden = !0), this.remoteBtn && !t.remotePlayback && (this.remoteBtn.hidden = !0);
175
+ }
176
+ /** İçerik şu an TV'de mi (herhangi bir yoldan). */
177
+ get casting() {
178
+ var t;
179
+ return !!this.proxy || this.airplayActive || ((t = this.ctx.videoEl.remote) == null ? void 0 : t.state) === "connected";
180
+ }
181
+ emit(t, e, s) {
182
+ this.ctx.hostEl.dispatchEvent(new CustomEvent("hp:cast", { detail: { state: t, via: e, device: s } }));
183
+ }
184
+ button(t, e, s) {
185
+ const i = this.ctx.addButton(t, e, s);
186
+ return i.btn.hidden = !0, i;
187
+ }
188
+ // ── Google Cast ─────────────────────────────────────────────────────────
189
+ async initChromecast() {
190
+ if (this.castBtn) return;
191
+ const { btn: t, icon: e } = this.button(this.ctx.i18n.castButton, "cast", () => this.requestCast());
192
+ t.setAttribute("part", "cast-button"), this.castBtn = t, this.castIcon = e;
193
+ const s = await w();
194
+ if (!s || this.destroyed) {
195
+ s || this.ctx.log({ message: "Google Cast is not available in this browser (Chrome / Edge over HTTPS needed)" });
196
+ return;
197
+ }
198
+ this.api = s;
199
+ const i = s.framework.CastContext.getInstance();
200
+ this.context = i, i.setOptions({
201
+ receiverApplicationId: this.options.receiverAppId || s.chrome.media.DEFAULT_MEDIA_RECEIVER_APP_ID,
202
+ autoJoinPolicy: s.chrome.AutoJoinPolicy.ORIGIN_SCOPED
203
+ });
204
+ const a = s.framework.CastContextEventType;
205
+ i.addEventListener(a.CAST_STATE_CHANGED, this.onCastState), i.addEventListener(a.SESSION_STATE_CHANGED, this.onSessionState), this.onCastState({ castState: i.getCastState() });
206
+ const n = i.getCurrentSession();
207
+ n && !m && this.tryResume(n);
208
+ }
209
+ requestCast() {
210
+ if (this.context) {
211
+ if (this.ctx.isAdPlaying()) {
212
+ this.ctx.log({ message: "Cast: wait for the ad to finish" });
213
+ return;
214
+ }
215
+ y = this, this.context.requestSession().catch((t) => {
216
+ y === this && (y = null), String(t) !== "cancel" && this.ctx.log({ message: `Cast session failed: ${String(t)}` });
217
+ });
218
+ }
219
+ }
220
+ tryResume(t) {
221
+ var i, a;
222
+ const e = this.ctx.getMedia(), s = (a = (i = t.getMediaSession()) == null ? void 0 : i.media) == null ? void 0 : a.contentId;
223
+ e && s && s === e.src && this.attach(t, !1);
224
+ }
225
+ async attach(t, e) {
226
+ var p, c, h, u;
227
+ const s = this.api;
228
+ if (!s || this.destroyed) return;
229
+ m && m !== this && m.detach(), m = this, this.session = t;
230
+ const i = this.ctx.videoEl, a = A(i, "currentTime"), n = A(i, "duration");
231
+ HTMLMediaElement.prototype.pause.call(i), this.savedAutoplay = i.autoplay, i.autoplay = !1;
232
+ const o = new s.framework.RemotePlayer(), d = new s.framework.RemotePlayerController(o);
233
+ this.player = o, this.controller = d, this.proxy = new N(
234
+ i,
235
+ {
236
+ play: () => o.isPaused && d.playOrPause(),
237
+ pause: () => !o.isPaused && d.playOrPause(),
238
+ seek: (f) => {
239
+ o.currentTime = f, d.seek();
240
+ },
241
+ setVolume: (f) => {
242
+ o.volumeLevel = f, d.setVolumeLevel();
243
+ },
244
+ setMuted: (f) => o.isMuted !== f && d.muteOrUnmute()
245
+ },
246
+ { paused: !1, currentTime: a, duration: n, volume: i.volume, muted: i.muted, ended: !1 }
247
+ ), this.proxy.install(), d.addEventListener(s.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange), i.addEventListener("loadstart", this.onLocalSourceChange), this.ctx.onRemoteChange(!0);
248
+ const v = ((p = t.getCastDevice()) == null ? void 0 : p.friendlyName) || this.ctx.i18n.castDeviceFallback;
249
+ this.showOverlay(this.ctx.i18n.castPlayingOn.replace("{device}", v)), (c = this.castBtn) == null || c.setAttribute("aria-pressed", "true"), this.castIcon && E(this.castIcon, "cast-connected"), this.emit("connected", "chromecast", v), e ? await this.loadMedia(a, !0) : (this.loadedSrc = ((u = (h = t.getMediaSession()) == null ? void 0 : h.media) == null ? void 0 : u.contentId) ?? "", this.loadedContent = this.ctx.contentKey());
250
+ }
251
+ /** O an çalan içeriği TV'ye yükler (reklam araları ve altyazılarla). */
252
+ async loadMedia(t, e) {
253
+ const s = this.api, i = this.session, a = this.ctx.getMedia();
254
+ if (!s || !i || !a) {
255
+ this.ctx.log({ message: "Cast: nothing to send (no playable source)" });
256
+ return;
257
+ }
258
+ const n = s.chrome.media, o = new n.MediaInfo(a.src, a.contentType);
259
+ o.streamType = a.live ? n.StreamType.LIVE : n.StreamType.BUFFERED;
260
+ const d = a.music ? new n.MusicTrackMediaMetadata() : new n.GenericMediaMetadata();
261
+ d.title = a.title, a.music ? d.artist = a.subtitle : d.subtitle = a.subtitle, a.image && (d.images = [new s.chrome.Image(a.image)]), o.metadata = d, /mpegurl/i.test(a.contentType) && this.options.hlsSegmentFormat === "fmp4" && (n.HlsSegmentFormat && (o.hlsSegmentFormat = n.HlsSegmentFormat.FMP4), n.HlsVideoSegmentFormat && (o.hlsVideoSegmentFormat = n.HlsVideoSegmentFormat.FMP4));
262
+ const v = [];
263
+ o.tracks = a.subtitles.map((c, h) => {
264
+ const u = new n.Track(h + 1, n.TrackType.TEXT);
265
+ return u.trackContentId = c.src, u.trackContentType = "text/vtt", u.subtype = n.TextTrackType.SUBTITLES, u.name = c.label, u.language = c.lang, c.default && v.push(h + 1), u;
266
+ }), this.applyAds(o, a);
267
+ const p = new n.LoadRequest(o);
268
+ p.currentTime = a.live ? void 0 : t, p.autoplay = e, v.length && (p.activeTrackIds = v), this.loadedSrc = a.src, this.loadedContent = this.ctx.contentKey();
269
+ try {
270
+ await i.loadMedia(p), this.ctx.log({ message: "Cast: media loaded on the TV", details: { src: a.src, ads: a.ads ? a.ads.vmap ? "vmap" : "vast" : "none" } });
271
+ } catch (c) {
272
+ this.ctx.log({ message: `Cast: the TV could not load the media: ${String(c)}`, fatal: !0, details: { src: a.src } });
273
+ }
274
+ }
275
+ /**
276
+ * Reklamlar TV'de: VMAP verilmişse receiver tüm araları kendisi planlar (vmapAdsRequest); yoksa VAST tag'leri
277
+ * ara olarak eklenir — preroll (0), aralıklı midroll'lar, postroll (-1). Reklamları receiver oynatır ve sayar.
278
+ */
279
+ applyAds(t, e) {
280
+ var p;
281
+ const s = e.ads, i = this.api.chrome.media;
282
+ if (!s) return;
283
+ if (s.vmap) {
284
+ const c = new i.VastAdsRequest();
285
+ c.adTagUrl = s.vmap, t.vmapAdsRequest = c;
286
+ return;
287
+ }
288
+ const a = [], n = [], o = (c, h, u) => {
289
+ const f = new i.BreakClip(`clip-${c}`), S = new i.VastAdsRequest();
290
+ S.adTagUrl = h, f.vastAdsRequest = S, a.push(f), n.push(new i.Break(`break-${c}`, [`clip-${c}`], u));
291
+ };
292
+ s.preroll && o("pre", s.preroll, 0);
293
+ const d = s.midrollIntervalSeconds ?? 0, v = ((p = this.proxy) == null ? void 0 : p.current.duration) ?? NaN;
294
+ if (s.midroll && d > 0 && !e.live && Number.isFinite(v))
295
+ for (let c = d, h = 1; c < v - _ && h <= B; c += d, h++) o(`mid-${h}`, s.midroll, c);
296
+ s.postroll && !e.live && o("post", s.postroll, -1), a.length && (t.breakClips = a, t.breaks = n);
297
+ }
298
+ detach() {
299
+ var n, o;
300
+ const t = this.proxy;
301
+ if (!t) return;
302
+ m === this && (m = null);
303
+ const { currentTime: e, paused: s, ended: i } = t.current, a = this.ctx.videoEl;
304
+ (n = this.controller) == null || n.removeEventListener(this.api.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange), a.removeEventListener("loadstart", this.onLocalSourceChange), t.uninstall(), this.proxy = null, this.player = null, this.controller = null, this.session = null, this.loadedSrc = "", a.autoplay = this.savedAutoplay, this.ctx.onRemoteChange(!1), this.hideOverlay(), (o = this.castBtn) == null || o.setAttribute("aria-pressed", "false"), this.castIcon && E(this.castIcon, "cast"), Number.isFinite(e) && e > 0 && !i && (a.currentTime = e), !s && !i && a.play().catch(() => {
305
+ }), this.emit("disconnected", "chromecast");
306
+ }
307
+ // ── AirPlay (Safari) ────────────────────────────────────────────────────
308
+ initAirPlay() {
309
+ if (this.airplayBtn || !("WebKitPlaybackTargetAvailabilityEvent" in window)) return;
310
+ const t = this.ctx.videoEl;
311
+ t.setAttribute("x-webkit-airplay", "allow");
312
+ const { btn: e } = this.button(this.ctx.i18n.airplayButton, "airplay", () => {
313
+ var s;
314
+ if (this.ctx.isMse()) {
315
+ this.ctx.log({ message: 'AirPlay: this source plays through hls.js (MSE) — use hls.engine: "auto" / "native" on Safari for AirPlay' });
316
+ return;
317
+ }
318
+ (s = t.webkitShowPlaybackTargetPicker) == null || s.call(t);
319
+ });
320
+ e.setAttribute("part", "airplay-button"), this.airplayBtn = e, t.addEventListener("webkitplaybacktargetavailabilitychanged", ((s) => {
321
+ const i = s.availability === "available";
322
+ e.hidden = !i || !this.options.airplay, this.airplayActive || this.emit(i ? "available" : "unavailable", "airplay");
323
+ })), t.addEventListener("webkitcurrentplaybacktargetiswirelesschanged", () => {
324
+ const s = !!t.webkitCurrentPlaybackTargetIsWireless;
325
+ s !== this.airplayActive && (this.airplayActive = s, e.setAttribute("aria-pressed", String(s)), s ? this.showOverlay(this.ctx.i18n.airplayPlaying) : this.hideOverlay(), this.emit(s ? "connected" : "disconnected", "airplay"));
326
+ });
327
+ }
328
+ // ── Remote Playback API ─────────────────────────────────────────────────
329
+ initRemotePlayback() {
330
+ const t = this.ctx.videoEl, e = t.remote;
331
+ if (this.remoteBtn || !e) return;
332
+ t.disableRemotePlayback = !1;
333
+ const { btn: s } = this.button(this.ctx.i18n.castButton, "cast", () => {
334
+ if (this.ctx.isMse()) {
335
+ this.ctx.log({ message: "Remote playback: hls.js (MSE) sources cannot be sent to the device" });
336
+ return;
337
+ }
338
+ e.prompt().catch((i) => this.ctx.log({ message: `Remote playback: ${String(i)}` }));
339
+ });
340
+ s.setAttribute("part", "remote-playback-button"), this.remoteBtn = s, e.watchAvailability((i) => {
341
+ s.hidden = !i || this.ctx.isMse() || !!(this.castBtn && !this.castBtn.hidden), e.state === "disconnected" && this.emit(i ? "available" : "unavailable", "remote");
342
+ }).then((i) => this.remoteWatchId = i).catch(() => s.hidden = !0), e.addEventListener("connecting", () => this.emit("connecting", "remote")), e.addEventListener("connect", () => {
343
+ s.setAttribute("aria-pressed", "true"), this.showOverlay(this.ctx.i18n.castPlayingOn.replace("{device}", this.ctx.i18n.castDeviceFallback)), this.emit("connected", "remote");
344
+ }), e.addEventListener("disconnect", () => {
345
+ s.setAttribute("aria-pressed", "false"), this.hideOverlay(), this.emit("disconnected", "remote");
346
+ });
347
+ }
348
+ // ── "TV'de oynatılıyor" katmanı ─────────────────────────────────────────
349
+ showOverlay(t) {
350
+ if (!this.overlay) {
351
+ const e = document.createElement("div");
352
+ e.className = "hp-cast-overlay", e.setAttribute("part", "cast-overlay"), e.setAttribute("role", "status");
353
+ const s = document.createElement("i");
354
+ s.className = "hp-icon hp-icon-cast-connected", s.setAttribute("aria-hidden", "true");
355
+ const i = document.createElement("span");
356
+ i.className = "hp-cast-overlay-text";
357
+ const a = document.createElement("span");
358
+ a.className = "hp-cast-overlay-ad", e.append(s, i, a), this.ctx.overlayEl.appendChild(e), this.overlay = e;
359
+ }
360
+ this.overlay.querySelector(".hp-cast-overlay-text").textContent = t, this.overlay.querySelector(".hp-cast-overlay-ad").textContent = this.ctx.i18n.castAdOnTv, this.overlay.removeAttribute("data-break"), this.overlay.setAttribute("data-open", ""), this.ctx.overlayEl.setAttribute("data-casting", "");
361
+ }
362
+ hideOverlay() {
363
+ var t;
364
+ (t = this.overlay) == null || t.removeAttribute("data-open"), this.ctx.overlayEl.removeAttribute("data-casting");
365
+ }
366
+ refreshLabels() {
367
+ var t, e, s;
368
+ (t = this.castBtn) == null || t.setAttribute("aria-label", this.ctx.i18n.castButton), (e = this.airplayBtn) == null || e.setAttribute("aria-label", this.ctx.i18n.airplayButton), (s = this.remoteBtn) == null || s.setAttribute("aria-label", this.ctx.i18n.castButton);
369
+ }
370
+ destroy() {
371
+ var t, e, s, i, a;
372
+ if (this.destroyed = !0, m === this && this.detach(), y === this && (y = null), this.context && this.api) {
373
+ const n = this.api.framework.CastContextEventType;
374
+ this.context.removeEventListener(n.CAST_STATE_CHANGED, this.onCastState), this.context.removeEventListener(n.SESSION_STATE_CHANGED, this.onSessionState);
375
+ }
376
+ this.remoteWatchId !== null && ((t = this.ctx.videoEl.remote) == null || t.cancelWatchAvailability(this.remoteWatchId).catch(() => {
377
+ })), (e = this.castBtn) == null || e.remove(), (s = this.airplayBtn) == null || s.remove(), (i = this.remoteBtn) == null || i.remove(), (a = this.overlay) == null || a.remove();
378
+ }
379
+ }
380
+ function D(l, t) {
381
+ return new L(l, t);
382
+ }
383
+ export {
384
+ L as CastController,
385
+ D as installCast
386
+ };
387
+ //# sourceMappingURL=index-Miba3PD_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-Miba3PD_.js","sources":["../../src/plugins/cast/castSdk.ts","../../src/plugins/cast/RemoteMediaProxy.ts","../../src/plugins/cast/CastController.ts","../../src/plugins/cast/index.ts"],"sourcesContent":["/**\n * Google Cast Web Sender SDK (CAF) — kullanılan yüzeyin minimal tipleri ve yükleyicisi.\n * https://developers.google.com/cast/docs/web_sender\n */\n\nexport interface CastImage {\n url: string;\n}\n\nexport interface CastMediaMetadata {\n metadataType?: number;\n title?: string;\n subtitle?: string;\n artist?: string;\n albumName?: string;\n images?: CastImage[];\n}\n\nexport interface CastTrack {\n trackContentId?: string;\n trackContentType?: string;\n subtype?: string;\n name?: string;\n language?: string;\n}\n\nexport interface CastVastAdsRequest {\n adTagUrl?: string;\n}\n\nexport interface CastBreakClip {\n vastAdsRequest?: CastVastAdsRequest;\n}\n\nexport interface CastMediaInfo {\n contentId: string;\n contentType: string;\n streamType?: string;\n metadata?: CastMediaMetadata;\n tracks?: CastTrack[];\n hlsSegmentFormat?: string;\n hlsVideoSegmentFormat?: string;\n vmapAdsRequest?: CastVastAdsRequest;\n breakClips?: CastBreakClip[];\n breaks?: unknown[];\n}\n\nexport interface CastLoadRequest {\n currentTime?: number;\n autoplay?: boolean;\n activeTrackIds?: number[];\n}\n\nexport interface CastSessionLike {\n loadMedia(request: CastLoadRequest): Promise<unknown>;\n getCastDevice(): { friendlyName?: string };\n getMediaSession(): { media?: { contentId?: string } } | null;\n}\n\nexport interface RemotePlayerLike {\n isConnected: boolean;\n isMediaLoaded: boolean;\n isPaused: boolean;\n currentTime: number;\n duration: number;\n volumeLevel: number;\n isMuted: boolean;\n playerState: string | null;\n isPlayingBreak: boolean;\n}\n\nexport interface RemotePlayerControllerLike {\n addEventListener(type: string, fn: (e: { field: string; value: unknown }) => void): void;\n removeEventListener(type: string, fn: (e: { field: string; value: unknown }) => void): void;\n playOrPause(): void;\n seek(): void;\n setVolumeLevel(): void;\n muteOrUnmute(): void;\n stop(): void;\n}\n\nexport interface CastContextLike {\n setOptions(options: Record<string, unknown>): void;\n addEventListener(type: string, fn: (e: { castState?: string; sessionState?: string; session?: CastSessionLike }) => void): void;\n removeEventListener(type: string, fn: (e: { castState?: string; sessionState?: string; session?: CastSessionLike }) => void): void;\n requestSession(): Promise<unknown>;\n getCurrentSession(): CastSessionLike | null;\n getCastState(): string;\n endCurrentSession(stopCasting: boolean): void;\n}\n\ntype Ctor<T> = new (...args: never[]) => T;\n\n/** `window.cast.framework` + `window.chrome.cast` — yalnızca kullandıklarımız. */\nexport interface CastApi {\n framework: {\n CastContext: { getInstance(): CastContextLike };\n CastContextEventType: { CAST_STATE_CHANGED: string; SESSION_STATE_CHANGED: string };\n RemotePlayer: Ctor<RemotePlayerLike>;\n RemotePlayerController: new (player: RemotePlayerLike) => RemotePlayerControllerLike;\n RemotePlayerEventType: { ANY_CHANGE: string };\n };\n chrome: {\n AutoJoinPolicy: { ORIGIN_SCOPED: string };\n media: {\n DEFAULT_MEDIA_RECEIVER_APP_ID: string;\n MediaInfo: new (contentId: string, contentType: string) => CastMediaInfo;\n GenericMediaMetadata: Ctor<CastMediaMetadata>;\n MusicTrackMediaMetadata: Ctor<CastMediaMetadata>;\n LoadRequest: new (media: CastMediaInfo) => CastLoadRequest;\n Track: new (trackId: number, type: string) => CastTrack;\n TrackType: { TEXT: string };\n TextTrackType: { SUBTITLES: string };\n StreamType: { BUFFERED: string; LIVE: string };\n VastAdsRequest: Ctor<CastVastAdsRequest>;\n BreakClip: new (id: string) => CastBreakClip;\n Break: new (id: string, breakClipIds: string[], position: number) => unknown;\n HlsSegmentFormat?: { TS: string; FMP4: string; AAC: string };\n HlsVideoSegmentFormat?: { MPEG2_TS: string; FMP4: string };\n };\n Image: new (url: string) => CastImage;\n };\n}\n\nconst CAST_SDK_SRC = 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1';\nconst LOAD_TIMEOUT_MS = 10_000;\nlet loading: Promise<CastApi | null> | null = null;\n\nfunction current(): CastApi | null {\n const w = window as unknown as { cast?: { framework?: CastApi['framework'] }; chrome?: { cast?: CastApi['chrome'] } };\n return w.cast?.framework && w.chrome?.cast ? { framework: w.cast.framework, chrome: w.chrome.cast } : null;\n}\n\n/**\n * Cast SDK'yı bir kez yükler. Yalnızca Chromium tarayıcılarda (Chrome / Edge) ve güvenli bağlamda (HTTPS) denenir;\n * diğerlerinde ya da SDK \"Cast yok\" derse null — buton hiç görünmez.\n */\nexport function loadCastSdk(): Promise<CastApi | null> {\n if (loading) return loading;\n const w = window as unknown as { chrome?: unknown; __onGCastApiAvailable?: (available: boolean, reason?: string) => void };\n if (current()) return (loading = Promise.resolve(current()));\n if (!w.chrome || !window.isSecureContext) return (loading = Promise.resolve(null));\n loading = new Promise<CastApi | null>((resolve) => {\n const previous = w.__onGCastApiAvailable;\n const timer = setTimeout(() => resolve(null), LOAD_TIMEOUT_MS);\n // SDK hazır olunca bu global geri çağrıyı çağırır — sayfa kendi kurduysa onu da çağır.\n w.__onGCastApiAvailable = (available, reason) => {\n previous?.(available, reason);\n clearTimeout(timer);\n resolve(available ? current() : null);\n };\n if (!document.querySelector('script[src*=\"cast_sender.js\"]')) {\n const s = document.createElement('script');\n s.async = true;\n s.src = CAST_SDK_SRC;\n s.onerror = () => {\n clearTimeout(timer);\n loading = null;\n resolve(null);\n };\n document.head.appendChild(s);\n }\n });\n return loading;\n}\n","/** Uzak oynatıcıya (TV) giden komutlar. */\nexport interface RemoteCommands {\n play(): void;\n pause(): void;\n seek(time: number): void;\n setVolume(volume: number): void;\n setMuted(muted: boolean): void;\n}\n\nexport interface RemoteState {\n paused: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n muted: boolean;\n ended: boolean;\n}\n\nconst PROXIED = ['paused', 'currentTime', 'duration', 'ended', 'volume', 'muted', 'readyState', 'seeking', 'buffered', 'play', 'pause'] as const;\nconst EMPTY_RANGES: TimeRanges = {\n length: 0,\n start: () => {\n throw new DOMException('Index out of range', 'IndexSizeError');\n },\n end: () => {\n throw new DOMException('Index out of range', 'IndexSizeError');\n },\n};\n/** Seek bar sürüklenirken her harekette TV'ye istek gitmesin. */\nconst SEEK_DEBOUNCE_MS = 150;\n\n/** <video>'nun gerçek (prototip) değeri — vekil kuruluyken de. */\nexport function nativeGet<K extends 'currentTime' | 'duration' | 'paused' | 'ended'>(video: HTMLVideoElement, key: K): HTMLMediaElement[K] {\n const d = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, key);\n return d!.get!.call(video) as HTMLMediaElement[K];\n}\n\n/**\n * Cast sırasında `<video>` örneğinin oynatma yüzeyini (paused, currentTime, play(), volume…) TV'ye bağlar ve TV'den\n * gelen durumu olay olarak (play / pause / timeupdate / volumechange…) yayar. Böylece kontrol çubuğu, seek bar,\n * klavye kısayolları ve eklentiler hiç değişmeden TV'yi yönetir. Kaldırılınca örnek özellikleri silinir, prototip\n * (gerçek video) geri gelir.\n */\nexport class RemoteMediaProxy {\n private state: RemoteState;\n private pendingSeek: number | null = null;\n private seekTimer: ReturnType<typeof setTimeout> | null = null;\n private installed = false;\n\n constructor(\n private readonly video: HTMLVideoElement,\n private readonly commands: RemoteCommands,\n initial: RemoteState\n ) {\n this.state = { ...initial };\n }\n\n get current(): Readonly<RemoteState> {\n return this.state;\n }\n\n install(): void {\n if (this.installed) return;\n this.installed = true;\n const v = this.video;\n const s = (): RemoteState => this.state;\n const define = (key: string, desc: PropertyDescriptor): void => {\n Object.defineProperty(v, key, { configurable: true, enumerable: false, ...desc });\n };\n define('paused', { get: () => s().paused });\n define('ended', { get: () => s().ended });\n define('duration', { get: () => s().duration });\n define('readyState', { get: () => 4 });\n define('seeking', { get: () => this.pendingSeek !== null });\n define('buffered', { get: () => EMPTY_RANGES });\n define('currentTime', {\n get: () => this.pendingSeek ?? s().currentTime,\n set: (t: number) => this.seek(t),\n });\n define('volume', {\n get: () => s().volume,\n set: (vol: number) => {\n const clamped = Math.min(1, Math.max(0, Number(vol) || 0));\n this.state.volume = clamped;\n this.commands.setVolume(clamped);\n this.fire('volumechange');\n },\n });\n define('muted', {\n get: () => s().muted,\n set: (m: boolean) => {\n this.state.muted = !!m;\n this.commands.setMuted(!!m);\n this.fire('volumechange');\n },\n });\n define('play', {\n value: () => {\n if (this.state.ended) this.seek(0);\n this.commands.play();\n return Promise.resolve();\n },\n });\n define('pause', { value: () => this.commands.pause() });\n }\n\n uninstall(): void {\n if (!this.installed) return;\n this.installed = false;\n if (this.seekTimer) clearTimeout(this.seekTimer);\n this.seekTimer = null;\n this.pendingSeek = null;\n for (const key of PROXIED) delete (this.video as unknown as Record<string, unknown>)[key];\n }\n\n /** TV'den gelen durum — değişen alanlar için olay yayar. */\n update(patch: Partial<RemoteState>): void {\n const prev = this.state;\n this.state = { ...prev, ...patch };\n const next = this.state;\n if (patch.duration !== undefined && patch.duration !== prev.duration) this.fire('durationchange');\n if (patch.currentTime !== undefined && patch.currentTime !== prev.currentTime && this.pendingSeek === null) this.fire('timeupdate');\n if (patch.volume !== undefined || patch.muted !== undefined) {\n if (next.volume !== prev.volume || next.muted !== prev.muted) this.fire('volumechange');\n }\n if (patch.paused !== undefined && patch.paused !== prev.paused) {\n if (next.paused) this.fire('pause');\n else {\n this.fire('play');\n this.fire('playing');\n }\n }\n if (patch.ended && !prev.ended) this.fire('ended');\n }\n\n private seek(t: number): void {\n const target = Math.max(0, Number(t) || 0);\n const first = this.pendingSeek === null;\n this.pendingSeek = target;\n if (first) this.fire('seeking');\n this.fire('timeupdate');\n if (this.seekTimer) clearTimeout(this.seekTimer);\n this.seekTimer = setTimeout(() => {\n this.seekTimer = null;\n const to = this.pendingSeek ?? target;\n this.commands.seek(to);\n this.state = { ...this.state, currentTime: to, ended: false };\n this.pendingSeek = null;\n this.fire('seeked');\n this.fire('timeupdate');\n }, SEEK_DEBOUNCE_MS);\n }\n\n private fire(type: string): void {\n this.video.dispatchEvent(new Event(type));\n }\n}\n","import type { CastOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { setIconName } from '../../icons/Icon';\nimport { loadCastSdk, type CastApi, type CastContextLike, type CastMediaInfo, type CastSessionLike, type RemotePlayerControllerLike, type RemotePlayerLike } from './castSdk';\nimport { RemoteMediaProxy, nativeGet } from './RemoteMediaProxy';\n\n/** TV'ye gönderilecek içerik — player o anki duruma göre hazırlar. */\nexport interface CastMedia {\n src: string;\n contentType: string;\n live: boolean;\n title?: string;\n subtitle?: string;\n image?: string;\n /** Ses modu: TV'de müzik parçası olarak (kapak, sanatçı). */\n music: boolean;\n subtitles: Array<{ src: string; label: string; lang: string; default?: boolean }>;\n /** TV'de oynatılacak reklamlar (makroları doldurulmuş tag'ler); null = reklamsız. */\n ads: { vmap?: string; preroll?: string; midroll?: string; midrollIntervalSeconds?: number; postroll?: string } | null;\n}\n\nexport interface CastPlayerContext {\n hostEl: HTMLElement;\n videoEl: HTMLVideoElement;\n overlayEl: HTMLElement;\n i18n: HopeLocaleStrings;\n log(entry: { message: string; fatal?: boolean; details?: Record<string, string | number | boolean | undefined> }): void;\n addButton(label: string, icon: string, onClick: () => void): { btn: HTMLButtonElement; icon: HTMLElement };\n getMedia(): CastMedia | null;\n /** Yerelde video reklamı oynuyor — bu sırada yayın başlatılmaz. */\n isAdPlaying(): boolean;\n /** hls.js (MSE) ile oynatılıyor — AirPlay / Remote Playback bu kaynağı TV'ye veremez. */\n isMse(): boolean;\n /** İçerik kimliği — kalite / yedek kaynak değişimi aynı içerik sayılır (TV'de konum korunur). */\n contentKey(): string;\n /** İçerik TV'de mi (Chromecast) — player yerel reklamları askıya alır, otomatik oynatmayı keser. */\n onRemoteChange(remote: boolean): void;\n}\n\ntype Via = 'chromecast' | 'airplay' | 'remote';\ntype CastState = 'available' | 'unavailable' | 'connecting' | 'connected' | 'disconnected';\n\n/** Aynı sayfada birden çok player: Cast oturumu, butonuna basılan player'ındır. */\nlet requester: CastController | null = null;\nlet owner: CastController | null = null;\n/** Midroll aralığından üretilecek en fazla ara. */\nconst MAX_INTERVAL_BREAKS = 20;\nconst MIDROLL_END_MARGIN_S = 5;\n\n/**\n * TV'ye yayın: Google Cast (Chromecast / Google TV), AirPlay ve Remote Playback API. Her biri ayrı ayrı açılır;\n * butonlar yalnızca uygun cihaz varken görünür. Chromecast'te içerik TV'de oynar, player kumandaya dönüşür\n * (RemoteMediaProxy); bağlantı bitince yerelde TV'deki saniyeden devam eder.\n */\nexport class CastController {\n private options: CastOptions;\n private api: CastApi | null = null;\n private context: CastContextLike | null = null;\n private session: CastSessionLike | null = null;\n private player: RemotePlayerLike | null = null;\n private controller: RemotePlayerControllerLike | null = null;\n private proxy: RemoteMediaProxy | null = null;\n private castBtn: HTMLButtonElement | null = null;\n private castIcon: HTMLElement | null = null;\n private airplayBtn: HTMLButtonElement | null = null;\n private remoteBtn: HTMLButtonElement | null = null;\n private overlay: HTMLDivElement | null = null;\n private loadedSrc = '';\n private loadedContent = '';\n private savedAutoplay = false;\n private airplayActive = false;\n private destroyed = false;\n private remoteWatchId: number | null = null;\n\n constructor(\n private readonly ctx: CastPlayerContext,\n options: CastOptions\n ) {\n this.options = options;\n if (options.chromecast) void this.initChromecast();\n if (options.airplay) this.initAirPlay();\n if (options.remotePlayback) this.initRemotePlayback();\n }\n\n update(options: CastOptions): void {\n const prev = this.options;\n this.options = options;\n if (options.chromecast && !prev.chromecast) void this.initChromecast();\n if (options.airplay && !prev.airplay) this.initAirPlay();\n if (options.remotePlayback && !prev.remotePlayback) this.initRemotePlayback();\n if (this.castBtn) this.castBtn.hidden = !options.chromecast || this.castBtn.hidden;\n if (this.airplayBtn && !options.airplay) this.airplayBtn.hidden = true;\n if (this.remoteBtn && !options.remotePlayback) this.remoteBtn.hidden = true;\n }\n\n /** İçerik şu an TV'de mi (herhangi bir yoldan). */\n get casting(): boolean {\n return !!this.proxy || this.airplayActive || this.ctx.videoEl.remote?.state === 'connected';\n }\n\n private emit(state: CastState, via: Via, device?: string): void {\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:cast', { detail: { state, via, device } }));\n }\n\n private button(label: string, icon: string, onClick: () => void): { btn: HTMLButtonElement; icon: HTMLElement } {\n const b = this.ctx.addButton(label, icon, onClick);\n b.btn.hidden = true;\n return b;\n }\n\n // ── Google Cast ─────────────────────────────────────────────────────────\n\n private async initChromecast(): Promise<void> {\n if (this.castBtn) return;\n const { btn, icon } = this.button(this.ctx.i18n.castButton, 'cast', () => this.requestCast());\n btn.setAttribute('part', 'cast-button');\n this.castBtn = btn;\n this.castIcon = icon;\n const api = await loadCastSdk();\n if (!api || this.destroyed) {\n if (!api) this.ctx.log({ message: 'Google Cast is not available in this browser (Chrome / Edge over HTTPS needed)' });\n return;\n }\n this.api = api;\n const context = api.framework.CastContext.getInstance();\n this.context = context;\n context.setOptions({\n receiverApplicationId: this.options.receiverAppId || api.chrome.media.DEFAULT_MEDIA_RECEIVER_APP_ID,\n autoJoinPolicy: api.chrome.AutoJoinPolicy.ORIGIN_SCOPED,\n });\n const types = api.framework.CastContextEventType;\n context.addEventListener(types.CAST_STATE_CHANGED, this.onCastState);\n context.addEventListener(types.SESSION_STATE_CHANGED, this.onSessionState);\n this.onCastState({ castState: context.getCastState() });\n // Sayfa yenilendi ve oturum sürüyor (TV aynı içeriği oynatıyor) → kumandayı yeniden bağla.\n const existing = context.getCurrentSession();\n if (existing && !owner) this.tryResume(existing);\n }\n\n private readonly onCastState = (e: { castState?: string }): void => {\n const state = e.castState ?? 'NO_DEVICES_AVAILABLE';\n if (this.castBtn) this.castBtn.hidden = state === 'NO_DEVICES_AVAILABLE';\n this.castBtn?.toggleAttribute('data-connecting', state === 'CONNECTING');\n if (!this.proxy) this.emit(state === 'NO_DEVICES_AVAILABLE' ? 'unavailable' : state === 'CONNECTING' ? 'connecting' : 'available', 'chromecast');\n };\n\n private readonly onSessionState = (e: { sessionState?: string; session?: CastSessionLike }): void => {\n const s = e.sessionState;\n if ((s === 'SESSION_STARTED' || s === 'SESSION_RESUMED') && e.session) {\n if (requester === this) {\n requester = null;\n void this.attach(e.session, true);\n } else if (s === 'SESSION_RESUMED' && !owner) {\n this.tryResume(e.session);\n }\n } else if (s === 'SESSION_ENDED' || s === 'SESSION_START_FAILED') {\n if (requester === this) requester = null;\n if (owner === this) this.detach();\n }\n };\n\n private requestCast(): void {\n if (!this.context) return;\n if (this.ctx.isAdPlaying()) {\n this.ctx.log({ message: 'Cast: wait for the ad to finish' });\n return;\n }\n requester = this;\n // Bağlıyken Chrome'un seçicisi \"yayını durdur\"u da sunar.\n this.context.requestSession().catch((err: unknown) => {\n if (requester === this) requester = null;\n // Kullanıcı seçiciyi kapattı ('cancel') — hata değil.\n if (String(err) !== 'cancel') this.ctx.log({ message: `Cast session failed: ${String(err)}` });\n });\n }\n\n private tryResume(session: CastSessionLike): void {\n const media = this.ctx.getMedia();\n const remoteId = session.getMediaSession()?.media?.contentId;\n if (media && remoteId && remoteId === media.src) void this.attach(session, false);\n }\n\n private async attach(session: CastSessionLike, load: boolean): Promise<void> {\n const api = this.api;\n if (!api || this.destroyed) return;\n if (owner && owner !== this) owner.detach();\n owner = this;\n this.session = session;\n const v = this.ctx.videoEl;\n const startAt = nativeGet(v, 'currentTime');\n const duration = nativeGet(v, 'duration');\n HTMLMediaElement.prototype.pause.call(v);\n // Cast sırasında kaynak değişirse (playlist / kalite) yerel video kendiliğinden çalmasın.\n this.savedAutoplay = v.autoplay;\n v.autoplay = false;\n\n const player = new api.framework.RemotePlayer();\n const controller = new api.framework.RemotePlayerController(player);\n this.player = player;\n this.controller = controller;\n this.proxy = new RemoteMediaProxy(\n v,\n {\n play: () => player.isPaused && controller.playOrPause(),\n pause: () => !player.isPaused && controller.playOrPause(),\n seek: (t) => {\n player.currentTime = t;\n controller.seek();\n },\n setVolume: (vol) => {\n player.volumeLevel = vol;\n controller.setVolumeLevel();\n },\n setMuted: (m) => player.isMuted !== m && controller.muteOrUnmute(),\n },\n { paused: false, currentTime: startAt, duration, volume: v.volume, muted: v.muted, ended: false }\n );\n this.proxy.install();\n controller.addEventListener(api.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange);\n v.addEventListener('loadstart', this.onLocalSourceChange);\n this.ctx.onRemoteChange(true);\n const device = session.getCastDevice()?.friendlyName || this.ctx.i18n.castDeviceFallback;\n this.showOverlay(this.ctx.i18n.castPlayingOn.replace('{device}', device));\n this.castBtn?.setAttribute('aria-pressed', 'true');\n if (this.castIcon) setIconName(this.castIcon, 'cast-connected');\n this.emit('connected', 'chromecast', device);\n if (load) await this.loadMedia(startAt, true);\n else {\n this.loadedSrc = session.getMediaSession()?.media?.contentId ?? '';\n this.loadedContent = this.ctx.contentKey();\n }\n }\n\n /** O an çalan içeriği TV'ye yükler (reklam araları ve altyazılarla). */\n private async loadMedia(currentTime: number, autoplay: boolean): Promise<void> {\n const api = this.api;\n const session = this.session;\n const media = this.ctx.getMedia();\n if (!api || !session || !media) {\n this.ctx.log({ message: 'Cast: nothing to send (no playable source)' });\n return;\n }\n const m = api.chrome.media;\n const info: CastMediaInfo = new m.MediaInfo(media.src, media.contentType);\n info.streamType = media.live ? m.StreamType.LIVE : m.StreamType.BUFFERED;\n const md = media.music ? new m.MusicTrackMediaMetadata() : new m.GenericMediaMetadata();\n md.title = media.title;\n if (media.music) md.artist = media.subtitle;\n else md.subtitle = media.subtitle;\n if (media.image) md.images = [new api.chrome.Image(media.image)];\n info.metadata = md;\n if (/mpegurl/i.test(media.contentType) && this.options.hlsSegmentFormat === 'fmp4') {\n if (m.HlsSegmentFormat) info.hlsSegmentFormat = m.HlsSegmentFormat.FMP4;\n if (m.HlsVideoSegmentFormat) info.hlsVideoSegmentFormat = m.HlsVideoSegmentFormat.FMP4;\n }\n const activeTrackIds: number[] = [];\n info.tracks = media.subtitles.map((s, i) => {\n const t = new m.Track(i + 1, m.TrackType.TEXT);\n t.trackContentId = s.src;\n t.trackContentType = 'text/vtt';\n t.subtype = m.TextTrackType.SUBTITLES;\n t.name = s.label;\n t.language = s.lang;\n if (s.default) activeTrackIds.push(i + 1);\n return t;\n });\n this.applyAds(info, media);\n const req = new m.LoadRequest(info);\n req.currentTime = media.live ? undefined : currentTime;\n req.autoplay = autoplay;\n if (activeTrackIds.length) req.activeTrackIds = activeTrackIds;\n this.loadedSrc = media.src;\n this.loadedContent = this.ctx.contentKey();\n try {\n await session.loadMedia(req);\n this.ctx.log({ message: 'Cast: media loaded on the TV', details: { src: media.src, ads: media.ads ? (media.ads.vmap ? 'vmap' : 'vast') : 'none' } });\n } catch (err) {\n this.ctx.log({ message: `Cast: the TV could not load the media: ${String(err)}`, fatal: true, details: { src: media.src } });\n }\n }\n\n /**\n * Reklamlar TV'de: VMAP verilmişse receiver tüm araları kendisi planlar (vmapAdsRequest); yoksa VAST tag'leri\n * ara olarak eklenir — preroll (0), aralıklı midroll'lar, postroll (-1). Reklamları receiver oynatır ve sayar.\n */\n private applyAds(info: CastMediaInfo, media: CastMedia): void {\n const ads = media.ads;\n const m = this.api!.chrome.media;\n if (!ads) return;\n if (ads.vmap) {\n const req = new m.VastAdsRequest();\n req.adTagUrl = ads.vmap;\n info.vmapAdsRequest = req;\n return;\n }\n const clips: unknown[] = [];\n const breaks: unknown[] = [];\n const add = (id: string, tag: string, position: number): void => {\n const clip = new m.BreakClip(`clip-${id}`);\n const req = new m.VastAdsRequest();\n req.adTagUrl = tag;\n clip.vastAdsRequest = req;\n clips.push(clip);\n breaks.push(new m.Break(`break-${id}`, [`clip-${id}`], position));\n };\n if (ads.preroll) add('pre', ads.preroll, 0);\n const every = ads.midrollIntervalSeconds ?? 0;\n const duration = this.proxy?.current.duration ?? NaN;\n if (ads.midroll && every > 0 && !media.live && Number.isFinite(duration)) {\n // Bitişe çok yakın midroll olmasın (orada postroll var).\n for (let t = every, i = 1; t < duration - MIDROLL_END_MARGIN_S && i <= MAX_INTERVAL_BREAKS; t += every, i++) add(`mid-${i}`, ads.midroll, t);\n }\n if (ads.postroll && !media.live) add('post', ads.postroll, -1);\n if (clips.length) {\n info.breakClips = clips as CastMediaInfo['breakClips'];\n info.breaks = breaks;\n }\n }\n\n private readonly onRemoteChange = (e: { field: string; value: unknown }): void => {\n const p = this.player;\n const proxy = this.proxy;\n if (!p || !proxy) return;\n switch (e.field) {\n case 'isPaused':\n proxy.update({ paused: !!e.value });\n break;\n case 'currentTime':\n proxy.update({ currentTime: Number(e.value) || 0 });\n break;\n case 'duration':\n proxy.update({ duration: Number(e.value) > 0 ? Number(e.value) : proxy.current.duration });\n break;\n case 'volumeLevel':\n proxy.update({ volume: Number(e.value) });\n break;\n case 'isMuted':\n proxy.update({ muted: !!e.value });\n break;\n case 'playerState':\n // İçerik TV'de bitti (IDLE + daha önce oynuyordu) → ended.\n if (e.value === 'IDLE' && p.isMediaLoaded === false && proxy.current.currentTime > 0) proxy.update({ ended: true, paused: true });\n else if (e.value === 'PLAYING') proxy.update({ ended: false, paused: false });\n break;\n case 'isPlayingBreak':\n this.overlay?.toggleAttribute('data-break', !!e.value);\n break;\n case 'isConnected':\n if (!e.value && owner === this) this.detach();\n break;\n }\n };\n\n /** Cast sırasında player başka bir kaynağa geçti (playlist sonraki öğe, kalite, yedek kaynak) → TV'ye de gönder. */\n private readonly onLocalSourceChange = (): void => {\n if (!this.proxy) return;\n HTMLMediaElement.prototype.pause.call(this.ctx.videoEl);\n const media = this.ctx.getMedia();\n if (!media || media.src === this.loadedSrc) return;\n // Aynı içeriğin başka kalitesi / yedeği ise kaldığı yerden, yeni bir içerikse (playlist) baştan.\n const same = this.ctx.contentKey() === this.loadedContent;\n void this.loadMedia(same ? this.proxy.current.currentTime : 0, true);\n };\n\n private detach(): void {\n const proxy = this.proxy;\n if (!proxy) return;\n if (owner === this) owner = null;\n const { currentTime, paused, ended } = proxy.current;\n const v = this.ctx.videoEl;\n this.controller?.removeEventListener(this.api!.framework.RemotePlayerEventType.ANY_CHANGE, this.onRemoteChange);\n v.removeEventListener('loadstart', this.onLocalSourceChange);\n proxy.uninstall();\n this.proxy = null;\n this.player = null;\n this.controller = null;\n this.session = null;\n this.loadedSrc = '';\n v.autoplay = this.savedAutoplay;\n this.ctx.onRemoteChange(false);\n this.hideOverlay();\n this.castBtn?.setAttribute('aria-pressed', 'false');\n if (this.castIcon) setIconName(this.castIcon, 'cast');\n // TV'deki saniyeden yerelde devam (bittiyse olduğu yerde kalır).\n if (Number.isFinite(currentTime) && currentTime > 0 && !ended) v.currentTime = currentTime;\n if (!paused && !ended) void v.play().catch(() => {});\n this.emit('disconnected', 'chromecast');\n }\n\n // ── AirPlay (Safari) ────────────────────────────────────────────────────\n\n private initAirPlay(): void {\n if (this.airplayBtn || !('WebKitPlaybackTargetAvailabilityEvent' in window)) return;\n const v = this.ctx.videoEl as HTMLVideoElement & { webkitShowPlaybackTargetPicker?: () => void; webkitCurrentPlaybackTargetIsWireless?: boolean };\n v.setAttribute('x-webkit-airplay', 'allow');\n const { btn } = this.button(this.ctx.i18n.airplayButton, 'airplay', () => {\n if (this.ctx.isMse()) {\n this.ctx.log({ message: 'AirPlay: this source plays through hls.js (MSE) — use hls.engine: \"auto\" / \"native\" on Safari for AirPlay' });\n return;\n }\n v.webkitShowPlaybackTargetPicker?.();\n });\n btn.setAttribute('part', 'airplay-button');\n this.airplayBtn = btn;\n v.addEventListener('webkitplaybacktargetavailabilitychanged', ((e: Event & { availability?: string }) => {\n const available = e.availability === 'available';\n btn.hidden = !available || !this.options.airplay;\n if (!this.airplayActive) this.emit(available ? 'available' : 'unavailable', 'airplay');\n }) as EventListener);\n v.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', () => {\n const on = !!v.webkitCurrentPlaybackTargetIsWireless;\n if (on === this.airplayActive) return;\n this.airplayActive = on;\n btn.setAttribute('aria-pressed', String(on));\n if (on) this.showOverlay(this.ctx.i18n.airplayPlaying);\n else this.hideOverlay();\n this.emit(on ? 'connected' : 'disconnected', 'airplay');\n });\n }\n\n // ── Remote Playback API ─────────────────────────────────────────────────\n\n private initRemotePlayback(): void {\n const v = this.ctx.videoEl;\n const remote = v.remote;\n if (this.remoteBtn || !remote) return;\n v.disableRemotePlayback = false;\n const { btn } = this.button(this.ctx.i18n.castButton, 'cast', () => {\n if (this.ctx.isMse()) {\n this.ctx.log({ message: 'Remote playback: hls.js (MSE) sources cannot be sent to the device' });\n return;\n }\n remote.prompt().catch((err: unknown) => this.ctx.log({ message: `Remote playback: ${String(err)}` }));\n });\n btn.setAttribute('part', 'remote-playback-button');\n this.remoteBtn = btn;\n remote\n .watchAvailability((available) => {\n // Google Cast butonu görünüyorsa aynı işi yapan ikinci butonu gösterme.\n btn.hidden = !available || this.ctx.isMse() || !!(this.castBtn && !this.castBtn.hidden);\n if (remote.state === 'disconnected') this.emit(available ? 'available' : 'unavailable', 'remote');\n })\n .then((id) => (this.remoteWatchId = id))\n .catch(() => (btn.hidden = true));\n remote.addEventListener('connecting', () => this.emit('connecting', 'remote'));\n remote.addEventListener('connect', () => {\n btn.setAttribute('aria-pressed', 'true');\n this.showOverlay(this.ctx.i18n.castPlayingOn.replace('{device}', this.ctx.i18n.castDeviceFallback));\n this.emit('connected', 'remote');\n });\n remote.addEventListener('disconnect', () => {\n btn.setAttribute('aria-pressed', 'false');\n this.hideOverlay();\n this.emit('disconnected', 'remote');\n });\n }\n\n // ── \"TV'de oynatılıyor\" katmanı ─────────────────────────────────────────\n\n private showOverlay(text: string): void {\n if (!this.overlay) {\n const el = document.createElement('div');\n el.className = 'hp-cast-overlay';\n el.setAttribute('part', 'cast-overlay');\n el.setAttribute('role', 'status');\n const icon = document.createElement('i');\n icon.className = 'hp-icon hp-icon-cast-connected';\n icon.setAttribute('aria-hidden', 'true');\n const label = document.createElement('span');\n label.className = 'hp-cast-overlay-text';\n const ad = document.createElement('span');\n ad.className = 'hp-cast-overlay-ad';\n el.append(icon, label, ad);\n this.ctx.overlayEl.appendChild(el);\n this.overlay = el;\n }\n this.overlay.querySelector('.hp-cast-overlay-text')!.textContent = text;\n this.overlay.querySelector('.hp-cast-overlay-ad')!.textContent = this.ctx.i18n.castAdOnTv;\n this.overlay.removeAttribute('data-break');\n this.overlay.setAttribute('data-open', '');\n this.ctx.overlayEl.setAttribute('data-casting', '');\n }\n\n private hideOverlay(): void {\n this.overlay?.removeAttribute('data-open');\n this.ctx.overlayEl.removeAttribute('data-casting');\n }\n\n refreshLabels(): void {\n this.castBtn?.setAttribute('aria-label', this.ctx.i18n.castButton);\n this.airplayBtn?.setAttribute('aria-label', this.ctx.i18n.airplayButton);\n this.remoteBtn?.setAttribute('aria-label', this.ctx.i18n.castButton);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (owner === this) {\n // Player sayfadan kalkıyor: TV'deki yayın sürsün (Cast'in olağan davranışı), kumanda bağı kopsun.\n this.detach();\n }\n if (requester === this) requester = null;\n if (this.context && this.api) {\n const types = this.api.framework.CastContextEventType;\n this.context.removeEventListener(types.CAST_STATE_CHANGED, this.onCastState);\n this.context.removeEventListener(types.SESSION_STATE_CHANGED, this.onSessionState);\n }\n if (this.remoteWatchId !== null) void this.ctx.videoEl.remote?.cancelWatchAvailability(this.remoteWatchId).catch(() => {});\n this.castBtn?.remove();\n this.airplayBtn?.remove();\n this.remoteBtn?.remove();\n this.overlay?.remove();\n }\n}\n","import { CastController, type CastMedia, type CastPlayerContext } from './CastController';\nimport type { CastOptions } from '../../types';\n\n/** TV'ye yayını kurar (Google Cast / AirPlay / Remote Playback — her biri seçenekle açılır). */\nexport function installCast(ctx: CastPlayerContext, options: CastOptions): CastController {\n return new CastController(ctx, options);\n}\n\nexport { CastController };\nexport type { CastMedia, CastPlayerContext };\n"],"names":["CAST_SDK_SRC","LOAD_TIMEOUT_MS","loading","current","w","_a","_b","loadCastSdk","resolve","previous","timer","available","reason","s","PROXIED","EMPTY_RANGES","SEEK_DEBOUNCE_MS","nativeGet","video","key","RemoteMediaProxy","commands","initial","__publicField","v","define","desc","t","vol","clamped","m","patch","prev","next","target","first","to","type","requester","owner","MAX_INTERVAL_BREAKS","MIDROLL_END_MARGIN_S","CastController","ctx","options","e","state","p","proxy","media","same","via","device","label","icon","onClick","b","btn","api","context","types","existing","err","session","remoteId","load","startAt","duration","player","controller","setIconName","_d","_c","currentTime","autoplay","info","md","activeTrackIds","i","req","ads","clips","breaks","add","id","tag","position","clip","every","paused","ended","on","remote","text","el","ad","_e","installCast"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  var u = Object.defineProperty;
2
2
  var m = (p, e, t) => e in p ? u(p, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[e] = t;
3
3
  var o = (p, e, t) => m(p, typeof e != "symbol" ? e + "" : e, t);
4
- import { c as b } from "./index-Dz0E1YPE.js";
4
+ import { c as b } from "./index-DEv3YqLg.js";
5
5
  const f = {
6
6
  enabled: !1,
7
7
  mode: "rich",
@@ -202,4 +202,4 @@ export {
202
202
  v as MarkProgress,
203
203
  y as installMarkers
204
204
  };
205
- //# sourceMappingURL=index-DcVUXkXo.js.map
205
+ //# sourceMappingURL=index-e00_M05B.js.map