調整 開關台流程 20250717
This commit is contained in:
parent
af3286292c
commit
e532e26b54
@ -35,11 +35,10 @@ namespace DBObj
|
||||
public string getArtist_B() { return B.getName();}
|
||||
public int getNameLength() { return basic.getName().Length; }
|
||||
public string getFileName() {return basic.getFileName();}
|
||||
public string next_artist_text()
|
||||
public string next_song_text()
|
||||
{
|
||||
return B!=null
|
||||
? String.Format("下一首:{0} {1} {2}", A.getName(false), B.getName(false), basic.getName(false))
|
||||
: String.Format("下一首:{0} {1}", A.getName(false), basic.getName(false));
|
||||
var str = (state == PlayState.InsertPlayback) ? GetStateTxt(false) : "";
|
||||
return String.Format("下一首:{0} {1}", basic.getName(false),str);
|
||||
}
|
||||
public string artist_text()
|
||||
{
|
||||
|
@ -6,7 +6,8 @@ namespace DBObj
|
||||
{
|
||||
public class SongList
|
||||
{
|
||||
public static SongData welcome ;
|
||||
private static bool isWelcome = true;
|
||||
public static SongData welcome;
|
||||
public static SongData close ;
|
||||
private static SongData publicPlaying=null;
|
||||
private static List<SongData> publicSong = new();
|
||||
@ -43,9 +44,17 @@ namespace DBObj
|
||||
}
|
||||
private static SongData NextPublicSong()
|
||||
{
|
||||
publicPlaying = publicSong[0];
|
||||
publicSong.RemoveAt(0);
|
||||
publicSong.Add(publicPlaying);
|
||||
if (Room.IsClose()) {
|
||||
publicPlaying = close;
|
||||
} else if(Room.IsOpen() && isWelcome){
|
||||
isWelcome = false;
|
||||
publicPlaying = welcome;
|
||||
} else {
|
||||
publicPlaying = publicSong[0];
|
||||
publicSong.RemoveAt(0);
|
||||
publicSong.Add(publicPlaying);
|
||||
}
|
||||
|
||||
return publicPlaying;
|
||||
}
|
||||
|
||||
@ -85,11 +94,13 @@ namespace DBObj
|
||||
public static void UpdateNextSongLabel()
|
||||
{
|
||||
VideoPlayerForm.overlayForm.UpdateTopLeftLabel(
|
||||
(not_played.Count > 0) ? not_played[0].getName() : "目前沒有下一首,請踴躍點歌!!!"
|
||||
(not_played.Count > 0) ? not_played[0].next_song_text() : "目前沒有下一首,請踴躍點歌!!!"
|
||||
);
|
||||
}
|
||||
public static void clearSong()
|
||||
{
|
||||
|
||||
isWelcome = true;
|
||||
not_played.Clear();
|
||||
played.Clear();
|
||||
}
|
||||
|
@ -527,19 +527,7 @@ namespace OverlayFormObj
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetMarqueeTextToWelcomeMessage()
|
||||
{
|
||||
try
|
||||
{
|
||||
string filePath = Path.Combine(Application.StartupPath,"txt","WelcomeMessage.txt");
|
||||
string welcomeMessage = File.ReadAllText(filePath);
|
||||
this.UpdateMarqueeText(welcomeMessage, MarqueeStartPosition.Right, Color.White);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error reading marquee text from file: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
|
@ -222,23 +222,6 @@ namespace DualScreenDemo
|
||||
this.Load += PrimaryForm_Load;
|
||||
|
||||
}
|
||||
public bool IsAppResponsive()
|
||||
{
|
||||
try
|
||||
{
|
||||
var form = this;
|
||||
if (form != null)
|
||||
{
|
||||
bool dummy = form.InvokeRequired; // 如果 Invoke 卡死,會丟錯
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 添加 DPI 感知支持
|
||||
[DllImport("user32.dll")]
|
||||
@ -2265,7 +2248,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
HotPlayButton_Click(null, EventArgs.Empty);
|
||||
}
|
||||
if (Program.RoomState.Equals("CLOSE"))
|
||||
if (Room.IsClose())
|
||||
{
|
||||
ShowSendOffScreen();
|
||||
}
|
||||
|
98
Program.cs
98
Program.cs
@ -1,30 +1,30 @@
|
||||
using System.IO;
|
||||
using Microsoft.Win32;
|
||||
using System.Diagnostics;
|
||||
using DBObj;
|
||||
using HeartbeatSender;
|
||||
namespace DualScreenDemo
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
// 定义全局变量
|
||||
internal static SongListManager songListManager;
|
||||
internal static DBObj.SongListManager songListManager;
|
||||
//internal static ArtistManager artistManager;
|
||||
internal static SerialPortManager serialPortManager;
|
||||
private static PrimaryForm primaryForm; // 儲存實例的參考
|
||||
public static string RoomState = Utils.Env.Get("RoomStates", "CLOSE");
|
||||
public static DataCheck.PublicSongChecker cherker;
|
||||
public static Room room = new Room();
|
||||
|
||||
|
||||
[STAThread]
|
||||
static void Main() {
|
||||
Console.WriteLine("Server V.1.2.1 202507171314");
|
||||
if(Utils.Env.GetBool("IsCursor", true))Cursor.Hide();
|
||||
static void Main()
|
||||
{
|
||||
Console.WriteLine("Server V.1.2.2 202507171805");
|
||||
if (Utils.Env.GetBool("IsCursor", true)) Cursor.Hide();
|
||||
AppDomain.CurrentDomain.ProcessExit += (s, e) => Cursor.Show();
|
||||
//Console.WriteLine("正在與中控取得聯繫...");
|
||||
var sender = new heartbeatSender();
|
||||
cherker =new DataCheck.PublicSongChecker(DBObj.SongList.PublicSong());
|
||||
|
||||
try {
|
||||
var cherker=new DataCheck.PublicSongChecker(DBObj.SongList.PublicSong());
|
||||
try
|
||||
{
|
||||
// COM 初始化
|
||||
int hr = ComInterop.CoInitializeEx(IntPtr.Zero, ComInterop.COINIT_APARTMENTTHREADED);
|
||||
if (hr < 0)
|
||||
@ -34,7 +34,7 @@ namespace DualScreenDemo
|
||||
}
|
||||
// 初始化管理器
|
||||
|
||||
songListManager = new SongListManager(); // 使用单例
|
||||
songListManager = new DBObj.SongListManager(); // 使用单例
|
||||
//artistManager = new ArtistManager();
|
||||
|
||||
var commandHandler = new CommandHandler(songListManager);
|
||||
@ -49,7 +49,7 @@ namespace DualScreenDemo
|
||||
}
|
||||
|
||||
// 啟動服務器
|
||||
var TCP = new TCPServer();
|
||||
|
||||
Task.Run(() => HttpServerManager.StartServer());
|
||||
|
||||
// 註冊事件
|
||||
@ -63,11 +63,14 @@ namespace DualScreenDemo
|
||||
primaryForm.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
|
||||
|
||||
// 在完整初始化後檢查狀態
|
||||
if (Screen.AllScreens.Length > 1) {
|
||||
if (Screen.AllScreens.Length > 1)
|
||||
{
|
||||
var secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary);
|
||||
if (secondaryScreen != null) {
|
||||
if (secondaryScreen != null)
|
||||
{
|
||||
// 确保 primaryForm 和 videoPlayerForm 已经正确初始化
|
||||
if (primaryForm.videoPlayerForm == null) {
|
||||
if (primaryForm.videoPlayerForm == null)
|
||||
{
|
||||
primaryForm.videoPlayerForm = new VideoPlayerForm();
|
||||
}
|
||||
|
||||
@ -85,45 +88,19 @@ namespace DualScreenDemo
|
||||
}
|
||||
primaryForm.Show();
|
||||
Application.Run(primaryForm);
|
||||
|
||||
|
||||
} catch (Exception ex) {
|
||||
WriteLog(ex.ToString());
|
||||
//} finally {
|
||||
//SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private static bool IsUrlAclExists(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "netsh",
|
||||
Arguments = "http show urlacl",
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using (Process process = Process.Start(startInfo))
|
||||
{
|
||||
using (StreamReader reader = process.StandardOutput)
|
||||
{
|
||||
string output = reader.ReadToEnd();
|
||||
return output.Contains(url); // 检查是否包含指定 URL
|
||||
}
|
||||
}
|
||||
|
||||
var TCP = new TCPServer();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("检查 URL ACL 时出错: " + ex.Message);
|
||||
return false;
|
||||
WriteLog(ex.ToString());
|
||||
//} finally {
|
||||
//SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
private static void OnDisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
// UI操作應該放在try-catch塊中
|
||||
@ -182,27 +159,6 @@ namespace DualScreenDemo
|
||||
Console.WriteLine(String.Format("Error writing to log file: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
/*
|
||||
private static Form CreatePrimaryForm()
|
||||
{
|
||||
return new Form
|
||||
{
|
||||
WindowState = FormWindowState.Maximized,
|
||||
FormBorderStyle = FormBorderStyle.None
|
||||
};
|
||||
}
|
||||
|
||||
private static Form CreateSecondaryForm(Screen screen)
|
||||
{
|
||||
return new Form
|
||||
{
|
||||
Text = "Secondary Screen Form",
|
||||
StartPosition = FormStartPosition.Manual,
|
||||
Bounds = screen.Bounds,
|
||||
WindowState = FormWindowState.Maximized,
|
||||
FormBorderStyle = FormBorderStyle.None
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
60
Room.cs
Normal file
60
Room.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using OverlayFormObj;
|
||||
|
||||
namespace DualScreenDemo
|
||||
{
|
||||
public class Room
|
||||
{
|
||||
private static string State=Utils.Env.Get("RoomStates", "CLOSE");
|
||||
public Room(){}
|
||||
public static void set(string value)
|
||||
{
|
||||
string marqueeMessage = "歡迎使用超級巨星歡唱,與你共度美好時光。";
|
||||
Color c = Color.White;
|
||||
State = value;
|
||||
if (value.Equals("PAUSE"))
|
||||
{
|
||||
PrimaryForm.Instance.ShowSendOffScreen();
|
||||
VideoPlayerForm.Instance.Pause();
|
||||
marqueeMessage = "發生火災,請跟隨引導至逃生出口!!!";
|
||||
c = Color.Red;
|
||||
}
|
||||
else if (value.Equals("OPEN"))
|
||||
{
|
||||
DBObj.SongList.clearSong();
|
||||
PrimaryForm.Instance.HotPlayButton_Click(null, EventArgs.Empty);
|
||||
PrimaryForm.Instance.HideSendOffScreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
DBObj.SongList.clearSong();
|
||||
PrimaryForm.Instance.pictureBoxQRCode.Visible = false;
|
||||
PrimaryForm.Instance.closeQRCodeButton.Visible = false;
|
||||
PrimaryForm.Instance.ShowSendOffScreen();
|
||||
|
||||
|
||||
OverlayForm.MainForm.topLeftLabel.Visible = false;
|
||||
|
||||
VideoPlayerForm.Instance.PlayNextSong();
|
||||
PrimaryForm.Instance.logout();
|
||||
|
||||
}
|
||||
|
||||
OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Middle, c);
|
||||
|
||||
}
|
||||
public static bool IsClose()
|
||||
{
|
||||
return State.Equals("CLOSE");
|
||||
}
|
||||
public static bool IsOpen()
|
||||
{
|
||||
return State.Equals("OPEN");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
66
TCPServer.cs
66
TCPServer.cs
@ -5,7 +5,6 @@ using System.Text.RegularExpressions;
|
||||
using System.IO; // 為 Path 和 File 提供支持
|
||||
using DBObj;
|
||||
using OverlayFormObj;
|
||||
using HeartbeatSender;
|
||||
namespace DualScreenDemo
|
||||
{
|
||||
public class TCPServer
|
||||
@ -123,50 +122,17 @@ namespace DualScreenDemo
|
||||
|
||||
if (command.Trim().Equals("X", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
PrimaryForm.Instance.pictureBoxQRCode.Visible = false;
|
||||
PrimaryForm.Instance.closeQRCodeButton.Visible = false;
|
||||
_ = SafeInvoke(VideoPlayerForm.Instance, async () =>
|
||||
{
|
||||
if (IsFormReady(PrimaryForm.Instance))
|
||||
{
|
||||
await SafeInvoke(PrimaryForm.Instance, async () =>
|
||||
{
|
||||
PrimaryForm.Instance.ShowSendOffScreen();
|
||||
Console.WriteLine("開始設置新的播放列表");
|
||||
|
||||
|
||||
string closePath = @"D:\video\CLOSE.MPG";
|
||||
if (File.Exists(closePath))
|
||||
{
|
||||
SongData closeSong = new SongData("0", "結束播放",closePath, 1,true);
|
||||
SongList.clearSong();
|
||||
SongList.Add(closeSong);
|
||||
|
||||
if (IsFormReady(OverlayForm.MainForm))
|
||||
OverlayForm.MainForm.topLeftLabel.Visible = false;
|
||||
|
||||
VideoPlayerForm.Instance.PlayNextSong();
|
||||
PrimaryForm.Instance.logout();
|
||||
Console.WriteLine("已設置新的播放列表,包含當前歌曲和 CLOSE.MPG");
|
||||
try
|
||||
{
|
||||
await HttpServer.RestartServer();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("RestartServer 發生錯誤: " + ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"錯誤: 找不到檔案 {closePath}");
|
||||
}
|
||||
OverlayForm.Instance.ResetMarqueeTextToWelcomeMessage();
|
||||
});
|
||||
Room.set("CLOSE");
|
||||
try{
|
||||
await HttpServer.RestartServer();
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("RestartServer 發生錯誤: " + ex.Message);
|
||||
}
|
||||
});
|
||||
|
||||
Program.RoomState = "CLOSE";
|
||||
|
||||
|
||||
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
||||
stream.Write(okResponse, 0, okResponse.Length);
|
||||
|
||||
@ -176,14 +142,7 @@ namespace DualScreenDemo
|
||||
if (command.Trim().Equals("O", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// 開台時跳至首頁
|
||||
|
||||
SongList.clearSong();
|
||||
PrimaryForm.Instance.HotPlayButton_Click(null, EventArgs.Empty);
|
||||
Program.RoomState = "OPEN";
|
||||
PrimaryForm.Instance.HideSendOffScreen();
|
||||
|
||||
OverlayForm.Instance.ResetMarqueeTextToWelcomeMessage();
|
||||
|
||||
Room.set("OPEN");
|
||||
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
||||
stream.Write(okResponse, 0, okResponse.Length);
|
||||
continue;
|
||||
@ -192,17 +151,10 @@ namespace DualScreenDemo
|
||||
{
|
||||
_ = SafeInvoke(PrimaryForm.Instance, () =>
|
||||
{
|
||||
PrimaryForm.Instance.ShowSendOffScreen();
|
||||
VideoPlayerForm.Instance.Pause();
|
||||
string marqueeMessage = "發生火災,請跟隨引導至逃生出口!!!";
|
||||
OverlayForm.MainForm.UpdateMarqueeText(marqueeMessage, OverlayForm.MarqueeStartPosition.Middle, Color.Red);
|
||||
Room.set("PAUSE");
|
||||
});
|
||||
|
||||
// 更新狀態檔案(可選,若你要記錄狀態)
|
||||
Program.RoomState = "PAUSE";
|
||||
byte[] okResponse = Encoding.UTF8.GetBytes("OK\n");
|
||||
stream.Write(okResponse, 0, okResponse.Length);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -623,8 +623,8 @@ namespace DualScreenDemo
|
||||
if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False);
|
||||
|
||||
// 清理並初始化 DirectShow 圖表
|
||||
RemoveAllFilters(graphBuilderPrimary);
|
||||
RemoveAllFilters(graphBuilderSecondary);
|
||||
//RemoveAllFilters(graphBuilderPrimary);
|
||||
//RemoveAllFilters(graphBuilderSecondary);
|
||||
InitializeGraphBuilderPrimary();
|
||||
InitializeGraphBuilderSecondary();
|
||||
|
||||
@ -667,8 +667,8 @@ namespace DualScreenDemo
|
||||
if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False); // 隐藏副屏幕窗口,避免闪烁
|
||||
|
||||
// 清理并初始化 DirectShow 图表
|
||||
RemoveAllFilters(graphBuilderPrimary);
|
||||
RemoveAllFilters(graphBuilderSecondary);
|
||||
//RemoveAllFilters(graphBuilderPrimary);
|
||||
//RemoveAllFilters(graphBuilderSecondary);
|
||||
InitializeGraphBuilderPrimary();
|
||||
InitializeGraphBuilderSecondary();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user