"use client"; import { useRef, useState, useEffect, useContext } from "react"; import { query } from "@/lib/actions/lyrics"; import { DanmuContext } from "./provider"; const useLyricsRunner = (runner: (lyric: string) => void, interval: number) => { const [lyrics, setLyrics] = useState([]); const [offset, setOffset] = useState(0); const timerRef = useRef | null>(null); const startTime = useRef(Date.now()); const ref = useRef<{ lyrics: string[]; offset: number }>({ lyrics, offset }); const clearTimer = (): void => { if (timerRef.current) { clearInterval(timerRef.current); } }; const doLyric = (): void => { console.log("testing ...", ref.current.lyrics.length); if (ref.current.lyrics.length > 0) { const currentTime = Date.now() - startTime.current; const found = ref.current.lyrics.find((lyric) => { const m = Number(lyric.slice(1, 3)); const s = Number(lyric.slice(4, 6)); const ms10 = Number(lyric.slice(7, 9)); const ms = (m * 60 + s) * 1000 + ms10 * 10; return ( currentTime > ms + ref.current.offset && ms + ref.current.offset > currentTime - interval ); }); if (found) { runner(found); } } }; useEffect(() => { ref.current.offset = offset; ref.current.lyrics = lyrics; }, [offset, lyrics]); const start = (): void => { clearTimer(); startTime.current = Date.now(); timerRef.current = setInterval(doLyric, interval); }; const pause = (): void => { clearTimer(); }; const resume = (): void => { clearTimer(); timerRef.current = setInterval(doLyric, interval); }; return { offset, setOffset, setLyrics, resume, start, pause, }; }; interface LyricItem { timestamp: string; content: string; } export default function Controls(): JSX.Element { const ref = useRef(null); const [history, setHistory] = useState([]); const { songId, songName, songArtist, listener } = useContext(DanmuContext); const { start, resume, pause, setLyrics, offset, setOffset } = useLyricsRunner((line) => { setHistory((items) => [ { timestamp: line.slice(0, 10), content: line.slice(10), }, ...items, ]); if (listener) { // 测试用 // listener('666'); // 实际输出歌词 listener(line.slice(0, 10)); } console.log(line); }, 200); return (
当前延迟 {offset / 1000} 秒
    {history.map((item, i) => (
  • {item.timestamp}{item.content}
    {/*
    */}
  • ))}
); }