202508120940

video 畫面改回去物件裡面
This commit is contained in:
jasonchenwork 2025-08-12 09:46:50 +08:00
parent e175309909
commit e7511ddba8
4 changed files with 60 additions and 52 deletions

View File

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

View File

@ -11,10 +11,22 @@ namespace DualScreenDemo.Services
public IBaseFilter renderer; public IBaseFilter renderer;
//private IBaseFilter audioRenderer; //private IBaseFilter audioRenderer;
private IBaseFilter lavSplitter; private IBaseFilter lavSplitter;
private IVideoWindow videoWindow;
public int Run() => (mediaControl != null) ? mediaControl.Run() : 0; public int Run() => (mediaControl != null) ? mediaControl.Run() : 0;
public int Stop() => (mediaControl != null) ? mediaControl.Stop() : 0; public int Stop() => (mediaControl != null) ? mediaControl.Stop() : 0;
public int Pause() => (mediaControl != null) ? mediaControl.Pause() : 0; public int Pause() => (mediaControl != null) ? mediaControl.Pause() : 0;
public bool isAtEnd()
public void VideoPlayerForm_FormClosing()
{
if (videoWindow != null)
{
videoWindow.put_Visible(OABool.False);
videoWindow.put_Owner(IntPtr.Zero);
Marshal.ReleaseComObject(videoWindow);
videoWindow = null;
}
}
public bool IsAtEnd()
{ {
bool isAtEnd = false; bool isAtEnd = false;
if (mediaControl == null) { return false; } if (mediaControl == null) { return false; }
@ -34,20 +46,22 @@ namespace DualScreenDemo.Services
Math.Abs(currentSeconds - durationSeconds) < 0.1; // 确保真的到了结尾 Math.Abs(currentSeconds - durationSeconds) < 0.1; // 确保真的到了结尾
//Console.WriteLine($"檢測到歌曲 - 當前位置: {currentSeconds:F2}秒, 總時長: {durationSeconds:F2}秒"); //Console.WriteLine($"檢測到歌曲 - 當前位置: {currentSeconds:F2}秒, 總時長: {durationSeconds:F2}秒");
if (isAtEnd) if (isAtEnd)
{ {
Console.WriteLine($"檢測到歌曲 -結束: {currentSeconds:F2}秒, 總時長: {durationSeconds:F2}秒"); Console.WriteLine($"檢測到歌曲 -結束: {currentSeconds:F2}秒, 總時長: {durationSeconds:F2}秒");
} }
} }
} }
return isAtEnd; return isAtEnd;
} }
public void RenderMediaFile(string filePath) public void RenderMediaFile(string filePath, nint Handle, int Width, int Height)
{ {
if (videoWindow != null) videoWindow.put_Visible(OABool.False);
Stop(); Stop();
SafeRelease(ref renderer); SafeRelease(ref renderer);
SafeRelease(ref lavSplitter); SafeRelease(ref lavSplitter);
SafeRelease(ref graphBuilder); SafeRelease(ref graphBuilder);
int hr = 0; int hr = 0;
graphBuilder = (IGraphBuilder)new FilterGraph(); graphBuilder = (IGraphBuilder)new FilterGraph();
try try
@ -67,7 +81,16 @@ namespace DualScreenDemo.Services
SetAudioTrackTo(1); SetAudioTrackTo(1);
else else
Console.WriteLine("Failed to render secondary file."); Console.WriteLine("Failed to render secondary file.");
// 绑定视频窗口到副屏幕
videoWindow = renderer 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);
}
mediaControl.Run();
} }
public void SetVolume(int volume) public void SetVolume(int volume)
{ {

View File

@ -12,12 +12,24 @@ namespace DualScreenDemo.Services
public IBaseFilter videoRenderer; public IBaseFilter videoRenderer;
IMediaControl mediaControl; IMediaControl mediaControl;
IBaseFilter sourceFilter; IBaseFilter sourceFilter;
private IVideoWindow videoWindow;
public MediaServicePrimary() { } public MediaServicePrimary() { }
public int Run() => (mediaControl != null) ? mediaControl.Run() : 0; public int Run() => (mediaControl != null) ? mediaControl.Run() : 0;
public int Stop() => (mediaControl != null)? mediaControl.Stop() : 0; public int Stop() => (mediaControl != null)? mediaControl.Stop() : 0;
public int Pause() => (mediaControl != null) ? mediaControl.Pause() : 0; public int Pause() => (mediaControl != null) ? mediaControl.Pause() : 0;
public void VideoPlayerForm_FormClosing() {
if (videoWindow != null)
{
videoWindow.put_Visible(OABool.False);
videoWindow.put_Owner(IntPtr.Zero);
Marshal.ReleaseComObject(videoWindow);
videoWindow = null;
}
}
public void StopAndReleaseResources() public void StopAndReleaseResources()
{ {
if (mediaControl != null) if (mediaControl != null)
@ -32,8 +44,9 @@ namespace DualScreenDemo.Services
SafeRelease(ref graphBuilder); SafeRelease(ref graphBuilder);
} }
public void RenderMediaFile(string filePath) public void RenderMediaFile(string filePath, nint Handle, int Width, int Height)
{ {
if (videoWindow != null) videoWindow.put_Visible(OABool.False);
StopAndReleaseResources(); StopAndReleaseResources();
@ -58,6 +71,16 @@ namespace DualScreenDemo.Services
DsError.ThrowExceptionForHR(hr); DsError.ThrowExceptionForHR(hr);
hr = ConnectFilters(graphBuilder, lavVideoDecoder, "Output", videoRenderer, "VMR Input0"); hr = ConnectFilters(graphBuilder, lavVideoDecoder, "Output", videoRenderer, "VMR Input0");
DsError.ThrowExceptionForHR(hr); DsError.ThrowExceptionForHR(hr);
videoWindow = videoRenderer as IVideoWindow;
if (videoWindow != null)
{
videoWindow.put_Owner(Handle);
videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipChildren);
videoWindow.SetWindowPosition(0, 0, Width, Height);
videoWindow.put_Visible(OABool.True);
}
mediaControl.Run();
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -71,8 +71,8 @@ namespace DualScreenDemo
private const uint SWP_NOZORDER = 0x0004; private const uint SWP_NOZORDER = 0x0004;
private MediaServicePrimary primary = new MediaServicePrimary(); private MediaServicePrimary primary = new MediaServicePrimary();
private MediaService secondary = new MediaService(); private MediaService secondary = new MediaService();
private IVideoWindow videoWindowPrimary;
private IVideoWindow videoWindowSecondary;
public static OverlayForm overlayForm; public static OverlayForm overlayForm;
public bool isMuted = false; public bool isMuted = false;
@ -160,20 +160,8 @@ namespace DualScreenDemo
private void VideoPlayerForm_FormClosing(object sender, FormClosingEventArgs e) private void VideoPlayerForm_FormClosing(object sender, FormClosingEventArgs e)
{ {
if (videoWindowPrimary != null) primary.VideoPlayerForm_FormClosing();
{ secondary.VideoPlayerForm_FormClosing();
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 // 清理COM
CoUninitialize(); CoUninitialize();
} }
@ -364,39 +352,13 @@ namespace DualScreenDemo
private Task InitializeAndPlayMedia(SongData song) private Task InitializeAndPlayMedia(SongData song)
{ {
string pathToPlay = song.getFile(); string pathToPlay = song.getFile();
if (videoWindowPrimary != null) videoWindowPrimary.put_Visible(OABool.False);
if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False);
// 渲染媒體文件 // 渲染媒體文件
primary.RenderMediaFile(pathToPlay); primary.RenderMediaFile(pathToPlay,PrimaryForm.Instance.primaryScreenPanel.Handle,newWidth,newHeight);
secondary.RenderMediaFile(pathToPlay); secondary.RenderMediaFile(pathToPlay,this.Handle,secondMonitor.Bounds.Width,secondMonitor.Bounds.Height);
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); SetVolume(isMuted ? -10000 : previousVolume);
// 開始播放
primary.Run();
secondary.Run();
if (isSyncToPrimaryMonitor) SyncToPrimaryMonitor(); if (isSyncToPrimaryMonitor) SyncToPrimaryMonitor();
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -427,7 +389,7 @@ namespace DualScreenDemo
{ {
try try
{ {
bool isAtEnd = secondary.isAtEnd() ; bool isAtEnd = secondary.IsAtEnd() ;
if (isAtEnd && !isPaused) if (isAtEnd && !isPaused)
{ {
BeginInvoke(new Action(async () => BeginInvoke(new Action(async () =>