diff --git a/DBObj/SongData.cs b/DBObj/SongData.cs index ced30c7..d6e2141 100644 --- a/DBObj/SongData.cs +++ b/DBObj/SongData.cs @@ -1,16 +1,22 @@ +using DualScreenDemo; +using System; +using System.IO; namespace DBObj { public class SongData { - public string SongNumber { get; set; } + public string SongNumber { get; set; } public string Song { get; set; } public string ArtistA { get; set; } public string ArtistB { get; set; } public string FileName { get; set; } - public string ArtistASimplified { get; set; } - public string ArtistBSimplified { get; set; } - public string SongSimplified { get; set; } + public string ArtistASimplified { get; set; } + public string ArtistBSimplified { get; set; } + public string SongSimplified { get; set; } public int HumanVoice { get; set; } + public bool isPublicSong { get; set; } + + public PlayState state; /* public SongData(string songNumber, string category, string song, double plays, string artistA, string artistB, string artistACategory, string artistBCategory, DateTime addedTime, string songFilePathHost1, string songFilePathHost2, string phoneticNotation, string pinyinNotation, string artistAPhonetic, string artistBPhonetic, string artistASimplified, string artistBSimplified, string songSimplified, string songGenre, string artistAPinyin, string artistBPinyin, int humanVoice) @@ -40,12 +46,13 @@ namespace DBObj } */ - public SongData(string songNumber, string song, string filename, int humanVoice) + public SongData(string songNumber, string song, string filename, int humanVoice, bool isPublic) { SongNumber = songNumber; Song = song; FileName = filename; HumanVoice = humanVoice; + isPublicSong = isPublic; } public SongData(string songNumber, string song, string artistA, string artistB, string filename, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice) { @@ -53,16 +60,32 @@ namespace DBObj Song = song; ArtistA = artistA; ArtistB = artistB; - FileName = filename; + FileName = FindExistingPath(filename); ArtistASimplified = artistASimplified; ArtistBSimplified = artistBSimplified; SongSimplified = songSimplified; HumanVoice = humanVoice; + isPublicSong = false; + } + private string FindExistingPath(string filename) + { + var servers = new[] { @"\\svr01\", @"\\svr02\", @"\\svr01\e", @"\\svr02\e" }; + foreach (var server in servers){ + string fullPath = Path.Combine(server, filename); + if (File.Exists(fullPath)) return fullPath; + } + return filename; // 找不到就回原本的 filename,不加路徑 + } + public void SetState(PlayState s) => state = s; + + public PlayState GetState() + { + return state; } public override string ToString() { - + return !string.IsNullOrWhiteSpace(ArtistB) ? String.Format("{0} - {1} - {2}", ArtistA, ArtistB, Song) : String.Format("{0} - {1}", ArtistA, Song); diff --git a/Env.cs b/Env.cs index 5493d90..22936eb 100644 --- a/Env.cs +++ b/Env.cs @@ -24,7 +24,7 @@ namespace Utils if (File.Exists(configPath)) { KtvPath = path; - Console.WriteLine("✅ 找到設定檔:" + configPath); + Console.WriteLine("找到設定檔:" + configPath); foreach (var line in File.ReadAllLines(configPath)) { @@ -47,7 +47,7 @@ namespace Utils } } - Console.WriteLine("❌ 所有指定目錄都找不到 config.ini"); + Console.WriteLine("所有指定目錄都找不到 config.ini"); } public static string Get(string key, string fallback = "") => diff --git a/PublicSongChecker.cs b/PublicSongChecker.cs index 66c99ef..ca4f719 100644 --- a/PublicSongChecker.cs +++ b/PublicSongChecker.cs @@ -63,7 +63,8 @@ namespace DataCheck match.Groups["songNumber"].Value, // songNumber match.Groups["songName"].Value, // song Path.Combine(localPath, serverFile.Key), // songFilePathHost1 - 1 // priority + 1, // priority + true )); } } diff --git a/SongChecker.cs b/SongChecker.cs new file mode 100644 index 0000000..f3eb36b --- /dev/null +++ b/SongChecker.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.IO; +using System.Linq; +using DBObj; + +namespace DataCheck +{ + public class SongChecker + { + private static List playingSongList= new(); + //public static List playStates; + private static List publicSongList = new(); + private SongData welcome = new SongData("0", "歡迎光臨", @"D:\video\welcome.mpg", 1 ,true); + private SongData close = new SongData("0", "結束播放", @"D:\video\CLOSE.MPG", 1 ,true); + + public SongChecker() + { + string serverPath = Utils.Env.GetPath("video", ""); + string localPath = @"D:\video"; + // 加入你要同步的資料夾 + SyncFolder(serverPath, localPath, "video", new[] { ".mpg" }); + } + public static bool AddSongToPlayList(SongData song) + { + playingSongList.Add(song); + return true; + } + public static bool isPlayingUserSong() + { + return playingSongList.Count == 0; + } + public static SongData GetCurrentSong() + { + SongData song = null; + int count = playingSongList.Count; + if (count == 0) + { + song = publicSongList[0]; + publicSongList.RemoveAt(0); + publicSongList.Add(song); + } + else + { + song = playingSongList[0]; + playingSongList.RemoveAt(0); + } + return song; + } + public static SongData GetNextSong() + { + return playingSongList.Count > 1 ? playingSongList[1] : null; + } + + private void SyncFolder(string serverPath, string localPath, string label, string[] extensions) + { + + if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath); + if (!Directory.Exists(serverPath)) + { + Console.WriteLine($"找不到伺服器資料夾:{serverPath}"); + return; + } + + var serverFiles = Directory.GetFiles(serverPath) + .Where(f => extensions.Contains(Path.GetExtension(f), StringComparer.OrdinalIgnoreCase)) + .Select(f => new FileInfo(f)) + .ToDictionary(f => f.Name, f => f); + + var localFiles = Directory.GetFiles(localPath) + .Where(f => extensions.Contains(Path.GetExtension(f), StringComparer.OrdinalIgnoreCase)) + .Select(f => new FileInfo(f)) + .ToDictionary(f => f.Name, f => f); + + // 1. 複製或更新檔案 + foreach (var serverFile in serverFiles) + { + string dest = Path.Combine(localPath, serverFile.Key); + bool needsCopy = !localFiles.ContainsKey(serverFile.Key) || + serverFile.Value.LastWriteTime > localFiles[serverFile.Key].LastWriteTime; + if (needsCopy) + { + try + { + File.Copy(serverFile.Value.FullName, dest, true); + Console.WriteLine($"✅ 更新 {label}: {serverFile.Key}"); + } + catch (Exception ex) + { + Console.WriteLine($"❌ 複製 {label} 失敗 {serverFile.Key}: {ex.Message}"); + continue; // 如果複製失敗就不加入 SongData + } + } + string fileName = Path.GetFileNameWithoutExtension(serverFile.Key); + Match match = Regex.Match(fileName, @"^(?\d+)-.*?-(?[^-]+)-"); + if (match.Success) + { + publicSongList.Add(new SongData( + match.Groups["songNumber"].Value, // songNumber + match.Groups["songName"].Value, // song + Path.Combine(localPath, serverFile.Key), // songFilePathHost1 + 1, // priority + true + )); + } + } + + // 2. 刪除多餘的本地檔案 + foreach (var localFile in localFiles) + { + if (!serverFiles.ContainsKey(localFile.Key)) + { + try + { + File.Delete(localFile.Value.FullName); + Console.WriteLine($"刪除多餘{label}: {localFile.Key}"); + } + catch (Exception ex) + { + Console.WriteLine($"刪除{label}失敗 {localFile.Key}: {ex.Message}"); + } + } + } + } + } +} diff --git a/TCPServer.cs b/TCPServer.cs index 8c62188..48ac2ac 100644 --- a/TCPServer.cs +++ b/TCPServer.cs @@ -138,7 +138,7 @@ namespace DualScreenDemo string closePath = @"D:\video\CLOSE.MPG"; if (File.Exists(closePath)) { - SongData closeSong = new SongData("0", "結束播放",closePath, 1); + SongData closeSong = new SongData("0", "結束播放",closePath, 1,true); VideoPlayerForm.publicPlaylist = new List(); VideoPlayerForm.playingSongList = new List(); PrimaryForm.playedSongsHistory = new List(); diff --git a/VideoPlayerForm.cs b/VideoPlayerForm.cs index b5e119d..e3bf6b1 100644 --- a/VideoPlayerForm.cs +++ b/VideoPlayerForm.cs @@ -612,7 +612,7 @@ namespace DualScreenDemo if (File.Exists(welcomePath)) { publicPlaylist.Add(new SongData( - "0", "歡迎光臨", welcomePath, 1 + "0", "歡迎光臨", welcomePath, 1,true )); } @@ -623,7 +623,7 @@ namespace DualScreenDemo if (File.Exists(bgmPath)) { publicPlaylist.Add(new SongData( - i.ToString(), $"背景音樂{i:D2}", bgmPath, 1 + i.ToString(), $"背景音樂{i:D2}", bgmPath, 1,true )); } } @@ -636,7 +636,7 @@ namespace DualScreenDemo foreach (var songPath in videoFiles) { string fileName = Path.GetFileNameWithoutExtension(songPath); - publicPlaylist.Add(new SongData("0", fileName,songPath,1)); + publicPlaylist.Add(new SongData("0", fileName,songPath,1,true)); } } @@ -960,7 +960,7 @@ namespace DualScreenDemo string welcomePath = @"D:\video\welcome.mpg"; if (File.Exists(welcomePath)) { - publicPlaylist.Add(new SongData("0", "歡迎光臨", welcomePath, 1)); + publicPlaylist.Add(new SongData("0", "歡迎光臨", welcomePath, 1,true)); } // 添加 BGM 序列 @@ -969,7 +969,7 @@ namespace DualScreenDemo string bgmPath = $@"D:\video\BGM{i:D2}.mpg"; if (File.Exists(bgmPath)) { - publicPlaylist.Add(new SongData(i.ToString(), $"背景音樂{i:D2}", bgmPath, 1)); + publicPlaylist.Add(new SongData(i.ToString(), $"背景音樂{i:D2}", bgmPath, 1,true)); } }