@amazon/vinyl 4.0.0 → 4.0.1-next.20261016184530

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 (76) hide show
  1. package/dist/index.cjs +40 -3
  2. package/dist/index.cjs.map +2 -2
  3. package/dist/index.js +41 -3
  4. package/dist/index.js.map +2 -2
  5. package/dist/test/benchmark.es5.js +5 -4
  6. package/dist/test/benchmark.js +11 -2
  7. package/dist/test/benchmark.js.map +3 -3
  8. package/dist/test/errata/mse-changetype-sequence.html +65 -0
  9. package/dist/test/errata/mse-changetype-sequence.js +179 -0
  10. package/dist/test/index.html +2 -2
  11. package/dist/test/integ.es5.js +287 -276
  12. package/dist/test/integ.js +629 -245
  13. package/dist/test/integ.js.map +4 -4
  14. package/dist/test/styles.css +23 -13
  15. package/dist/types/current/playback/PlaybackControllerImpl.d.ts +12 -0
  16. package/dist/types/current/playback/PlaybackControllerImpl.d.ts.map +1 -1
  17. package/dist/types/current/playback/PlaybackControllerImpl.js +42 -1
  18. package/dist/types/current/streaming/buffering/BufferingController.d.ts.map +1 -1
  19. package/dist/types/current/streaming/buffering/BufferingController.js +9 -2
  20. package/dist/types/current/streaming/buffering/MediaSourceController.d.ts.map +1 -1
  21. package/dist/types/current/streaming/buffering/MediaSourceController.js +4 -2
  22. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  23. package/dist/types/ts3.7/playback/PlaybackControllerImpl.d.ts +12 -0
  24. package/dist/types/ts4.1/playback/PlaybackControllerImpl.d.ts +12 -0
  25. package/dist/types/ts4.7/playback/PlaybackControllerImpl.d.ts +12 -0
  26. package/dist/unit/types/current/playback/PlaybackControllerImpl.test.js +86 -0
  27. package/dist/unit/types/current/setup.js +6 -5
  28. package/dist/unit/types/current/streaming/SegmentControllerImpl.test.js +44 -1
  29. package/dist/unit/types/current/streaming/buffering/BufferingController.test.js +14 -0
  30. package/dist/unit/types/current/streaming/buffering/MediaSourceController.test.js +13 -0
  31. package/dist/unit/types/current/track/dash/createDashFactories.test.js +15 -5
  32. package/dist/unit/types/current/track/hls/createHlsFactories.test.js +36 -12
  33. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  34. package/dist/unit/types/current/vinyl/VinylPlayerAdBreaks.test.js +8 -5
  35. package/dist/vinylTestUtil/index.js +92 -60
  36. package/dist/vinylTestUtil/index.js.map +4 -4
  37. package/dist/vinylTestUtil/types/current/media/FrequencyAnalyzer.d.ts +8 -5
  38. package/dist/vinylTestUtil/types/current/media/FrequencyAnalyzer.d.ts.map +1 -1
  39. package/dist/vinylTestUtil/types/current/media/FrequencyAnalyzer.js +23 -29
  40. package/dist/vinylTestUtil/types/current/media/unlockMediaElement.d.ts +10 -1
  41. package/dist/vinylTestUtil/types/current/media/unlockMediaElement.d.ts.map +1 -1
  42. package/dist/vinylTestUtil/types/current/media/unlockMediaElement.js +34 -6
  43. package/dist/vinylTestUtil/types/current/player/createVinylSuite.d.ts.map +1 -1
  44. package/dist/vinylTestUtil/types/current/player/createVinylSuite.js +6 -1
  45. package/dist/vinylTestUtil/types/current/player/mediaRef.d.ts +7 -0
  46. package/dist/vinylTestUtil/types/current/player/mediaRef.d.ts.map +1 -1
  47. package/dist/vinylTestUtil/types/current/player/mediaRef.js +8 -1
  48. package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
  49. package/dist/vinylTestUtil/types/current/ui/requireUserInteraction.d.ts +6 -2
  50. package/dist/vinylTestUtil/types/current/ui/requireUserInteraction.d.ts.map +1 -1
  51. package/dist/vinylTestUtil/types/current/ui/requireUserInteraction.js +31 -15
  52. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlays.d.ts +9 -2
  53. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlays.d.ts.map +1 -1
  54. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlays.js +10 -7
  55. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlaysUntil.d.ts +4 -1
  56. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlaysUntil.d.ts.map +1 -1
  57. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlaysUntil.js +3 -2
  58. package/dist/vinylTestUtil/types/ts3.7/media/FrequencyAnalyzer.d.ts +8 -5
  59. package/dist/vinylTestUtil/types/ts3.7/media/unlockMediaElement.d.ts +10 -1
  60. package/dist/vinylTestUtil/types/ts3.7/player/mediaRef.d.ts +7 -0
  61. package/dist/vinylTestUtil/types/ts3.7/ui/requireUserInteraction.d.ts +6 -2
  62. package/dist/vinylTestUtil/types/ts3.7/util/playback/expectTrackPlays.d.ts +9 -2
  63. package/dist/vinylTestUtil/types/ts3.7/util/playback/expectTrackPlaysUntil.d.ts +4 -1
  64. package/dist/vinylTestUtil/types/ts4.1/media/FrequencyAnalyzer.d.ts +8 -5
  65. package/dist/vinylTestUtil/types/ts4.1/media/unlockMediaElement.d.ts +10 -1
  66. package/dist/vinylTestUtil/types/ts4.1/player/mediaRef.d.ts +7 -0
  67. package/dist/vinylTestUtil/types/ts4.1/ui/requireUserInteraction.d.ts +6 -2
  68. package/dist/vinylTestUtil/types/ts4.1/util/playback/expectTrackPlays.d.ts +9 -2
  69. package/dist/vinylTestUtil/types/ts4.1/util/playback/expectTrackPlaysUntil.d.ts +4 -1
  70. package/dist/vinylTestUtil/types/ts4.7/media/FrequencyAnalyzer.d.ts +8 -5
  71. package/dist/vinylTestUtil/types/ts4.7/media/unlockMediaElement.d.ts +10 -1
  72. package/dist/vinylTestUtil/types/ts4.7/player/mediaRef.d.ts +7 -0
  73. package/dist/vinylTestUtil/types/ts4.7/ui/requireUserInteraction.d.ts +6 -2
  74. package/dist/vinylTestUtil/types/ts4.7/util/playback/expectTrackPlays.d.ts +9 -2
  75. package/dist/vinylTestUtil/types/ts4.7/util/playback/expectTrackPlaysUntil.d.ts +4 -1
  76. package/package.json +11 -10
@@ -15,11 +15,14 @@ describe('VinylPlayer ad break API', () => {
15
15
  beforeEach(() => {
16
16
  base = createMockVinylDependencies();
17
17
  // Use a real ad controller so setTrackAds drives state and events that the
18
- // player getters and redispatch reflect.
19
- adController = new AdControllerImpl({
20
- playbackController: base.playbackController,
21
- });
22
- depFactories = externalDependencies({ ...base, adController });
18
+ // player getters and redispatch reflect. The player owns it, so disposing
19
+ // the player cancels the load timeout an entered ad arms.
20
+ depFactories = {
21
+ ...externalDependencies(base),
22
+ adController: () => (adController = new AdControllerImpl({
23
+ playbackController: base.playbackController,
24
+ })),
25
+ };
23
26
  player = createVinylPlayer({ media: new MockHTMLAudioElement() }, depFactories);
24
27
  });
25
28
  afterEach(() => {
@@ -1653,9 +1653,10 @@ import { createLogPrefix } from "@amazon/vinyl-util";
1653
1653
 
1654
1654
  // test/vinylTestUtil/player/mediaRef.ts
1655
1655
  import { lazy } from "@amazon/vinyl-util";
1656
+ var MEDIA_VOLUME = 1e-4;
1656
1657
  var mediaRef = lazy(() => {
1657
1658
  const media = document.createElement("video");
1658
- media.muted = true;
1659
+ media.volume = MEDIA_VOLUME;
1659
1660
  media.playsInline = true;
1660
1661
  media.disableRemotePlayback = true;
1661
1662
  return media;
@@ -1668,39 +1669,7 @@ afterEach(() => {
1668
1669
  }
1669
1670
  });
1670
1671
 
1671
- // test/vinylTestUtil/ui/requireUserInteraction.ts
1672
- async function requireUserInteraction() {
1673
- const audioPrompt = document.getElementById("unlockAudioPrompt");
1674
- audioPrompt.style.removeProperty("display");
1675
- const body = document.body;
1676
- body.focus();
1677
- await new Promise((resolve) => {
1678
- const done = () => {
1679
- body.removeEventListener("click", done);
1680
- body.removeEventListener("keypress", done);
1681
- body.removeEventListener("touchend", done);
1682
- return resolve(void 0);
1683
- };
1684
- body.addEventListener("click", done);
1685
- body.addEventListener("keypress", done);
1686
- body.addEventListener("touchend", done);
1687
- });
1688
- audioPrompt.style.display = "none";
1689
- }
1690
-
1691
- // test/vinylTestUtil/media/unlockMediaElement.ts
1692
- import { noop } from "@amazon/vinyl-util";
1693
- async function unlockMediaElement() {
1694
- const media = mediaRef.value;
1695
- media.src = vinylTestAssets.prog.libmp3lame_60s_2ch_16bit_44100Hz_48kbps;
1696
- await media.play().catch(noop);
1697
- media.pause();
1698
- media.removeAttribute("src");
1699
- media.load();
1700
- }
1701
-
1702
1672
  // test/vinylTestUtil/media/FrequencyAnalyzer.ts
1703
- import { setNextTestTimeout } from "@amazon/vinyl-util/browserTestUtil";
1704
1673
  var TIME_ESTIMATE_TOLERANCE = 0.02;
1705
1674
  var defaultFrequencyAnalyzerOptions = {
1706
1675
  startFrequency: 100,
@@ -1798,6 +1767,7 @@ var FrequencyAnalyzer = class {
1798
1767
  }
1799
1768
  }
1800
1769
  };
1770
+ var ANALYZER_VOLUME = 0.01;
1801
1771
  var _a;
1802
1772
  var shouldCheckAudio = parseBoolean(
1803
1773
  ((_a = getSearchParams().get("checkAudio")) != null ? _a : "0").toLowerCase()
@@ -1808,26 +1778,80 @@ function assertFrequency() {
1808
1778
  return (_a2 = frequencyAnalyzer == null ? void 0 : frequencyAnalyzer.assertFrequency()) != null ? _a2 : Promise.resolve();
1809
1779
  }
1810
1780
  function initializeFrequencyAnalyzer() {
1811
- if (shouldCheckAudio) {
1812
- setNextTestTimeout(300);
1813
- beforeAll(async () => {
1814
- const media = mediaRef.value;
1815
- media.crossOrigin = "anonymous";
1816
- media.muted = false;
1817
- media.volume = 0.01;
1818
- await requireUserInteraction();
1819
- const audioContext = getAudioContext();
1820
- await unlockMediaElement();
1821
- if (audioContext) {
1822
- const source = audioContext.createMediaElementSource(
1823
- mediaRef.value
1781
+ if (!shouldCheckAudio) return;
1782
+ beforeAll(() => {
1783
+ const media = mediaRef.value;
1784
+ media.crossOrigin = "anonymous";
1785
+ media.volume = ANALYZER_VOLUME;
1786
+ const audioContext = getAudioContext();
1787
+ if (audioContext) {
1788
+ const source = audioContext.createMediaElementSource(media);
1789
+ frequencyAnalyzer = new FrequencyAnalyzer(audioContext, source);
1790
+ } else {
1791
+ console.warn("AudioContext not supported");
1792
+ }
1793
+ });
1794
+ }
1795
+
1796
+ // test/vinylTestUtil/media/unlockMediaElement.ts
1797
+ import { getAudioContext as getAudioContext2 } from "@amazon/vinyl";
1798
+
1799
+ // test/vinylTestUtil/ui/requireUserInteraction.ts
1800
+ async function requireUserInteraction(onInteraction) {
1801
+ var _a2;
1802
+ const prompt = document.getElementById("unlockAudioPrompt");
1803
+ prompt.style.removeProperty("display");
1804
+ (_a2 = prompt.querySelector("button")) == null ? void 0 : _a2.focus();
1805
+ await new Promise((resolve) => {
1806
+ let handling = false;
1807
+ const handler = (event) => {
1808
+ var _a3;
1809
+ if (handling) return;
1810
+ handling = true;
1811
+ const result = (_a3 = onInteraction == null ? void 0 : onInteraction()) != null ? _a3 : Promise.resolve();
1812
+ result.then(() => {
1813
+ prompt.removeEventListener("click", handler);
1814
+ document.removeEventListener("keydown", handler);
1815
+ resolve();
1816
+ }).catch((error) => {
1817
+ console.warn(
1818
+ `The ${event.type} (isTrusted: ${event.isTrusted}) was not accepted as a user gesture; interact again.`,
1819
+ error
1824
1820
  );
1825
- frequencyAnalyzer = new FrequencyAnalyzer(audioContext, source);
1826
- } else {
1827
- console.warn("AudioContext not supported");
1828
- }
1829
- });
1821
+ }).finally(() => {
1822
+ handling = false;
1823
+ });
1824
+ };
1825
+ prompt.addEventListener("click", handler);
1826
+ document.addEventListener("keydown", handler);
1827
+ });
1828
+ prompt.style.display = "none";
1829
+ }
1830
+
1831
+ // test/vinylTestUtil/media/unlockMediaElement.ts
1832
+ import { noop } from "@amazon/vinyl-util";
1833
+ var MAX_TIMEOUT_MS = 2147483647;
1834
+ async function unlockMediaElement() {
1835
+ var _a2;
1836
+ const media = mediaRef.value;
1837
+ media.src = vinylTestAssets.prog.libmp3lame_60s_2ch_16bit_44100Hz_48kbps;
1838
+ const played = media.play();
1839
+ const resumed = (_a2 = getAudioContext2()) == null ? void 0 : _a2.resume().catch(noop);
1840
+ try {
1841
+ await played;
1842
+ } finally {
1843
+ media.pause();
1844
+ media.removeAttribute("src");
1845
+ media.load();
1830
1846
  }
1847
+ await resumed;
1848
+ }
1849
+ function initializeMediaUnlock() {
1850
+ if (typeof document === "undefined") return;
1851
+ beforeAll(async () => {
1852
+ await requireUserInteraction(unlockMediaElement);
1853
+ console.info("Media element unlocked");
1854
+ }, MAX_TIMEOUT_MS);
1831
1855
  }
1832
1856
 
1833
1857
  // test/vinylTestUtil/mediaSource/ControlledMediaSource.ts
@@ -2863,6 +2887,7 @@ var VinylSuite = class {
2863
2887
  this.visibilityChangeHandler
2864
2888
  );
2865
2889
  this._player = this.playerFactory();
2890
+ this._player.volume = shouldCheckAudio ? ANALYZER_VOLUME : MEDIA_VOLUME;
2866
2891
  add(
2867
2892
  this._player.on("error", (e) => {
2868
2893
  logError(this, "player emitted error event", toJson(e));
@@ -3041,13 +3066,13 @@ import { sleep as sleep3 } from "@amazon/vinyl-util";
3041
3066
  var sleepInterval = 1;
3042
3067
  var affordanceBefore = 1;
3043
3068
  var affordanceAfter = 3;
3044
- async function expectTrackPlaysUntil(player, endTime, timeout = 20) {
3069
+ async function expectTrackPlaysUntil(player, endTime, timeout = 20, { timeoutScale = 1 } = {}) {
3045
3070
  await onPlaying(player);
3046
3071
  await onTimeUpdate(player);
3047
3072
  const startedBeforeEnd = player.currentTime < endTime;
3048
3073
  await assertFrequency();
3049
3074
  let elapsed = 0;
3050
- const maxTime = endTime - player.currentTime + timeout;
3075
+ const maxTime = (endTime - player.currentTime + timeout) * timeoutScale;
3051
3076
  while (!player.ended && player.currentTime < endTime && elapsed < maxTime) {
3052
3077
  await sleep3(sleepInterval);
3053
3078
  elapsed += sleepInterval;
@@ -3060,7 +3085,7 @@ async function expectTrackPlaysUntil(player, endTime, timeout = 20) {
3060
3085
 
3061
3086
  // test/vinylTestUtil/util/playback/expectTrackPlays.ts
3062
3087
  var PLAYBACK_DURATION = 6;
3063
- async function expectTrackPlays(player) {
3088
+ async function expectTrackPlays(player, { timeoutScale = 1 } = {}) {
3064
3089
  const { dispose, add } = createDisposer3();
3065
3090
  const ended = add(createEventSpy2(player, "ended"));
3066
3091
  const timeUpdate = add(createEventSpy2(player, "timeUpdate"));
@@ -3071,12 +3096,14 @@ async function expectTrackPlays(player) {
3071
3096
  if (player.duration > PLAYBACK_DURATION) {
3072
3097
  await expectTrackPlaysUntil(
3073
3098
  player,
3074
- player.currentTime + PLAYBACK_DURATION / 2
3099
+ player.currentTime + PLAYBACK_DURATION / 2,
3100
+ void 0,
3101
+ { timeoutScale }
3075
3102
  );
3076
3103
  const time = player.duration - PLAYBACK_DURATION / 2;
3077
3104
  await player.seekTo(time);
3078
3105
  }
3079
- await ended.next(PLAYBACK_DURATION + 10);
3106
+ await ended.next((PLAYBACK_DURATION + 10) * timeoutScale);
3080
3107
  expect(player.currentTime).toBeCloseToWithin(duration, 3);
3081
3108
  expect(player.ended).withContext("ended").toBeTrue();
3082
3109
  expect(timeUpdate.calls.count()).toBeGreaterThanOrEqual(
@@ -3084,10 +3111,10 @@ async function expectTrackPlays(player) {
3084
3111
  );
3085
3112
  dispose();
3086
3113
  }
3087
- async function expectPlaylistPlays(player, playlist) {
3114
+ async function expectPlaylistPlays(player, playlist, { timeoutScale = 1 } = {}) {
3088
3115
  var _a2;
3089
3116
  const { dispose, add } = createDisposer3();
3090
- const trackTimeout = PLAYBACK_DURATION + 60;
3117
+ const trackTimeout = (PLAYBACK_DURATION + 60) * timeoutScale;
3091
3118
  const queueEnded = add(createEventSpy2(player, "queueEnded"));
3092
3119
  const queueChange = add(createEventSpy2(player, "queueChange"));
3093
3120
  const trackChange = add(createEventSpy2(player, "trackActivated"));
@@ -3102,15 +3129,19 @@ async function expectPlaylistPlays(player, playlist) {
3102
3129
  const isLastTrack = i === playlist.length - 1;
3103
3130
  expect((_a2 = player.activeTrack) == null ? void 0 : _a2.uri).withContext("activeTrack uri").toBe(playlist[i].uri);
3104
3131
  const nextTrack = isLastTrack ? queueEnded.next(trackTimeout) : trackChange.next(trackTimeout);
3105
- await expectTrackPlays(player);
3106
- await nextTrack;
3132
+ await Promise.all([
3133
+ expectTrackPlays(player, { timeoutScale }),
3134
+ nextTrack
3135
+ ]);
3107
3136
  assertQueueChangeCount(isLastTrack ? 0 : 1);
3108
3137
  }
3109
3138
  dispose();
3110
3139
  }
3111
3140
  export {
3141
+ ANALYZER_VOLUME,
3112
3142
  ControlledMediaSource,
3113
3143
  FrequencyAnalyzer,
3144
+ MEDIA_VOLUME,
3114
3145
  MockAdController,
3115
3146
  MockAutoResetController,
3116
3147
  MockBufferingController,
@@ -3164,6 +3195,7 @@ export {
3164
3195
  expectTrackPlays,
3165
3196
  expectTrackPlaysUntil,
3166
3197
  initializeFrequencyAnalyzer,
3198
+ initializeMediaUnlock,
3167
3199
  mediaRef,
3168
3200
  mockDashManifest,
3169
3201
  mockHlsManifestData,