avbridge 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/{chunk-NQULEIA3.cjs → chunk-37UOSAVI.cjs} +15 -7
  3. package/dist/chunk-37UOSAVI.cjs.map +1 -0
  4. package/dist/{chunk-5KVLE6YI.js → chunk-EDDWAN2L.js} +3 -2
  5. package/dist/chunk-EDDWAN2L.js.map +1 -0
  6. package/dist/{chunk-3GKM5DFM.js → chunk-IHNHHEA2.js} +11 -3
  7. package/dist/chunk-IHNHHEA2.js.map +1 -0
  8. package/dist/{chunk-S4WAZC2T.cjs → chunk-WRKO6Q42.cjs} +3 -2
  9. package/dist/chunk-WRKO6Q42.cjs.map +1 -0
  10. package/dist/element-browser.js +23 -1
  11. package/dist/element-browser.js.map +1 -1
  12. package/dist/element.cjs +18 -5
  13. package/dist/element.cjs.map +1 -1
  14. package/dist/element.js +17 -4
  15. package/dist/element.js.map +1 -1
  16. package/dist/index.cjs +10 -10
  17. package/dist/index.js +2 -2
  18. package/dist/player.cjs +106 -18
  19. package/dist/player.cjs.map +1 -1
  20. package/dist/player.d.cts +15 -0
  21. package/dist/player.d.ts +15 -0
  22. package/dist/player.js +102 -14
  23. package/dist/player.js.map +1 -1
  24. package/dist/subtitles-5H24MEBJ.js +4 -0
  25. package/dist/{subtitles-4T74JRGT.js.map → subtitles-5H24MEBJ.js.map} +1 -1
  26. package/dist/subtitles-HMVGWTU2.cjs +29 -0
  27. package/dist/{subtitles-QUH4LPI4.cjs.map → subtitles-HMVGWTU2.cjs.map} +1 -1
  28. package/package.json +1 -1
  29. package/src/element/avbridge-player.ts +92 -10
  30. package/src/element/avbridge-subtitles.ts +273 -0
  31. package/src/element/avbridge-video.ts +21 -1
  32. package/src/strategies/fallback/audio-output.ts +10 -0
  33. package/src/subtitles/index.ts +2 -0
  34. package/dist/chunk-3GKM5DFM.js.map +0 -1
  35. package/dist/chunk-5KVLE6YI.js.map +0 -1
  36. package/dist/chunk-NQULEIA3.cjs.map +0 -1
  37. package/dist/chunk-S4WAZC2T.cjs.map +0 -1
  38. package/dist/subtitles-4T74JRGT.js +0 -4
  39. package/dist/subtitles-QUH4LPI4.cjs +0 -29
package/CHANGELOG.md CHANGED
@@ -4,6 +4,40 @@ All notable changes to **avbridge.js** are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [2.11.0]
8
+
9
+ Subtitle panel, interaction fixes, and quality-of-life.
10
+
11
+ ### Added
12
+
13
+ - **`<avbridge-subtitles>` element** — scrollable cue timeline panel.
14
+ Connects to a player via `for` attribute, renders all subtitle cues
15
+ as timestamped rows, highlights the active cue, auto-scrolls to
16
+ follow playback, and click-to-seek. Shadow DOM with dark styles.
17
+ - **Frame-by-frame keyboard shortcuts** (`,` / `.`) — YouTube-style.
18
+ Pauses if playing, then steps back/forward one frame (1/fps).
19
+ - **Real-time scrub seeking on narrow seekbars** — when the seekbar
20
+ is <400px wide, dragging seeks in real-time (throttled to 4 Hz)
21
+ instead of preview-only. Immediate video feedback on small players.
22
+ - **`controls-timeout` attribute** on `<avbridge-player>`. Customize
23
+ the auto-hide duration (default 3000ms). Set to `"0"` to disable
24
+ auto-hide entirely (always-visible controls).
25
+
26
+ ### Fixed
27
+
28
+ - **Subtitles not showing** — `addSubtitle()` didn't dispatch
29
+ `trackschange` (settings sheet never showed the new track) and the
30
+ `<track>` element was created with `mode="disabled"` (never
31
+ rendered on native strategy). Now dispatches + auto-enables.
32
+ - **Audio bleed on pause** for hybrid/fallback — already-scheduled
33
+ AudioBufferSourceNodes kept playing ~200ms after pause. Now
34
+ disconnects the gain node immediately (same pattern as seek/reset).
35
+ - **Double-tap fires both ff/rw AND fullscreen on touch** — browser's
36
+ synthetic `dblclick` after two rapid taps was calling fullscreen
37
+ on top of the touch handler's ff/rw. Blocked via a consumed flag.
38
+ - **Settings sheet didn't show active audio/subtitle selection** —
39
+ always displayed "Track 1" / "Off" regardless of actual state.
40
+
7
41
  ## [2.10.0]
8
42
 
9
43
  Settings UI overhaul + playback rate on all strategies.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkS4WAZC2T_cjs = require('./chunk-S4WAZC2T.cjs');
3
+ var chunkWRKO6Q42_cjs = require('./chunk-WRKO6Q42.cjs');
4
4
  var chunkBYGZN4Z5_cjs = require('./chunk-BYGZN4Z5.cjs');
5
5
  var chunk2IJ66NTD_cjs = require('./chunk-2IJ66NTD.cjs');
6
6
  var chunkL7A3ECI2_cjs = require('./chunk-L7A3ECI2.cjs');
@@ -1055,7 +1055,7 @@ var VideoRenderer = class {
1055
1055
  }
1056
1056
  target.style.visibility = "hidden";
1057
1057
  const overlayParent = parent instanceof HTMLElement ? parent : document.body;
1058
- this.subtitleOverlay = new chunkS4WAZC2T_cjs.SubtitleOverlay(overlayParent);
1058
+ this.subtitleOverlay = new chunkWRKO6Q42_cjs.SubtitleOverlay(overlayParent);
1059
1059
  this.watchTextTracks(target);
1060
1060
  const ctx = this.canvas.getContext("2d");
1061
1061
  if (!ctx) throw new Error("video renderer: failed to acquire 2D context");
@@ -1520,6 +1520,10 @@ var AudioOutput = class {
1520
1520
  if (this.ctx.state === "suspended") {
1521
1521
  await this.ctx.resume();
1522
1522
  }
1523
+ try {
1524
+ this.gain.connect(this.ctx.destination);
1525
+ } catch {
1526
+ }
1523
1527
  if (this.state === "paused") {
1524
1528
  this.ctxTimeAtAnchor = this.ctx.currentTime;
1525
1529
  this.state = "playing";
@@ -1546,6 +1550,10 @@ var AudioOutput = class {
1546
1550
  this.mediaTimeOfAnchor = this.now();
1547
1551
  this.state = "paused";
1548
1552
  if (this.noAudio) return;
1553
+ try {
1554
+ this.gain.disconnect();
1555
+ } catch {
1556
+ }
1549
1557
  if (this.ctx.state === "running") {
1550
1558
  await this.ctx.suspend();
1551
1559
  }
@@ -3045,7 +3053,7 @@ var UnifiedPlayer = class _UnifiedPlayer {
3045
3053
  switchingPromise = Promise.resolve();
3046
3054
  // Owns blob URLs created during sidecar discovery + SRT->VTT conversion.
3047
3055
  // Revoked at destroy() so repeated source swaps don't leak.
3048
- subtitleResources = new chunkS4WAZC2T_cjs.SubtitleResourceBag();
3056
+ subtitleResources = new chunkWRKO6Q42_cjs.SubtitleResourceBag();
3049
3057
  // Transport config extracted from CreatePlayerOptions. Threaded to probe,
3050
3058
  // subtitle fetches, and strategy session creators. Not stored on MediaContext
3051
3059
  // because it's runtime config, not media analysis.
@@ -3091,7 +3099,7 @@ var UnifiedPlayer = class _UnifiedPlayer {
3091
3099
  }
3092
3100
  }
3093
3101
  if (this.options.directory && this.options.source instanceof File) {
3094
- const found = await chunkS4WAZC2T_cjs.discoverSidecars(this.options.source, this.options.directory);
3102
+ const found = await chunkWRKO6Q42_cjs.discoverSidecars(this.options.source, this.options.directory);
3095
3103
  for (const s of found) {
3096
3104
  this.subtitleResources.track(s.url);
3097
3105
  ctx.subtitleTracks.push({
@@ -3114,7 +3122,7 @@ var UnifiedPlayer = class _UnifiedPlayer {
3114
3122
  reason: decision.reason
3115
3123
  });
3116
3124
  await this.startSession(decision.strategy, decision.reason);
3117
- await chunkS4WAZC2T_cjs.attachSubtitleTracks(
3125
+ await chunkWRKO6Q42_cjs.attachSubtitleTracks(
3118
3126
  this.options.target,
3119
3127
  ctx.subtitleTracks,
3120
3128
  this.subtitleResources,
@@ -3543,5 +3551,5 @@ exports.NATIVE_VIDEO_CODECS = NATIVE_VIDEO_CODECS;
3543
3551
  exports.UnifiedPlayer = UnifiedPlayer;
3544
3552
  exports.classifyContext = classifyContext;
3545
3553
  exports.createPlayer = createPlayer;
3546
- //# sourceMappingURL=chunk-NQULEIA3.cjs.map
3547
- //# sourceMappingURL=chunk-NQULEIA3.cjs.map
3554
+ //# sourceMappingURL=chunk-37UOSAVI.cjs.map
3555
+ //# sourceMappingURL=chunk-37UOSAVI.cjs.map