遠端 svr 邏輯調整 20250708
This commit is contained in:
parent
c1437a02d9
commit
7500f6b8fa
@ -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);
|
||||
|
4
Env.cs
4
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 = "") =>
|
||||
|
@ -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
|
||||
));
|
||||
}
|
||||
}
|
||||
|
127
SongChecker.cs
Normal file
127
SongChecker.cs
Normal file
@ -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<SongData> playingSongList= new();
|
||||
//public static List<PlayState> playStates;
|
||||
private static List<SongData> 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, @"^(?<songNumber>\d+)-.*?-(?<songName>[^-]+)-");
|
||||
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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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<SongData>();
|
||||
VideoPlayerForm.playingSongList = new List<SongData>();
|
||||
PrimaryForm.playedSongsHistory = new List<SongData>();
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user