@ghchinoy/lit-audio-ui 0.4.18 → 0.4.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT_SKILL.md +4 -0
- package/custom-elements.json +143 -47
- package/dist/components/atoms/ui-audio-progress-slider.js +74 -16
- package/dist/components/atoms/ui-audio-time-display.js +13 -10
- package/dist/components/molecules/ui-live-waveform.js +23 -19
- package/dist/components/molecules/ui-spectrum-visualizer.js +23 -19
- package/dist/components/organisms/ui-audio-player.js +11 -7
- package/dist/components/providers/ui-audio-provider.js +19 -11
- package/dist/components/providers/ui-speech-provider.js +16 -12
- package/dist/index.js +35 -35
- package/dist/scream-audio-ui.umd.js +77 -25
- package/dist/src/components/atoms/ui-audio-progress-slider.d.ts +6 -0
- package/dist/src/utils/audio-utils.d.ts +6 -0
- package/dist/standalone/scream-audio-ui.standalone.js +1600 -1486
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/audio-utils.js +26 -1
- package/package.json +1 -1
package/AGENT_SKILL.md
CHANGED
|
@@ -83,3 +83,7 @@ Do not forget to inject the Material Symbols font into the host document's `<hea
|
|
|
83
83
|
- **Transparent Progress Overlays:** The `<ui-audio-progress-slider>` exposes its internal Material slider via `part="slider"`. This allows you to create "Producer Bar" layouts by setting `--md-slider-inactive-track-color: transparent` and layering it directly over a `<ui-waveform>`.
|
|
84
84
|
- **Waveform Alignment:** Use `align="bottom"` on static or scrolling waveforms to draw bars upwards from the bottom of the container, rather than the default vertically-centered mirrored style.
|
|
85
85
|
|
|
86
|
+
|
|
87
|
+
### 11. Interactive UX (v0.4.19+)
|
|
88
|
+
- **Hover Timestamps:** To give users precision seeking capabilities, add `hoverTimestamp="true"` to `<ui-audio-progress-slider>`. This will automatically render a floating `MM:SS` tooltip above the cursor based on the context's total duration.
|
|
89
|
+
|
package/custom-elements.json
CHANGED
|
@@ -636,6 +636,29 @@
|
|
|
636
636
|
}
|
|
637
637
|
],
|
|
638
638
|
"description": "Creates an edge-fade gradient over a canvas to smoothly blend the left and right edges."
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"kind": "function",
|
|
642
|
+
"name": "formatAudioTime",
|
|
643
|
+
"return": {
|
|
644
|
+
"type": {
|
|
645
|
+
"text": "string"
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
"parameters": [
|
|
649
|
+
{
|
|
650
|
+
"name": "seconds",
|
|
651
|
+
"type": {
|
|
652
|
+
"text": "number"
|
|
653
|
+
},
|
|
654
|
+
"description": "The time in seconds"
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
"description": "If true, omits leading zeros for minutes if under an hour.",
|
|
658
|
+
"name": "compact"
|
|
659
|
+
}
|
|
660
|
+
],
|
|
661
|
+
"description": "Formats a duration in seconds into a standard MM:SS or HH:MM:SS string."
|
|
639
662
|
}
|
|
640
663
|
],
|
|
641
664
|
"exports": [
|
|
@@ -678,6 +701,14 @@
|
|
|
678
701
|
"name": "applyCanvasEdgeFade",
|
|
679
702
|
"module": "src/utils/audio-utils.ts"
|
|
680
703
|
}
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"kind": "js",
|
|
707
|
+
"name": "formatAudioTime",
|
|
708
|
+
"declaration": {
|
|
709
|
+
"name": "formatAudioTime",
|
|
710
|
+
"module": "src/utils/audio-utils.ts"
|
|
711
|
+
}
|
|
681
712
|
}
|
|
682
713
|
]
|
|
683
714
|
},
|
|
@@ -928,16 +959,72 @@
|
|
|
928
959
|
"privacy": "private",
|
|
929
960
|
"default": "0"
|
|
930
961
|
},
|
|
962
|
+
{
|
|
963
|
+
"kind": "field",
|
|
964
|
+
"name": "hoverTimestamp",
|
|
965
|
+
"type": {
|
|
966
|
+
"text": "boolean"
|
|
967
|
+
},
|
|
968
|
+
"default": "false"
|
|
969
|
+
},
|
|
970
|
+
{
|
|
971
|
+
"kind": "field",
|
|
972
|
+
"name": "_hoverX",
|
|
973
|
+
"type": {
|
|
974
|
+
"text": "number"
|
|
975
|
+
},
|
|
976
|
+
"privacy": "private",
|
|
977
|
+
"default": "0"
|
|
978
|
+
},
|
|
979
|
+
{
|
|
980
|
+
"kind": "field",
|
|
981
|
+
"name": "_showHover",
|
|
982
|
+
"type": {
|
|
983
|
+
"text": "boolean"
|
|
984
|
+
},
|
|
985
|
+
"privacy": "private",
|
|
986
|
+
"default": "false"
|
|
987
|
+
},
|
|
988
|
+
{
|
|
989
|
+
"kind": "field",
|
|
990
|
+
"name": "_hoverTime",
|
|
991
|
+
"type": {
|
|
992
|
+
"text": "number"
|
|
993
|
+
},
|
|
994
|
+
"privacy": "private",
|
|
995
|
+
"default": "0"
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
"kind": "field",
|
|
999
|
+
"name": "_sliderEl",
|
|
1000
|
+
"type": {
|
|
1001
|
+
"text": "HTMLElement"
|
|
1002
|
+
},
|
|
1003
|
+
"privacy": "private"
|
|
1004
|
+
},
|
|
931
1005
|
{
|
|
932
1006
|
"kind": "field",
|
|
933
1007
|
"name": "styles",
|
|
934
1008
|
"static": true,
|
|
935
|
-
"default": "css` :host { display: flex; width: 100%; align-items: center; min-width: 0; } md-slider { width: 100%; min-width: 0; flex: 1; /* Give the slider track better contrast against backgrounds */ --md-slider-inactive-track-color: var(--md-sys-color-outline, #79747e); } `"
|
|
1009
|
+
"default": "css` :host { display: flex; width: 100%; align-items: center; min-width: 0; position: relative; } .hover-tooltip { position: absolute; top: -32px; transform: translateX(-50%); background: var(--md-sys-color-inverse-surface, #313033); color: var(--md-sys-color-inverse-on-surface, #f4eff4); padding: 4px 8px; border-radius: 4px; font-size: 12px; font-family: inherit; font-variant-numeric: tabular-nums; pointer-events: none; white-space: nowrap; opacity: 0; visibility: hidden; transition: opacity 0.1s ease; z-index: 100; } .hover-tooltip.show { opacity: 1; visibility: visible; } /* Little downward pointing triangle */ .hover-tooltip::after { content: ''; position: absolute; bottom: -4px; left: 50%; transform: translateX(-50%); border-width: 4px 4px 0; border-style: solid; border-color: var(--md-sys-color-inverse-surface, #313033) transparent transparent transparent; } md-slider { width: 100%; min-width: 0; flex: 1; /* Give the slider track better contrast against backgrounds */ --md-slider-inactive-track-color: var(--md-sys-color-outline, #79747e); } `"
|
|
936
1010
|
},
|
|
937
1011
|
{
|
|
938
1012
|
"kind": "method",
|
|
939
1013
|
"name": "render"
|
|
940
1014
|
},
|
|
1015
|
+
{
|
|
1016
|
+
"kind": "method",
|
|
1017
|
+
"name": "_handleMouseMove",
|
|
1018
|
+
"privacy": "private",
|
|
1019
|
+
"parameters": [
|
|
1020
|
+
{
|
|
1021
|
+
"name": "e",
|
|
1022
|
+
"type": {
|
|
1023
|
+
"text": "MouseEvent"
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
]
|
|
1027
|
+
},
|
|
941
1028
|
{
|
|
942
1029
|
"kind": "method",
|
|
943
1030
|
"name": "_handleInput",
|
|
@@ -1654,6 +1741,51 @@
|
|
|
1654
1741
|
}
|
|
1655
1742
|
]
|
|
1656
1743
|
},
|
|
1744
|
+
{
|
|
1745
|
+
"kind": "javascript-module",
|
|
1746
|
+
"path": "src/components/organisms/ui-audio-player.ts",
|
|
1747
|
+
"declarations": [
|
|
1748
|
+
{
|
|
1749
|
+
"kind": "class",
|
|
1750
|
+
"description": "A monolithic backward-compatibility wrapper that renders the classic ElevenLabs\npill-shaped audio player. Internally, it relies completely on the new\ncompound <ui-audio-provider> architecture.",
|
|
1751
|
+
"name": "UiAudioPlayer",
|
|
1752
|
+
"members": [
|
|
1753
|
+
{
|
|
1754
|
+
"kind": "field",
|
|
1755
|
+
"name": "item",
|
|
1756
|
+
"type": {
|
|
1757
|
+
"text": "AudioPlayerItem | undefined"
|
|
1758
|
+
}
|
|
1759
|
+
},
|
|
1760
|
+
{
|
|
1761
|
+
"kind": "field",
|
|
1762
|
+
"name": "styles",
|
|
1763
|
+
"static": true,
|
|
1764
|
+
"default": "css` :host { display: inline-block; width: 100%; max-width: 400px; } .player-pill { display: flex; align-items: center; gap: var(--ui-audio-player-gap, 16px); padding: var(--ui-audio-player-padding, 12px 24px); background: var(--md-sys-color-surface-container-high, #e2e2e2); border-radius: 999px; /* Pill shape */ width: fit-content; font-family: inherit; } .time-container { min-width: 85px; /* prevent jitter when times change */ } .slider-container { width: 200px; display: flex; align-items: center; } `"
|
|
1765
|
+
},
|
|
1766
|
+
{
|
|
1767
|
+
"kind": "method",
|
|
1768
|
+
"name": "render"
|
|
1769
|
+
}
|
|
1770
|
+
],
|
|
1771
|
+
"superclass": {
|
|
1772
|
+
"name": "LitElement",
|
|
1773
|
+
"package": "lit"
|
|
1774
|
+
},
|
|
1775
|
+
"customElement": true
|
|
1776
|
+
}
|
|
1777
|
+
],
|
|
1778
|
+
"exports": [
|
|
1779
|
+
{
|
|
1780
|
+
"kind": "js",
|
|
1781
|
+
"name": "UiAudioPlayer",
|
|
1782
|
+
"declaration": {
|
|
1783
|
+
"name": "UiAudioPlayer",
|
|
1784
|
+
"module": "src/components/organisms/ui-audio-player.ts"
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
]
|
|
1788
|
+
},
|
|
1657
1789
|
{
|
|
1658
1790
|
"kind": "javascript-module",
|
|
1659
1791
|
"path": "src/components/providers/ui-audio-provider.ts",
|
|
@@ -1881,7 +2013,16 @@
|
|
|
1881
2013
|
{
|
|
1882
2014
|
"kind": "method",
|
|
1883
2015
|
"name": "_handleError",
|
|
1884
|
-
"privacy": "private"
|
|
2016
|
+
"privacy": "private",
|
|
2017
|
+
"parameters": [
|
|
2018
|
+
{
|
|
2019
|
+
"name": "e",
|
|
2020
|
+
"optional": true,
|
|
2021
|
+
"type": {
|
|
2022
|
+
"text": "Event"
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
]
|
|
1885
2026
|
},
|
|
1886
2027
|
{
|
|
1887
2028
|
"kind": "method",
|
|
@@ -2141,51 +2282,6 @@
|
|
|
2141
2282
|
}
|
|
2142
2283
|
]
|
|
2143
2284
|
},
|
|
2144
|
-
{
|
|
2145
|
-
"kind": "javascript-module",
|
|
2146
|
-
"path": "src/components/organisms/ui-audio-player.ts",
|
|
2147
|
-
"declarations": [
|
|
2148
|
-
{
|
|
2149
|
-
"kind": "class",
|
|
2150
|
-
"description": "A monolithic backward-compatibility wrapper that renders the classic ElevenLabs\npill-shaped audio player. Internally, it relies completely on the new\ncompound <ui-audio-provider> architecture.",
|
|
2151
|
-
"name": "UiAudioPlayer",
|
|
2152
|
-
"members": [
|
|
2153
|
-
{
|
|
2154
|
-
"kind": "field",
|
|
2155
|
-
"name": "item",
|
|
2156
|
-
"type": {
|
|
2157
|
-
"text": "AudioPlayerItem | undefined"
|
|
2158
|
-
}
|
|
2159
|
-
},
|
|
2160
|
-
{
|
|
2161
|
-
"kind": "field",
|
|
2162
|
-
"name": "styles",
|
|
2163
|
-
"static": true,
|
|
2164
|
-
"default": "css` :host { display: inline-block; width: 100%; max-width: 400px; } .player-pill { display: flex; align-items: center; gap: var(--ui-audio-player-gap, 16px); padding: var(--ui-audio-player-padding, 12px 24px); background: var(--md-sys-color-surface-container-high, #e2e2e2); border-radius: 999px; /* Pill shape */ width: fit-content; font-family: inherit; } .time-container { min-width: 85px; /* prevent jitter when times change */ } .slider-container { width: 200px; display: flex; align-items: center; } `"
|
|
2165
|
-
},
|
|
2166
|
-
{
|
|
2167
|
-
"kind": "method",
|
|
2168
|
-
"name": "render"
|
|
2169
|
-
}
|
|
2170
|
-
],
|
|
2171
|
-
"superclass": {
|
|
2172
|
-
"name": "LitElement",
|
|
2173
|
-
"package": "lit"
|
|
2174
|
-
},
|
|
2175
|
-
"customElement": true
|
|
2176
|
-
}
|
|
2177
|
-
],
|
|
2178
|
-
"exports": [
|
|
2179
|
-
{
|
|
2180
|
-
"kind": "js",
|
|
2181
|
-
"name": "UiAudioPlayer",
|
|
2182
|
-
"declaration": {
|
|
2183
|
-
"name": "UiAudioPlayer",
|
|
2184
|
-
"module": "src/components/organisms/ui-audio-player.ts"
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
]
|
|
2188
|
-
},
|
|
2189
2285
|
{
|
|
2190
2286
|
"kind": "javascript-module",
|
|
2191
2287
|
"path": "src/components/molecules/scream-voice-button.ts",
|
|
@@ -1,24 +1,62 @@
|
|
|
1
1
|
import { audioPlayerContext as e } from "../../utils/audio-context.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { formatAudioTime as t } from "../../utils/audio-utils.js";
|
|
3
|
+
import { LitElement as n, css as r, html as i } from "lit";
|
|
4
|
+
import { customElement as a, property as o, query as s, state as c } from "lit/decorators.js";
|
|
5
|
+
import { consume as l } from "@lit/context";
|
|
5
6
|
import "@material/web/slider/slider.js";
|
|
6
|
-
var
|
|
7
|
+
var u = function(e, t, n, r) {
|
|
7
8
|
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
8
9
|
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
9
10
|
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
10
11
|
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
11
|
-
},
|
|
12
|
+
}, d = class extends n {
|
|
12
13
|
constructor() {
|
|
13
|
-
super(...arguments), this._isDragging = !1, this._dragValue = 0;
|
|
14
|
+
super(...arguments), this._isDragging = !1, this._dragValue = 0, this.hoverTimestamp = !1, this._hoverX = 0, this._showHover = !1, this._hoverTime = 0;
|
|
14
15
|
}
|
|
15
16
|
static {
|
|
16
|
-
this.styles =
|
|
17
|
+
this.styles = r`
|
|
18
|
+
|
|
19
|
+
|
|
17
20
|
:host {
|
|
18
21
|
display: flex;
|
|
19
22
|
width: 100%;
|
|
20
23
|
align-items: center;
|
|
21
24
|
min-width: 0;
|
|
25
|
+
position: relative;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.hover-tooltip {
|
|
29
|
+
position: absolute;
|
|
30
|
+
top: -32px;
|
|
31
|
+
transform: translateX(-50%);
|
|
32
|
+
background: var(--md-sys-color-inverse-surface, #313033);
|
|
33
|
+
color: var(--md-sys-color-inverse-on-surface, #f4eff4);
|
|
34
|
+
padding: 4px 8px;
|
|
35
|
+
border-radius: 4px;
|
|
36
|
+
font-size: 12px;
|
|
37
|
+
font-family: inherit;
|
|
38
|
+
font-variant-numeric: tabular-nums;
|
|
39
|
+
pointer-events: none;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
opacity: 0;
|
|
42
|
+
visibility: hidden;
|
|
43
|
+
transition: opacity 0.1s ease;
|
|
44
|
+
z-index: 100;
|
|
45
|
+
}
|
|
46
|
+
.hover-tooltip.show {
|
|
47
|
+
opacity: 1;
|
|
48
|
+
visibility: visible;
|
|
49
|
+
}
|
|
50
|
+
/* Little downward pointing triangle */
|
|
51
|
+
.hover-tooltip::after {
|
|
52
|
+
content: '';
|
|
53
|
+
position: absolute;
|
|
54
|
+
bottom: -4px;
|
|
55
|
+
left: 50%;
|
|
56
|
+
transform: translateX(-50%);
|
|
57
|
+
border-width: 4px 4px 0;
|
|
58
|
+
border-style: solid;
|
|
59
|
+
border-color: var(--md-sys-color-inverse-surface, #313033) transparent transparent transparent;
|
|
22
60
|
}
|
|
23
61
|
|
|
24
62
|
md-slider {
|
|
@@ -31,21 +69,41 @@ var s = function(e, t, n, r) {
|
|
|
31
69
|
`;
|
|
32
70
|
}
|
|
33
71
|
render() {
|
|
34
|
-
let e = this.playerState?.duration || 0,
|
|
35
|
-
return
|
|
36
|
-
<
|
|
72
|
+
let e = this.playerState?.duration || 0, n = e === 0 || !this.playerState?.src, r = this._isDragging ? this._dragValue : this.playerState?.currentTime || 0;
|
|
73
|
+
return i`
|
|
74
|
+
<div
|
|
75
|
+
style="position: relative; width: 100%; display: flex; align-items: center;"
|
|
76
|
+
@mousemove="${this._handleMouseMove}"
|
|
77
|
+
@mouseenter="${() => this._showHover = !0}"
|
|
78
|
+
@mouseleave="${() => this._showHover = !1}"
|
|
79
|
+
>
|
|
80
|
+
${this.hoverTimestamp && this.playerState?.src ? i`
|
|
81
|
+
<div
|
|
82
|
+
class="hover-tooltip ${this._showHover ? "show" : ""}"
|
|
83
|
+
style="left: ${this._hoverX}px;"
|
|
84
|
+
>
|
|
85
|
+
${t(this._hoverTime)}
|
|
86
|
+
</div>
|
|
87
|
+
` : ""}
|
|
88
|
+
<md-slider
|
|
37
89
|
part="slider"
|
|
38
90
|
aria-label="Playback progress"
|
|
39
91
|
min="0"
|
|
40
92
|
max="${e || 100}"
|
|
41
|
-
value="${
|
|
93
|
+
value="${r}"
|
|
42
94
|
step="0.1"
|
|
43
|
-
?disabled="${
|
|
95
|
+
?disabled="${n}"
|
|
44
96
|
@input="${this._handleInput}"
|
|
45
97
|
@change="${this._handleChange}"
|
|
46
|
-
|
|
98
|
+
></md-slider>
|
|
99
|
+
</div>
|
|
47
100
|
`;
|
|
48
101
|
}
|
|
102
|
+
_handleMouseMove(e) {
|
|
103
|
+
if (!this.hoverTimestamp || !this._sliderEl || !this.playerState?.duration) return;
|
|
104
|
+
let t = e.currentTarget.getBoundingClientRect(), n = e.clientX - t.left;
|
|
105
|
+
n = Math.max(0, Math.min(n, t.width)), this._hoverX = n, this._hoverTime = n / t.width * this.playerState.duration;
|
|
106
|
+
}
|
|
49
107
|
_handleInput(e) {
|
|
50
108
|
this._isDragging = !0, this._dragValue = e.target.value;
|
|
51
109
|
}
|
|
@@ -53,8 +111,8 @@ var s = function(e, t, n, r) {
|
|
|
53
111
|
this._dragValue = e.target.value, this.playerState && this.playerState.seek(this._dragValue), this._isDragging = !1;
|
|
54
112
|
}
|
|
55
113
|
};
|
|
56
|
-
|
|
114
|
+
u([l({
|
|
57
115
|
context: e,
|
|
58
116
|
subscribe: !0
|
|
59
|
-
}),
|
|
60
|
-
export {
|
|
117
|
+
}), o({ attribute: !1 })], d.prototype, "playerState", void 0), u([o({ type: Boolean })], d.prototype, "hoverTimestamp", void 0), u([c()], d.prototype, "_hoverX", void 0), u([c()], d.prototype, "_showHover", void 0), u([c()], d.prototype, "_hoverTime", void 0), u([s("md-slider")], d.prototype, "_sliderEl", void 0), d = u([a("ui-audio-progress-slider")], d);
|
|
118
|
+
export { d as UiAudioProgressSlider };
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { audioPlayerContext as e } from "../../utils/audio-context.js";
|
|
2
|
-
import {
|
|
2
|
+
import { formatAudioTime as t } from "../../utils/audio-utils.js";
|
|
3
3
|
import { LitElement as n, css as r, html as i } from "lit";
|
|
4
4
|
import { customElement as a, property as o } from "lit/decorators.js";
|
|
5
5
|
import { consume as s } from "@lit/context";
|
|
6
|
-
var c =
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
var c = function(e, t, n, r) {
|
|
7
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
8
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
9
|
+
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
10
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
11
|
+
}, l = class extends n {
|
|
12
|
+
constructor() {
|
|
13
|
+
super(...arguments), this.format = "combined", this.separator = " / ", this.compact = !1;
|
|
9
14
|
}
|
|
10
15
|
static {
|
|
11
16
|
this.styles = r`
|
|
@@ -27,13 +32,11 @@ var c = class extends n {
|
|
|
27
32
|
} else return i`${this._formatTime(e)}${this.separator}${t ? this._formatTime(t) : "--:--"}`;
|
|
28
33
|
}
|
|
29
34
|
_formatTime(e) {
|
|
30
|
-
|
|
31
|
-
let t = Math.floor(e / 3600), n = Math.floor(e % 3600 / 60), r = Math.floor(e % 60), i = "";
|
|
32
|
-
return t > 0 ? i += "" + t + ":" + (n < 10 ? "0" : "") : this.compact, i += "" + n + ":" + (r < 10 ? "0" : ""), i += "" + r, i;
|
|
35
|
+
return t(e);
|
|
33
36
|
}
|
|
34
37
|
};
|
|
35
|
-
|
|
38
|
+
c([s({
|
|
36
39
|
context: e,
|
|
37
40
|
subscribe: !0
|
|
38
|
-
}), o({ attribute: !1 })],
|
|
39
|
-
export {
|
|
41
|
+
}), o({ attribute: !1 })], l.prototype, "playerState", void 0), c([o({ type: String })], l.prototype, "format", void 0), c([o({ type: String })], l.prototype, "separator", void 0), c([o({ type: Boolean })], l.prototype, "compact", void 0), l = c([a("ui-audio-time-display")], l);
|
|
42
|
+
export { l as UiAudioTimeDisplay };
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { customElement as o, property as s, query as c } from "lit/decorators.js";
|
|
1
|
+
import { applyCanvasEdgeFade as e, getNormalizedFrequencyData as t } from "../../utils/audio-utils.js";
|
|
2
|
+
import { LitElement as n, css as r, html as i } from "lit";
|
|
3
|
+
import { customElement as a, property as o, query as s } from "lit/decorators.js";
|
|
5
4
|
/**
|
|
6
5
|
* Copyright 2026 Google LLC
|
|
7
6
|
*/
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
var c = function(e, t, n, r) {
|
|
8
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
9
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
10
|
+
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
11
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
12
|
+
}, l = class extends n {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments), this.active = !1, this.processing = !1, this.barWidth = 3, this.barHeight = 4, this.barGap = 1, this.barRadius = 1.5, this.fadeEdges = !0, this.fadeWidth = 24, this.height = 64, this.sensitivity = 1, this.updateRate = 30, this._animationFrameId = 0, this._lastUpdateTime = 0, this._currentBars = [], this._processingTime = 0, this._transitionProgress = 0, this._lastActiveData = [];
|
|
11
15
|
}
|
|
12
16
|
static {
|
|
13
|
-
this.styles =
|
|
17
|
+
this.styles = r`
|
|
14
18
|
:host {
|
|
15
19
|
display: block;
|
|
16
20
|
width: 100%;
|
|
@@ -30,7 +34,7 @@ var l = class extends r {
|
|
|
30
34
|
`;
|
|
31
35
|
}
|
|
32
36
|
render() {
|
|
33
|
-
return
|
|
37
|
+
return i`
|
|
34
38
|
<div class="container" style="height: ${this.height}px;">
|
|
35
39
|
<canvas></canvas>
|
|
36
40
|
</div>
|
|
@@ -67,11 +71,11 @@ var l = class extends r {
|
|
|
67
71
|
}
|
|
68
72
|
_updateData(e) {
|
|
69
73
|
if (!this._canvas) return;
|
|
70
|
-
let
|
|
74
|
+
let n = this._canvas.getBoundingClientRect(), r = Math.floor(n.width / (this.barWidth + this.barGap));
|
|
71
75
|
if (this.active && this.analyserNode && this._dataArray) {
|
|
72
76
|
if (e - this._lastUpdateTime > this.updateRate) {
|
|
73
77
|
this._lastUpdateTime = e;
|
|
74
|
-
let
|
|
78
|
+
let n = t(this.analyserNode, this._dataArray), i = Math.floor(n.length * .05), a = Math.floor(n.length * .4), o = n.slice(i, a), s = Math.floor(r / 2), c = Array(r).fill(.05), l = o.length - 1;
|
|
75
79
|
for (let e = 0; e <= s; e++) {
|
|
76
80
|
let t = e / s, n = o[Math.floor(t * l)] || 0;
|
|
77
81
|
t > .8 && (n *= 1 - (t - .8) * 5);
|
|
@@ -100,10 +104,10 @@ var l = class extends r {
|
|
|
100
104
|
}
|
|
101
105
|
_renderFrame() {
|
|
102
106
|
if (!this._canvas) return;
|
|
103
|
-
let
|
|
104
|
-
if (!
|
|
107
|
+
let t = this._canvas.getContext("2d");
|
|
108
|
+
if (!t) return;
|
|
105
109
|
let n = this._canvas.getBoundingClientRect();
|
|
106
|
-
|
|
110
|
+
t.clearRect(0, 0, n.width, n.height);
|
|
107
111
|
let r = getComputedStyle(this), i = this.barColor || "currentColor";
|
|
108
112
|
if (i.startsWith("var(")) {
|
|
109
113
|
let e = i.match(/var\(([^,)]+)/)?.[1].trim();
|
|
@@ -114,12 +118,12 @@ var l = class extends r {
|
|
|
114
118
|
}
|
|
115
119
|
(i === "currentColor" || !i) && (i = r.getPropertyValue("--md-sys-color-primary").trim() || "#0066cc");
|
|
116
120
|
let a = this.barWidth + this.barGap, o = Math.floor(n.width / a), s = n.height / 2;
|
|
117
|
-
for (let
|
|
118
|
-
let r = this._currentBars[
|
|
119
|
-
|
|
121
|
+
for (let e = 0; e < o && e < this._currentBars.length; e++) {
|
|
122
|
+
let r = this._currentBars[e] || .05, o = e * a, c = Math.max(this.barHeight, r * n.height * .8), l = s - c / 2;
|
|
123
|
+
t.fillStyle = i, t.globalAlpha = .6 + r * .4, this.barRadius > 0 ? (t.beginPath(), t.roundRect(o, l, this.barWidth, c, this.barRadius), t.fill()) : t.fillRect(o, l, this.barWidth, c);
|
|
120
124
|
}
|
|
121
|
-
this.fadeEdges && t
|
|
125
|
+
this.fadeEdges && e(t, n.width, n.height, this.fadeWidth), t.globalAlpha = 1;
|
|
122
126
|
}
|
|
123
127
|
};
|
|
124
|
-
|
|
128
|
+
c([o({ type: Boolean })], l.prototype, "active", void 0), c([o({ type: Boolean })], l.prototype, "processing", void 0), c([o({ attribute: !1 })], l.prototype, "analyserNode", void 0), c([o({ type: Number })], l.prototype, "barWidth", void 0), c([o({ type: Number })], l.prototype, "barHeight", void 0), c([o({ type: Number })], l.prototype, "barGap", void 0), c([o({ type: Number })], l.prototype, "barRadius", void 0), c([o({ type: String })], l.prototype, "barColor", void 0), c([o({ type: Boolean })], l.prototype, "fadeEdges", void 0), c([o({ type: Number })], l.prototype, "fadeWidth", void 0), c([o({ type: Number })], l.prototype, "height", void 0), c([o({ type: Number })], l.prototype, "sensitivity", void 0), c([o({ type: Number })], l.prototype, "updateRate", void 0), c([s("canvas")], l.prototype, "_canvas", void 0), c([s(".container")], l.prototype, "_container", void 0), l = c([a("ui-live-waveform")], l);
|
|
125
129
|
export { l as UiLiveWaveform };
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { audioPlayerContext as e } from "../../utils/audio-context.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { consume as l } from "@lit/context";
|
|
2
|
+
import { getNormalizedFrequencyData as t } from "../../utils/audio-utils.js";
|
|
3
|
+
import { LitElement as n, css as r, html as i } from "lit";
|
|
4
|
+
import { customElement as a, property as o, query as s } from "lit/decorators.js";
|
|
5
|
+
import { consume as c } from "@lit/context";
|
|
7
6
|
/**
|
|
8
7
|
* Copyright 2026 Google LLC
|
|
9
8
|
*
|
|
@@ -19,12 +18,17 @@ import { consume as l } from "@lit/context";
|
|
|
19
18
|
* See the License for the specific language governing permissions and
|
|
20
19
|
* limitations under the License.
|
|
21
20
|
*/
|
|
22
|
-
var
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
var l = function(e, t, n, r) {
|
|
22
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
23
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
24
|
+
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
25
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
26
|
+
}, u = class extends n {
|
|
27
|
+
constructor() {
|
|
28
|
+
super(...arguments), this.barWidth = 4, this.barGap = 2, this.height = 100, this._animationFrameId = 0;
|
|
25
29
|
}
|
|
26
30
|
static {
|
|
27
|
-
this.styles =
|
|
31
|
+
this.styles = r`
|
|
28
32
|
:host {
|
|
29
33
|
display: block;
|
|
30
34
|
width: 100%;
|
|
@@ -38,7 +42,7 @@ var u = class extends r {
|
|
|
38
42
|
`;
|
|
39
43
|
}
|
|
40
44
|
render() {
|
|
41
|
-
return
|
|
45
|
+
return i`<canvas style="height: ${this.height}px;"></canvas>`;
|
|
42
46
|
}
|
|
43
47
|
firstUpdated() {
|
|
44
48
|
this._startLoop();
|
|
@@ -56,20 +60,20 @@ var u = class extends r {
|
|
|
56
60
|
if (!this._canvas || !this.playerState?.analyserNode) return;
|
|
57
61
|
let e = this.playerState.analyserNode;
|
|
58
62
|
this._dataArray ||= new Uint8Array(e.frequencyBinCount);
|
|
59
|
-
let
|
|
60
|
-
if (!
|
|
63
|
+
let n = this._canvas.getContext("2d");
|
|
64
|
+
if (!n) return;
|
|
61
65
|
let r = this._canvas.getBoundingClientRect(), i = window.devicePixelRatio || 1;
|
|
62
|
-
this._canvas.width !== r.width * i && (this._canvas.width = r.width * i, this._canvas.height = r.height * i,
|
|
63
|
-
let a =
|
|
64
|
-
l ||= c.getPropertyValue("--md-sys-color-primary").trim() || "#0066cc",
|
|
66
|
+
this._canvas.width !== r.width * i && (this._canvas.width = r.width * i, this._canvas.height = r.height * i, n.scale(i, i)), n.clearRect(0, 0, r.width, r.height);
|
|
67
|
+
let a = t(e, this._dataArray), o = this.barWidth + this.barGap, s = Math.floor(r.width / o), c = getComputedStyle(this), l = this.color;
|
|
68
|
+
l ||= c.getPropertyValue("--md-sys-color-primary").trim() || "#0066cc", n.fillStyle = l;
|
|
65
69
|
for (let e = 0; e < s; e++) {
|
|
66
|
-
let
|
|
67
|
-
|
|
70
|
+
let t = (a[Math.floor(e / s * (a.length * .6))] || 0) * r.height, i = e * o, c = r.height - t;
|
|
71
|
+
n.fillRect(i, c, this.barWidth, t);
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
};
|
|
71
|
-
|
|
75
|
+
l([c({
|
|
72
76
|
context: e,
|
|
73
77
|
subscribe: !0
|
|
74
|
-
})], u.prototype, "playerState", void 0),
|
|
78
|
+
})], u.prototype, "playerState", void 0), l([o({ type: Number })], u.prototype, "barWidth", void 0), l([o({ type: Number })], u.prototype, "barGap", void 0), l([o({ type: Number })], u.prototype, "height", void 0), l([o({ type: String })], u.prototype, "color", void 0), l([s("canvas")], u.prototype, "_canvas", void 0), u = l([a("ui-spectrum-visualizer")], u);
|
|
75
79
|
export { u as UiSpectrumVisualizer };
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { __decorate as e } from "../../_virtual/_@oxc-project_runtime@0.113.0/helpers/decorate.js";
|
|
2
1
|
import "../atoms/ui-audio-play-button.js";
|
|
3
2
|
import "../atoms/ui-audio-progress-slider.js";
|
|
4
3
|
import "../atoms/ui-audio-time-display.js";
|
|
5
4
|
import "../atoms/ui-audio-player-error.js";
|
|
6
5
|
import "../providers/ui-audio-provider.js";
|
|
7
|
-
import { LitElement as
|
|
8
|
-
import { customElement as
|
|
9
|
-
var
|
|
6
|
+
import { LitElement as e, css as t, html as n } from "lit";
|
|
7
|
+
import { customElement as r, property as i } from "lit/decorators.js";
|
|
8
|
+
var a = function(e, t, n, r) {
|
|
9
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
10
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
11
|
+
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
12
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
13
|
+
}, o = class extends e {
|
|
10
14
|
static {
|
|
11
|
-
this.styles =
|
|
15
|
+
this.styles = t`
|
|
12
16
|
:host {
|
|
13
17
|
display: inline-block;
|
|
14
18
|
width: 100%;
|
|
@@ -38,7 +42,7 @@ var o = class extends t {
|
|
|
38
42
|
`;
|
|
39
43
|
}
|
|
40
44
|
render() {
|
|
41
|
-
return
|
|
45
|
+
return n`
|
|
42
46
|
<ui-audio-provider .src="${this.item?.src || ""}">
|
|
43
47
|
<div class="player-pill" part="container">
|
|
44
48
|
<!-- Atomic Play/Pause Button -->
|
|
@@ -61,5 +65,5 @@ var o = class extends t {
|
|
|
61
65
|
`;
|
|
62
66
|
}
|
|
63
67
|
};
|
|
64
|
-
|
|
68
|
+
a([i({ type: Object })], o.prototype, "item", void 0), o = a([r("ui-audio-player")], o);
|
|
65
69
|
export { o as UiAudioPlayer };
|