Przeglądaj źródła

fix(card): expand lyric parser

onecold 4 miesięcy temu
rodzic
commit
94a89ee425

+ 32 - 14
entry/src/main/ets/common/player/MusicCardSnapshot.ets

@@ -1,7 +1,7 @@
 import { MUSIC_CARD_EMPTY_ARTIST, MUSIC_CARD_EMPTY_TITLE } from './MusicCardConstants'
 
 const DEFAULT_TIME_TEXT = '00:00'
-const LYRIC_LINE_PATTERN = /^\[(\d{2}):(\d{2})\.(\d{2})\](.*)$/
+const LYRIC_TIMESTAMP_PATTERN = /\[(\d{2}):(\d{2})\.(\d{2,3})\]/g
 
 const isNonEmpty = (value?: string): boolean => {
   return !!value && value.trim() !== ''
@@ -92,27 +92,45 @@ export function resolveMusicCardLyricLines(
       continue
     }
 
-    const match = rawLine.match(LYRIC_LINE_PATTERN)
-    if (!match) {
+    const timestamps: Array<{ timeMs: number }> = []
+    let lastMatchEnd = 0
+    LYRIC_TIMESTAMP_PATTERN.lastIndex = 0
+    let match = LYRIC_TIMESTAMP_PATTERN.exec(rawLine)
+
+    while (match) {
+      const minutes = parseInt(match[1], 10)
+      const seconds = parseInt(match[2], 10)
+      const msPart = match[3]
+      const msValue =
+        msPart.length === 2 ? parseInt(msPart, 10) * 10 : parseInt(msPart, 10)
+      const timeMs = minutes * 60 * 1000 + seconds * 1000 + msValue
+
+      timestamps.push({ timeMs })
+      lastMatchEnd = LYRIC_TIMESTAMP_PATTERN.lastIndex
+      match = LYRIC_TIMESTAMP_PATTERN.exec(rawLine)
+    }
+
+    if (timestamps.length === 0) {
       continue
     }
 
-    const minutes = parseInt(match[1])
-    const seconds = parseInt(match[2])
-    const centiseconds = parseInt(match[3])
-    const text = match[4].trim()
-    const timeMs = minutes * 60 * 1000 + seconds * 1000 + centiseconds * 10
+    const text = rawLine.slice(lastMatchEnd).trim()
+    if (text === '') {
+      continue
+    }
 
-    entries.push({
-      timeMs,
-      text
-    })
+    for (let j = 0; j < timestamps.length; j++) {
+      entries.push({
+        timeMs: timestamps[j].timeMs,
+        text
+      })
+    }
   }
 
   if (entries.length === 0) {
     return {
-      line1: MUSIC_CARD_EMPTY_TITLE,
-      line2: MUSIC_CARD_EMPTY_ARTIST,
+      line1: '',
+      line2: '',
       hasLyric: false
     }
   }

+ 32 - 0
entry/src/ohosTest/ets/test/MusicCardSnapshot.test.ets

@@ -16,6 +16,38 @@ export default function musicCardSnapshotTest() {
       expect(lines.hasLyric).assertEqual(true)
     })
 
+    it('resolveMusicCardLyricLinesSupportsThreeDigitMs', 0, () => {
+      const lines = resolveMusicCardLyricLines('[00:05.123]三位', 6000)
+
+      expect(lines.line1).assertEqual('三位')
+      expect(lines.line2).assertEqual('')
+      expect(lines.hasLyric).assertEqual(true)
+    })
+
+    it('resolveMusicCardLyricLinesHandlesMultipleTimestamps', 0, () => {
+      const lines = resolveMusicCardLyricLines('[00:00.00][00:05.00]第二句', 6000)
+
+      expect(lines.line1).assertEqual('第二句')
+      expect(lines.line2).assertEqual('')
+      expect(lines.hasLyric).assertEqual(true)
+    })
+
+    it('resolveMusicCardLyricLinesIgnoresEmptyText', 0, () => {
+      const lines = resolveMusicCardLyricLines('[00:12.000]   ', 12000)
+
+      expect(lines.line1).assertEqual('')
+      expect(lines.line2).assertEqual('')
+      expect(lines.hasLyric).assertEqual(false)
+    })
+
+    it('resolveMusicCardLyricLinesReturnsEmptyForBlankInput', 0, () => {
+      const lines = resolveMusicCardLyricLines('', 0)
+
+      expect(lines.line1).assertEqual('')
+      expect(lines.line2).assertEqual('')
+      expect(lines.hasLyric).assertEqual(false)
+    })
+
     it('buildMusicCardBindingDataForEmptySnapshot', 0, () => {
       const binding = buildMusicCardBindingData(createEmptyMusicCardSnapshot())