lrc-audio-player 0.1.4 → 0.1.5

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/react.cjs CHANGED
@@ -402,9 +402,13 @@ function useLyricPlayer(options) {
402
402
  const [player, setPlayer] = (0, import_react.useState)(null);
403
403
  const [currentLine, setCurrentLine] = (0, import_react.useState)(null);
404
404
  const [currentIndex, setCurrentIndex] = (0, import_react.useState)(-1);
405
+ const [currentToken, setCurrentToken] = (0, import_react.useState)(null);
405
406
  const [lines, setLines] = (0, import_react.useState)([]);
406
407
  const [isLoading, setIsLoading] = (0, import_react.useState)(false);
407
408
  const [error, setError] = (0, import_react.useState)(null);
409
+ const [isPlaying, setIsPlaying] = (0, import_react.useState)(false);
410
+ const [currentTime, setCurrentTime] = (0, import_react.useState)(0);
411
+ const [duration, setDuration] = (0, import_react.useState)(0);
408
412
  const optionsRef = (0, import_react.useRef)(options);
409
413
  optionsRef.current = options;
410
414
  (0, import_react.useEffect)(() => {
@@ -419,6 +423,10 @@ function useLyricPlayer(options) {
419
423
  setLines([]);
420
424
  setCurrentLine(null);
421
425
  setCurrentIndex(-1);
426
+ setCurrentToken(null);
427
+ setIsPlaying(false);
428
+ setCurrentTime(0);
429
+ setDuration(0);
422
430
  LyricPlayer.create({
423
431
  audio: audioEl,
424
432
  lyrics,
@@ -432,11 +440,19 @@ function useLyricPlayer(options) {
432
440
  }
433
441
  setPlayer(instance);
434
442
  setLines(instance.lines);
443
+ setDuration(instance.duration);
435
444
  setIsLoading(false);
436
445
  instance.on("linechange", (line, index) => {
437
446
  setCurrentLine(line);
438
447
  setCurrentIndex(index);
439
448
  });
449
+ instance.on("timeupdate", (time) => {
450
+ setCurrentTime(time);
451
+ setCurrentToken(instance.getCurrentToken());
452
+ });
453
+ instance.on("play", () => setIsPlaying(true));
454
+ instance.on("pause", () => setIsPlaying(false));
455
+ instance.on("ended", () => setIsPlaying(false));
440
456
  }).catch((err) => {
441
457
  if (!cancelled) {
442
458
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -457,14 +473,44 @@ function useLyricPlayer(options) {
457
473
  options.skipCBR,
458
474
  options.cbrBitrate
459
475
  ]);
476
+ const seek = (0, import_react.useCallback)(
477
+ (timeSeconds) => {
478
+ player?.seek(timeSeconds);
479
+ },
480
+ [player]
481
+ );
482
+ const seekToLine = (0, import_react.useCallback)(
483
+ (index) => {
484
+ player?.seekToLine(index);
485
+ },
486
+ [player]
487
+ );
488
+ const play = (0, import_react.useCallback)(() => {
489
+ return player?.play() ?? Promise.resolve();
490
+ }, [player]);
491
+ const pause = (0, import_react.useCallback)(() => {
492
+ player?.pause();
493
+ }, [player]);
494
+ const toggle = (0, import_react.useCallback)(() => {
495
+ return player?.toggle();
496
+ }, [player]);
460
497
  return {
461
498
  player,
462
499
  audioRef,
463
500
  currentLine,
464
501
  currentIndex,
502
+ currentToken,
465
503
  lines,
466
504
  isLoading,
467
- error
505
+ error,
506
+ isPlaying,
507
+ currentTime,
508
+ duration,
509
+ seek,
510
+ seekToLine,
511
+ play,
512
+ pause,
513
+ toggle
468
514
  };
469
515
  }
470
516
  // Annotate the CommonJS export names for ESM import in node:
package/dist/react.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { h as LyricPlayerOptions, b as LyricPlayer, L as LyricLine } from './player-sLsiwLVO.cjs';
1
+ import { h as LyricPlayerOptions, b as LyricPlayer, L as LyricLine, g as LyricToken } from './player-sLsiwLVO.cjs';
2
2
  export { f as LyricSource } from './player-sLsiwLVO.cjs';
3
3
 
4
4
  interface UseLyricPlayerOptions extends Omit<LyricPlayerOptions, "audio"> {
@@ -18,12 +18,30 @@ interface UseLyricPlayerResult {
18
18
  currentLine: LyricLine | null;
19
19
  /** Index of the currently active lyric line (-1 if none yet). */
20
20
  currentIndex: number;
21
+ /** The currently active word/token (for word-level LRC), or null. */
22
+ currentToken: LyricToken | null;
21
23
  /** All parsed lyric lines (empty until lyrics are loaded). */
22
24
  lines: LyricLine[];
23
25
  /** Whether the player is initializing (CBR conversion in progress). */
24
26
  isLoading: boolean;
25
27
  /** Error if initialization failed. */
26
28
  error: Error | null;
29
+ /** Whether audio is currently playing. */
30
+ isPlaying: boolean;
31
+ /** Current playback time in seconds. */
32
+ currentTime: number;
33
+ /** Total audio duration in seconds (0 if unknown). */
34
+ duration: number;
35
+ /** Jump to a specific time in seconds. */
36
+ seek: (timeSeconds: number) => void;
37
+ /** Jump to the start of a specific lyric line. */
38
+ seekToLine: (index: number) => void;
39
+ /** Play the audio. */
40
+ play: () => Promise<void>;
41
+ /** Pause the audio. */
42
+ pause: () => void;
43
+ /** Toggle play/pause. */
44
+ toggle: () => Promise<void> | void;
27
45
  }
28
46
  /**
29
47
  * React hook that creates a {@link LyricPlayer} bound to an `<audio>`
@@ -36,7 +54,7 @@ interface UseLyricPlayerResult {
36
54
  * ```tsx
37
55
  * 'use client';
38
56
  *
39
- * const { audioRef, currentLine, lines, player, isLoading } = useLyricPlayer({
57
+ * const { audioRef, currentLine, lines, isLoading, isPlaying, currentTime } = useLyricPlayer({
40
58
  * audio: '/song.mp3',
41
59
  * lyrics: lrcText,
42
60
  * });
package/dist/react.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { h as LyricPlayerOptions, b as LyricPlayer, L as LyricLine } from './player-sLsiwLVO.js';
1
+ import { h as LyricPlayerOptions, b as LyricPlayer, L as LyricLine, g as LyricToken } from './player-sLsiwLVO.js';
2
2
  export { f as LyricSource } from './player-sLsiwLVO.js';
3
3
 
4
4
  interface UseLyricPlayerOptions extends Omit<LyricPlayerOptions, "audio"> {
@@ -18,12 +18,30 @@ interface UseLyricPlayerResult {
18
18
  currentLine: LyricLine | null;
19
19
  /** Index of the currently active lyric line (-1 if none yet). */
20
20
  currentIndex: number;
21
+ /** The currently active word/token (for word-level LRC), or null. */
22
+ currentToken: LyricToken | null;
21
23
  /** All parsed lyric lines (empty until lyrics are loaded). */
22
24
  lines: LyricLine[];
23
25
  /** Whether the player is initializing (CBR conversion in progress). */
24
26
  isLoading: boolean;
25
27
  /** Error if initialization failed. */
26
28
  error: Error | null;
29
+ /** Whether audio is currently playing. */
30
+ isPlaying: boolean;
31
+ /** Current playback time in seconds. */
32
+ currentTime: number;
33
+ /** Total audio duration in seconds (0 if unknown). */
34
+ duration: number;
35
+ /** Jump to a specific time in seconds. */
36
+ seek: (timeSeconds: number) => void;
37
+ /** Jump to the start of a specific lyric line. */
38
+ seekToLine: (index: number) => void;
39
+ /** Play the audio. */
40
+ play: () => Promise<void>;
41
+ /** Pause the audio. */
42
+ pause: () => void;
43
+ /** Toggle play/pause. */
44
+ toggle: () => Promise<void> | void;
27
45
  }
28
46
  /**
29
47
  * React hook that creates a {@link LyricPlayer} bound to an `<audio>`
@@ -36,7 +54,7 @@ interface UseLyricPlayerResult {
36
54
  * ```tsx
37
55
  * 'use client';
38
56
  *
39
- * const { audioRef, currentLine, lines, player, isLoading } = useLyricPlayer({
57
+ * const { audioRef, currentLine, lines, isLoading, isPlaying, currentTime } = useLyricPlayer({
40
58
  * audio: '/song.mp3',
41
59
  * lyrics: lrcText,
42
60
  * });
package/dist/react.js CHANGED
@@ -4,15 +4,19 @@ import {
4
4
  } from "./chunk-3A2M5KTA.js";
5
5
 
6
6
  // src/react.ts
7
- import { useEffect, useRef, useState } from "react";
7
+ import { useEffect, useRef, useState, useCallback } from "react";
8
8
  function useLyricPlayer(options) {
9
9
  const audioRef = useRef(null);
10
10
  const [player, setPlayer] = useState(null);
11
11
  const [currentLine, setCurrentLine] = useState(null);
12
12
  const [currentIndex, setCurrentIndex] = useState(-1);
13
+ const [currentToken, setCurrentToken] = useState(null);
13
14
  const [lines, setLines] = useState([]);
14
15
  const [isLoading, setIsLoading] = useState(false);
15
16
  const [error, setError] = useState(null);
17
+ const [isPlaying, setIsPlaying] = useState(false);
18
+ const [currentTime, setCurrentTime] = useState(0);
19
+ const [duration, setDuration] = useState(0);
16
20
  const optionsRef = useRef(options);
17
21
  optionsRef.current = options;
18
22
  useEffect(() => {
@@ -27,6 +31,10 @@ function useLyricPlayer(options) {
27
31
  setLines([]);
28
32
  setCurrentLine(null);
29
33
  setCurrentIndex(-1);
34
+ setCurrentToken(null);
35
+ setIsPlaying(false);
36
+ setCurrentTime(0);
37
+ setDuration(0);
30
38
  LyricPlayer.create({
31
39
  audio: audioEl,
32
40
  lyrics,
@@ -40,11 +48,19 @@ function useLyricPlayer(options) {
40
48
  }
41
49
  setPlayer(instance);
42
50
  setLines(instance.lines);
51
+ setDuration(instance.duration);
43
52
  setIsLoading(false);
44
53
  instance.on("linechange", (line, index) => {
45
54
  setCurrentLine(line);
46
55
  setCurrentIndex(index);
47
56
  });
57
+ instance.on("timeupdate", (time) => {
58
+ setCurrentTime(time);
59
+ setCurrentToken(instance.getCurrentToken());
60
+ });
61
+ instance.on("play", () => setIsPlaying(true));
62
+ instance.on("pause", () => setIsPlaying(false));
63
+ instance.on("ended", () => setIsPlaying(false));
48
64
  }).catch((err) => {
49
65
  if (!cancelled) {
50
66
  setError(err instanceof Error ? err : new Error(String(err)));
@@ -65,14 +81,44 @@ function useLyricPlayer(options) {
65
81
  options.skipCBR,
66
82
  options.cbrBitrate
67
83
  ]);
84
+ const seek = useCallback(
85
+ (timeSeconds) => {
86
+ player?.seek(timeSeconds);
87
+ },
88
+ [player]
89
+ );
90
+ const seekToLine = useCallback(
91
+ (index) => {
92
+ player?.seekToLine(index);
93
+ },
94
+ [player]
95
+ );
96
+ const play = useCallback(() => {
97
+ return player?.play() ?? Promise.resolve();
98
+ }, [player]);
99
+ const pause = useCallback(() => {
100
+ player?.pause();
101
+ }, [player]);
102
+ const toggle = useCallback(() => {
103
+ return player?.toggle();
104
+ }, [player]);
68
105
  return {
69
106
  player,
70
107
  audioRef,
71
108
  currentLine,
72
109
  currentIndex,
110
+ currentToken,
73
111
  lines,
74
112
  isLoading,
75
- error
113
+ error,
114
+ isPlaying,
115
+ currentTime,
116
+ duration,
117
+ seek,
118
+ seekToLine,
119
+ play,
120
+ pause,
121
+ toggle
76
122
  };
77
123
  }
78
124
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lrc-audio-player",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Sync LRC/word-level lyrics to an HTML audio element with one constructor. Includes an optional React hook at lrc-audio-player/react.",
5
5
  "repository": {
6
6
  "type": "git",