PublicSongChecker 完成
還原 點歌流 20250704
This commit is contained in:
parent
8f456c347d
commit
c1437a02d9
@ -7,8 +7,6 @@ namespace DBObj
|
||||
public string ArtistA { get; set; }
|
||||
public string ArtistB { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string SongFilePathHost1 { get; set; }
|
||||
public string SongFilePathHost2 { get; set; }
|
||||
public string ArtistASimplified { get; set; }
|
||||
public string ArtistBSimplified { get; set; }
|
||||
public string SongSimplified { get; set; }
|
||||
@ -42,19 +40,24 @@ namespace DBObj
|
||||
}
|
||||
|
||||
*/
|
||||
public SongData(string songNumber, string song, string artistA, string artistB, string filename, string songFilePathHost1, string songFilePathHost2, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice)
|
||||
public SongData(string songNumber, string song, string filename, int humanVoice)
|
||||
{
|
||||
SongNumber = songNumber;
|
||||
Song = song;
|
||||
FileName = filename;
|
||||
HumanVoice = humanVoice;
|
||||
}
|
||||
public SongData(string songNumber, string song, string artistA, string artistB, string filename, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice)
|
||||
{
|
||||
SongNumber = songNumber;
|
||||
Song = song;
|
||||
ArtistA = artistA;
|
||||
ArtistB = artistB;
|
||||
FileName = filename;
|
||||
SongFilePathHost1 = songFilePathHost1;
|
||||
SongFilePathHost2 = songFilePathHost2;
|
||||
FileName = filename;
|
||||
ArtistASimplified = artistASimplified;
|
||||
ArtistBSimplified = artistBSimplified;
|
||||
SongSimplified = songSimplified;
|
||||
HumanVoice = humanVoice;
|
||||
HumanVoice = humanVoice;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
80
DataCheck.cs
80
DataCheck.cs
@ -1,80 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace DataCheck
|
||||
{
|
||||
public class DataChecker
|
||||
{
|
||||
public DataChecker()
|
||||
{
|
||||
// 加入你要同步的資料夾
|
||||
SyncFolder(Utils.Env.GetPath("video", ""), @"D:\video", "video", new[] { ".mpg" });
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
bool needsCopy = !localFiles.ContainsKey(serverFile.Key) ||
|
||||
serverFile.Value.LastWriteTime > localFiles[serverFile.Key].LastWriteTime;
|
||||
|
||||
if (needsCopy)
|
||||
{
|
||||
try
|
||||
{
|
||||
string dest = Path.Combine(localPath, serverFile.Key);
|
||||
File.Copy(serverFile.Value.FullName, dest, true);
|
||||
Console.WriteLine($"更新{label}: {serverFile.Key}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"複製{label}失敗 {serverFile.Key}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -786,8 +786,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
song.Song,
|
||||
song.ArtistA,
|
||||
song.SongFilePathHost1,
|
||||
song.SongFilePathHost2,
|
||||
song.FileName,
|
||||
PlayState = playState.HasValue ? (playState.Value == PlayState.Playing ? "播放中" : "播放完畢") : null // 如果状态为 null,不返回状态信息
|
||||
};
|
||||
}
|
||||
@ -1118,21 +1117,11 @@ namespace DualScreenDemo
|
||||
song.Song,
|
||||
song.ArtistA,
|
||||
song.SongNumber,
|
||||
//song.Category,
|
||||
//song.PhoneticNotation,
|
||||
//song.PinyinNotation,
|
||||
//song.ArtistAPhonetic,
|
||||
//song.ArtistBPhonetic,
|
||||
song.ArtistASimplified,
|
||||
song.ArtistBSimplified,
|
||||
song.SongSimplified,
|
||||
//song.SongGenre,
|
||||
//song.ArtistAPinyin,
|
||||
//song.ArtistBPinyin,
|
||||
song.HumanVoice,
|
||||
//song.AddedTime,
|
||||
song.SongFilePathHost1,
|
||||
song.SongFilePathHost2 // 例如语言类别等信息
|
||||
song.FileName
|
||||
})
|
||||
.ToList(),
|
||||
status = "success",
|
||||
|
@ -1004,7 +1004,7 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
if (songIndex >= 0 && songIndex < totalSongs)
|
||||
{
|
||||
selectedSong = LanguageSongList[songIndex];
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Song + " " + selectedSong.SongFilePathHost1);
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Song + " " + selectedSong.FileName);
|
||||
|
||||
|
||||
// DisplayActionWithSong(currentPage, songIndex, "點播");
|
||||
@ -1036,7 +1036,7 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
if (songIndex < totalSongs)
|
||||
{
|
||||
selectedSong = LanguageSongList[songIndex];
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Song + " " + selectedSong.SongFilePathHost1 );
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Song + " " + selectedSong.FileName );
|
||||
|
||||
|
||||
// DisplayActionWithSong(currentPage, songIndex, "插播");
|
||||
@ -1120,7 +1120,7 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
if (songIndex < totalSongs)
|
||||
{
|
||||
selectedSong = LanguageSongList[songIndex];
|
||||
Console.WriteLine("Adding song to playlist C: " + LanguageSongList[songIndex].Song + " " + selectedSong.SongFilePathHost1);
|
||||
Console.WriteLine("Adding song to playlist C: " + LanguageSongList[songIndex].Song + " " + selectedSong.FileName);
|
||||
|
||||
|
||||
DisplaySongsWithArrows(currentPage, songIndex);
|
||||
@ -1531,40 +1531,12 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
{
|
||||
try
|
||||
{
|
||||
var filePath1 = songData.SongFilePathHost1;
|
||||
var filePath2 = songData.SongFilePathHost2;
|
||||
//var filePath1 = songData.SongFilePathHost1;
|
||||
//var filePath2 = songData.SongFilePathHost2;
|
||||
// 之後還要設計成本地的資料夾位置
|
||||
var filename = songData.FileName;
|
||||
bool checkpath = false;
|
||||
string pathToPlay = "";
|
||||
if (File.Exists(filename))
|
||||
string pathToPlay = songData.FileName;
|
||||
if (File.Exists(pathToPlay))
|
||||
{
|
||||
pathToPlay = filename;
|
||||
checkpath = true;
|
||||
PrimaryForm.WriteLog(String.Format("{0} Using local file: {1}", songData.Song,filename));
|
||||
}
|
||||
else if (File.Exists(filePath1))
|
||||
{
|
||||
pathToPlay = filePath1;
|
||||
checkpath = true;
|
||||
PrimaryForm.WriteLog(String.Format("{0} Using Host1 file: {1}", songData.Song, filePath1));
|
||||
}
|
||||
else if (File.Exists(filePath2))
|
||||
{
|
||||
pathToPlay = filePath2;
|
||||
checkpath = true;
|
||||
PrimaryForm.WriteLog(String.Format("{0} Using Host2 file: {1}", songData.Song, filePath2));
|
||||
}
|
||||
else
|
||||
{
|
||||
PrimaryForm.WriteLog(String.Format("File not found on hosts: {0}, {1} and {2}", filename, filePath1, filePath2));
|
||||
}
|
||||
|
||||
if (checkpath)
|
||||
{
|
||||
//做判定 決定pathToPlay值
|
||||
//pathToPlay = File.Exists(filePath1) ? filePath1 : filePath2;
|
||||
|
||||
bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0;
|
||||
|
||||
PrimaryForm.userRequestedSongs.Add(songData);
|
||||
@ -1599,19 +1571,13 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
try
|
||||
{
|
||||
// 從 songData 中取得兩個可能的檔案路徑(主機1與主機2)
|
||||
var filePath1 = songData.SongFilePathHost1;
|
||||
var filePath2 = songData.SongFilePathHost2;
|
||||
var pathToPlay = songData.FileName;
|
||||
|
||||
// 檢查兩個主機上的檔案是否皆不存在
|
||||
if (!File.Exists(filePath1) && !File.Exists(filePath2))
|
||||
{
|
||||
// 若兩個都找不到,寫入 Log 並不加入歌單
|
||||
PrimaryForm.WriteLog(String.Format("File not found on both hosts: {0} and {1}", filePath1, filePath2));
|
||||
}
|
||||
else
|
||||
if (File.Exists(pathToPlay))
|
||||
{
|
||||
// 若其中一個存在,就用第一個存在的那個檔案
|
||||
var pathToPlay = File.Exists(filePath1) ? filePath1 : filePath2;
|
||||
|
||||
Console.WriteLine("path to play" + pathToPlay);
|
||||
|
||||
// 檢查目前使用者歌單是否為空
|
||||
|
@ -37,23 +37,16 @@ namespace DualScreenDemo{
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
string songNumber = reader["song_id"].ToString();
|
||||
string song = reader["song_name"].ToString();
|
||||
string artistA = reader["artistA"].ToString();
|
||||
string artistB = reader["artistB"].ToString();
|
||||
string fileName = reader["song_filename"].ToString();
|
||||
string songFilePathHost1 = Path.Combine(@"\\SVR01\e\", fileName);
|
||||
string songFilePathHost2 = Path.Combine(@"\\SVR02\e\", fileName);
|
||||
string artistASimplified = reader["artistA_simplified"].ToString();
|
||||
string artistBSimplified = reader["artistB_simplified"].ToString();
|
||||
string songSimplified = reader["song_simplified"].ToString();
|
||||
int humanVoice = Convert.ToInt32(reader["vocal"]);
|
||||
|
||||
searchResults.Add(new SongData(
|
||||
songNumber, song, artistA, artistB,fileName,
|
||||
songFilePathHost1, songFilePathHost2,
|
||||
artistASimplified, artistBSimplified,
|
||||
songSimplified, humanVoice
|
||||
reader["song_id"].ToString(),
|
||||
reader["song_name"].ToString(),
|
||||
reader["artistA"].ToString(),
|
||||
reader["artistB"].ToString(),
|
||||
reader["song_filename"].ToString(),
|
||||
reader["artistA_simplified"].ToString(),
|
||||
reader["artistB_simplified"].ToString(),
|
||||
reader["song_simplified"].ToString(),
|
||||
Convert.ToInt32(reader["vocal"])
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ namespace DualScreenDemo
|
||||
public VideoPlayerForm videoPlayerForm;
|
||||
public List<SongData> currentSongList;
|
||||
public List<Artist> currentArtistList;
|
||||
public List<SongData> publicSongList;
|
||||
public static List<SongData> userRequestedSongs;
|
||||
public static List<SongData> playedSongsHistory;
|
||||
public static List<PlayState> playStates;
|
||||
@ -1546,50 +1545,9 @@ namespace DualScreenDemo
|
||||
private void LoadSongData()
|
||||
{
|
||||
userRequestedSongs = new List<SongData>();
|
||||
publicSongList = new List<SongData>();
|
||||
playedSongsHistory = new List<SongData>();
|
||||
playStates = new List<PlayState>();
|
||||
LoadLocalVideoFiles();
|
||||
}
|
||||
|
||||
// 將原本的本地文件載入邏輯抽取為單獨的方法
|
||||
private void LoadLocalVideoFiles()
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] videoFiles = Directory.GetFiles(@"D:\video\", "*.mpg");
|
||||
string pattern = @"^(?<songNumber>\d+)-.*?-(?<songName>[^-]+)-";
|
||||
|
||||
foreach (var songPath in videoFiles)
|
||||
{
|
||||
string fileName = Path.GetFileNameWithoutExtension(songPath);
|
||||
Match match = Regex.Match(fileName, pattern);
|
||||
string songNumber = "";
|
||||
string songName = "";
|
||||
if (match.Success){
|
||||
songNumber = match.Groups["songNumber"].Value;
|
||||
songName = match.Groups["songName"].Value;
|
||||
}
|
||||
SongData song = new SongData(
|
||||
songNumber, // songNumber
|
||||
songName, // song
|
||||
"", // artistA
|
||||
"", // artistB
|
||||
"", // filename
|
||||
songPath, // songFilePathHost1
|
||||
"", // songFilePathHost2
|
||||
"", // songFilePathHost3
|
||||
"", // songFilePathHost4
|
||||
"", // songFilePathHost5
|
||||
1 // priority
|
||||
);
|
||||
publicSongList.Add(song);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"Failed to read video files: {ex.Message}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Bitmap ResizeImage(Image image, int width, int height)
|
||||
|
21
Program.cs
21
Program.cs
@ -13,6 +13,7 @@ namespace DualScreenDemo
|
||||
internal static SerialPortManager serialPortManager;
|
||||
private static PrimaryForm primaryForm; // 儲存實例的參考
|
||||
public static string RoomState = Utils.Env.Get("RoomStates", "CLOSE");
|
||||
public static DataCheck.PublicSongChecker cherker;
|
||||
|
||||
[STAThread]
|
||||
static void Main()
|
||||
@ -36,7 +37,7 @@ namespace DualScreenDemo
|
||||
|
||||
//Console.WriteLine("正在與中控取得聯繫...");
|
||||
var sender = new heartbeatSender();
|
||||
var cherker =new DataCheck.DataChecker();
|
||||
cherker =new DataCheck.PublicSongChecker();
|
||||
|
||||
try
|
||||
{
|
||||
@ -64,8 +65,8 @@ namespace DualScreenDemo
|
||||
}
|
||||
|
||||
// 啟動服務器
|
||||
var TCP = new TCPServer();
|
||||
Task.Run(() => HttpServerManager.StartServer());
|
||||
Task.Run(() => TCPServerManager.StartServer());
|
||||
|
||||
// 註冊事件
|
||||
Application.ApplicationExit += (sender, e) => SerialPortManager.CloseSerialPortSafely();
|
||||
@ -82,18 +83,6 @@ namespace DualScreenDemo
|
||||
// 在完整初始化後檢查狀態
|
||||
InitializeSecondaryScreen();
|
||||
|
||||
WatchDog _watchDog = new WatchDog(
|
||||
() => VideoPlayerForm.Instance.GetCurrentVideoStatus(),
|
||||
() => primaryForm.IsAppResponsive()
|
||||
);
|
||||
_watchDog.Start();
|
||||
Console.WriteLine("啟動WatchDog進行監聽");
|
||||
AppDomain.CurrentDomain.ProcessExit += (s, e) =>
|
||||
{
|
||||
_watchDog.Stop();
|
||||
};
|
||||
|
||||
|
||||
primaryForm.Show();
|
||||
Application.Run(primaryForm);
|
||||
|
||||
@ -161,7 +150,7 @@ namespace DualScreenDemo
|
||||
primaryForm.videoPlayerForm.Show();
|
||||
|
||||
// 初始化公共播放列表
|
||||
primaryForm.videoPlayerForm.InitializePublicPlaylist(primaryForm.publicSongList);
|
||||
primaryForm.videoPlayerForm.InitializePublicPlaylist(cherker.GetSongs());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,7 +174,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
primaryForm.videoPlayerForm = new VideoPlayerForm();
|
||||
// primaryForm.primaryMediaPlayerForm = new PrimaryMediaPlayerForm(primaryForm, primaryForm.secondaryMediaPlayerForm);
|
||||
primaryForm.videoPlayerForm.InitializePublicPlaylist(primaryForm.publicSongList);
|
||||
primaryForm.videoPlayerForm.InitializePublicPlaylist(cherker.GetSongs());
|
||||
primaryForm.videoPlayerForm.Show();
|
||||
}
|
||||
}
|
||||
|
84
PublicSongChecker.cs
Normal file
84
PublicSongChecker.cs
Normal file
@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using DBObj;
|
||||
|
||||
namespace DataCheck
|
||||
{
|
||||
public class PublicSongChecker
|
||||
{
|
||||
|
||||
private List<SongData> publicSongList = new();
|
||||
public PublicSongChecker()
|
||||
{
|
||||
string serverPath = Utils.Env.GetPath("video", "");
|
||||
string localPath = @"D:\video";
|
||||
// 加入你要同步的資料夾
|
||||
SyncFolder(serverPath, localPath, "video", new[] { ".mpg" });
|
||||
}
|
||||
public List<SongData> GetSongs()
|
||||
{
|
||||
return publicSongList;
|
||||
}
|
||||
|
||||
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
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// 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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
10
TCPServer.cs
10
TCPServer.cs
@ -14,12 +14,14 @@ namespace DualScreenDemo
|
||||
private const int Port = 1000;
|
||||
private readonly string hostNameSuffix;
|
||||
//private bool isProcessingCommand = false;
|
||||
|
||||
|
||||
|
||||
public TCPServer()
|
||||
{
|
||||
listener = new TcpListener(IPAddress.Any, Port);
|
||||
hostNameSuffix = GetHostNameSuffix();
|
||||
|
||||
_ = Task.Run(() => Start());
|
||||
}
|
||||
|
||||
private bool IsFormReady(Form form)
|
||||
@ -136,11 +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);
|
||||
VideoPlayerForm.publicPlaylist = new List<SongData>();
|
||||
VideoPlayerForm.playingSongList = new List<SongData>();
|
||||
PrimaryForm.playedSongsHistory = new List<SongData>();
|
||||
|
@ -1,11 +0,0 @@
|
||||
namespace DualScreenDemo
|
||||
{
|
||||
public static class TCPServerManager
|
||||
{
|
||||
public static void StartServer()
|
||||
{
|
||||
TCPServer server = new TCPServer();
|
||||
server.Start();
|
||||
}
|
||||
}
|
||||
}
|
@ -612,8 +612,7 @@ namespace DualScreenDemo
|
||||
if (File.Exists(welcomePath))
|
||||
{
|
||||
publicPlaylist.Add(new SongData(
|
||||
"0", "歡迎光臨", "", "", "", welcomePath,
|
||||
"", "", "", "", 1
|
||||
"0", "歡迎光臨", welcomePath, 1
|
||||
));
|
||||
}
|
||||
|
||||
@ -624,8 +623,7 @@ namespace DualScreenDemo
|
||||
if (File.Exists(bgmPath))
|
||||
{
|
||||
publicPlaylist.Add(new SongData(
|
||||
i.ToString(), $"背景音樂{i:D2}",
|
||||
"", "", "", bgmPath, "", "", "", "", 1
|
||||
i.ToString(), $"背景音樂{i:D2}", bgmPath, 1
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -638,11 +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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -769,7 +763,7 @@ namespace DualScreenDemo
|
||||
var songToPlay = currentPlaylist[currentSongIndex];
|
||||
|
||||
// pathToPlay 需要調整
|
||||
var pathToPlay = File.Exists(songToPlay.SongFilePathHost1) ? songToPlay.SongFilePathHost1 : songToPlay.SongFilePathHost2;
|
||||
var pathToPlay = songToPlay.FileName;
|
||||
|
||||
// 若兩個 host 上都找不到檔案就直接結束
|
||||
if (!File.Exists(pathToPlay))
|
||||
@ -966,9 +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));
|
||||
}
|
||||
|
||||
// 添加 BGM 序列
|
||||
@ -977,10 +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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1000,7 +989,7 @@ namespace DualScreenDemo
|
||||
List<SongData> currentPlaylist = isUserPlaylistPlaying ? playingSongList : publicPlaylist;
|
||||
if (!currentPlaylist.Any()) return;
|
||||
var songToPlay = currentPlaylist[currentSongIndex];
|
||||
var pathToPlay = File.Exists(songToPlay.SongFilePathHost1) ? songToPlay.SongFilePathHost1 : songToPlay.SongFilePathHost2;
|
||||
var pathToPlay = songToPlay.FileName;
|
||||
if (!File.Exists(pathToPlay))
|
||||
{
|
||||
MessageBox.Show("File does not exist on both hosts.");
|
||||
@ -1570,9 +1559,7 @@ namespace DualScreenDemo
|
||||
if (audioTrack1 == -1)
|
||||
{
|
||||
audioTrack1 = i;
|
||||
}
|
||||
else if (audioTrack2 == -1)
|
||||
{
|
||||
} else if (audioTrack2 == -1) {
|
||||
audioTrack2 = i;
|
||||
}
|
||||
|
||||
@ -1663,19 +1650,8 @@ namespace DualScreenDemo
|
||||
|
||||
public void AddSongToPlaylist(SongData songData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filePath1 = songData.SongFilePathHost1;
|
||||
var filePath2 = songData.SongFilePathHost2;
|
||||
|
||||
if (!File.Exists(filePath1) && !File.Exists(filePath2))
|
||||
{
|
||||
PrimaryForm.WriteLog(String.Format("File not found on both hosts: {0} and {1}", filePath1, filePath2));
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0;
|
||||
|
||||
// 查找所有相同歌曲的索引
|
||||
var sameNameIndices = new List<int>();
|
||||
for (int i = 0; i < PrimaryForm.playedSongsHistory.Count; i++)
|
||||
@ -1745,19 +1721,8 @@ namespace DualScreenDemo
|
||||
|
||||
public void InsertSongToPlaylist(SongData songData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filePath1 = songData.SongFilePathHost1;
|
||||
var filePath2 = songData.SongFilePathHost2;
|
||||
|
||||
if (!File.Exists(filePath1) && !File.Exists(filePath2))
|
||||
{
|
||||
PrimaryForm.WriteLog(String.Format("File not found on both hosts: {0} and {1}", filePath1, filePath2));
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0;
|
||||
|
||||
// 查找所有相同歌曲的索引
|
||||
var sameNameIndices = new List<int>();
|
||||
for (int i = 0; i < PrimaryForm.playedSongsHistory.Count; i++)
|
||||
|
84
WatchDog.cs
84
WatchDog.cs
@ -1,84 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using DualScreenDemo.Shared;
|
||||
public class WatchDog
|
||||
{
|
||||
|
||||
private Func<VideoStatus> getVideoStatus;
|
||||
private Func<bool> isApplicationResponsive;
|
||||
private Thread watchdogThread;
|
||||
private bool running = false;
|
||||
private double lastPosition = -1;
|
||||
private int freezeCounter = 0;
|
||||
|
||||
public WatchDog(Func<VideoStatus> getVideoPositionFunc, Func<bool> isAppResponsiveFunc)
|
||||
{
|
||||
getVideoStatus = getVideoPositionFunc;
|
||||
isApplicationResponsive = isAppResponsiveFunc;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
running = true;
|
||||
watchdogThread = new Thread(Run);
|
||||
watchdogThread.IsBackground = true;
|
||||
watchdogThread.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
running = false;
|
||||
watchdogThread?.Join();
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
while (running)
|
||||
{
|
||||
var status = getVideoStatus(); // 改用 getVideoStatus 取得完整狀態
|
||||
bool responsive = isApplicationResponsive();
|
||||
|
||||
if (!status.IsGraphOk)
|
||||
{
|
||||
Log($"影片圖表異常: {status.LastError}");
|
||||
}
|
||||
else if(status.PlayState != "Paused")
|
||||
{
|
||||
double currentPosition = status.PositionSeconds;
|
||||
|
||||
if (Math.Abs(currentPosition - lastPosition) < 0.001)
|
||||
{
|
||||
freezeCounter++;
|
||||
if (freezeCounter >= 3)
|
||||
{
|
||||
Log($"影片疑似卡死(3次位置沒變):位置={currentPosition:F2}秒,播放狀態={status.PlayState}");
|
||||
freezeCounter = 0; // 記得 reset
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freezeCounter = 0;
|
||||
}
|
||||
|
||||
lastPosition = currentPosition;
|
||||
}
|
||||
|
||||
if (!responsive)
|
||||
{
|
||||
Log("UI 疑似卡死(Invoke 失敗)");
|
||||
}
|
||||
|
||||
Thread.Sleep(5000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Log(string message)
|
||||
{
|
||||
string logFilePath = Path.Combine("txt", "watchdog_log.txt");
|
||||
File.AppendAllText(logFilePath, $"{DateTime.Now}: {message}{Environment.NewLine}");
|
||||
}
|
||||
}
|
@ -71,11 +71,6 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- 複製資料夾 foods -->
|
||||
<Content Include="foods\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
<!-- 複製資料夾 db -->
|
||||
<Content Include="db\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
@ -90,11 +85,6 @@
|
||||
<Content Include="themes\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<!-- 複製資料夾 news -->
|
||||
<Content Include="news\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
<!-- 複製資料夾 sounds -->
|
||||
<Content Include="sounds\**\*.*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
Loading…
x
Reference in New Issue
Block a user