202508111732

調整開包廂計算關包廂時間
調整寫法
This commit is contained in:
jasonchenwork 2025-08-11 17:36:01 +08:00
parent be19d8bcf7
commit fdd8cf047d
13 changed files with 133 additions and 349 deletions

View File

@ -15,12 +15,9 @@ namespace DBObj
NameSimplified=nameSimplified;
}
public string getName(bool IsSimplified=false) { return IsSimplified ? NameSimplified : Name; }
public string getName() {return Name;}
public string getName() => Name;
public override string ToString() => $"Name: {Name}";
public override string ToString()
{
//return $"Name: {Name}, Phonetic: {Phonetic}, Category: {Category}, Strokes: {Strokes}";
return $"Name: {Name}";
}
}
}

View File

@ -119,53 +119,22 @@ namespace DBObj
}
return dict;
}
public void moveNext()
{
cursor++;
}
public void movePrevious()
{
cursor--;
}
public void move(int index)
{
cursor = index;
}
public void moveFirst()
{
cursor = 0;
}
public void moveEnd()
{
cursor = table.Rows.Count - 1;
}
public bool bof()
{
return (cursor < 0) || (table.Rows.Count == 0);
}
public bool eof()
{
return cursor > table.Rows.Count - 1;
}
public void moveNext() => cursor++;
public void movePrevious() => cursor--;
public void move(int index) => cursor = index;
public void moveFirst() => cursor = 0;
public void moveEnd() => cursor = table.Rows.Count - 1;
public bool bof() => (cursor < 0) || (table.Rows.Count == 0);
public bool eof() => cursor > table.Rows.Count - 1;
public bool Read()
{
if (eof()) return false;
moveNext();
return !eof();
}
public int recordCount()
{
return table.Rows.Count;
}
public bool found()
{
return table.Rows.Count > 0;
}
public void clear()
{
table.Clear();
}
public int recordCount() => table.Rows.Count;
public bool found() => table.Rows.Count > 0;
public void clear() => table.Clear();
// INSERT / UPDATE / DELETE 方法
public int ExecuteNonQuery(string query, MySqlParameter[] parameters)

View File

@ -17,10 +17,10 @@ namespace DBObj
FileName=filename;
HumanVoice =humanVoice;
}
public string getNumber() {return Number;}
public string getName(bool IsSimplified) {return IsSimplified ? Name_Simplified : Name;}
public string getName() { return Name;}
public string getFileName() { return FileName;}
public int getHumanVoice() { return HumanVoice;}
public string getNumber() => Number;
public string getName(bool IsSimplified) => IsSimplified ? Name_Simplified : Name;
public string getName() =>Name;
public string getFileName() => FileName;
public int getHumanVoice() => HumanVoice;
}
}

View File

@ -20,14 +20,9 @@ namespace DBObj
public SongData(string songNumber, string song, string artistA, string artistB, string filename, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice)
{
basic=new(songNumber,song,songSimplified,filename,humanVoice);
A= new Artist(artistA, artistASimplified);
if(!artistB.Equals("")){
B = new Artist(artistB, artistBSimplified);
} else
{
B = null;
}
isPublicSong = false;
A = new Artist(artistA, artistASimplified);
B = !artistB.Equals("") ? new Artist(artistB, artistBSimplified) : null;
isPublicSong = false;
}
public SongData(SongData value,PlayState s){
basic = value.getBasic();
@ -39,15 +34,15 @@ namespace DBObj
public Artist getA() => A;
public Artist getB() => B;
public string getNumber() {return basic.getNumber();}
public string getName(bool IsSimplified=false) { return basic.getName(IsSimplified); }
public string getName() { return basic.getName();}
public string getArtist_A(bool IsSimplified) { return A.getName(IsSimplified); }
public string getArtist_A() { return A.getName();}
public string getArtist_B(bool IsSimplified) { return B.getName(IsSimplified); }
public string getArtist_B() { return B.getName();}
public int getNameLength() { return basic.getName().Length; }
public string getFileName() {return basic.getFileName();}
public string getNumber() => basic.getNumber();
public string getName(bool IsSimplified=false) => basic.getName(IsSimplified);
public string getName() => basic.getName();
public string getArtist_A(bool IsSimplified) => A.getName(IsSimplified);
public string getArtist_A() => A.getName();
public string getArtist_B(bool IsSimplified) => B.getName(IsSimplified);
public string getArtist_B() => B.getName();
public int getNameLength() =>basic.getName().Length;
public string getFileName() => basic.getFileName();
public string next_song_text()
{
var str = (state == PlayState.InsertPlayback) ? GetStateTxt(false) : "";
@ -101,26 +96,21 @@ namespace DBObj
}
return null; // 找不到就回原本的 filename不加路徑
}
public Color GetStateColor(){
Color c = Color.White;
if (state == PlayState.Played) c = Color.Gray;//Color.FromArgb(200, 75, 125); // 播畢顏色:紫紅色
else if (state == PlayState.Skipped)c = Color.Gray;
else if (state == PlayState.NoFile)c = Color.Gray;
else if (state == PlayState.Playing)c = Color.LimeGreen;
else if (state == PlayState.InsertPlayback)c = Color.Gold;
return c;
}
public string GetStateTxt(bool IsSimplified){
return (state==PlayState.NotPlayed)?"":$"({state.GetDescription(IsSimplified)})";
}
public Color GetStateColor() => state switch
{
PlayState.Played => Color.Gray,
PlayState.Skipped => Color.Gray,
PlayState.NoFile => Color.Gray,
PlayState.Playing => Color.LimeGreen,
PlayState.InsertPlayback => Color.Gold,
_ => Color.White
};
public string GetStateTxt(bool IsSimplified) => (state==PlayState.NotPlayed)?"":$"({state.GetDescription(IsSimplified)})";
public void SetState(PlayState s) => state = s;
public PlayState GetState()
{
return state;
}
public PlayState GetState() => state;
public int getHumanVoice() { return basic.getHumanVoice(); }
public int getHumanVoice() => basic.getHumanVoice();
public override string ToString()
{
return String.Format("{0} {1}", basic.getName(),state.GetDescription() );

View File

@ -162,7 +162,6 @@ namespace DBObj
}
public static void clearSong()
{
isWelcome = true;
not_played.Clear();
played.Clear();

View File

@ -38,7 +38,6 @@ namespace OverlayFormObj
private int topMargin;
private int bottomMargin;
public static System.Windows.Forms.Timer displayTimer = new System.Windows.Forms.Timer();
public static System.Timers.Timer songDisplayTimer = new System.Timers.Timer();
public static System.Timers.Timer unifiedTimer;
private System.Windows.Forms.Timer stickerTimer1 = new System.Windows.Forms.Timer();
private System.Windows.Forms.Timer stickerTimer2 = new System.Windows.Forms.Timer();
@ -360,12 +359,6 @@ namespace OverlayFormObj
displayTimer.Interval = 15000;
displayTimer.Tick += DisplayTimer_Tick;
songDisplayTimer = new System.Timers.Timer(30000);
songDisplayTimer.Elapsed += new ElapsedEventHandler(SongDisplayTimer_Elapsed);
songDisplayTimer.AutoReset = true;
songDisplayTimer.Enabled = true;
unifiedTimer = new System.Timers.Timer(15000);
unifiedTimer.Elapsed += new ElapsedEventHandler(UnifiedTimer_Elapsed);
@ -416,35 +409,6 @@ namespace OverlayFormObj
displayTimer.Stop(); // 停止计时器
}
// 當 songDisplayTimer 計時完成時會呼叫此函式
private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
{
// 檢查是否需要跨執行緒操作 UI 控制項
if (MainForm.InvokeRequired)
{
// 如果目前不在 UI 執行緒上,必須透過 Invoke 安全執行 UI 更新邏輯
Console.WriteLine("SongDisplayTimer_Tick invoked on UI thread.");
MainForm.BeginInvoke(new Action(() =>
{
if (MainForm.topLeftLabel != null)
MainForm.topLeftLabel.Visible = true;
}));
}
else
{
// 如果已經在 UI 執行緒,就直接更新 UI 控制項
Console.WriteLine("SongDisplayTimer_Tick invoked on background thread.");
//MainForm.songDisplayLabel.Text = "";
MainForm.topLeftLabel.Visible = true;
}
// 停止計時器,避免重複觸發
songDisplayTimer.Stop();
}
private readonly object _lockObject = new object();
private bool _handlingTimeout = false;
private async void UnifiedTimer_Elapsed(object sender, EventArgs e)

View File

@ -175,7 +175,6 @@ namespace DualScreenDemo
private PictureBox serviceBellPictureBox; // 添加为类成员变量
private Timer autoRefreshTimer;
private TimeSpan remainingTime;
private Timer timerCountdown;
string Rtime;
@ -232,7 +231,7 @@ namespace DualScreenDemo
timerCountdown = new Timer();
timerCountdown.Interval = 1000; // 1 second
timerCountdown.Tick += TimerCountdown_Tick;
timerCountdown.Start();
}
// 添加 DPI 感知支持
@ -252,18 +251,10 @@ namespace DualScreenDemo
}
}
public void RoomTimeStart()
{
//DateTime now = DateTime.Now;
//DateTime tenMinutesLater = now.AddMinutes(120);
//remainingTime = tenMinutesLater - now;
remainingTime = Program.room.timePeriod;
timerCountdown.Start();
}
private async void TimerCountdown_Tick(object sender, EventArgs e)
{
TimeSpan remainingTime = Program.room.getTimeSpan();
if (remainingTime.TotalSeconds > 0)
{
remainingTime = remainingTime.Subtract(TimeSpan.FromSeconds(1));

View File

@ -13,7 +13,7 @@ namespace DualScreenDemo
private static PrimaryForm primaryForm; // 儲存實例的參考
public static Room room = new Room();
public static string verSion = "Server V2.8 202508081823";
public static string verSion = "Server V2.8 202508111732";
[STAThread]
static void Main()

19
Room.cs
View File

@ -13,7 +13,6 @@ namespace DualScreenDemo
private string State = "error";
private DateTime? startedAt;
private DateTime? endedAt;
public TimeSpan timePeriod;
public Room()
{
@ -47,14 +46,13 @@ namespace DualScreenDemo
var Statedb = db.Field<string>("status");
startedAt = ParseTime(db.Field<string>("started_at"));
endedAt = ParseTime(db.Field<string>("ended_at"));
timePeriod = (TimeSpan)(endedAt - DateTime.Now);
PrimaryForm.Instance.RoomTimeStart();
if (Statedb.Equals("maintain")) { Statedb = "active"; }
return Statedb;
}
}
return "error";
}
public TimeSpan getTimeSpan() => (endedAt!=null && endedAt.HasValue) ?(TimeSpan)(endedAt.Value - DateTime.Now):TimeSpan.Zero;
public void setDB(string value)
{
using (var db = new MyDB())
@ -72,13 +70,9 @@ namespace DualScreenDemo
{
string StateDB=getDB();
if (!StateDB.Equals(State))
{
State = StateDB;
}
else
{
return;
}
string marqueeMessage = "歡迎使用超級巨星歡唱,與你共度美好時光。";
Color c = Color.White;
@ -119,14 +113,9 @@ namespace DualScreenDemo
return dt;
return null;
}
public bool IsClose()
{
return State.Equals("closed");
}
public bool IsOpen()
{
return State.Equals("active");
}
public bool IsClose() => State.Equals("closed");
public bool IsOpen() => State.Equals("active");
}

View File

@ -8,63 +8,12 @@ namespace DualScreenDemo.Services
{
public IGraphBuilder graphBuilder;
private IMediaControl mediaControl;
private IBaseFilter videoRenderer;
public IBaseFilter renderer;
//private IBaseFilter audioRenderer;
private IBaseFilter lavSplitter;
private IBaseFilter lavVideoDecoder;
private IBaseFilter lavAudioDecoder;
private IPin outputPin;
private IBaseFilter audioRenderer;
private IVideoWindow videoWindow;
public int Run()
{
if (mediaControl != null)
return mediaControl.Run();
else
return 0;
}
public int Stop()
{
if (mediaControl != null)
return mediaControl.Stop();
else
return 0;
}
public int Pause()
{
if (mediaControl != null)
return mediaControl.Pause();
else
return 0;
}
public void VideoPlayerFormClosing()
{
if (videoWindow != null)
{
videoWindow.put_Visible(OABool.False);
videoWindow.put_Owner(IntPtr.Zero);
Marshal.ReleaseComObject(videoWindow);
videoWindow = null;
}
}
public void StopAndReleaseResources()
{
if (mediaControl != null)
{
mediaControl.Stop();
SafeRelease(ref mediaControl);
}
SafeRelease(ref videoWindow);
SafeRelease(ref videoRenderer);
SafeRelease(ref lavAudioDecoder);
SafeRelease(ref outputPin);
SafeRelease(ref lavVideoDecoder);
SafeRelease(ref lavSplitter);
SafeRelease(ref graphBuilder);
}
public int Run() => (mediaControl != null) ? mediaControl.Run() : 0;
public int Stop() => (mediaControl != null) ? mediaControl.Stop() : 0;
public int Pause() => (mediaControl != null) ? mediaControl.Pause() : 0;
public bool isAtEnd()
{
bool isAtEnd = false;
@ -92,42 +41,22 @@ namespace DualScreenDemo.Services
}
return isAtEnd;
}
public void RenderMediaFile(string filePath, nint Handle, int Width, int Height)
public void RenderMediaFile(string filePath)
{
StopAndReleaseResources();
if (videoWindow != null) videoWindow.put_Visible(OABool.False);
Stop();
SafeRelease(ref renderer);
SafeRelease(ref lavSplitter);
SafeRelease(ref graphBuilder);
int hr = 0;
graphBuilder = (IGraphBuilder)new FilterGraph();
if (graphBuilder == null)
{
Console.WriteLine("Failed to create FilterGraph");
throw new Exception("Failed to create FilterGraph");
}
try
{
lavSplitter = AddFilterByClsid(graphBuilder, "LAV Splitter", Clsid.LAVSplitter);
lavVideoDecoder = AddFilterByClsid(graphBuilder, "LAV Video Decoder", Clsid.LAVVideoDecoder);
lavAudioDecoder = AddFilterByClsid(graphBuilder, "LAV Audio Decoder", Clsid.LAVAudioDecoder);
outputPin = FindPin(lavAudioDecoder, "Output");
videoRenderer = AddFilterByClsid(graphBuilder, "Secondary Video Renderer", Clsid.VideoRenderer);
if (videoRenderer == null)
{
Console.WriteLine("Failed to initialize Secondary Video Renderer.");
return;
}
hr = graphBuilder.AddFilter(videoRenderer, "Secondary Video Renderer");
DsError.ThrowExceptionForHR(hr);
var clsidAudioRenderer = new Guid("79376820-07D0-11CF-A24D-0020AFD79767"); // CLSID for DirectSound Renderer
audioRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(clsidAudioRenderer));
hr = graphBuilder.AddFilter(audioRenderer, "Default DirectSound Device");
DsError.ThrowExceptionForHR(hr);
AddFilterByClsid(graphBuilder, "LAV Video Decoder", Clsid.LAVVideoDecoder);
renderer = AddFilterByClsid(graphBuilder, "Secondary Video Renderer", Clsid.VideoRenderer);
//audioRenderer = AddFilterByClsid(graphBuilder, "Default DirectSound Device", Clsid.AudioRenderer);
mediaControl = (IMediaControl)graphBuilder;
if (mediaControl == null)
{
Console.WriteLine("Failed to get Media Control");
return;
}
}
catch (Exception ex)
{
@ -135,40 +64,25 @@ namespace DualScreenDemo.Services
}
hr = graphBuilder.RenderFile(filePath, null);
if (hr == 0)
{
Console.WriteLine("Secondary File rendered successfully.");
SetAudioTrackTo(1);
}
else
{
Console.WriteLine("Failed to render secondary file.");
}
// 绑定视频窗口到副屏幕
videoWindow = videoRenderer as IVideoWindow;
if (videoWindow != null)
{
videoWindow.put_Owner(Handle); // 副屏幕窗口句柄
videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings);
videoWindow.SetWindowPosition(0, 0, Width, Height);
videoWindow.put_Visible(OABool.True); // 显示窗口
}
}
public void SetVolume(int volume)
{
if (audioRenderer != null)
if (graphBuilder != null)
{
IBasicAudio basicAudio = audioRenderer as IBasicAudio;
IBasicAudio basicAudio = graphBuilder as IBasicAudio;
if (basicAudio != null)
{
basicAudio.put_Volume(volume);
}
basicAudio.put_Volume( Math.Max(-10000, Math.Min(0, volume)));
}
}
public int GetVolume()
{
if (audioRenderer != null)
if (graphBuilder != null)
{
IBasicAudio basicAudio = audioRenderer as IBasicAudio;
IBasicAudio basicAudio = graphBuilder as IBasicAudio;
if (basicAudio != null)
{
int volume;

View File

@ -9,46 +9,14 @@ namespace DualScreenDemo.Services
IGraphBuilder graphBuilder;
IBaseFilter lavSplitter;
IBaseFilter lavVideoDecoder;
IBaseFilter videoRenderer;
IVideoWindow videoWindow;
public IBaseFilter videoRenderer;
IMediaControl mediaControl;
IBaseFilter sourceFilter;
public MediaServicePrimary() { }
public int Run()
{
if (mediaControl != null)
return mediaControl.Run();
else
return 0;
}
public int Stop()
{
if (mediaControl != null)
return mediaControl.Stop();
else
return 0;
}
public int Pause()
{
if (mediaControl != null)
return mediaControl.Pause();
else
return 0;
}
public void VideoPlayerFormClosing()
{
if (videoWindow != null)
{
videoWindow.put_Visible(OABool.False);
videoWindow.put_Owner(IntPtr.Zero);
Marshal.ReleaseComObject(videoWindow);
videoWindow = null;
}
}
public int Run() => (mediaControl != null) ? mediaControl.Run() : 0;
public int Stop() => (mediaControl != null)? mediaControl.Stop() : 0;
public int Pause() => (mediaControl != null) ? mediaControl.Pause() : 0;
public void StopAndReleaseResources()
{
@ -57,7 +25,6 @@ namespace DualScreenDemo.Services
mediaControl.Stop();
SafeRelease(ref mediaControl);
}
SafeRelease(ref videoWindow);
SafeRelease(ref videoRenderer);
SafeRelease(ref sourceFilter);
SafeRelease(ref lavVideoDecoder);
@ -65,10 +32,10 @@ namespace DualScreenDemo.Services
SafeRelease(ref graphBuilder);
}
public void RenderMediaFile(string filePath, nint Handle, int Width, int Height)
public void RenderMediaFile(string filePath)
{
StopAndReleaseResources();
if (videoWindow != null) videoWindow.put_Visible(OABool.False);
int hr;
graphBuilder = (IGraphBuilder)new FilterGraph();
@ -84,38 +51,12 @@ namespace DualScreenDemo.Services
hr = graphBuilder.AddFilter(videoRenderer, "Primary Video Renderer");
DsError.ThrowExceptionForHR(hr);
mediaControl = (IMediaControl)graphBuilder;
if (mediaControl == null)
{
Console.WriteLine("Failed to get Media Control for primary monitor.");
return;
}
hr = ConnectFilters(graphBuilder, sourceFilter, "Output", lavSplitter, "Input");
DsError.ThrowExceptionForHR(hr);
hr = ConnectFilters(graphBuilder, lavSplitter, "Video", lavVideoDecoder, "Input");
DsError.ThrowExceptionForHR(hr);
hr = ConnectFilters(graphBuilder, lavVideoDecoder, "Output", videoRenderer, "VMR Input0");
DsError.ThrowExceptionForHR(hr);
try
{
IVideoWindow videoWindow = (IVideoWindow)videoRenderer;
videoWindow.put_Owner(Handle);
videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
// ⬅ 左上角對齊(固定從 0,0 開始)
videoWindow.SetWindowPosition(0, 0, Width, Height);
videoWindow.put_Visible(OABool.True);
// Console.WriteLine("Video window configured successfully.");
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Error syncing to primary monitor: {0}", ex.Message));
MessageBox.Show(String.Format("Error syncing to primary monitor: {0}", ex.Message));
}
}
catch (Exception ex)
{

View File

@ -54,7 +54,7 @@ namespace DualScreenDemo.Services
{
PinInfo pinInfo;
pins[0].QueryPinInfo(out pinInfo);
Console.WriteLine(pinInfo);
//Console.WriteLine(pinInfo+":"+pinInfo.name);
if (pinInfo.name == pinName)
{

View File

@ -71,6 +71,8 @@ namespace DualScreenDemo
private const uint SWP_NOZORDER = 0x0004;
private MediaServicePrimary primary = new MediaServicePrimary();
private MediaService secondary = new MediaService();
private IVideoWindow videoWindowPrimary;
private IVideoWindow videoWindowSecondary;
public static OverlayForm overlayForm;
public bool isMuted = false;
@ -158,8 +160,20 @@ namespace DualScreenDemo
private void VideoPlayerForm_FormClosing(object sender, FormClosingEventArgs e)
{
primary.VideoPlayerFormClosing();
secondary.VideoPlayerFormClosing();
if (videoWindowPrimary != null)
{
videoWindowPrimary.put_Visible(OABool.False);
videoWindowPrimary.put_Owner(IntPtr.Zero);
Marshal.ReleaseComObject(videoWindowPrimary);
videoWindowPrimary = null;
}
if (videoWindowSecondary != null)
{
videoWindowSecondary.put_Visible(OABool.False);
videoWindowSecondary.put_Owner(IntPtr.Zero);
Marshal.ReleaseComObject(videoWindowSecondary);
videoWindowSecondary = null;
}
// 清理COM
CoUninitialize();
}
@ -273,10 +287,6 @@ namespace DualScreenDemo
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch1, 0, commandBytesIncreasePitch1.Length);
}
}
// pathToPlay 需要調整
var pathToPlay = songToPlay.getFile();
// 更新畫面上顯示的下一首歌資訊
SongList.UpdateNextSongLabel();
@ -286,45 +296,40 @@ namespace DualScreenDemo
// 隱藏「暫停中」標籤
overlayForm.HidePauseLabel();
await _InitializeAndPlayMedia(pathToPlay);
await _InitializeAndPlayMedia(songToPlay);
}
public async Task ReplayCurrentSong()
{
var songToPlay = SongList.Current();
var pathToPlay = songToPlay.getFile();
// UpdateMarqueeTextForCurrentSong(songToPlay);
await _InitializeAndPlayMedia(pathToPlay);
}
private async Task _InitializeAndPlayMedia(string pathToPlay)
public async Task ReplayCurrentSong() =>await _InitializeAndPlayMedia(SongList.Current());
private async Task _InitializeAndPlayMedia(SongData song)
{
try
{
if (InvokeRequired)
{
await InvokeAsync(() => InitializeAndPlayMedia(pathToPlay));
await InvokeAsync(() => InitializeAndPlayMedia(song));
}
else
{
await InitializeAndPlayMedia(pathToPlay);
await InitializeAndPlayMedia(song);
}
}
catch (Exception ex)
{
Console.WriteLine($"播放時發生錯誤: {ex.Message}");
await RetryInitializeAndPlayMedia(pathToPlay);
await RetryInitializeAndPlayMedia(song);
}
}
private async Task RetryInitializeAndPlayMedia(string path)
private async Task RetryInitializeAndPlayMedia(SongData song)
{
try
{
int hr = CoInitializeEx(IntPtr.Zero, COINIT.APARTMENTTHREADED);
if (hr >= 0)
{
await InitializeAndPlayMedia(path);
await InitializeAndPlayMedia(song);
}
else
{
@ -356,11 +361,35 @@ namespace DualScreenDemo
return tcs.Task;
}
private Task InitializeAndPlayMedia(string pathToPlay)
private Task InitializeAndPlayMedia(SongData song)
{
string pathToPlay = song.getFile();
if (videoWindowPrimary != null) videoWindowPrimary.put_Visible(OABool.False);
if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False);
// 渲染媒體文件
primary.RenderMediaFile(pathToPlay,PrimaryForm.Instance.primaryScreenPanel.Handle,newWidth,newHeight);
secondary.RenderMediaFile(pathToPlay,this.Handle,secondMonitor.Bounds.Width,secondMonitor.Bounds.Height);
primary.RenderMediaFile(pathToPlay);
secondary.RenderMediaFile(pathToPlay);
videoWindowPrimary = primary.videoRenderer as IVideoWindow;
if (videoWindowPrimary != null)
{
videoWindowPrimary.put_Owner(PrimaryForm.Instance.primaryScreenPanel.Handle);
videoWindowPrimary.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
videoWindowPrimary.SetWindowPosition(0, 0, newWidth, newHeight);
videoWindowPrimary.put_Visible(OABool.True);
}
// 绑定视频窗口到副屏幕
videoWindowSecondary = secondary.renderer as IVideoWindow;
if (videoWindowSecondary != null)
{
videoWindowSecondary.put_Owner(this.Handle);
videoWindowSecondary.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren | WindowStyle.ClipSiblings);
videoWindowSecondary.SetWindowPosition(0, 0, secondMonitor.Bounds.Width, secondMonitor.Bounds.Height);
videoWindowSecondary.put_Visible(OABool.True);
}
// 音量處理
SetVolume(isMuted ? -10000 : previousVolume);
@ -392,6 +421,7 @@ namespace DualScreenDemo
{
Task.Run(async () =>
{
await Task.Delay(10000);
Console.WriteLine("開始監聽媒體事件...");
while (true)
{