@munsonlabs/video-player 0.2.1 → 0.2.2

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 (31) hide show
  1. package/README.md +95 -95
  2. package/dist/chunks/{ads-Dj9QMKvd.mjs → ads-CF9PWPJJ.mjs} +1 -1
  3. package/dist/{elements/chunks/brightcove-CIqE1989.mjs → chunks/brightcove-DUITad7n.mjs} +1 -1
  4. package/dist/{elements/chunks/constants-DRD0PsRw.mjs → chunks/constants-BUQXC_ZT.mjs} +1 -1
  5. package/dist/{elements/chunks/dailymotion-CHtFXCBp.mjs → chunks/dailymotion-CwCwD6rN.mjs} +1 -1
  6. package/dist/chunks/{embedShared-Cq4Qj9Kt.mjs → embedShared-DgFZ58OV.mjs} +1 -1
  7. package/dist/chunks/{jwplayer-Dv826deA.mjs → jwplayer-BxpEGj9-.mjs} +1 -1
  8. package/dist/chunks/{sourceHelpers-DlkCZiTJ.mjs → sourceHelpers-CAGxjbbu.mjs} +1 -1
  9. package/dist/chunks/{vimeo-mHVlA0Ra.mjs → vimeo-BNsFVvtc.mjs} +1 -1
  10. package/dist/chunks/{youtube-D8sBVM7Q.mjs → youtube-B7s74nf6.mjs} +1 -1
  11. package/dist/elements/chunks/{ads-Dj9QMKvd.mjs → ads-CF9PWPJJ.mjs} +1 -1
  12. package/dist/{chunks/brightcove-CIqE1989.mjs → elements/chunks/brightcove-DUITad7n.mjs} +1 -1
  13. package/dist/{chunks/constants-DRD0PsRw.mjs → elements/chunks/constants-BUQXC_ZT.mjs} +1 -1
  14. package/dist/{chunks/dailymotion-CHtFXCBp.mjs → elements/chunks/dailymotion-CwCwD6rN.mjs} +1 -1
  15. package/dist/elements/chunks/{embedShared-Cq4Qj9Kt.mjs → embedShared-DgFZ58OV.mjs} +1 -1
  16. package/dist/elements/chunks/{jwplayer-Dv826deA.mjs → jwplayer-BxpEGj9-.mjs} +1 -1
  17. package/dist/elements/chunks/{sourceHelpers-DlkCZiTJ.mjs → sourceHelpers-CAGxjbbu.mjs} +1 -1
  18. package/dist/elements/chunks/{vimeo-mHVlA0Ra.mjs → vimeo-BNsFVvtc.mjs} +1 -1
  19. package/dist/elements/chunks/{youtube-D8sBVM7Q.mjs → youtube-B7s74nf6.mjs} +1 -1
  20. package/dist/elements/controls.css +1 -1
  21. package/dist/elements/controls.mjs +1 -1
  22. package/dist/elements/core.css +1 -1
  23. package/dist/elements/core.d.mts +7 -7
  24. package/dist/elements/core.mjs +1 -1
  25. package/dist/elements/index.d.mts +7 -7
  26. package/dist/elements/index.mjs +1 -1
  27. package/dist/elements/style.css +1 -1
  28. package/dist/index.d.mts +11 -11
  29. package/dist/index.mjs +1 -1
  30. package/dist/style.css +1 -1
  31. package/package.json +1 -1
package/README.md CHANGED
@@ -14,14 +14,14 @@ npm install @munsonlabs/video-player
14
14
 
15
15
  ```vue
16
16
  <script setup>
17
- import { VideoItem } from '@munsonlabs/video-player'
17
+ import { VideoCard } from '@munsonlabs/video-player'
18
18
  import '@munsonlabs/video-player/style'
19
19
  </script>
20
20
 
21
21
  <template>
22
- <VideoItem
22
+ <VideoCard
23
23
  title="Big Buck Bunny"
24
- video-url="https://cdn.jwplayer.com/videos/O5chtspP-4VHSaSK0.mp4"
24
+ src="https://cdn.jwplayer.com/videos/O5chtspP-4VHSaSK0.mp4"
25
25
  poster="https://storage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg"
26
26
  />
27
27
  </template>
@@ -29,36 +29,36 @@ import '@munsonlabs/video-player/style'
29
29
 
30
30
  ### Pinning a single player
31
31
 
32
- Set `pin-position` on a standalone `VideoItem`/`VideoPlayer` (no `VideoStage` involved) to get the same corner-pinning mini-player behaviour `VideoStage` has, scoped to just that one player: once it scrolls out of view while playing, it pins to the given corner instead of auto-pausing, and shrinks back to its inline size once scrolled back into view.
32
+ Set `pin` on a standalone `VideoCard`/`VideoPlayer` (no `VideoStage` involved) to get the same corner-pinning mini-player behaviour `VideoStage` has, scoped to just that one player: once it scrolls out of view while playing, it pins to the given corner instead of auto-pausing, and shrinks back to its inline size once scrolled back into view.
33
33
 
34
34
  ```vue
35
- <VideoItem video-url="https://cdn.jwplayer.com/videos/O5chtspP-4VHSaSK0.mp4" pin-position="bottom-right" />
35
+ <VideoCard src="https://cdn.jwplayer.com/videos/O5chtspP-4VHSaSK0.mp4" pin="bottom-right" />
36
36
  ```
37
37
 
38
- - Only `'bottom-right'`, `'bottom-left'`, `'top-right'`, `'top-left'` are supported here (unlike `VideoStage`'s `pinPosition`, there's no `'full-width'` option for a single player).
38
+ - Only `'bottom-right'`, `'bottom-left'`, `'top-right'`, `'top-left'` are supported here (unlike `VideoStage`'s `pin`, there's no `'full-width'` option for a single player).
39
39
  - Pausing while pinned does **not** unpin it - like a mini-player, it stays put, paused, in the corner until scrolled back into view. A dismiss button and a scroll-to-player button are shown on the pinned box.
40
- - Omit `pin-position` to disable pinning entirely - the player then just auto-pauses offscreen as usual.
40
+ - Omit `pin` to disable pinning entirely - the player then just auto-pauses offscreen as usual.
41
41
  - `HideMarker` (see [Hiding the pinned stage over content](#hiding-the-pinned-stage-over-content)) works the same way here too, since there's only ever one pinned/tucked element on a page at a time.
42
42
 
43
43
  ### Stage player
44
44
 
45
- `VideoStage` is a sticky full-width player that receives videos from `VideoItem` components anywhere on the page via window events. When the stage scrolls out of view it minifies to a pip in the bottom-right corner.
45
+ `VideoStage` is a sticky full-width player that receives videos from `VideoCard` components anywhere on the page via window events. When the stage scrolls out of view it minifies to a pip in the bottom-right corner.
46
46
 
47
47
  ```vue
48
48
  <script setup>
49
- import { VideoStage, VideoItem } from '@munsonlabs/video-player'
49
+ import { VideoStage, VideoCard } from '@munsonlabs/video-player'
50
50
  import '@munsonlabs/video-player/style'
51
51
  </script>
52
52
 
53
53
  <template>
54
54
  <VideoStage @state-change="onStateChange" />
55
- <VideoItem v-for="video in videos" :key="video.videoUrl" v-bind="video" />
55
+ <VideoCard v-for="video in videos" :key="video.src" v-bind="video" />
56
56
  </template>
57
57
  ```
58
58
 
59
59
  ### Playlists
60
60
 
61
- Pass `playlist` (a `VideoEntry[]`, the same shape as a `VideoItem`'s props) to let the stage track the currently-playing video's position within it. Position updates automatically when a user clicks a `VideoItem` elsewhere on the page, with nothing extra to keep in sync.
61
+ Pass `playlist` (a `VideoEntry[]`, the same shape as a `VideoCard`'s props) to let the stage track the currently-playing video's position within it. Position updates automatically when a user clicks a `VideoCard` elsewhere on the page, with nothing extra to keep in sync.
62
62
 
63
63
  ```vue
64
64
  <VideoStage :playlist="videos" @state-change="onStateChange" />
@@ -75,7 +75,7 @@ Pass `playlist` (a `VideoEntry[]`, the same shape as a `VideoItem`'s props) to l
75
75
 
76
76
  ### Hiding the pinned stage over content
77
77
 
78
- When `VideoStage` is pinned to a corner (any `pinPosition` other than `'full-width'`), it can sit over content you'd rather it not cover - a footer, a signup form, a comments section. `HideMarker` is a plain sentinel element: place it just before that content, and the stage slides mostly off-screen (leaving a small sliver) for as long as the marker is in the viewport, sliding back once it isn't.
78
+ When `VideoStage` is pinned to a corner (any `pin` other than `'full-width'`), it can sit over content you'd rather it not cover - a footer, a signup form, a comments section. `HideMarker` is a plain sentinel element: place it just before that content, and the stage slides mostly off-screen (leaving a small sliver) for as long as the marker is in the viewport, sliding back once it isn't.
79
79
 
80
80
  ```vue
81
81
  <script setup>
@@ -83,7 +83,7 @@ import { VideoStage, HideMarker } from '@munsonlabs/video-player'
83
83
  </script>
84
84
 
85
85
  <template>
86
- <VideoStage pin-position="bottom-right" :playlist="videos" />
86
+ <VideoStage pin="bottom-right" :playlist="videos" />
87
87
 
88
88
  <!-- ...page content... -->
89
89
 
@@ -93,16 +93,16 @@ import { VideoStage, HideMarker } from '@munsonlabs/video-player'
93
93
  ```
94
94
 
95
95
  - There's no prop linking `HideMarker` to a specific `VideoStage` - there's only ever one stage on a page, so it always applies to whichever one is mounted.
96
- - The sliver width is a CSS custom property: `--mvp-stage-tuck` (default `32px`), see [theming variables](#theming-the-hud-buttons).
96
+ - The sliver width is a CSS custom property: `--mlv-stage-tuck` (default `32px`), see [theming variables](#theming-the-hud-buttons).
97
97
  - Place it precisely where you want the stage to tuck away - it renders a 1px-tall invisible `div`, so it triggers briefly as the page scrolls past that exact line.
98
98
 
99
99
  ---
100
100
 
101
- ## VideoItem / VideoPlayer Props
101
+ ## VideoCard / VideoPlayer Props
102
102
 
103
103
  | Prop | Type | Default | Description |
104
104
  | ------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
105
- | `videoUrl` | `string` | - | **Required.** The video URL or platform-specific URI (the platform is auto-detected from its shape, see [Platform URLs](#platform-urls)) |
105
+ | `src` | `string` | - | **Required.** The video URL or platform-specific URI (the platform is auto-detected from its shape, see [Platform URLs](#platform-urls)) |
106
106
  | `title` | `string` | `''` | Video title |
107
107
  | `poster` | `string` | `''` | Poster image URL |
108
108
  | `aspectRatio` | `string` | `'16:9'` | e.g. `'16:9'`, `'9:16'`, `'4:3'` |
@@ -114,17 +114,17 @@ import { VideoStage, HideMarker } from '@munsonlabs/video-player'
114
114
  | `autoStage` | `boolean` | `false` | Immediately send this video to the stage on mount |
115
115
  | `playbackRate` | `number` | `1` | Initial playback rate |
116
116
  | `adTagUrl` | `string` | `''` | VAST or VMAP ad tag URL |
117
- | `adTagParams` | `object` | - | Fills `{macro}` tokens on whichever ad tag URL ends up in use, see [Ads](#ads-ima--vast--vmap) |
117
+ | `adMacroParams` | `object` | - | Fills `{macro}` tokens on whichever ad tag URL ends up in use, see [Ads](#ads-ima--vast--vmap) |
118
118
  | `headerBidding` | `object` | - | Runs a Prebid.js auction before the ad plays, see [Header bidding](#header-bidding-prebidjs) |
119
119
  | `tracks` | `array` | - | WebVTT caption/subtitle tracks, see [Captions](#captions-webvtt) |
120
120
  | `payload` | `object` | `{}` | Arbitrary data attached to every `state-change` event |
121
121
  | `action` | `PlayerAction` | `null` | Button shown in the player HUD, see [Actions](#actions) |
122
122
  | `disableTapCapture` | `boolean` | `false` | Disables the full-video tap-to-reveal-controls overlay (tap/click still reaches embed platform UI underneath, e.g. YouTube's own) |
123
123
  | `controls` | `boolean` | `true` | Set `false` to render a bare `<video>` with no built-in HUD - drive playback with your own UI instead, see [Headless Controls](#headless-controls) |
124
- | `playWhenInView` | `boolean` | `false` | Auto-play once at least half the player is visible, auto-pause once it isn't - e.g. for a scroll-snap feed, see [Autoplay, mute & volume](#autoplay-mute--volume) |
125
- | `pinPosition` | `PinCorner` | - | Pins the player to this screen corner once it scrolls out of view while playing, instead of auto-pausing - see [Pinning a single player](#pinning-a-single-player) |
124
+ | `playInView` | `boolean` | `false` | Auto-play once at least half the player is visible, auto-pause once it isn't - e.g. for a scroll-snap feed, see [Autoplay, mute & volume](#autoplay-mute--volume) |
125
+ | `pin` | `PinCorner` | - | Pins the player to this screen corner once it scrolls out of view while playing, instead of auto-pausing - see [Pinning a single player](#pinning-a-single-player) |
126
126
 
127
- \* `lazy` only has an effect on `VideoItem` (default `true`), which is what actually implements the placeholder-until-clicked behaviour. `VideoPlayer` accepts the prop for type compatibility but defaults to `false` and never reads it: using `<VideoPlayer>` directly always mounts the real player immediately, regardless of `lazy`.
127
+ \* `lazy` only has an effect on `VideoCard` (default `true`), which is what actually implements the placeholder-until-clicked behaviour. `VideoPlayer` accepts the prop for type compatibility but defaults to `false` and never reads it: using `<VideoPlayer>` directly always mounts the real player immediately, regardless of `lazy`.
128
128
 
129
129
  ### Autoplay, mute & volume
130
130
 
@@ -132,7 +132,7 @@ Unless a video sets `muted`/`volume` explicitly, every player on the page shares
132
132
 
133
133
  ### Platform URLs
134
134
 
135
- The platform is detected automatically from the shape of `videoUrl`; there's no separate prop to set it.
135
+ The platform is detected automatically from the shape of `src`; there's no separate prop to set it.
136
136
 
137
137
  | Platform | URL format |
138
138
  | ------------- | -------------------------------------------------------------------------------------------------------- |
@@ -171,7 +171,7 @@ This works identically from the [web component bundles](#web-component-usage) -
171
171
 
172
172
  ## Headless Controls
173
173
 
174
- Unstyled control primitives for building your own HUD instead of the built-in one (set `:controls="false"` on the player) - each is published both as a Vue component and as a `muns-controls-*` custom element from the exact same source:
174
+ Unstyled control primitives for building your own HUD instead of the built-in one (set `:controls="false"` on the player) - each is published both as a Vue component and as a `ml-controls-*` custom element from the exact same source:
175
175
 
176
176
  Building a custom HUD out of these and never rendering `VideoPlayer`'s own built-in controls? Import `@munsonlabs/video-player/style/controls` instead of the full `/style` bundle to skip the built-in HUD/popup CSS - see [Web Component Usage](#web-component-usage) for the full breakdown of the three style bundles.
177
177
 
@@ -193,7 +193,7 @@ import {
193
193
  } from '@munsonlabs/video-player'
194
194
  ```
195
195
 
196
- Every control takes a `player` prop pointing at the same object `VideoPlayer`/`VideoItem`/`VideoStage` expose via a template ref:
196
+ Every control takes a `player` prop pointing at the same object `VideoPlayer`/`VideoCard`/`VideoStage` expose via a template ref:
197
197
 
198
198
  ```vue
199
199
  <script setup>
@@ -203,7 +203,7 @@ const player = ref(null)
203
203
  </script>
204
204
 
205
205
  <template>
206
- <VideoPlayer ref="player" video-url="..." :controls="false" />
206
+ <VideoPlayer ref="player" src="..." :controls="false" />
207
207
  <PlayButton :player="player" />
208
208
  <MuteButton :player="player" />
209
209
  <Scrubber :player="player" />
@@ -213,18 +213,18 @@ const player = ref(null)
213
213
  Or, `<label for>`-style, skip the ref and point at an element id instead:
214
214
 
215
215
  ```vue
216
- <VideoPlayer id="my-player" video-url="..." :controls="false" />
216
+ <VideoPlayer id="my-player" src="..." :controls="false" />
217
217
  <PlayButton for="my-player" />
218
218
  ```
219
219
 
220
- `player` and `for` are both optional - if both are given, `player` wins. Each button's own CSS uses `:where()` (zero specificity), so a single class you add always wins, and most expose their state via a scoped slot for full custom markup (e.g. `PlayButton`'s `#default="{ isPlaying }"`). See [Web Component Usage](#web-component-usage) for using these as raw custom elements (`<muns-controls-play-button>` etc.) outside Vue.
220
+ `player` and `for` are both optional - if both are given, `player` wins. Each button's own CSS uses `:where()` (zero specificity), so a single class you add always wins, and most expose their state via a scoped slot for full custom markup (e.g. `PlayButton`'s `#default="{ isPlaying }"`). See [Web Component Usage](#web-component-usage) for using these as raw custom elements (`<ml-controls-play-button>` etc.) outside Vue.
221
221
 
222
222
  ### Transcript
223
223
 
224
224
  `Transcript` renders a clickable transcript for the linked player: pass `cues` as `{ time, end?, text }[]` (times in seconds), clicking a cue seeks to its timestamp (starting playback first if paused), and the cue at the playhead is highlighted and kept scrolled into view:
225
225
 
226
226
  ```vue
227
- <VideoPlayer id="my-player" video-url="..." />
227
+ <VideoPlayer id="my-player" src="..." />
228
228
  <Transcript
229
229
  for="my-player"
230
230
  :cues="[
@@ -238,11 +238,11 @@ Or, `<label for>`-style, skip the ref and point at an element id instead:
238
238
  - Works on **every** platform (YouTube/Vimeo/Dailymotion included) - only needs current time and `seek`.
239
239
  - `end` is optional: when set, nothing is highlighted between that cue's `end` and the next cue's start.
240
240
  - Auto-scroll pauses while the pointer is over the list. A scoped slot customises each cue's markup: `#default="{ cue, index, isActive, formatTime }"`.
241
- - As a custom element (`<muns-controls-transcript>`), pass cues as an inline JSON string attribute: `cues='[{"time":0,"text":"..."}]'`.
241
+ - As a custom element (`<ml-controls-transcript>`), pass cues as an inline JSON string attribute: `cues='[{"time":0,"text":"..."}]'`.
242
242
 
243
243
  ### Building your own wrapper component
244
244
 
245
- `useForwardedPlayer` is what `VideoItem`/`VideoStage` themselves use to forward a template-ref'd `VideoPlayer`'s controls/state onto their own `defineExpose` - the same mechanism is available for building a custom wrapper component of your own:
245
+ `useForwardedPlayer` is what `VideoCard`/`VideoStage` themselves use to forward a template-ref'd `VideoPlayer`'s controls/state onto their own `defineExpose` - the same mechanism is available for building a custom wrapper component of your own:
246
246
 
247
247
  ```vue
248
248
  <script setup>
@@ -263,7 +263,7 @@ Because it's wired up via `defineExpose`, this works the same way whether your w
263
263
 
264
264
  ### Exposing a plain Vue player to independent, non-Vue code
265
265
 
266
- A plain `<VideoPlayer>`/`<VideoItem>`/`<VideoStage>` used the normal Vue way doesn't expose its API onto the DOM - its state lives on the Vue component instance, reachable only via a template ref inside your own app. `exposePlayerOnElement` bridges that gap for code with no access to your Vue app (a third party's own script, a `<muns-controls-*>` custom element from a separate bundle):
266
+ A plain `<VideoPlayer>`/`<VideoCard>`/`<VideoStage>` used the normal Vue way doesn't expose its API onto the DOM - its state lives on the Vue component instance, reachable only via a template ref inside your own app. `exposePlayerOnElement` bridges that gap for code with no access to your Vue app (a third party's own script, a `<ml-controls-*>` custom element from a separate bundle):
267
267
 
268
268
  ```vue
269
269
  <script setup>
@@ -277,7 +277,7 @@ onMounted(() => exposePlayerOnElement(wrapperEl.value, playerRef.value))
277
277
 
278
278
  <template>
279
279
  <div id="my-player" ref="wrapperEl">
280
- <VideoPlayer ref="playerRef" video-url="..." />
280
+ <VideoPlayer ref="playerRef" src="..." />
281
281
  </div>
282
282
  </template>
283
283
  ```
@@ -287,7 +287,7 @@ onMounted(() => exposePlayerOnElement(wrapperEl.value, playerRef.value))
287
287
  <script type="module">
288
288
  import '@munsonlabs/video-player/element/controls'
289
289
  </script>
290
- <muns-controls-transcript for="my-player" cues='[{"time":0,"text":"..."}]'></muns-controls-transcript>
290
+ <ml-controls-transcript for="my-player" cues='[{"time":0,"text":"..."}]'></ml-controls-transcript>
291
291
  ```
292
292
 
293
293
  State fields are copied as live getters (not a one-time snapshot) and methods directly. `el` doesn't need to be the player's own root element - a wrapper `<div>` works the same.
@@ -298,7 +298,7 @@ State fields are copied as live getters (not a one-time snapshot) and methods di
298
298
 
299
299
  ### `state-change`
300
300
 
301
- Emitted by `VideoItem`, `VideoPlayer`, and `VideoStage`. Every event includes `currentTime`, `duration`, `src`, and `payload` (arbitrary user data).
301
+ Emitted by `VideoCard`, `VideoPlayer`, and `VideoStage`. Every event includes `currentTime`, `duration`, `src`, and `payload` (arbitrary user data).
302
302
 
303
303
  | Event | When it fires | Extra fields |
304
304
  | -------------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
@@ -335,9 +335,9 @@ The `action` prop adds a button to the player HUD. Pass a built-in string or a c
335
335
  ### Built-in actions
336
336
 
337
337
  ```vue
338
- <VideoItem action="mute" ... />
339
- <VideoItem action="loop" ... />
340
- <VideoItem action="autoplay" ... />
338
+ <VideoCard action="mute" ... />
339
+ <VideoCard action="loop" ... />
340
+ <VideoCard action="autoplay" ... />
341
341
  ```
342
342
 
343
343
  `action="autoplay"` toggles [auto-advance](#playlists) and only makes sense when rendered inside a `VideoStage` with a `playlist` set: it reads and flips the same `autoAdvance` state as the controls popup's built-in "Auto" button, just as a HUD button instead.
@@ -347,7 +347,7 @@ The `action` prop adds a button to the player HUD. Pass a built-in string or a c
347
347
  Pass an object with `icon` (SVG string), `label`, and `onClick`:
348
348
 
349
349
  ```vue
350
- <VideoItem :action="{ icon: '<svg .../>', label: 'Save', onClick: () => console.log('saved') }" ... />
350
+ <VideoCard :action="{ icon: '<svg .../>', label: 'Save', onClick: () => console.log('saved') }" ... />
351
351
  ```
352
352
 
353
353
  ---
@@ -357,20 +357,20 @@ Pass an object with `icon` (SVG string), `label`, and `onClick`:
357
357
  **Step by step:**
358
358
 
359
359
  1. Get a VAST or VMAP ad tag URL. For testing, use [Google's public IMA sample tags](https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags); for production, this comes from your ad server (Google Ad Manager): ask whoever manages ad ops for the tag, or build it yourself if you already know the ad unit path.
360
- 2. Pass it as `adTagUrl` on `VideoItem`/`VideoPlayer`. That's it for a basic pre-roll/VMAP schedule: the Google IMA SDK is loaded automatically on demand, nothing else to configure.
360
+ 2. Pass it as `adTagUrl` on `VideoCard`/`VideoPlayer`. That's it for a basic pre-roll/VMAP schedule: the Google IMA SDK is loaded automatically on demand, nothing else to configure.
361
361
  3. Confirm it's working: watch for `adstart`/`adend` on the `state-change` event, or check the Network tab for a request to `pubads.g.doubleclick.net` (or wherever your ad server lives) when the video plays.
362
- 4. Only if your ad tag is a **macro template** (contains literal `{tokenName}` placeholders, as Brightcove's auto-discovered ad tags usually do, see below) do you need `adTagParams` too. Otherwise skip it entirely.
362
+ 4. Only if your ad tag is a **macro template** (contains literal `{tokenName}` placeholders, as Brightcove's auto-discovered ad tags usually do, see below) do you need `adMacroParams` too. Otherwise skip it entirely.
363
363
 
364
364
  ```vue
365
- <VideoItem video-url="https://..." ad-tag-url="https://pubads.g.doubleclick.net/..." />
365
+ <VideoCard src="https://..." ad-tag-url="https://pubads.g.doubleclick.net/..." />
366
366
  ```
367
367
 
368
368
  Ads are not supported on YouTube, Vimeo, or Dailymotion.
369
369
 
370
- Some platforms (currently Brightcove) auto-discover their own ad tag URL: the platform's own wins if you don't pass `adTagUrl` yourself. Brightcove's ad tag URLs are typically macro templates (e.g. `...&iu={adUnit}&vid={referenceId}&cust_params={customParameters}`), not ready-to-use URLs. `adTagParams` fills these in on **whichever** ad tag URL ends up in use, prop-supplied or auto-discovered:
370
+ Some platforms (currently Brightcove) auto-discover their own ad tag URL: the platform's own wins if you don't pass `adTagUrl` yourself. Brightcove's ad tag URLs are typically macro templates (e.g. `...&iu={adUnit}&vid={referenceId}&cust_params={customParameters}`), not ready-to-use URLs. `adMacroParams` fills these in on **whichever** ad tag URL ends up in use, prop-supplied or auto-discovered:
371
371
 
372
372
  ```vue
373
- <VideoItem video-url="https://players.brightcove.net/..." :ad-tag-params="{ adUnit: 'network/section', referenceId: videoId, rdid: deviceId }" />
373
+ <VideoCard src="https://players.brightcove.net/..." :ad-tag-params="{ adUnit: 'network/section', referenceId: videoId, rdid: deviceId }" />
374
374
  ```
375
375
 
376
376
  Name each key exactly after the macro it fills (`vid={referenceId}` means the key is `referenceId`, not `vid`). A key with no matching `{macro}` is a no-op.
@@ -381,14 +381,14 @@ Name each key exactly after the macro it fills (`vid={referenceId}` means the ke
381
381
 
382
382
  1. Confirm your organisation already runs Prebid.js somewhere on the page (`window.pbjs` in the console). If not, this isn't something to set up from this package.
383
383
  2. Get a Prebid **video ad unit** config from ad ops (with `code`, `mediaTypes.video`, and `bids`) and the GAM ad unit path (`iu`).
384
- 3. Pass both as `headerBidding: { adUnit, params: { iu: '...' } }`, alongside a plain `adTagUrl`/`adTagParams` as fallback. Never rely on `headerBidding` alone.
384
+ 3. Pass both as `headerBidding: { adUnit, params: { iu: '...' } }`, alongside a plain `adTagUrl`/`adMacroParams` as fallback. Never rely on `headerBidding` alone.
385
385
  4. Verify: run `pbjs.getBidResponsesForAdUnitCode('your-ad-unit-code')` in the console after playing.
386
386
 
387
387
  The auction runs **in the background** and is never awaited: it can't block mounting, playback, or controls. Its result is only used if ready by the time the ad is requested (first play); otherwise the plain ad tag is used. Every failure mode (no `pbjs`, timeout, no bid, `buildVideoUrl()` throwing) fails open:
388
388
 
389
389
  ```vue
390
- <VideoItem
391
- video-url="https://players.brightcove.net/..."
390
+ <VideoCard
391
+ src="https://players.brightcove.net/..."
392
392
  :header-bidding="{
393
393
  adUnit: {
394
394
  code: 'video-preroll',
@@ -401,7 +401,7 @@ The auction runs **in the background** and is never awaited: it can't block moun
401
401
  />
402
402
  ```
403
403
 
404
- `adUnit` is a standard Prebid video ad unit. `params` is passed through to `buildVideoUrl()` (GAM ad tag params). `timeoutMs` (default `1000`) bounds the auction. Every failure mode fails open to whatever `adTagUrl`/`adTagParams` would have resolved to.
404
+ `adUnit` is a standard Prebid video ad unit. `params` is passed through to `buildVideoUrl()` (GAM ad tag params). `timeoutMs` (default `1000`) bounds the auction. Every failure mode fails open to whatever `adTagUrl`/`adMacroParams` would have resolved to.
405
405
 
406
406
  ### Ad overlay UI
407
407
 
@@ -423,8 +423,8 @@ There are two ways a caption track ends up available, and you don't have to pick
423
423
  - **Everything else** (a plain MP4, or an HLS stream with no subtitle rendition of its own) needs WebVTT tracks supplied explicitly via `tracks`:
424
424
 
425
425
  ```vue
426
- <VideoItem
427
- video-url="https://.../video.mp4"
426
+ <VideoCard
427
+ src="https://.../video.mp4"
428
428
  :tracks="[
429
429
  { src: '/captions/en.vtt', kind: 'captions', srclang: 'en', label: 'English', default: true },
430
430
  { src: '/captions/fr.vtt', kind: 'captions', srclang: 'fr', label: 'Français' },
@@ -466,26 +466,26 @@ Set the variables on any ancestor of the player (e.g. a wrapper `<div>` or `:roo
466
466
 
467
467
  ```css
468
468
  .my-video-wrapper {
469
- --mvp-btn-bg: #e11d48;
470
- --mvp-btn-color: #fff;
469
+ --mlv-btn-bg: #e11d48;
470
+ --mlv-btn-color: #fff;
471
471
  }
472
472
  ```
473
473
 
474
- Icons use `fill="currentColor"`, so `--mvp-btn-color` recolours the icon along with `--mvp-btn-bg` for the background. Hover state is a `filter: brightness()` lift on top of `--mvp-btn-bg`, so it works for both the default translucent look and a solid theme colour.
474
+ Icons use `fill="currentColor"`, so `--mlv-btn-color` recolours the icon along with `--mlv-btn-bg` for the background. Hover state is a `filter: brightness()` lift on top of `--mlv-btn-bg`, so it works for both the default translucent look and a solid theme colour.
475
475
 
476
476
  ### Full controls popup
477
477
 
478
478
  | Variable | Default | Description |
479
479
  | ---------------------- | ------------------------------- | ---------------------------------------------------------------------------------------- |
480
- | `--mvp-controls-width` | `min(450px, calc(100% - 32px))` | Controls popup width |
481
- | `--mvp-popup-align` | `center` | Horizontal alignment of the popup (`center` or `flex-end` to dock at the bottom) |
482
- | `--mvp-btn-bg` | (frosted glass) | Background of action, play/pause, and show-controls buttons |
483
- | `--mvp-btn-color` | (frosted glass) | Icon/text colour of the same buttons |
484
- | `--mvp-stage-tuck` | `32px` | Width of the sliver left visible when `HideMarker` tucks the pinned stage off-screen |
485
- | `--mvp-radius` | `12px` | Border-radius of the pinned corner box |
486
- | `--mvp-accent` | — | Active-state highlight colour for the loop/autoplay toggle buttons in the controls popup |
480
+ | `--mlv-controls-width` | `min(450px, calc(100% - 32px))` | Controls popup width |
481
+ | `--mlv-popup-align` | `center` | Horizontal alignment of the popup (`center` or `flex-end` to dock at the bottom) |
482
+ | `--mlv-btn-bg` | (frosted glass) | Background of action, play/pause, and show-controls buttons |
483
+ | `--mlv-btn-color` | (frosted glass) | Icon/text colour of the same buttons |
484
+ | `--mlv-stage-tuck` | `32px` | Width of the sliver left visible when `HideMarker` tucks the pinned stage off-screen |
485
+ | `--mlv-radius` | `12px` | Border-radius of the pinned corner box |
486
+ | `--mlv-accent` | — | Active-state highlight colour for the loop/autoplay toggle buttons in the controls popup |
487
487
 
488
- Real fullscreen always docks the popup to the bottom regardless of `--mvp-popup-align`.
488
+ Real fullscreen always docks the popup to the bottom regardless of `--mlv-popup-align`.
489
489
 
490
490
  ### Fullscreen controls
491
491
 
@@ -500,8 +500,8 @@ Import an element bundle to register components as native custom elements. These
500
500
  Three bundles are available: pick exactly one, since importing more than one double-registers any tag they share and throws:
501
501
 
502
502
  - `@munsonlabs/video-player/element`: everything (player + all headless controls). Auto-injects its own CSS.
503
- - `@munsonlabs/video-player/element/core`: just `<muns-video-player>`/`<muns-video-stage>`/`<muns-video-item>`/`<muns-video-placeholder>`. Import `@munsonlabs/video-player/style/core` yourself.
504
- - `@munsonlabs/video-player/element/controls`: just the `<muns-controls-*>` primitives. Import `@munsonlabs/video-player/style/controls` alongside it.
503
+ - `@munsonlabs/video-player/element/core`: just `<ml-video-player>`/`<ml-video-stage>`/`<ml-video-card>`/`<ml-video-placeholder>`. Import `@munsonlabs/video-player/style/core` yourself.
504
+ - `@munsonlabs/video-player/element/controls`: just the `<ml-controls-*>` primitives. Import `@munsonlabs/video-player/style/controls` alongside it.
505
505
 
506
506
  `/element` and `/element/core` dynamically `import()` platform adapter code only when a URL for that platform mounts (from a sibling `chunks/` directory); self-hosting either bundle means deploying `chunks/` alongside it.
507
507
 
@@ -515,11 +515,11 @@ Three bundles are available: pick exactly one, since importing more than one dou
515
515
  </script>
516
516
  <script type="module" src="@munsonlabs/video-player/element"></script>
517
517
 
518
- <muns-video-item
519
- video-url="https://cdn.jwplayer.com/videos/O5chtspP-4VHSaSK0.mp4"
518
+ <ml-video-card
519
+ src="https://cdn.jwplayer.com/videos/O5chtspP-4VHSaSK0.mp4"
520
520
  title="Big Buck Bunny"
521
521
  poster="https://storage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg"
522
- ></muns-video-item>
522
+ ></ml-video-card>
523
523
  ```
524
524
 
525
525
  If you'll be playing HLS (`.m3u8`) or DASH (`.mpd`) sources, also add an import map entry for `hls.js`/`dashjs`. Each is loaded on demand via a dynamic `import(...)`, which (unlike the Vue usage, where your own bundler resolves it) has no resolution path in a plain browser without one:
@@ -540,51 +540,51 @@ If you'll be playing HLS (`.m3u8`) or DASH (`.mpd`) sources, also add an import
540
540
 
541
541
  Core (in `/element` and `/element/core`):
542
542
 
543
- | Element | Vue equivalent |
544
- | -------------------------- | -------------------- |
545
- | `<muns-video-item>` | `<VideoItem>` |
546
- | `<muns-video-stage>` | `<VideoStage>` |
547
- | `<muns-video-player>` | `<VideoPlayer>` |
548
- | `<muns-video-placeholder>` | `<VideoPlaceholder>` |
549
- | `<muns-hide-marker>` | `<HideMarker>` |
543
+ | Element | Vue equivalent |
544
+ | ------------------------ | -------------------- |
545
+ | `<ml-video-card>` | `<VideoCard>` |
546
+ | `<ml-video-stage>` | `<VideoStage>` |
547
+ | `<ml-video-player>` | `<VideoPlayer>` |
548
+ | `<ml-video-placeholder>` | `<VideoPlaceholder>` |
549
+ | `<ml-hide-marker>` | `<HideMarker>` |
550
550
 
551
551
  Controls (in `/element` and `/element/controls`), see [Headless Controls](#headless-controls) for what each does:
552
552
 
553
- | Element | Vue equivalent |
554
- | -------------------------------------- | ---------------------- |
555
- | `<muns-controls-play-button>` | `<PlayButton>` |
556
- | `<muns-controls-mute-button>` | `<MuteButton>` |
557
- | `<muns-controls-fullscreen-button>` | `<FullscreenButton>` |
558
- | `<muns-controls-loop-button>` | `<LoopButton>` |
559
- | `<muns-controls-pip-button>` | `<PipButton>` |
560
- | `<muns-controls-captions-button>` | `<CaptionsButton>` |
561
- | `<muns-controls-quality-button>` | `<QualityButton>` |
562
- | `<muns-controls-playback-rate-button>` | `<PlaybackRateButton>` |
563
- | `<muns-controls-buffering>` | `<Buffering>` |
564
- | `<muns-controls-scrubber>` | `<Scrubber>` |
565
- | `<muns-controls-volume-slider>` | `<VolumeSlider>` |
566
- | `<muns-controls-time-display>` | `<TimeDisplay>` |
567
- | `<muns-controls-transcript>` | `<Transcript>` |
553
+ | Element | Vue equivalent |
554
+ | ------------------------------------ | ---------------------- |
555
+ | `<ml-controls-play-button>` | `<PlayButton>` |
556
+ | `<ml-controls-mute-button>` | `<MuteButton>` |
557
+ | `<ml-controls-fullscreen-button>` | `<FullscreenButton>` |
558
+ | `<ml-controls-loop-button>` | `<LoopButton>` |
559
+ | `<ml-controls-pip-button>` | `<PipButton>` |
560
+ | `<ml-controls-captions-button>` | `<CaptionsButton>` |
561
+ | `<ml-controls-quality-button>` | `<QualityButton>` |
562
+ | `<ml-controls-playback-rate-button>` | `<PlaybackRateButton>` |
563
+ | `<ml-controls-buffering>` | `<Buffering>` |
564
+ | `<ml-controls-scrubber>` | `<Scrubber>` |
565
+ | `<ml-controls-volume-slider>` | `<VolumeSlider>` |
566
+ | `<ml-controls-time-display>` | `<TimeDisplay>` |
567
+ | `<ml-controls-transcript>` | `<Transcript>` |
568
568
 
569
569
  ### Passing objects as web component attributes
570
570
 
571
571
  Boolean and string props map directly to HTML attributes. Object props (`payload`) can be passed as inline JSON strings:
572
572
 
573
573
  ```html
574
- <muns-video-item video-url="https://..." ad-tag-url="https://..." payload='{"articleId":"123"}'></muns-video-item>
574
+ <ml-video-card src="https://..." ad-tag-url="https://..." payload='{"articleId":"123"}'></ml-video-card>
575
575
  ```
576
576
 
577
577
  For `action` (which contains a function), set it via JavaScript:
578
578
 
579
579
  ```js
580
- const player = document.querySelector('muns-video-item')
580
+ const player = document.querySelector('ml-video-card')
581
581
  player.action = { icon: '<svg.../>', label: 'Save', onClick: () => {} }
582
582
  ```
583
583
 
584
584
  ### Listening to events
585
585
 
586
586
  ```js
587
- const player = document.querySelector('muns-video-item')
587
+ const player = document.querySelector('ml-video-card')
588
588
  player.addEventListener('state-change', (e) => {
589
589
  console.log(e.detail)
590
590
  })
@@ -592,10 +592,10 @@ player.addEventListener('state-change', (e) => {
592
592
 
593
593
  ### Calling player methods
594
594
 
595
- `<muns-video-item>`/`<muns-video-stage>` expose the same forwarded API a Vue template ref would (see [Building your own wrapper component](#building-your-own-wrapper-component)) - methods and state land directly on the element itself:
595
+ `<ml-video-card>`/`<ml-video-stage>` expose the same forwarded API a Vue template ref would (see [Building your own wrapper component](#building-your-own-wrapper-component)) - methods and state land directly on the element itself:
596
596
 
597
597
  ```js
598
- const player = document.querySelector('muns-video-item')
598
+ const player = document.querySelector('ml-video-card')
599
599
  player.togglePlay()
600
600
  console.log(player.isPlaying)
601
601
  ```
@@ -609,13 +609,13 @@ console.log(player.isPlaying)
609
609
  import { registerPlatform } from 'https://esm.sh/@munsonlabs/video-player/element/core'
610
610
  registerPlatform({ key: 'acme', test: (url) => url.includes('acme.tv'), embed: true, createAdapter: createAcmeAdapter })
611
611
 
612
- const player = document.createElement('muns-video-player')
613
- player.setAttribute('video-url', 'https://acme.tv/watch/123')
612
+ const player = document.createElement('ml-video-player')
613
+ player.setAttribute('src', 'https://acme.tv/watch/123')
614
614
  document.body.append(player)
615
615
  </script>
616
616
  ```
617
617
 
618
- **Timing note:** importing `/element`/`/element/core` calls `customElements.define()`, which synchronously upgrades any matching tag already in the DOM. A statically-declared `<muns-video-player>` gets upgraded before your `registerPlatform` call on the next line. Creating the tag from script, after registering, as above sidesteps this.
618
+ **Timing note:** importing `/element`/`/element/core` calls `customElements.define()`, which synchronously upgrades any matching tag already in the DOM. A statically-declared `<ml-video-player>` gets upgraded before your `registerPlatform` call on the next line. Creating the tag from script, after registering, as above sidesteps this.
619
619
 
620
620
  If your tags are statically declared, load `/element/core` with a **`?defer`** query instead: it skips the automatic `customElements.define()`, so you register your platform first and then call the exported `defineElements()` yourself:
621
621
 
@@ -626,7 +626,7 @@ If your tags are statically declared, load `/element/core` with a **`?defer`** q
626
626
  defineElements()
627
627
  </script>
628
628
 
629
- <muns-video-player video-url="https://acme.tv/watch/123"></muns-video-player>
629
+ <ml-video-player src="https://acme.tv/watch/123"></ml-video-player>
630
630
  ```
631
631
 
632
632
  `?defer` is read from the `/element/core` module's own URL. `defineElements()` is idempotent: it only defines whichever tags aren't already registered.
@@ -1 +1 @@
1
- import{c as e,d as t,f as n}from"./constants-DRD0PsRw.mjs";import{n as r}from"./platform-Dg9JBh8M.mjs";import{t as i}from"./loadScript-Du6JsTc2.mjs";function a(){return window.google?.ima?Promise.resolve():i(e,`ima`)}function o(e,i,o,s){let c=document.createElement(`div`);c.className=`ima-ad-container`,e.appendChild(c);let l=o,u=null,d=null,f=null,p=!1,m=!1,h=!1,g=!1,_=!1,v=!1,y=1,b=!1,x=``,S=new ResizeObserver(([e])=>{let t=window.google?.ima;if(!f||!t)return;let{width:n,height:r}=e.contentRect;f.resize(n,r,t.ViewMode.NORMAL)});S.observe(i);function C(){d?.contentComplete()}function w(r){g=r,e.classList.toggle(n,r),r||(_=!1,e.classList.remove(t))}function T(){if(p||!m||!h||!u||!d||!l)return;p=!0;let e=window.google?.ima;if(!e)return;u.initialize();let t=new e.AdsRequest;t.adTagUrl=l,d.requestAds(t)}function E(e){l=e,T()}a().then(()=>{if(v)return;let n=window.google?.ima;n&&(u=new n.AdDisplayContainer(c,i),d=new n.AdsLoader(u),m=!0,d.addEventListener(n.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,a=>{if(v)return;let o=new n.AdsRenderingSettings;o.restoreCustomPlaybackStateOnAdBreakComplete=!0,f=a.getAdsManager(i,o),i.addEventListener(`ended`,C),x=i.currentSrc,f.addEventListener(n.AdEvent.Type.CONTENT_PAUSE_REQUESTED,()=>{i.removeEventListener(`ended`,C),i.ended&&r()&&(b=!0),i.pause(),w(!0),s.onAdStart();let e=f?.getVolume()??1;e>0&&(y=e),s.onAdMuteChange(e===0)}),f.addEventListener(n.AdEvent.Type.CONTENT_RESUME_REQUESTED,()=>{if(i.addEventListener(`ended`,C),w(!1),s.onAdEnd(),b){b=!1,x&&i.currentSrc!==x&&(i.src=x);let e=i.duration;e&&isFinite(e)&&(i.currentTime=e-.5);return}i.ended||i.play()}),f.addEventListener(n.AdEvent.Type.PAUSED,()=>{_=!0,e.classList.add(t),s.onAdPauseChange(!0)}),f.addEventListener(n.AdEvent.Type.RESUMED,()=>{_=!1,e.classList.remove(t),s.onAdPauseChange(!1)}),f.addEventListener(n.AdEvent.Type.AD_PROGRESS,()=>{s.onAdProgress(f?.getRemainingTime()??0)}),f.addEventListener(n.AdErrorEvent.Type.AD_ERROR,e=>{w(!1),s.onError(e.getError().getMessage()),i.play()});try{f.init(i.clientWidth,i.clientHeight,n.ViewMode.NORMAL),f.start()}catch(e){s.onError(e instanceof Error?e.message:`Ad playback failed to start.`)}}),d.addEventListener(n.AdErrorEvent.Type.AD_ERROR,e=>{s.onError(e.getError().getMessage())}),T())}).catch(e=>s.onError(e.message));function D(){h=!0,T()}function O(){if(!f)return;let e=f.getVolume();e>0?(y=e,f.setVolume(0)):f.setVolume(y||1),s.onAdMuteChange(f.getVolume()===0)}return{isAdPlaying:()=>g,isAdPaused:()=>_,requestAdsOnFirstPlay:D,setAdTagUrl:E,pauseAd:()=>f?.pause(),resumeAd:()=>f?.resume(),toggleAdMute:O,dispose:()=>{v=!0,b=!1,x=``,S.disconnect(),i.removeEventListener(`ended`,C),f?.destroy(),d?.destroy(),c.remove(),e.classList.remove(n,t)}}}export{o as attachAds};
1
+ import{c as e,d as t,f as n}from"./constants-BUQXC_ZT.mjs";import{n as r}from"./platform-Dg9JBh8M.mjs";import{t as i}from"./loadScript-Du6JsTc2.mjs";function a(){return window.google?.ima?Promise.resolve():i(e,`ima`)}function o(e,i,o,s){let c=document.createElement(`div`);c.className=`ima-ad-container`,e.appendChild(c);let l=o,u=null,d=null,f=null,p=!1,m=!1,h=!1,g=!1,_=!1,v=!1,y=1,b=!1,x=``,S=new ResizeObserver(([e])=>{let t=window.google?.ima;if(!f||!t)return;let{width:n,height:r}=e.contentRect;f.resize(n,r,t.ViewMode.NORMAL)});S.observe(i);function C(){d?.contentComplete()}function w(r){g=r,e.classList.toggle(n,r),r||(_=!1,e.classList.remove(t))}function T(){if(p||!m||!h||!u||!d||!l)return;p=!0;let e=window.google?.ima;if(!e)return;u.initialize();let t=new e.AdsRequest;t.adTagUrl=l,d.requestAds(t)}function E(e){l=e,T()}a().then(()=>{if(v)return;let n=window.google?.ima;n&&(u=new n.AdDisplayContainer(c,i),d=new n.AdsLoader(u),m=!0,d.addEventListener(n.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,a=>{if(v)return;let o=new n.AdsRenderingSettings;o.restoreCustomPlaybackStateOnAdBreakComplete=!0,f=a.getAdsManager(i,o),i.addEventListener(`ended`,C),x=i.currentSrc,f.addEventListener(n.AdEvent.Type.CONTENT_PAUSE_REQUESTED,()=>{i.removeEventListener(`ended`,C),i.ended&&r()&&(b=!0),i.pause(),w(!0),s.onAdStart();let e=f?.getVolume()??1;e>0&&(y=e),s.onAdMuteChange(e===0)}),f.addEventListener(n.AdEvent.Type.CONTENT_RESUME_REQUESTED,()=>{if(i.addEventListener(`ended`,C),w(!1),s.onAdEnd(),b){b=!1,x&&i.currentSrc!==x&&(i.src=x);let e=i.duration;e&&isFinite(e)&&(i.currentTime=e-.5);return}i.ended||i.play()}),f.addEventListener(n.AdEvent.Type.PAUSED,()=>{_=!0,e.classList.add(t),s.onAdPauseChange(!0)}),f.addEventListener(n.AdEvent.Type.RESUMED,()=>{_=!1,e.classList.remove(t),s.onAdPauseChange(!1)}),f.addEventListener(n.AdEvent.Type.AD_PROGRESS,()=>{s.onAdProgress(f?.getRemainingTime()??0)}),f.addEventListener(n.AdErrorEvent.Type.AD_ERROR,e=>{w(!1),s.onError(e.getError().getMessage()),i.play()});try{f.init(i.clientWidth,i.clientHeight,n.ViewMode.NORMAL),f.start()}catch(e){s.onError(e instanceof Error?e.message:`Ad playback failed to start.`)}}),d.addEventListener(n.AdErrorEvent.Type.AD_ERROR,e=>{s.onError(e.getError().getMessage())}),T())}).catch(e=>s.onError(e.message));function D(){h=!0,T()}function O(){if(!f)return;let e=f.getVolume();e>0?(y=e,f.setVolume(0)):f.setVolume(y||1),s.onAdMuteChange(f.getVolume()===0)}return{isAdPlaying:()=>g,isAdPaused:()=>_,requestAdsOnFirstPlay:D,setAdTagUrl:E,pauseAd:()=>f?.pause(),resumeAd:()=>f?.resume(),toggleAdMute:O,dispose:()=>{v=!0,b=!1,x=``,S.disconnect(),i.removeEventListener(`ended`,C),f?.destroy(),d?.destroy(),c.remove(),e.classList.remove(n,t)}}}export{o as attachAds};
@@ -1 +1 @@
1
- import{n as e,t}from"./constants-DRD0PsRw.mjs";import{n,t as r}from"./sourceHelpers-DlkCZiTJ.mjs";function i(e){let t;try{t=new URL(e)}catch{return null}if(t.hostname!==`players.brightcove.net`)return null;let[,n,r]=t.pathname.split(`/`),i=t.searchParams.get(`videoId`),a=r?.indexOf(`_`)??-1;return!n||a===-1||!i?null:{accountId:n,playerId:r.slice(0,a),embed:r.slice(a+1),videoId:i}}function a(e){for(let t of e?.plugins??[]){let e=t.options?.serverUrl??t.options?.imaOptions?.serverUrl;if(e)return e}return null}const o=r(async(t,n,r,i)=>{let o=await fetch(`${e}/${t}/${n}_${r}/config.json`);if(!o.ok)throw Error(`Brightcove: could not load player config (${o.status})`);let s=await o.json(),c=i??s?.video_cloud?.policy_key;if(!c)throw Error(`Brightcove: policy_key not found in player config`);return{policyKey:c,adTagUrl:a(s)}},(e,t,n)=>`${e}/${t}_${n}`);async function s(e,r,i){let a=await fetch(`${t}/${e}/videos/${r}`,{headers:{Accept:`application/json;pk=${i}`}});if(!a.ok)throw Error(`Brightcove Playback API error: ${a.status}`);let o=await a.json(),s=n(o.sources||[]);if(!s.length)throw Error(`Brightcove: no playable sources found`);return{sources:s.map(e=>({src:e.src,type:e.type})),poster:o.poster??o.thumbnail??null}}async function c(e,t){let n=i(e);if(!n)throw Error(`Brightcove: invalid src — expected a Brightcove embed URL, e.g. "https://players.brightcove.net/{accountId}/{playerId}_{embed}/index.html?videoId={videoId}"`);let{accountId:r,playerId:a,embed:c,videoId:l}=n,{policyKey:u,adTagUrl:d}=await o(r,a,c,t),{sources:f,poster:p}=await s(r,l,u);return{...f[0],poster:p,adTagUrl:d}}export{c as resolveSource};
1
+ import{n as e,t}from"./constants-BUQXC_ZT.mjs";import{n,t as r}from"./sourceHelpers-CAGxjbbu.mjs";function i(e){let t;try{t=new URL(e)}catch{return null}if(t.hostname!==`players.brightcove.net`)return null;let[,n,r]=t.pathname.split(`/`),i=t.searchParams.get(`videoId`),a=r?.indexOf(`_`)??-1;return!n||a===-1||!i?null:{accountId:n,playerId:r.slice(0,a),embed:r.slice(a+1),videoId:i}}function a(e){for(let t of e?.plugins??[]){let e=t.options?.serverUrl??t.options?.imaOptions?.serverUrl;if(e)return e}return null}const o=r(async(t,n,r,i)=>{let o=await fetch(`${e}/${t}/${n}_${r}/config.json`);if(!o.ok)throw Error(`Brightcove: could not load player config (${o.status})`);let s=await o.json(),c=i??s?.video_cloud?.policy_key;if(!c)throw Error(`Brightcove: policy_key not found in player config`);return{policyKey:c,adTagUrl:a(s)}},(e,t,n)=>`${e}/${t}_${n}`);async function s(e,r,i){let a=await fetch(`${t}/${e}/videos/${r}`,{headers:{Accept:`application/json;pk=${i}`}});if(!a.ok)throw Error(`Brightcove Playback API error: ${a.status}`);let o=await a.json(),s=n(o.sources||[]);if(!s.length)throw Error(`Brightcove: no playable sources found`);return{sources:s.map(e=>({src:e.src,type:e.type})),poster:o.poster??o.thumbnail??null}}async function c(e,t){let n=i(e);if(!n)throw Error(`Brightcove: invalid src — expected a Brightcove embed URL, e.g. "https://players.brightcove.net/{accountId}/{playerId}_{embed}/index.html?videoId={videoId}"`);let{accountId:r,playerId:a,embed:c,videoId:l}=n,{policyKey:u,adTagUrl:d}=await o(r,a,c,t),{sources:f,poster:p}=await s(r,l,u);return{...f[0],poster:p,adTagUrl:d}}export{c as resolveSource};
@@ -1 +1 @@
1
- const e=`video-select`,t=`video-toggle`,n=`video-state`,r=`fullscreen-pending`,i=`fullscreen-pending-done`,a=`player:positions`,o=`player:autoAdvance`,s=`player:audio`,c={muted:!1,volume:1},l=`mvp-tech`,u=`mvp-youtube`,d=`mvp-vimeo`,f=`mvp-dailymotion`,p=`mvp-ad-playing`,m=`mvp-ad-paused`,h=`16:9`,g=`application/x-mpegURL`,_=`application/dash+xml`,v=`video/mp4`,y=[g,v],b=[.5,.75,1,1.25,1.5,2],x=3500,S=.1,C=3e3,w=[[.25,`firstQuartile`],[.5,`midpoint`],[.75,`thirdQuartile`]],T=`https://imasdk.googleapis.com/js/sdkloader/ima3.js`,E=`https://player.vimeo.com/api/player.js`,D=`https://cdn.jwplayer.com/v2/media`,O=`https://edge.api.brightcove.com/playback/v1/accounts`,k=`https://players.brightcove.net`;export{t as A,y as C,E as D,a as E,e as O,C as S,o as T,d as _,c as a,b,T as c,m as d,p as f,l as g,i as h,h as i,n as k,D as l,r as m,k as n,g as o,f as p,_ as r,x as s,O as t,v as u,u as v,s as w,w as x,S as y};
1
+ const e=`video-select`,t=`video-toggle`,n=`video-state`,r=`fullscreen-pending`,i=`fullscreen-pending-done`,a=`player:positions`,o=`player:autoAdvance`,s=`player:audio`,c={muted:!1,volume:1},l=`mlv-tech`,u=`mlv-youtube`,d=`mlv-vimeo`,f=`mlv-dailymotion`,p=`mlv-ad-playing`,m=`mlv-ad-paused`,h=`16:9`,g=`application/x-mpegURL`,_=`application/dash+xml`,v=`video/mp4`,y=[g,v],b=[.5,.75,1,1.25,1.5,2],x=3500,S=.1,C=3e3,w=[[.25,`firstQuartile`],[.5,`midpoint`],[.75,`thirdQuartile`]],T=`https://imasdk.googleapis.com/js/sdkloader/ima3.js`,E=`https://player.vimeo.com/api/player.js`,D=`https://cdn.jwplayer.com/v2/media`,O=`https://edge.api.brightcove.com/playback/v1/accounts`,k=`https://players.brightcove.net`;export{t as A,y as C,E as D,a as E,e as O,C as S,o as T,d as _,c as a,b,T as c,m as d,p as f,l as g,i as h,h as i,n as k,D as l,r as m,k as n,g as o,f as p,_ as r,x as s,O as t,v as u,u as v,s as w,w as x,S as y};
@@ -1 +1 @@
1
- import{p as e}from"./constants-DRD0PsRw.mjs";import{r as t}from"./embedShared-Cq4Qj9Kt.mjs";import{t as n}from"./loadScript-Du6JsTc2.mjs";function r(e){let t=e.match(/[?&]video=([a-zA-Z0-9]+)/);return t?t[1]:e.match(/(?:dailymotion\.com\/(?:embed\/)?video\/|dai\.ly\/)([a-zA-Z0-9]+)/)?.[1]??null}function i(i,a){let o=null;return t(i,a,{cssClass:e,connect:async({techId:e,emitter:t,state:i,isDisposed:s,consumeQueuedPlay:c})=>{let l=r(a.src);if(!l){i.errorState={code:4,message:`Could not parse video ID from source URL`},t.trigger(`error`);return}let u=!1;try{let r=typeof a.customVars?.playerId==`string`?a.customVars.playerId:void 0,d=await n(r?`https://geo.dailymotion.com/libs/player/${r}.js`:`https://geo.dailymotion.com/libs/player.js`,r||`dailymotion-sdk`).then(()=>window.dailymotion);if(!d||s())return;let f=await d.createPlayer(e,{...r&&{player:r},video:l,params:{autoplay:!!a.autoplay,mute:!!a.muted}});o=f,a.volume!==void 0&&f.setVolume(a.volume);let p=d.events;c(()=>o?.play()),f.on(p.PLAYER_CRITICALPATHREADY,e=>{let n=e.videoThumbnails;if(!n)return;let r=Object.keys(n).map(Number).sort((e,t)=>t-e)[0],i=r===void 0?void 0:n[r];i&&t.trigger(`posterchange`,i)}),f.on(p.VIDEO_PLAY,()=>{i.paused=!1,t.trigger(`play`),t.trigger(`playing`),!a.autoplay&&!u&&(u=!0,f.pause())}),f.on(p.VIDEO_PLAYING,()=>{i.paused=!1,t.trigger(`play`),t.trigger(`playing`)}),f.on(p.VIDEO_PAUSE,()=>{i.paused=!0,t.trigger(`pause`)}),p.VIDEO_BUFFERING&&f.on(p.VIDEO_BUFFERING,()=>t.trigger(`waiting`)),f.on(p.VIDEO_END,()=>{i.paused=!0,t.trigger(`ended`)}),f.on(p.VIDEO_TIMECHANGE,e=>{i.currentTime=e.videoTime??i.currentTime,i.duration=e.videoDuration??i.duration,t.trigger(`timeupdate`)}),f.on(p.VIDEO_DURATIONCHANGE,e=>{i.duration=e.videoDuration??i.duration,t.trigger(`durationchange`)}),f.on(p.VIDEO_SEEKSTART,()=>t.trigger(`seeking`)),f.on(p.VIDEO_SEEKEND,e=>{i.currentTime=e.videoTime??i.currentTime,t.trigger(`seeked`)}),f.on(p.PLAYER_VOLUMECHANGE,e=>{i.volume=e.playerVolume??i.volume,i.muted=e.playerIsMuted??i.muted,t.trigger(`volumechange`)}),f.on(p.PLAYER_ERROR,()=>t.trigger(`error`)),p.AD_START&&f.on(p.AD_START,()=>{i.paused=!1,t.trigger(`play`),t.trigger(`adstart`)}),p.AD_END&&f.on(p.AD_END,()=>t.trigger(`adend`))}catch(e){i.errorState={code:4,message:e instanceof Error?e.message:`This video could not be played.`},t.trigger(`error`)}},hasPlayer:()=>!!o,play:()=>o?.play(),pause:()=>o?.pause(),seekToSdk:e=>o?.seek(e),volumeToSdk:e=>o?.setVolume(e),muteToSdk:(e,t)=>o?.setMute(t),sdkFullscreenEnter:()=>o?.setFullscreen(!0),sdkFullscreenExit:()=>o?.setFullscreen(!1),destroyPlayer:()=>{let e=o;o=null,e?.destroy?.()}})}export{i as createDailymotionAdapter};
1
+ import{p as e}from"./constants-BUQXC_ZT.mjs";import{r as t}from"./embedShared-DgFZ58OV.mjs";import{t as n}from"./loadScript-Du6JsTc2.mjs";function r(e){let t=e.match(/[?&]video=([a-zA-Z0-9]+)/);return t?t[1]:e.match(/(?:dailymotion\.com\/(?:embed\/)?video\/|dai\.ly\/)([a-zA-Z0-9]+)/)?.[1]??null}function i(i,a){let o=null;return t(i,a,{cssClass:e,connect:async({techId:e,emitter:t,state:i,isDisposed:s,consumeQueuedPlay:c})=>{let l=r(a.src);if(!l){i.errorState={code:4,message:`Could not parse video ID from source URL`},t.trigger(`error`);return}let u=!1;try{let r=typeof a.customVars?.playerId==`string`?a.customVars.playerId:void 0,d=await n(r?`https://geo.dailymotion.com/libs/player/${r}.js`:`https://geo.dailymotion.com/libs/player.js`,r||`dailymotion-sdk`).then(()=>window.dailymotion);if(!d||s())return;let f=await d.createPlayer(e,{...r&&{player:r},video:l,params:{autoplay:!!a.autoplay,mute:!!a.muted}});o=f,a.volume!==void 0&&f.setVolume(a.volume);let p=d.events;c(()=>o?.play()),f.on(p.PLAYER_CRITICALPATHREADY,e=>{let n=e.videoThumbnails;if(!n)return;let r=Object.keys(n).map(Number).sort((e,t)=>t-e)[0],i=r===void 0?void 0:n[r];i&&t.trigger(`posterchange`,i)}),f.on(p.VIDEO_PLAY,()=>{i.paused=!1,t.trigger(`play`),t.trigger(`playing`),!a.autoplay&&!u&&(u=!0,f.pause())}),f.on(p.VIDEO_PLAYING,()=>{i.paused=!1,t.trigger(`play`),t.trigger(`playing`)}),f.on(p.VIDEO_PAUSE,()=>{i.paused=!0,t.trigger(`pause`)}),p.VIDEO_BUFFERING&&f.on(p.VIDEO_BUFFERING,()=>t.trigger(`waiting`)),f.on(p.VIDEO_END,()=>{i.paused=!0,t.trigger(`ended`)}),f.on(p.VIDEO_TIMECHANGE,e=>{i.currentTime=e.videoTime??i.currentTime,i.duration=e.videoDuration??i.duration,t.trigger(`timeupdate`)}),f.on(p.VIDEO_DURATIONCHANGE,e=>{i.duration=e.videoDuration??i.duration,t.trigger(`durationchange`)}),f.on(p.VIDEO_SEEKSTART,()=>t.trigger(`seeking`)),f.on(p.VIDEO_SEEKEND,e=>{i.currentTime=e.videoTime??i.currentTime,t.trigger(`seeked`)}),f.on(p.PLAYER_VOLUMECHANGE,e=>{i.volume=e.playerVolume??i.volume,i.muted=e.playerIsMuted??i.muted,t.trigger(`volumechange`)}),f.on(p.PLAYER_ERROR,()=>t.trigger(`error`)),p.AD_START&&f.on(p.AD_START,()=>{i.paused=!1,t.trigger(`play`),t.trigger(`adstart`)}),p.AD_END&&f.on(p.AD_END,()=>t.trigger(`adend`))}catch(e){i.errorState={code:4,message:e instanceof Error?e.message:`This video could not be played.`},t.trigger(`error`)}},hasPlayer:()=>!!o,play:()=>o?.play(),pause:()=>o?.pause(),seekToSdk:e=>o?.seek(e),volumeToSdk:e=>o?.setVolume(e),muteToSdk:(e,t)=>o?.setMute(t),sdkFullscreenEnter:()=>o?.setFullscreen(!0),sdkFullscreenExit:()=>o?.setFullscreen(!1),destroyPlayer:()=>{let e=o;o=null,e?.destroy?.()}})}export{i as createDailymotionAdapter};
@@ -1 +1 @@
1
- import{g as e,h as t,m as n}from"./constants-DRD0PsRw.mjs";import{n as r,r as i,t as a}from"./platform-Dg9JBh8M.mjs";function o(){let e=new Map;function t(t,n){for(let r of Array.isArray(t)?t:[t])e.has(r)||e.set(r,new Set),e.get(r)?.add(n)}function n(t,n){e.get(t)?.delete(n)}function r(t,...n){e.get(t)?.forEach(e=>e(...n))}function i(){e.clear()}return{on:t,off:n,trigger:r,dispose:i}}const s={supportsCaptions:()=>!1,getCaptionTracks:()=>[],setCaptionTrack:()=>{},getActiveCaptionTrack:()=>null,supportsQuality:()=>!1,getQualityLevels:()=>[],getCurrentQuality:()=>null,isAutoQuality:()=>!0,setQuality:()=>{},supportsPip:()=>!1,isPipActive:()=>!1,togglePip:()=>{}};let c=0;function l(t,n){t.parentElement?.classList.add(n);let r=`${n}-${++c}`,i=document.createElement(`div`);i.id=r,i.className=e,i.style.cssText=`width:100%;height:100%;top:0;left:0;position:absolute`;let a=document.createElement(`div`);return a.style.cssText=`width:100%;height:100%;position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity 0.2s`,a.appendChild(i),t.parentElement?.insertBefore(a,t),{techId:r,wrapper:a,innerDiv:i}}function u(e,t){e.style.display=`none`,t.style.opacity=`1`,t.style.pointerEvents=``}function d(e,t,n){t.remove(),e.parentElement?.classList.remove(n),e.style.display=``}function f(e){return e.closest(`.player__shell`)}function p(e,t){if(r()&&t()!==!1)return;let n=f(e);n&&i(n)}function m(){a()}function h(){let e=new Set;return{schedule(t,n=0){let r=setTimeout(()=>{e.delete(r),t()},n);e.add(r)},clearAll(){e.forEach(clearTimeout),e.clear()}}}function g(e){e.trigger(n);let r=document.createElement(`div`);r.style.cssText=`position:fixed;inset:0;z-index:99999;opacity:0;pointer-events:none`,document.body.appendChild(r);let i=!1;function a(){i||e.trigger(t)}function o(n){i||(i=!0,e.trigger(t),r.remove(),n?.())}return{overlay:r,reveal:a,finish:o}}function _(e,t,n){let i=o(),{techId:c,wrapper:u}=l(e,n.cssClass),{schedule:f,clearAll:m}=h(),g={currentTime:0,duration:0,volume:t.volume??1,muted:!1,paused:!0,playQueued:!1,errorState:null},_=!1,v={techId:c,wrapper:u,emitter:i,state:g,schedule:f,isDisposed:()=>_,consumeQueuedPlay(e){g.playQueued&&(g.playQueued=!1,e())}};n.connect(v);function y(){p(e,()=>{if(!n.sdkFullscreenEnter)return!1;n.sdkFullscreenEnter()})}function b(){if(r()&&n.sdkFullscreenExit){n.sdkFullscreenExit();return}a()}return{el:u,play:()=>{n.hasPlayer()?n.play():g.playQueued=!0},pause:()=>n.pause(),paused:()=>g.paused,currentTime:()=>g.currentTime,setCurrentTime:e=>{if(n.setCurrentTime){n.setCurrentTime(v,e);return}g.currentTime=e,n.seekToSdk?.(e),i.trigger(`seeking`)},duration:()=>g.duration,volume:()=>g.volume,setVolume:e=>{g.volume=e,n.volumeToSdk(e)},muted:()=>g.muted,setMuted:e=>{g.muted=e,n.muteToSdk(v,e)},...n.rate?n.rate(v):{playbackRate:()=>1,setPlaybackRate:()=>{}},bufferedEnd:()=>g.currentTime,error:()=>g.errorState,setSrc:()=>{},supportsPlaybackRate:()=>!1,...s,enterFullscreen:y,exitFullscreen:b,on:i.on,off:i.off,dispose:()=>{_=!0,m(),n.destroyPlayer(),d(e,u,n.cssClass),i.dispose()}}}export{p as a,u as c,o as d,h as i,g as l,l as n,m as o,_ as r,f as s,s as t,d as u};
1
+ import{g as e,h as t,m as n}from"./constants-BUQXC_ZT.mjs";import{n as r,r as i,t as a}from"./platform-Dg9JBh8M.mjs";function o(){let e=new Map;function t(t,n){for(let r of Array.isArray(t)?t:[t])e.has(r)||e.set(r,new Set),e.get(r)?.add(n)}function n(t,n){e.get(t)?.delete(n)}function r(t,...n){e.get(t)?.forEach(e=>e(...n))}function i(){e.clear()}return{on:t,off:n,trigger:r,dispose:i}}const s={supportsCaptions:()=>!1,getCaptionTracks:()=>[],setCaptionTrack:()=>{},getActiveCaptionTrack:()=>null,supportsQuality:()=>!1,getQualityLevels:()=>[],getCurrentQuality:()=>null,isAutoQuality:()=>!0,setQuality:()=>{},supportsPip:()=>!1,isPipActive:()=>!1,togglePip:()=>{}};let c=0;function l(t,n){t.parentElement?.classList.add(n);let r=`${n}-${++c}`,i=document.createElement(`div`);i.id=r,i.className=e,i.style.cssText=`width:100%;height:100%;top:0;left:0;position:absolute`;let a=document.createElement(`div`);return a.style.cssText=`width:100%;height:100%;position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity 0.2s`,a.appendChild(i),t.parentElement?.insertBefore(a,t),{techId:r,wrapper:a,innerDiv:i}}function u(e,t){e.style.display=`none`,t.style.opacity=`1`,t.style.pointerEvents=``}function d(e,t,n){t.remove(),e.parentElement?.classList.remove(n),e.style.display=``}function f(e){return e.closest(`.player__shell`)}function p(e,t){if(r()&&t()!==!1)return;let n=f(e);n&&i(n)}function m(){a()}function h(){let e=new Set;return{schedule(t,n=0){let r=setTimeout(()=>{e.delete(r),t()},n);e.add(r)},clearAll(){e.forEach(clearTimeout),e.clear()}}}function g(e){e.trigger(n);let r=document.createElement(`div`);r.style.cssText=`position:fixed;inset:0;z-index:99999;opacity:0;pointer-events:none`,document.body.appendChild(r);let i=!1;function a(){i||e.trigger(t)}function o(n){i||(i=!0,e.trigger(t),r.remove(),n?.())}return{overlay:r,reveal:a,finish:o}}function _(e,t,n){let i=o(),{techId:c,wrapper:u}=l(e,n.cssClass),{schedule:f,clearAll:m}=h(),g={currentTime:0,duration:0,volume:t.volume??1,muted:!1,paused:!0,playQueued:!1,errorState:null},_=!1,v={techId:c,wrapper:u,emitter:i,state:g,schedule:f,isDisposed:()=>_,consumeQueuedPlay(e){g.playQueued&&(g.playQueued=!1,e())}};n.connect(v);function y(){p(e,()=>{if(!n.sdkFullscreenEnter)return!1;n.sdkFullscreenEnter()})}function b(){if(r()&&n.sdkFullscreenExit){n.sdkFullscreenExit();return}a()}return{el:u,play:()=>{n.hasPlayer()?n.play():g.playQueued=!0},pause:()=>n.pause(),paused:()=>g.paused,currentTime:()=>g.currentTime,setCurrentTime:e=>{if(n.setCurrentTime){n.setCurrentTime(v,e);return}g.currentTime=e,n.seekToSdk?.(e),i.trigger(`seeking`)},duration:()=>g.duration,volume:()=>g.volume,setVolume:e=>{g.volume=e,n.volumeToSdk(e)},muted:()=>g.muted,setMuted:e=>{g.muted=e,n.muteToSdk(v,e)},...n.rate?n.rate(v):{playbackRate:()=>1,setPlaybackRate:()=>{}},bufferedEnd:()=>g.currentTime,error:()=>g.errorState,setSrc:()=>{},supportsPlaybackRate:()=>!1,...s,enterFullscreen:y,exitFullscreen:b,on:i.on,off:i.off,dispose:()=>{_=!0,m(),n.destroyPlayer(),d(e,u,n.cssClass),i.dispose()}}}export{p as a,u as c,o as d,h as i,g as l,l as n,m as o,_ as r,f as s,s as t,d as u};
@@ -1 +1 @@
1
- import{l as e,o as t,u as n}from"./constants-DRD0PsRw.mjs";import{n as r,t as i}from"./sourceHelpers-DlkCZiTJ.mjs";function a(e){return e.match(/cdn\.jwplayer\.com\/videos\/([^-]+)/)?.[1]??e.match(/cdn\.jwplayer\.com\/manifests\/([^.]+)/)?.[1]??e.match(/^jwplayer:\/\/([^/]+)$/)?.[1]??null}function o(e){let t=e?.advertising?.schedule;return Array.isArray(t)&&t.length?t[0].tag??null:e?.advertising?.tag??null}const s=i(async t=>{let n=await fetch(`${e}/${t}`);if(!n.ok)throw Error(`JW Platform API error: ${n.status}`);let i=(await n.json()).playlist?.[0];if(!i)throw Error(`JW Platform: empty playlist`);let a=r((i.sources??[]).map(e=>({src:e.file,type:e.type})));if(!a.length)throw Error(`JW Platform: no playable sources found`);return{src:a[0].src,type:a[0].type,poster:i.image??null,adTagUrl:o(i)}});async function c(e){let r=a(e);if(!r)throw Error(`JW Platform: unrecognised source URL: ${e}`);let i=await s(r);if(e.startsWith(`jwplayer://`))return i;let o=/\.mp4(\?|#|$)/.test(e)?n:t;return{...i,src:e,type:o}}export{c as resolveSource};
1
+ import{l as e,o as t,u as n}from"./constants-BUQXC_ZT.mjs";import{n as r,t as i}from"./sourceHelpers-CAGxjbbu.mjs";function a(e){return e.match(/cdn\.jwplayer\.com\/videos\/([^-]+)/)?.[1]??e.match(/cdn\.jwplayer\.com\/manifests\/([^.]+)/)?.[1]??e.match(/^jwplayer:\/\/([^/]+)$/)?.[1]??null}function o(e){let t=e?.advertising?.schedule;return Array.isArray(t)&&t.length?t[0].tag??null:e?.advertising?.tag??null}const s=i(async t=>{let n=await fetch(`${e}/${t}`);if(!n.ok)throw Error(`JW Platform API error: ${n.status}`);let i=(await n.json()).playlist?.[0];if(!i)throw Error(`JW Platform: empty playlist`);let a=r((i.sources??[]).map(e=>({src:e.file,type:e.type})));if(!a.length)throw Error(`JW Platform: no playable sources found`);return{src:a[0].src,type:a[0].type,poster:i.image??null,adTagUrl:o(i)}});async function c(e){let r=a(e);if(!r)throw Error(`JW Platform: unrecognised source URL: ${e}`);let i=await s(r);if(e.startsWith(`jwplayer://`))return i;let o=/\.mp4(\?|#|$)/.test(e)?n:t;return{...i,src:e,type:o}}export{c as resolveSource};
@@ -1 +1 @@
1
- import{C as e}from"./constants-DRD0PsRw.mjs";function t(e,t=(...e)=>String(e[0])){let n={};return async(...r)=>{let i=t(...r);if(n[i])return n[i];let a=await e(...r);return n[i]=a,a}}function n(t){return t.filter(t=>t.src&&e.includes(t.type)).sort((t,n)=>e.indexOf(t.type)-e.indexOf(n.type))}export{n,t};
1
+ import{C as e}from"./constants-BUQXC_ZT.mjs";function t(e,t=(...e)=>String(e[0])){let n={};return async(...r)=>{let i=t(...r);if(n[i])return n[i];let a=await e(...r);return n[i]=a,a}}function n(t){return t.filter(t=>t.src&&e.includes(t.type)).sort((t,n)=>e.indexOf(t.type)-e.indexOf(n.type))}export{n,t};
@@ -1 +1 @@
1
- import{D as e,_ as t}from"./constants-DRD0PsRw.mjs";import{r as n}from"./embedShared-Cq4Qj9Kt.mjs";import{t as r}from"./loadScript-Du6JsTc2.mjs";function i(e){return e.match(/(?:vimeo\.com\/(?:video\/|channels\/[^/]+\/|groups\/[^/]+\/videos\/)?|player\.vimeo\.com\/video\/)(\d+)/)?.[1]??null}function a(a,o){let s=null,c=1;return n(a,o,{cssClass:t,connect:async({techId:t,emitter:n,state:a,isDisposed:c,consumeQueuedPlay:l})=>{let u=i(o.src);if(!u||(await r(e,`vimeo`),c()||!window.Vimeo))return;let d={id:Number(u),byline:!1,portrait:!1,title:!1,transparent:!0,controls:!!o.nativeUi,autopause:!1,...o.autoplay!==void 0&&{autoplay:o.autoplay},...o.muted!==void 0&&{muted:o.muted}};s=new window.Vimeo.Player(t,d),o.autoplay&&(a.playQueued=!0),s.ready().then(()=>{o.muted&&s?.setMuted(!0).catch(()=>{}),o.volume!==void 0&&s?.setVolume(o.volume).catch(()=>{}),l(()=>void s?.play().catch(()=>{}))}).catch(e=>{a.errorState={code:4,message:e?.message||`This video is unavailable or cannot be embedded here.`},n.trigger(`error`)}),s.on(`play`,()=>{a.paused=!1,n.trigger(`play`),n.trigger(`playing`)}),s.on(`pause`,()=>{a.paused=!0,n.trigger(`pause`)}),s.on(`ended`,()=>{a.paused=!0,n.trigger(`ended`)});let f=!1;s.on(`timeupdate`,e=>{let{seconds:t,duration:r}=e;a.currentTime=t,a.duration=r,n.trigger(`timeupdate`),r&&!f&&(f=!0,n.trigger(`durationchange`))}),s.on(`loaded`,()=>{f=!1,n.trigger(`loadedmetadata`),n.trigger(`durationchange`)}),s.on(`seeking`,e=>{a.currentTime=e.seconds,n.trigger(`seeking`)}),s.on(`seeked`,e=>{a.currentTime=e.seconds,n.trigger(`seeked`),n.trigger(`timeupdate`)}),s.on(`bufferstart`,()=>n.trigger(`waiting`)),s.on(`bufferend`,()=>n.trigger(`canplay`)),s.on(`volumechange`,e=>{a.volume=e.volume,n.trigger(`volumechange`)}),s.on(`error`,()=>n.trigger(`error`))},hasPlayer:()=>!!s,play:()=>void s?.play().catch(()=>{}),pause:()=>void s?.pause().catch(()=>{}),rate:({emitter:e})=>({playbackRate:()=>c,setPlaybackRate:t=>{c=t,s?.setPlaybackRate(t).catch(()=>{}),e.trigger(`ratechange`)}}),setCurrentTime:({emitter:e},t)=>{s?.setCurrentTime(t).catch(()=>{}),e.trigger(`timeupdate`),e.trigger(`seeking`)},volumeToSdk:e=>void s?.setVolume(e).catch(()=>{}),muteToSdk:({emitter:e,schedule:t},n)=>{s?.setMuted(n).then(()=>t(()=>e.trigger(`volumechange`),50)).catch(()=>{})},sdkFullscreenEnter:()=>void s?.requestFullscreen().catch(()=>{}),destroyPlayer:()=>{let e=s;s=null,e?.destroy().catch(()=>{})}})}export{a as createVimeoAdapter};
1
+ import{D as e,_ as t}from"./constants-BUQXC_ZT.mjs";import{r as n}from"./embedShared-DgFZ58OV.mjs";import{t as r}from"./loadScript-Du6JsTc2.mjs";function i(e){return e.match(/(?:vimeo\.com\/(?:video\/|channels\/[^/]+\/|groups\/[^/]+\/videos\/)?|player\.vimeo\.com\/video\/)(\d+)/)?.[1]??null}function a(a,o){let s=null,c=1;return n(a,o,{cssClass:t,connect:async({techId:t,emitter:n,state:a,isDisposed:c,consumeQueuedPlay:l})=>{let u=i(o.src);if(!u||(await r(e,`vimeo`),c()||!window.Vimeo))return;let d={id:Number(u),byline:!1,portrait:!1,title:!1,transparent:!0,controls:!!o.nativeUi,autopause:!1,...o.autoplay!==void 0&&{autoplay:o.autoplay},...o.muted!==void 0&&{muted:o.muted}};s=new window.Vimeo.Player(t,d),o.autoplay&&(a.playQueued=!0),s.ready().then(()=>{o.muted&&s?.setMuted(!0).catch(()=>{}),o.volume!==void 0&&s?.setVolume(o.volume).catch(()=>{}),l(()=>void s?.play().catch(()=>{}))}).catch(e=>{a.errorState={code:4,message:e?.message||`This video is unavailable or cannot be embedded here.`},n.trigger(`error`)}),s.on(`play`,()=>{a.paused=!1,n.trigger(`play`),n.trigger(`playing`)}),s.on(`pause`,()=>{a.paused=!0,n.trigger(`pause`)}),s.on(`ended`,()=>{a.paused=!0,n.trigger(`ended`)});let f=!1;s.on(`timeupdate`,e=>{let{seconds:t,duration:r}=e;a.currentTime=t,a.duration=r,n.trigger(`timeupdate`),r&&!f&&(f=!0,n.trigger(`durationchange`))}),s.on(`loaded`,()=>{f=!1,n.trigger(`loadedmetadata`),n.trigger(`durationchange`)}),s.on(`seeking`,e=>{a.currentTime=e.seconds,n.trigger(`seeking`)}),s.on(`seeked`,e=>{a.currentTime=e.seconds,n.trigger(`seeked`),n.trigger(`timeupdate`)}),s.on(`bufferstart`,()=>n.trigger(`waiting`)),s.on(`bufferend`,()=>n.trigger(`canplay`)),s.on(`volumechange`,e=>{a.volume=e.volume,n.trigger(`volumechange`)}),s.on(`error`,()=>n.trigger(`error`))},hasPlayer:()=>!!s,play:()=>void s?.play().catch(()=>{}),pause:()=>void s?.pause().catch(()=>{}),rate:({emitter:e})=>({playbackRate:()=>c,setPlaybackRate:t=>{c=t,s?.setPlaybackRate(t).catch(()=>{}),e.trigger(`ratechange`)}}),setCurrentTime:({emitter:e},t)=>{s?.setCurrentTime(t).catch(()=>{}),e.trigger(`timeupdate`),e.trigger(`seeking`)},volumeToSdk:e=>void s?.setVolume(e).catch(()=>{}),muteToSdk:({emitter:e,schedule:t},n)=>{s?.setMuted(n).then(()=>t(()=>e.trigger(`volumechange`),50)).catch(()=>{})},sdkFullscreenEnter:()=>void s?.requestFullscreen().catch(()=>{}),destroyPlayer:()=>{let e=s;s=null,e?.destroy().catch(()=>{})}})}export{a as createVimeoAdapter};