@wq-hook/volcano-react 1.0.6 → 1.0.7

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/dist/index.d.mts CHANGED
@@ -247,8 +247,12 @@ interface UseMessageTTSReturn {
247
247
  isSynthesizing: boolean;
248
248
  /** 错误信息 */
249
249
  error: string | null;
250
- /** 播放进度(0-1) */
250
+ /** 播放进度(0-100) */
251
251
  progress: number;
252
+ /** 当前播放时间(秒) */
253
+ currentTime: number;
254
+ /** 音频总时长(秒) */
255
+ duration: number;
252
256
  /** 播放文本方法 */
253
257
  play: (text: string) => Promise<void>;
254
258
  /** 暂停播放方法 */
@@ -348,6 +352,10 @@ interface UseStreamTTSReturn {
348
352
  streamText: string;
349
353
  /** 播放进度(0-100) */
350
354
  progress: number;
355
+ /** 当前播放时间(秒) */
356
+ currentTime: number;
357
+ /** 音频总时长(秒) */
358
+ duration: number;
351
359
  /** 建立 WebSocket 连接 */
352
360
  connect: () => Promise<string>;
353
361
  /** 接收流式文本块 */
@@ -395,6 +403,10 @@ interface StreamPlaybackState {
395
403
  isPaused: boolean;
396
404
  isSynthesizing: boolean;
397
405
  progress: number;
406
+ /** 当前播放时间(秒) */
407
+ currentTime: number;
408
+ /** 音频总时长(秒) */
409
+ duration: number;
398
410
  visualizationData: VisualizationData;
399
411
  error: string | null;
400
412
  isConnected: boolean;
@@ -693,6 +705,10 @@ declare const AudioWaveVisualizer: React$1.FC<AudioWaveVisualizerProps>;
693
705
  interface AudioProgressBarProps {
694
706
  /** 播放进度(0-100) */
695
707
  progress: number;
708
+ /** 当前播放时间(秒),传入后将显示时间格式 */
709
+ currentTime?: number;
710
+ /** 音频总时长(秒),传入后将显示时间格式 */
711
+ duration?: number;
696
712
  /** 宽度(px 或百分比) */
697
713
  width?: number | string;
698
714
  /** 高度(px) */
package/dist/index.d.ts CHANGED
@@ -247,8 +247,12 @@ interface UseMessageTTSReturn {
247
247
  isSynthesizing: boolean;
248
248
  /** 错误信息 */
249
249
  error: string | null;
250
- /** 播放进度(0-1) */
250
+ /** 播放进度(0-100) */
251
251
  progress: number;
252
+ /** 当前播放时间(秒) */
253
+ currentTime: number;
254
+ /** 音频总时长(秒) */
255
+ duration: number;
252
256
  /** 播放文本方法 */
253
257
  play: (text: string) => Promise<void>;
254
258
  /** 暂停播放方法 */
@@ -348,6 +352,10 @@ interface UseStreamTTSReturn {
348
352
  streamText: string;
349
353
  /** 播放进度(0-100) */
350
354
  progress: number;
355
+ /** 当前播放时间(秒) */
356
+ currentTime: number;
357
+ /** 音频总时长(秒) */
358
+ duration: number;
351
359
  /** 建立 WebSocket 连接 */
352
360
  connect: () => Promise<string>;
353
361
  /** 接收流式文本块 */
@@ -395,6 +403,10 @@ interface StreamPlaybackState {
395
403
  isPaused: boolean;
396
404
  isSynthesizing: boolean;
397
405
  progress: number;
406
+ /** 当前播放时间(秒) */
407
+ currentTime: number;
408
+ /** 音频总时长(秒) */
409
+ duration: number;
398
410
  visualizationData: VisualizationData;
399
411
  error: string | null;
400
412
  isConnected: boolean;
@@ -693,6 +705,10 @@ declare const AudioWaveVisualizer: React$1.FC<AudioWaveVisualizerProps>;
693
705
  interface AudioProgressBarProps {
694
706
  /** 播放进度(0-100) */
695
707
  progress: number;
708
+ /** 当前播放时间(秒),传入后将显示时间格式 */
709
+ currentTime?: number;
710
+ /** 音频总时长(秒),传入后将显示时间格式 */
711
+ duration?: number;
696
712
  /** 宽度(px 或百分比) */
697
713
  width?: number | string;
698
714
  /** 高度(px) */
package/dist/index.js CHANGED
@@ -804,6 +804,8 @@ var PlaybackSession = class {
804
804
  isPaused: false,
805
805
  isSynthesizing: false,
806
806
  progress: 0,
807
+ currentTime: 0,
808
+ duration: 0,
807
809
  visualizationData: {
808
810
  frequencyData: new Uint8Array(0),
809
811
  timeDomainData: new Uint8Array(0)
@@ -907,7 +909,11 @@ var PlaybackSession = class {
907
909
  }
908
910
  if (isFinite(duration) && duration > 0) {
909
911
  const progress = this.audio.currentTime / duration * 100;
910
- this.updateState({ progress });
912
+ this.updateState({
913
+ progress,
914
+ currentTime: this.audio.currentTime,
915
+ duration
916
+ });
911
917
  }
912
918
  };
913
919
  }
@@ -1429,6 +1435,8 @@ function useMessageTTS({
1429
1435
  isPaused: false,
1430
1436
  isSynthesizing: false,
1431
1437
  progress: 0,
1438
+ currentTime: 0,
1439
+ duration: 0,
1432
1440
  visualizationData: {
1433
1441
  frequencyData: new Uint8Array(0),
1434
1442
  timeDomainData: new Uint8Array(0)
@@ -1679,6 +1687,8 @@ function useMessageTTS({
1679
1687
  isPaused: state.isPaused,
1680
1688
  isSynthesizing: state.isSynthesizing,
1681
1689
  progress: state.progress,
1690
+ currentTime: state.currentTime,
1691
+ duration: state.duration,
1682
1692
  error,
1683
1693
  play,
1684
1694
  pause,
@@ -1717,6 +1727,8 @@ function useStreamTTS({
1717
1727
  isPaused: false,
1718
1728
  isSynthesizing: false,
1719
1729
  progress: 0,
1730
+ currentTime: 0,
1731
+ duration: 0,
1720
1732
  visualizationData: {
1721
1733
  frequencyData: new Uint8Array(0),
1722
1734
  timeDomainData: new Uint8Array(0)
@@ -1835,6 +1847,8 @@ function useStreamTTS({
1835
1847
  error: state.error,
1836
1848
  streamText,
1837
1849
  progress: state.progress,
1850
+ currentTime: state.currentTime,
1851
+ duration: state.duration,
1838
1852
  connect,
1839
1853
  onMessage,
1840
1854
  finishStream,
@@ -2017,8 +2031,20 @@ var AudioWaveVisualizer_default = AudioWaveVisualizer;
2017
2031
  // src/components/AudioProgressBar.tsx
2018
2032
  var import_react6 = require("react");
2019
2033
  var import_jsx_runtime2 = require("react/jsx-runtime");
2034
+ var formatTime = (seconds) => {
2035
+ if (!isFinite(seconds) || seconds < 0) return "0:00";
2036
+ const hours = Math.floor(seconds / 3600);
2037
+ const minutes = Math.floor(seconds % 3600 / 60);
2038
+ const secs = Math.floor(seconds % 60);
2039
+ if (hours > 0) {
2040
+ return `${hours}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
2041
+ }
2042
+ return `${minutes}:${secs.toString().padStart(2, "0")}`;
2043
+ };
2020
2044
  var AudioProgressBar = ({
2021
2045
  progress,
2046
+ currentTime,
2047
+ duration,
2022
2048
  width = "100%",
2023
2049
  height = 6,
2024
2050
  color = "#8b5cf6",
@@ -2037,6 +2063,16 @@ var AudioProgressBar = ({
2037
2063
  const isDragging = (0, import_react6.useRef)(false);
2038
2064
  const isHovering = (0, import_react6.useRef)(false);
2039
2065
  const isTouch = (0, import_react6.useRef)(false);
2066
+ const useTimeFormat = (0, import_react6.useMemo)(() => {
2067
+ return currentTime !== void 0 && duration !== void 0 && isFinite(currentTime) && isFinite(duration) && duration > 0;
2068
+ }, [currentTime, duration]);
2069
+ const getDisplayText = (percentage) => {
2070
+ if (useTimeFormat && currentTime !== void 0 && duration !== void 0) {
2071
+ const timeFromPercentage = percentage / 100 * duration;
2072
+ return `${formatTime(timeFromPercentage)} / ${formatTime(duration)}`;
2073
+ }
2074
+ return `${Math.round(percentage)}%`;
2075
+ };
2040
2076
  (0, import_react6.useEffect)(() => {
2041
2077
  const match = window.matchMedia("(pointer: coarse)");
2042
2078
  isTouch.current = match.matches;
@@ -2067,9 +2103,9 @@ var AudioProgressBar = ({
2067
2103
  thumbRef.current.style.left = `${next}%`;
2068
2104
  }
2069
2105
  if (showText && progressTextRef.current) {
2070
- const rounded = Math.round(next);
2071
- if (progressTextRef.current.textContent !== `${rounded}%`) {
2072
- progressTextRef.current.textContent = `${rounded}%`;
2106
+ const newText = getDisplayText(next);
2107
+ if (progressTextRef.current.textContent !== newText) {
2108
+ progressTextRef.current.textContent = newText;
2073
2109
  }
2074
2110
  }
2075
2111
  if (Math.abs(target - next) >= 0.1) {
@@ -2083,7 +2119,7 @@ var AudioProgressBar = ({
2083
2119
  cancelAnimationFrame(requestRef.current);
2084
2120
  }
2085
2121
  };
2086
- }, [progress, showText]);
2122
+ }, [progress, showText, currentTime, duration]);
2087
2123
  const calculateProgress = (clientX) => {
2088
2124
  if (!containerRef.current) return 0;
2089
2125
  const rect = containerRef.current.getBoundingClientRect();
@@ -2101,9 +2137,9 @@ var AudioProgressBar = ({
2101
2137
  thumbRef.current.style.left = `${percentage}%`;
2102
2138
  }
2103
2139
  if (showText && progressTextRef.current) {
2104
- const rounded = Math.round(percentage);
2105
- if (progressTextRef.current.textContent !== `${rounded}%`) {
2106
- progressTextRef.current.textContent = `${rounded}%`;
2140
+ const newText = getDisplayText(percentage);
2141
+ if (progressTextRef.current.textContent !== newText) {
2142
+ progressTextRef.current.textContent = newText;
2107
2143
  }
2108
2144
  }
2109
2145
  };
@@ -2236,22 +2272,19 @@ var AudioProgressBar = ({
2236
2272
  ]
2237
2273
  }
2238
2274
  ),
2239
- showText && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2275
+ showText && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2240
2276
  "span",
2241
2277
  {
2242
2278
  ref: progressTextRef,
2243
2279
  style: {
2244
2280
  fontSize: "12px",
2245
2281
  color: textColor,
2246
- minWidth: "32px",
2282
+ minWidth: useTimeFormat ? "80px" : "32px",
2247
2283
  textAlign: "right",
2248
2284
  fontFamily: "monospace",
2249
2285
  lineHeight: 1
2250
2286
  },
2251
- children: [
2252
- Math.round(displayedProgress.current),
2253
- "%"
2254
- ]
2287
+ children: getDisplayText(displayedProgress.current)
2255
2288
  }
2256
2289
  )
2257
2290
  ]
package/dist/index.mjs CHANGED
@@ -760,6 +760,8 @@ var PlaybackSession = class {
760
760
  isPaused: false,
761
761
  isSynthesizing: false,
762
762
  progress: 0,
763
+ currentTime: 0,
764
+ duration: 0,
763
765
  visualizationData: {
764
766
  frequencyData: new Uint8Array(0),
765
767
  timeDomainData: new Uint8Array(0)
@@ -863,7 +865,11 @@ var PlaybackSession = class {
863
865
  }
864
866
  if (isFinite(duration) && duration > 0) {
865
867
  const progress = this.audio.currentTime / duration * 100;
866
- this.updateState({ progress });
868
+ this.updateState({
869
+ progress,
870
+ currentTime: this.audio.currentTime,
871
+ duration
872
+ });
867
873
  }
868
874
  };
869
875
  }
@@ -1385,6 +1391,8 @@ function useMessageTTS({
1385
1391
  isPaused: false,
1386
1392
  isSynthesizing: false,
1387
1393
  progress: 0,
1394
+ currentTime: 0,
1395
+ duration: 0,
1388
1396
  visualizationData: {
1389
1397
  frequencyData: new Uint8Array(0),
1390
1398
  timeDomainData: new Uint8Array(0)
@@ -1635,6 +1643,8 @@ function useMessageTTS({
1635
1643
  isPaused: state.isPaused,
1636
1644
  isSynthesizing: state.isSynthesizing,
1637
1645
  progress: state.progress,
1646
+ currentTime: state.currentTime,
1647
+ duration: state.duration,
1638
1648
  error,
1639
1649
  play,
1640
1650
  pause,
@@ -1673,6 +1683,8 @@ function useStreamTTS({
1673
1683
  isPaused: false,
1674
1684
  isSynthesizing: false,
1675
1685
  progress: 0,
1686
+ currentTime: 0,
1687
+ duration: 0,
1676
1688
  visualizationData: {
1677
1689
  frequencyData: new Uint8Array(0),
1678
1690
  timeDomainData: new Uint8Array(0)
@@ -1791,6 +1803,8 @@ function useStreamTTS({
1791
1803
  error: state.error,
1792
1804
  streamText,
1793
1805
  progress: state.progress,
1806
+ currentTime: state.currentTime,
1807
+ duration: state.duration,
1794
1808
  connect,
1795
1809
  onMessage,
1796
1810
  finishStream,
@@ -1971,10 +1985,22 @@ var AudioWaveVisualizer = ({
1971
1985
  var AudioWaveVisualizer_default = AudioWaveVisualizer;
1972
1986
 
1973
1987
  // src/components/AudioProgressBar.tsx
1974
- import { useEffect as useEffect5, useRef as useRef6 } from "react";
1988
+ import { useEffect as useEffect5, useRef as useRef6, useMemo } from "react";
1975
1989
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
1990
+ var formatTime = (seconds) => {
1991
+ if (!isFinite(seconds) || seconds < 0) return "0:00";
1992
+ const hours = Math.floor(seconds / 3600);
1993
+ const minutes = Math.floor(seconds % 3600 / 60);
1994
+ const secs = Math.floor(seconds % 60);
1995
+ if (hours > 0) {
1996
+ return `${hours}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
1997
+ }
1998
+ return `${minutes}:${secs.toString().padStart(2, "0")}`;
1999
+ };
1976
2000
  var AudioProgressBar = ({
1977
2001
  progress,
2002
+ currentTime,
2003
+ duration,
1978
2004
  width = "100%",
1979
2005
  height = 6,
1980
2006
  color = "#8b5cf6",
@@ -1993,6 +2019,16 @@ var AudioProgressBar = ({
1993
2019
  const isDragging = useRef6(false);
1994
2020
  const isHovering = useRef6(false);
1995
2021
  const isTouch = useRef6(false);
2022
+ const useTimeFormat = useMemo(() => {
2023
+ return currentTime !== void 0 && duration !== void 0 && isFinite(currentTime) && isFinite(duration) && duration > 0;
2024
+ }, [currentTime, duration]);
2025
+ const getDisplayText = (percentage) => {
2026
+ if (useTimeFormat && currentTime !== void 0 && duration !== void 0) {
2027
+ const timeFromPercentage = percentage / 100 * duration;
2028
+ return `${formatTime(timeFromPercentage)} / ${formatTime(duration)}`;
2029
+ }
2030
+ return `${Math.round(percentage)}%`;
2031
+ };
1996
2032
  useEffect5(() => {
1997
2033
  const match = window.matchMedia("(pointer: coarse)");
1998
2034
  isTouch.current = match.matches;
@@ -2023,9 +2059,9 @@ var AudioProgressBar = ({
2023
2059
  thumbRef.current.style.left = `${next}%`;
2024
2060
  }
2025
2061
  if (showText && progressTextRef.current) {
2026
- const rounded = Math.round(next);
2027
- if (progressTextRef.current.textContent !== `${rounded}%`) {
2028
- progressTextRef.current.textContent = `${rounded}%`;
2062
+ const newText = getDisplayText(next);
2063
+ if (progressTextRef.current.textContent !== newText) {
2064
+ progressTextRef.current.textContent = newText;
2029
2065
  }
2030
2066
  }
2031
2067
  if (Math.abs(target - next) >= 0.1) {
@@ -2039,7 +2075,7 @@ var AudioProgressBar = ({
2039
2075
  cancelAnimationFrame(requestRef.current);
2040
2076
  }
2041
2077
  };
2042
- }, [progress, showText]);
2078
+ }, [progress, showText, currentTime, duration]);
2043
2079
  const calculateProgress = (clientX) => {
2044
2080
  if (!containerRef.current) return 0;
2045
2081
  const rect = containerRef.current.getBoundingClientRect();
@@ -2057,9 +2093,9 @@ var AudioProgressBar = ({
2057
2093
  thumbRef.current.style.left = `${percentage}%`;
2058
2094
  }
2059
2095
  if (showText && progressTextRef.current) {
2060
- const rounded = Math.round(percentage);
2061
- if (progressTextRef.current.textContent !== `${rounded}%`) {
2062
- progressTextRef.current.textContent = `${rounded}%`;
2096
+ const newText = getDisplayText(percentage);
2097
+ if (progressTextRef.current.textContent !== newText) {
2098
+ progressTextRef.current.textContent = newText;
2063
2099
  }
2064
2100
  }
2065
2101
  };
@@ -2192,22 +2228,19 @@ var AudioProgressBar = ({
2192
2228
  ]
2193
2229
  }
2194
2230
  ),
2195
- showText && /* @__PURE__ */ jsxs(
2231
+ showText && /* @__PURE__ */ jsx2(
2196
2232
  "span",
2197
2233
  {
2198
2234
  ref: progressTextRef,
2199
2235
  style: {
2200
2236
  fontSize: "12px",
2201
2237
  color: textColor,
2202
- minWidth: "32px",
2238
+ minWidth: useTimeFormat ? "80px" : "32px",
2203
2239
  textAlign: "right",
2204
2240
  fontFamily: "monospace",
2205
2241
  lineHeight: 1
2206
2242
  },
2207
- children: [
2208
- Math.round(displayedProgress.current),
2209
- "%"
2210
- ]
2243
+ children: getDisplayText(displayedProgress.current)
2211
2244
  }
2212
2245
  )
2213
2246
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wq-hook/volcano-react",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Volcano Engine ASR & TTS React Hooks",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",