mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-12 10:54:55 +08:00
149 lines
5.4 KiB
C#
149 lines
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using ATL;
|
|
using BetterLyrics.WinUI3.Helper;
|
|
using BetterLyrics.WinUI3.Models;
|
|
using Microsoft.UI.Xaml.Controls;
|
|
using Microsoft.UI.Xaml.Media.Imaging;
|
|
using SQLite;
|
|
using Ude;
|
|
using Windows.Media.Control;
|
|
using Windows.Storage;
|
|
using Windows.Storage.Streams;
|
|
|
|
namespace BetterLyrics.WinUI3.Services.Database
|
|
{
|
|
public class DatabaseService : IDatabaseService
|
|
{
|
|
private readonly SQLiteConnection _connection;
|
|
|
|
private readonly CharsetDetector _charsetDetector = new();
|
|
|
|
public DatabaseService()
|
|
{
|
|
_connection = new SQLiteConnection(Helper.AppInfo.DatabasePath);
|
|
if (_connection.GetTableInfo("MetadataIndex").Count == 0)
|
|
{
|
|
_connection.CreateTable<MetadataIndex>();
|
|
}
|
|
}
|
|
|
|
public async Task RebuildDatabaseAsync(IList<string> paths)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
_connection.DeleteAll<MetadataIndex>();
|
|
foreach (var path in paths)
|
|
{
|
|
if (Directory.Exists(path))
|
|
{
|
|
foreach (var file in Directory.GetFiles(path))
|
|
{
|
|
var fileExtension = Path.GetExtension(file);
|
|
var track = new Track(file);
|
|
_connection.Insert(
|
|
new MetadataIndex
|
|
{
|
|
Path = file,
|
|
Title = track.Title,
|
|
Artist = track.Artist,
|
|
}
|
|
);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public async Task<SongInfo> FindSongInfoAsync(
|
|
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps
|
|
)
|
|
{
|
|
if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null)
|
|
return new();
|
|
|
|
var songInfo = new SongInfo { Title = mediaProps?.Title, Artist = mediaProps?.Artist };
|
|
|
|
// App.ResourceLoader!.GetString("MainPageNoLocalFilesMatched");
|
|
|
|
if (mediaProps?.Thumbnail is IRandomAccessStreamReference streamReference)
|
|
{
|
|
songInfo.AlbumArt = await ImageHelper.ToByteArrayAsync(streamReference);
|
|
}
|
|
|
|
return FindSongInfo(songInfo, mediaProps!.Title, mediaProps!.Artist);
|
|
}
|
|
|
|
public SongInfo FindSongInfo(SongInfo initSongInfo, string searchTitle, string searchArtist)
|
|
{
|
|
var founds = _connection
|
|
.Table<MetadataIndex>()
|
|
// Look up by Title and Artist (these two props were fetched by reading metadata in music file befoe) first
|
|
// then by Path (music file name usually contains song name and artist so this can be a second way to look up for)
|
|
// Please note for .lrc file, only the second way works for it
|
|
.Where(m =>
|
|
(
|
|
m.Title != null
|
|
&& m.Artist != null
|
|
&& m.Title.Contains(searchTitle)
|
|
&& m.Artist.Contains(searchArtist)
|
|
)
|
|
|| (
|
|
m.Path != null
|
|
&& m.Path.Contains(searchTitle)
|
|
&& m.Path.Contains(searchArtist)
|
|
)
|
|
)
|
|
.ToList();
|
|
|
|
foreach (var found in founds)
|
|
{
|
|
if (initSongInfo.LyricsLines == null || initSongInfo.AlbumArt == null)
|
|
{
|
|
Track track = new(found.Path);
|
|
initSongInfo.ParseLyrics(track);
|
|
|
|
// Find lyrics
|
|
if (initSongInfo.LyricsLines == null && found?.Path?.EndsWith(".lrc") == true)
|
|
{
|
|
using (FileStream fs = File.OpenRead(found.Path))
|
|
{
|
|
_charsetDetector.Feed(fs);
|
|
_charsetDetector.DataEnd();
|
|
}
|
|
|
|
string content;
|
|
if (_charsetDetector.Charset != null)
|
|
{
|
|
Encoding encoding = Encoding.GetEncoding(_charsetDetector.Charset);
|
|
content = File.ReadAllText(found.Path, encoding);
|
|
}
|
|
else
|
|
{
|
|
content = File.ReadAllText(found.Path, Encoding.UTF8);
|
|
}
|
|
initSongInfo.ParseLyrics(track, content);
|
|
initSongInfo.FilesUsed ??= [];
|
|
initSongInfo.FilesUsed.Add(found.Path);
|
|
}
|
|
|
|
// Finf album art
|
|
if (initSongInfo.AlbumArt == null)
|
|
{
|
|
if (track.EmbeddedPictures.Count > 0)
|
|
{
|
|
initSongInfo.AlbumArt = track.EmbeddedPictures[0].PictureData;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
return initSongInfo;
|
|
}
|
|
}
|
|
}
|