using System; using System.Collections.Generic; using System.IO; using System.Linq; using Jellyfin.Extensions; using LrcParser.Model; using LrcParser.Parser; using MediaBrowser.Controller.Lyrics; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Lyrics; namespace MediaBrowser.Providers.Lyric; /// /// LRC Lyric Parser. /// public class LrcLyricParser : ILyricParser { private readonly LyricParser _lrcLyricParser; private static readonly string[] _supportedMediaTypes = [".lrc", ".elrc"]; /// /// Initializes a new instance of the class. /// public LrcLyricParser() { _lrcLyricParser = new LrcParser.Parser.Lrc.LrcParser(); } /// public string Name => "LrcLyricProvider"; /// /// Gets the priority. /// /// The priority. public ResolverPriority Priority => ResolverPriority.Fourth; /// public LyricDto? ParseLyrics(LyricFile lyrics) { if (!_supportedMediaTypes.Contains(Path.GetExtension(lyrics.Name.AsSpan()), StringComparison.OrdinalIgnoreCase)) { return null; } Song lyricData; try { lyricData = _lrcLyricParser.Decode(lyrics.Content); } catch (Exception) { // Failed to parse, return null so the next parser will be tried return null; } List sortedLyricData = lyricData.Lyrics.OrderBy(x => x.StartTime).ToList(); if (sortedLyricData.Count == 0) { return null; } List lyricList = []; for (int i = 0; i < sortedLyricData.Count; i++) { long ticks = TimeSpan.FromMilliseconds(sortedLyricData[i].StartTime).Ticks; lyricList.Add(new LyricLine(sortedLyricData[i].Text.Trim(), ticks)); } return new LyricDto { Lyrics = lyricList }; } }