Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94b22552e5 | ||
|
|
6deb16f6cb | ||
|
|
e467ab9c73 | ||
|
|
ea038c9c56 | ||
|
|
560250ad30 | ||
|
|
536acc69a5 | ||
|
|
0bbb379912 | ||
|
|
1f4d29e6f2 | ||
|
|
5d1d7476c9 | ||
|
|
e016baefe1 | ||
|
|
70b6194788 | ||
|
|
9f103b0ea3 | ||
|
|
2924140f95 | ||
|
|
3d3f168926 | ||
|
|
63b2285a36 |
@@ -12,7 +12,7 @@
|
||||
<Identity
|
||||
Name="37412.BetterLyrics"
|
||||
Publisher="CN=E1428B0E-DC1D-4EA4-ACB1-4556569D5BA9"
|
||||
Version="1.0.73.0" />
|
||||
Version="1.0.75.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="ca4a4830-fc19-40d9-b823-53e2bff3d816" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
|
||||
@@ -21,11 +21,14 @@ namespace BetterLyrics.WinUI3.Models
|
||||
public partial double? DurationMs { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string? SourceAppUserModelId { get; set; } = null;
|
||||
public partial string? PlayerId { get; set; } = null;
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string? SongId { get; set; } = null;
|
||||
|
||||
public SongInfo() { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
{
|
||||
public interface ILyricsSearchService
|
||||
{
|
||||
Task<LyricsSearchResult> SearchSmartlyAsync(string mediaSessionId, string title, string artist, string album, double durationMs, CancellationToken token);
|
||||
Task<LyricsSearchResult> SearchSmartlyAsync(string mediaSessionId, string title, string artist, string album, double durationMs, string? songId, CancellationToken token);
|
||||
|
||||
Task<List<LyricsSearchResult>> SearchAllAsync(string title, string artist, string album, double durationMs, CancellationToken token);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<LyricsSearchResult> SearchSmartlyAsync(string mediaSessionId, string title, string artist, string album, double durationMs, CancellationToken token)
|
||||
public async Task<LyricsSearchResult> SearchSmartlyAsync(string mediaSessionId, string title, string artist, string album, double durationMs, string? songId, CancellationToken token)
|
||||
{
|
||||
var lyricsSearchResult = new LyricsSearchResult();
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
var targetProvider = found.LyricsSearchProvider;
|
||||
if (targetProvider != null)
|
||||
{
|
||||
return await SearchSingleAsync(targetProvider.Value, overridenTitle, overridenArtist, album, durationMs, token);
|
||||
return await SearchSingleAsync(targetProvider.Value, overridenTitle, overridenArtist, album, durationMs, songId, token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
continue;
|
||||
}
|
||||
|
||||
lyricsSearchResult = await SearchSingleAsync(provider.Provider, overridenTitle, overridenArtist, album, durationMs, token);
|
||||
lyricsSearchResult = await SearchSingleAsync(provider.Provider, overridenTitle, overridenArtist, album, durationMs, null, token);
|
||||
|
||||
if (lyricsSearchResult.IsFound)
|
||||
{
|
||||
@@ -151,13 +151,13 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
var results = new List<LyricsSearchResult>();
|
||||
foreach (var provider in Enum.GetValues<LyricsSearchProvider>())
|
||||
{
|
||||
var searchResult = await SearchSingleAsync(provider, title, artist, album, durationMs, token);
|
||||
var searchResult = await SearchSingleAsync(provider, title, artist, album, durationMs, null, token);
|
||||
results.Add(searchResult);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private async Task<LyricsSearchResult> SearchSingleAsync(LyricsSearchProvider provider, string title, string artist, string album, double durationMs, CancellationToken token)
|
||||
private async Task<LyricsSearchResult> SearchSingleAsync(LyricsSearchProvider provider, string title, string artist, string album, double durationMs, string? songId, CancellationToken token)
|
||||
{
|
||||
var lyricsSearchResult = new LyricsSearchResult
|
||||
{
|
||||
@@ -200,13 +200,13 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
lyricsSearchResult = await SearchLrcLibAsync(title, artist, album, (int)(durationMs / 1000));
|
||||
break;
|
||||
case LyricsSearchProvider.QQ:
|
||||
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, Searchers.QQMusic);
|
||||
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, songId, Searchers.QQMusic);
|
||||
break;
|
||||
case LyricsSearchProvider.Kugou:
|
||||
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, Searchers.Kugou);
|
||||
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, songId, Searchers.Kugou);
|
||||
break;
|
||||
case LyricsSearchProvider.Netease:
|
||||
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, Searchers.Netease);
|
||||
lyricsSearchResult = await SearchQQNeteaseKugouAsync(title, artist, album, (int)durationMs, songId, Searchers.Netease);
|
||||
break;
|
||||
case LyricsSearchProvider.AmllTtmlDb:
|
||||
lyricsSearchResult = await SearchAmllTtmlDbAsync(title, artist);
|
||||
@@ -436,7 +436,7 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
return lyricsSearchResult;
|
||||
}
|
||||
|
||||
private static async Task<LyricsSearchResult> SearchQQNeteaseKugouAsync(string title, string artist, string album, int durationMs, Searchers searchers)
|
||||
private static async Task<LyricsSearchResult> SearchQQNeteaseKugouAsync(string title, string artist, string album, int durationMs, string? songId, Searchers searchers)
|
||||
{
|
||||
var lyricsSearchResult = new LyricsSearchResult();
|
||||
|
||||
@@ -457,15 +457,23 @@ namespace BetterLyrics.WinUI3.Services.LyricsSearchService
|
||||
break;
|
||||
}
|
||||
|
||||
var result = await SearchersHelper.GetSearcher(searchers).SearchForResult(
|
||||
new Lyricify.Lyrics.Models.TrackMultiArtistMetadata()
|
||||
{
|
||||
DurationMs = durationMs,
|
||||
Album = album,
|
||||
Artists = [artist],
|
||||
Title = title,
|
||||
}
|
||||
);
|
||||
ISearchResult? result;
|
||||
if (searchers == Searchers.Netease && songId != null)
|
||||
{
|
||||
result = new NeteaseSearchResult(title, [artist], album, null, durationMs, songId);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await SearchersHelper.GetSearcher(searchers).SearchForResult(
|
||||
new Lyricify.Lyrics.Models.TrackMultiArtistMetadata()
|
||||
{
|
||||
DurationMs = durationMs,
|
||||
Album = album,
|
||||
Artists = [artist],
|
||||
Title = title,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (result is QQMusicSearchResult qqResult)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
}
|
||||
|
||||
byte[]? bytes = await Task.Run(async () => await _albumArtSearchService.SearchAsync(
|
||||
SongInfo?.SourceAppUserModelId ?? "",
|
||||
SongInfo?.PlayerId ?? "",
|
||||
_cachedSongInfo.Title,
|
||||
_cachedSongInfo.Artist,
|
||||
_cachedSongInfo?.Album ?? string.Empty,
|
||||
|
||||
@@ -156,11 +156,12 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
SongInfo.Title, SongInfo.Artist, SongInfo.Album, SongInfo.DurationMs);
|
||||
|
||||
var lyricsSearchResult = await Task.Run(async () => await _lyrcsSearchService.SearchSmartlyAsync(
|
||||
SongInfo.SourceAppUserModelId ?? "",
|
||||
SongInfo.PlayerId ?? "",
|
||||
SongInfo.Title,
|
||||
SongInfo.Artist,
|
||||
SongInfo.Album ?? "",
|
||||
SongInfo.DurationMs ?? 0,
|
||||
SongInfo.SongId,
|
||||
token
|
||||
), token);
|
||||
if (token.IsCancellationRequested) return;
|
||||
|
||||
@@ -284,21 +284,21 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
if (!_mediaManager.IsStarted) return;
|
||||
if (mediaSession == null) return;
|
||||
|
||||
string id = mediaSession.Id;
|
||||
string sessionId = mediaSession.Id;
|
||||
|
||||
var desiredSession = GetCurrentSession();
|
||||
|
||||
//RecordMediaSourceProviderInfo(mediaSession);
|
||||
if (mediaSession != desiredSession) return;
|
||||
|
||||
if (!IsMediaSourceEnabled(id))
|
||||
if (!IsMediaSourceEnabled(sessionId))
|
||||
{
|
||||
_cachedSongInfo = null;
|
||||
|
||||
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
|
||||
mediaProperties.Title, mediaProperties.Artist, mediaProperties.AlbumTitle);
|
||||
|
||||
if (id == Constants.PlayerID.LXMusic)
|
||||
if (sessionId == Constants.PlayerID.LXMusic)
|
||||
{
|
||||
StopSSE();
|
||||
}
|
||||
@@ -313,38 +313,39 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
currentMediaSourceProviderInfo?.PositionOffset = 0;
|
||||
}
|
||||
|
||||
if (id == Constants.PlayerID.AppleMusic || id == Constants.PlayerID.AppleMusicAlternative)
|
||||
{
|
||||
string fixedArtist = mediaProperties.Artist.Split(" — ").FirstOrDefault() ?? mediaProperties.Artist;
|
||||
string fixedAlbum = mediaProperties.Artist.Split(" — ").LastOrDefault() ?? mediaProperties.AlbumTitle;
|
||||
string fixedArtist = mediaProperties.Artist;
|
||||
string fixedAlbum = mediaProperties.AlbumTitle;
|
||||
string? songId = null;
|
||||
|
||||
_cachedSongInfo = new SongInfo
|
||||
{
|
||||
Title = mediaProperties.Title,
|
||||
Artist = fixedArtist,
|
||||
Album = fixedAlbum,
|
||||
DurationMs = mediaSession.ControlSession.GetTimelineProperties().EndTime.TotalMilliseconds,
|
||||
SourceAppUserModelId = id,
|
||||
};
|
||||
}
|
||||
else
|
||||
if (sessionId == Constants.PlayerID.AppleMusic || sessionId == Constants.PlayerID.AppleMusicAlternative)
|
||||
{
|
||||
_cachedSongInfo = new SongInfo
|
||||
fixedArtist = mediaProperties.Artist.Split(" — ").FirstOrDefault() ?? mediaProperties.Artist;
|
||||
fixedAlbum = mediaProperties.Artist.Split(" — ").LastOrDefault() ?? mediaProperties.AlbumTitle;
|
||||
}
|
||||
else if (sessionId == Constants.PlayerID.NetEaseCloudMusic)
|
||||
{
|
||||
songId = mediaProperties.Genres.FirstOrDefault()?.Replace("NCM-", "");
|
||||
if (songId != null && songId.Length != 10)
|
||||
{
|
||||
Title = mediaProperties.Title,
|
||||
Artist = mediaProperties.Artist,
|
||||
Album = mediaProperties.AlbumTitle,
|
||||
DurationMs = mediaSession.ControlSession.GetTimelineProperties().EndTime.TotalMilliseconds,
|
||||
SourceAppUserModelId = id,
|
||||
};
|
||||
songId = null;
|
||||
}
|
||||
}
|
||||
|
||||
_cachedSongInfo = new SongInfo
|
||||
{
|
||||
Title = mediaProperties.Title,
|
||||
Artist = fixedArtist,
|
||||
Album = fixedAlbum,
|
||||
DurationMs = mediaSession.ControlSession.GetTimelineProperties().EndTime.TotalMilliseconds,
|
||||
PlayerId = sessionId,
|
||||
SongId = songId
|
||||
};
|
||||
_cachedSongInfo.Duration = (int)(_cachedSongInfo.DurationMs / 1000f);
|
||||
|
||||
_logger.LogInformation("Media properties changed: Title: {Title}, Artist: {Artist}, Album: {Album}",
|
||||
mediaProperties.Title, mediaProperties.Artist, mediaProperties.AlbumTitle);
|
||||
|
||||
if (id == Constants.PlayerID.LXMusic)
|
||||
if (sessionId == Constants.PlayerID.LXMusic)
|
||||
{
|
||||
StartSSE();
|
||||
}
|
||||
@@ -353,7 +354,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
StopSSE();
|
||||
}
|
||||
|
||||
if (id == Constants.PlayerID.LXMusic && _lxMusicAlbumArtBytes != null)
|
||||
if (sessionId == Constants.PlayerID.LXMusic && _lxMusicAlbumArtBytes != null)
|
||||
{
|
||||
_SMTCAlbumArtBytes = _lxMusicAlbumArtBytes;
|
||||
}
|
||||
@@ -507,7 +508,7 @@ namespace BetterLyrics.WinUI3.Services.MediaSessionsService
|
||||
{
|
||||
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Low, async () =>
|
||||
{
|
||||
if (_cachedSongInfo?.SourceAppUserModelId == Constants.PlayerID.LXMusic)
|
||||
if (_cachedSongInfo?.PlayerId == Constants.PlayerID.LXMusic)
|
||||
{
|
||||
var data = JsonSerializer.Deserialize(e.Message, Serialization.SourceGenerationContext.Default.JsonElement);
|
||||
if (data.ValueKind == JsonValueKind.Number)
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
private void MediaSessionsService_SongInfoChanged(object? sender, Events.SongInfoChangedEventArgs e)
|
||||
{
|
||||
var current = AppSettings.MediaSourceProvidersInfo.Where(x => x.Provider == e.SongInfo?.SourceAppUserModelId)?.FirstOrDefault();
|
||||
var current = AppSettings.MediaSourceProvidersInfo.Where(x => x.Provider == e.SongInfo?.PlayerId)?.FirstOrDefault();
|
||||
if (_mediaSessionsService.Position.TotalSeconds <= 1 && current?.ResetPositionOffsetOnSongChanged == true)
|
||||
{
|
||||
current.PositionOffset = 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) [year] [fullname]
|
||||
Copyright (c) 2025 Zhe Fang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
81
README.md
@@ -23,7 +23,7 @@ BetterLyrics
|
||||
</div>
|
||||
|
||||
<h4 align="center">
|
||||
Your dynamic lyrics display tool built with WinUI 3 and Win2D — works with local playback and other players
|
||||
Your dynamic lyrics display tool, built with WinUI 3 and Win2D, works with local playback and other players
|
||||
</h3>
|
||||
|
||||
## 🎉 This project was featured by SSPAI!
|
||||
@@ -32,24 +32,22 @@ Check out the article: [BetterLyrics – An immersive and smooth lyrics display
|
||||
|
||||
## 🔈 Feedback and chat group
|
||||
|
||||
- [<img src="BetterLyrics.WinUI3\BetterLyrics.WinUI3\Assets\QQ.png" height="20"> QQ](https://qun.qq.com/universal-share/share?ac=1&authKey=4Q%2BYTq3wZldYpF5SbS5c19ECFsiYoLZFAIcBNNzYpBUtiEjaZ8sZ%2F%2BnFN0qw3lad&busi_data=eyJncm91cENvZGUiOiIxMDU0NzAwMzg4IiwidG9rZW4iOiJiVnhqemVYN0N5QVc3b1ZkR24wWmZOTUtvUkJoWm1JRWlaWW5iZnlBcXJtZUtGc2FFTHNlUlFZMi9iRm03cWF5IiwidWluIjoiMTM5NTczOTY2MCJ9&data=39UmAihyH_o6CZaOs7nk2mO_lz2ruODoDou6pxxh7utcxP4WF5sbDBDOPvZ_Wqfzeey4441anegsLYQJxkrBAA&svctype=4&tempid=h5_group_info) (1054700388)
|
||||
- [<img src="BetterLyrics.WinUI3\BetterLyrics.WinUI3\Assets\Discord.png" height="12"> Discord](https://discord.gg/5yAQPnyCKv)
|
||||
- [<img src="BetterLyrics.WinUI3\BetterLyrics.WinUI3\Assets\Telegram.png" height="16"> Telegram](https://t.me/+svhSLZ7awPsxNGY1)
|
||||
[QQ 群](https://qun.qq.com/universal-share/share?ac=1&authKey=4Q%2BYTq3wZldYpF5SbS5c19ECFsiYoLZFAIcBNNzYpBUtiEjaZ8sZ%2F%2BnFN0qw3lad&busi_data=eyJncm91cENvZGUiOiIxMDU0NzAwMzg4IiwidG9rZW4iOiJiVnhqemVYN0N5QVc3b1ZkR24wWmZOTUtvUkJoWm1JRWlaWW5iZnlBcXJtZUtGc2FFTHNlUlFZMi9iRm03cWF5IiwidWluIjoiMTM5NTczOTY2MCJ9&data=39UmAihyH_o6CZaOs7nk2mO_lz2ruODoDou6pxxh7utcxP4WF5sbDBDOPvZ_Wqfzeey4441anegsLYQJxkrBAA&svctype=4&tempid=h5_group_info) (1054700388) | [Discord Server](https://discord.gg/5yAQPnyCKv) | [Telegram Group](https://t.me/+svhSLZ7awPsxNGY1)
|
||||
|
||||
## 🌟 Highlighted features
|
||||
|
||||
- 🌠 **Pleasing User Interface**
|
||||
- Fluent animations and effects
|
||||
- ↔️ **Strong Lyrics Translation**
|
||||
- Offline machine translation (supporting 30 languages)
|
||||
- Auto reading local lyrics files for embedded translation
|
||||
- Offline machine translation (supporting 30+ languages)
|
||||
- Auto-reading local lyrics files for embedded translation
|
||||
- 🧩 **Various Lyrics Source**
|
||||
- Local storage
|
||||
- 💾 Local storage
|
||||
- Music files (with embedded lyrics)
|
||||
- [.lrc](<https://en.wikipedia.org/wiki/LRC_(file_format)>) files (with both core format and enhanced format)
|
||||
- [.eslrc](https://github.com/ESLyric/release) files
|
||||
- [.ttml](https://en.wikipedia.org/wiki/Timed_Text_Markup_Language) files
|
||||
- Online lyrics providers
|
||||
- ☁️ Online lyrics providers
|
||||
- QQ 音乐
|
||||
- 网易云音乐
|
||||
- 酷狗音乐
|
||||
@@ -58,44 +56,49 @@ Check out the article: [BetterLyrics – An immersive and smooth lyrics display
|
||||
- <details><summary>⚠️ Apple Music (additional config needed)</summary>
|
||||
|
||||
- Open the Apple Music web app and the Developer Tools window. Refresh the page. Return to the Developer Tools window, select Fetch/XHR, select a request, find the Media-User-Token header in the request header, and copy its value.
|
||||
- Open BetterLyrics and go to the Playback Source settings. Enter the copied value in the Media-User-Token (for Apple Music) setting and click the checkbox.
|
||||
- Open BetterLyrics and go to the Playback Source settings. Enter the copied value in the Media-User-Token (for Apple Music) setting and click the accept icon on the right-hand side.
|
||||
|
||||
- 🎶 **Multiple Music Players Supported**
|
||||
|
||||
- <details><summary>⚠️ 网易云音乐</summary>
|
||||
- <details><summary>网易云音乐</summary>
|
||||
|
||||
- Please be sure that that your Netease Cloud Music is at 3.1.4 version
|
||||
- Please make sure that you have latest version (3.1.20+) of 网易云音乐 installed on your PC.
|
||||
- Install the [BetterNCM plugin](https://microblock.cc/betterncm) first
|
||||
- After that, install the InfLink plugin in PluginMarket. After the installation is complete, please restart NetEase Cloud Music. At this point, all preparatory operations have been completed, enjoy it!
|
||||
- ⚠️ Please note that there is issues with timeline due to plugin issue
|
||||
- After that, install the [InfLink-rs](https://github.com/apoint123/inflink-rs) plugin in PluginMarket. After the installation is complete, please restart 网易云音乐. At this point, all preparatory operations have been completed. Enjoy it!
|
||||
|
||||
</details>
|
||||
|
||||
- <details><summary>⚠️ 酷狗音乐</summary>
|
||||
|
||||
- Please make sure that the Kugou Music setting "Support system playback controls, such as lock screen interface" is turned on
|
||||
- No timeline information broadcasted, which means when you change timeline position in Kugou Music, BetterLyrics has no way to detect this change
|
||||
- ⚠️ Please note that there is issues with timeline due to Kugou itself
|
||||
- Please make sure that the 酷狗音乐 setting "Support system playback controls, such as lock screen interface" is turned on
|
||||
- No timeline information broadcast, which means when you change the timeline position in Kugou Music, BetterLyrics has no way to detect this change
|
||||
- ⚠️ Please note that there are issues with the timeline due to Kugou itself
|
||||
|
||||
</details>
|
||||
|
||||
- <details><summary>⚠️ foobar2000</summary>
|
||||
|
||||
- Make sure you have https://github.com/dumbie/foo_mediacontrol installed with it
|
||||
- ⚠️ Please note that there is issues with timeline due to plugin issue
|
||||
- ⚠️ Please note that there are issues with the timeline due to a plugin issue
|
||||
|
||||
</details>
|
||||
|
||||
- Apple Music
|
||||
- Spotify
|
||||
- QQ 音乐
|
||||
- PotPlayer
|
||||
- Media Player (System)
|
||||
|
||||
- <details><summary>QQ 音乐</summary>
|
||||
|
||||
- Please keep it at the latest version
|
||||
- Then open Settings in QQ 音乐, enable "Show System Media Transport Controls (SMTC)".
|
||||
|
||||
</details>
|
||||
|
||||
- <details><summary>LX Music</summary>
|
||||
|
||||
- Please make sure you have enabled "Open API" in LX Music settings page
|
||||
- Then open BetterLyrics, go to settings, go to "Advanced options", input your LX Music server address (mostly like http://127.0.0.1:23330) and there you go!
|
||||
- Then open BetterLyrics, go to settings, go to "Playback sources", input your LX Music server address (mostly like http://127.0.0.1:23330) and there you go!
|
||||
|
||||
</details>
|
||||
|
||||
@@ -119,7 +122,7 @@ Check out the article: [BetterLyrics – An immersive and smooth lyrics display
|
||||
|
||||
- 🪟 **Multiple Display Modes**
|
||||
- **Standard Mode**
|
||||
- Enjoy an immersive listening journey with rich lyrics animations and beautifully dynamic backgrounds
|
||||
- Enjoy an immersive listening journey with rich lyrics, animations and beautifully dynamic backgrounds
|
||||
- **Dock Mode**
|
||||
- A smart animated lyrics bar docked to your screen edge
|
||||
- **Desktop Mode**
|
||||
@@ -127,33 +130,29 @@ Check out the article: [BetterLyrics – An immersive and smooth lyrics display
|
||||
- 🧠 **Smart Behaviors**
|
||||
- Auto hide when music paused
|
||||
|
||||
> This project is still under development, bugs and unexpected behaviors may be existed in the latest branch.
|
||||
> This project is still under development, bugs and unexpected behaviours may exist in the latest branch.
|
||||
|
||||
## Screenshots
|
||||
|
||||
### Standard mode
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
### Standard mode (narrow)
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
### Standard mode (fullscreen)
|
||||
|
||||

|
||||

|
||||
|
||||
### Dock mode
|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
### Desktop mode
|
||||
|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
## Demonstration
|
||||
|
||||
@@ -177,13 +176,13 @@ Watch our introduction video (uploaded on 18 Aug 2025) on Bilibili [here](https:
|
||||
2. Type https://apps.microsoft.com/detail/9p1wcd1p597r in the link input area
|
||||
3. Select Retail from the drop-down list
|
||||
4. Click the check mark
|
||||
5. Select the largest installation package in the resulting list to download and install. If you fail to install, try to install dependencies packages first.
|
||||
5. Select the largest installation package in the resulting list to download and install. If you fail to install, try to install the dependency packages first.
|
||||
|
||||
### Unable to launch the app?
|
||||
|
||||
If you are using third-party modified Windows, you are probably can not launch the app.
|
||||
If you are using a third-party modified Windows, you probably can not launch the app.
|
||||
|
||||
To solve this issue, please try to download from [Google Drive (v1.0.71.0)](https://drive.google.com/file/d/15FiqmSVG3_SZ9Y-_2ZS_qbFvogbNp5Y5/view?usp=sharing) (may not be the latest version) and follow the instruction [here](https://github.com/jayfunc/BetterLyrics/blob/dev/How2Install/How2Install.md).
|
||||
To solve this issue, please try to download from [Google Drive (v1.0.75.0)](https://drive.google.com/file/d/12cEnyfwM_aNjAgBoh_ru-UqjgYmSjsHY/view?usp=sharing) (may not be the latest version) and follow the instructions [here](https://github.com/jayfunc/BetterLyrics/blob/dev/How2Install/How2Install.md).
|
||||
|
||||
## Build
|
||||
|
||||
@@ -192,17 +191,17 @@ Before you build, make sure that you have already replaced `BetterLyrics\BetterL
|
||||
## 💖 Many thanks to
|
||||
|
||||
- [Lyricify-Lyrics-Helper](https://github.com/WXRIW/Lyricify-Lyrics-Helper)
|
||||
- Provide lyrics fetch, decryption, and parse for QQ, Netease, Kugou sources
|
||||
- Provide lyrics fetch, decryption, and parsing for QQ, Netease, and Kugou sources
|
||||
- [lrclib](https://github.com/tranxuanthang/lrclib)
|
||||
- LRCLIB lyrics API provider
|
||||
- [Manzana-Apple-Music-Lyrics](https://github.com/dropcreations/Manzana-Apple-Music-Lyrics)
|
||||
- Apple Music lyrics fetch using Python
|
||||
- [Audio Tools Library (ATL) for .NET](https://github.com/Zeugma440/atldotnet)
|
||||
- Used for extracting pictures in music files
|
||||
- Used for extracting pictures from music files
|
||||
- [WinUIEx](https://github.com/dotMorten/WinUIEx)
|
||||
- Provide easy ways to access Win32 API regarding windowing
|
||||
- Provide easy ways to access the Win32 API regarding windowing
|
||||
- [TagLib#](https://github.com/mono/taglib-sharp)
|
||||
- Used for reading original lyrics content
|
||||
- Used for reading the original lyrics content
|
||||
- [Vanara](https://github.com/dahall/Vanara)
|
||||
- Win32 API wrapper
|
||||
- [LibreTranslate](https://github.com/LibreTranslate/LibreTranslate)
|
||||
@@ -233,9 +232,9 @@ Fork this project and navigate to `BetterLyrics\BetterLyrics.WinUI3\BetterLyrics
|
||||
|
||||
[](https://www.star-history.com/#jayfunc/BetterLyrics&Date)
|
||||
|
||||
## Any issues and PRs are welcomed
|
||||
## Any issues and PRs are welcome
|
||||
|
||||
If you find a bug please file it in issues or if you have any ideas feel free to share it here.
|
||||
If you find a bug, please file it in issues, or if you have any ideas, feel free to share them here.
|
||||
|
||||
## Donations
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 560 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 764 KiB |
BIN
Screenshots/desktop.png
Normal file
|
After Width: | Height: | Size: 565 KiB |
|
Before Width: | Height: | Size: 757 KiB |
|
Before Width: | Height: | Size: 34 KiB |
BIN
Screenshots/dock.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 694 KiB |
|
Before Width: | Height: | Size: 7.6 MiB |
|
Before Width: | Height: | Size: 775 KiB |
|
Before Width: | Height: | Size: 382 KiB |
BIN
Screenshots/std-fullscreen.png
Normal file
|
After Width: | Height: | Size: 642 KiB |
BIN
Screenshots/std-narrow.png
Normal file
|
After Width: | Height: | Size: 847 KiB |
BIN
Screenshots/std.png
Normal file
|
After Width: | Height: | Size: 823 KiB |