From 7d71e85d57290f43779cbbb868a8482c25e3b4a3 Mon Sep 17 00:00:00 2001 From: jasonchenwork Date: Tue, 19 Aug 2025 17:50:37 +0800 Subject: [PATCH] =?UTF-8?q?2508191749=20=E6=92=A5=E6=94=BE=E5=99=A8?= =?UTF-8?q?=E5=8F=83=E6=95=B8=E8=AA=BF=E6=95=B4=20=E5=AA=92=E9=AB=94?= =?UTF-8?q?=E6=92=AD=E7=95=A2=E9=82=8F=E8=BC=AF=E5=88=A4=E6=96=B7=E6=9B=B4?= =?UTF-8?q?=E6=94=B9=20=E7=B3=BB=E7=B5=B1=E5=85=AC=E5=91=8A=E9=A1=8F?= =?UTF-8?q?=E8=89=B2=E6=94=B9=E5=9B=9E=E7=B4=85=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OverlayFormObj/OverlayForm.Labels.cs | 7 +-- Services/MediaService.cs | 74 ++++++++++++---------------- VideoPlayerForm.cs | 50 +++++++++++-------- 3 files changed, 65 insertions(+), 66 deletions(-) diff --git a/OverlayFormObj/OverlayForm.Labels.cs b/OverlayFormObj/OverlayForm.Labels.cs index 3eab05f..23ca154 100644 --- a/OverlayFormObj/OverlayForm.Labels.cs +++ b/OverlayFormObj/OverlayForm.Labels.cs @@ -266,6 +266,7 @@ namespace OverlayFormObj using (Font largeFont = new Font("微軟正黑體", 34, FontStyle.Bold)) using (Font secondLineFont = new Font("微軟正黑體", 34, FontStyle.Bold)) using (Brush whiteBrush = new SolidBrush(Color.White)) + using (Brush RedBrush = new SolidBrush(Color.Red)) using (Brush marqueeBrush = new SolidBrush(marqueeTextColor)) using (Brush backgroundBrush = new SolidBrush(Color.FromArgb(255, 0, 0, 0))) { @@ -279,10 +280,10 @@ namespace OverlayFormObj float yPosition2 = 56; Rectangle clipRect = new Rectangle( // (int)(this.Width / 32), // 从1/8改成1/16(因为要居中) - (int)(this.Width*0.32), + (int)(this.Width * 0.32), (int)yPosition2, // (int)(15 * this.Width / 16), // 从3/4改成7/8 - (int)(this.Width*0.56), + (int)(this.Width * 0.56), (int)textSize.Height ); Region originalClip = e.Graphics.Clip; @@ -294,7 +295,7 @@ namespace OverlayFormObj e.Graphics.FillRectangle(backgroundBrush, centeredXPos, yPosition2, textSizeSecondLine.Width, textSizeSecondLine.Height); // 系統公告塗色調整區域 // e.Graphics.DrawString(displayText, secondLineFont, RedBrush, new PointF(centeredXPos, yPosition2)); - e.Graphics.DrawString(displayText, secondLineFont, marqueeBrush, new PointF((int)(this.Width*0.32), yPosition2)); + e.Graphics.DrawString(displayText, secondLineFont, RedBrush, new PointF((int)(this.Width * 0.32), yPosition2)); // 还原裁剪区域 e.Graphics.Clip = originalClip; diff --git a/Services/MediaService.cs b/Services/MediaService.cs index 11f84ea..a94a329 100644 --- a/Services/MediaService.cs +++ b/Services/MediaService.cs @@ -4,8 +4,8 @@ namespace DualScreenDemo.Services { public class MediaService : IDisposable { - private readonly LibVLC _libVLC; - private readonly MediaPlayer _mediaPlayer; + private LibVLC _libVLC; + private MediaPlayer _mediaPlayer; private Media? _media; private bool _disposed; @@ -13,14 +13,14 @@ namespace DualScreenDemo.Services { Core.Initialize(); _libVLC = new LibVLC( - - "--vout=automatic", - "--h264-fps=25", + // "--verbose=2", + "--audio-time-stretch", + // "--vout=automatic", + "--h264-fps=30", "--aout=directsound", "--network-caching=250", "--file-caching=250", "--audio-time-stretch" - ); _mediaPlayer = new MediaPlayer(_libVLC); @@ -47,66 +47,56 @@ namespace DualScreenDemo.Services public MediaPlayer Player => _mediaPlayer; public bool IsPlaying => _mediaPlayer.IsPlaying; - public bool IsAtEnd() - { - try - { - var duration = _mediaPlayer.Media?.Duration ?? 0; - var time = _mediaPlayer.Time; - return duration > 0 && Math.Abs(duration - time) < 1000; - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - return true; - } - } - - // public void LoadMedia(string filePath, int audioTrackIndex = 0) + // public bool IsAtEnd() // { // try // { - // Console.WriteLine($"LoadMedia. in"); - // _media?.ParseStop(); - // Console.WriteLine($"LoadMedia. ParseStop"); - // _mediaPlayer.Stop(); - // Console.WriteLine($"LoadMedia. Stop"); - // _media?.Dispose(); - // Console.WriteLine($"LoadMedia. Dispose"); - - // _media = new Media(_libVLC, filePath, FromType.FromPath); - // _media.AddOption(":audio-output=directsound"); - // _media.AddOption($":audio-track={audioTrackIndex}"); - // _mediaPlayer.Play(_media); + // _mediaPlayer.EndReached += (sender, args) => { }; + // var duration = _mediaPlayer.Media?.Duration ?? 0; + // var time = _mediaPlayer.Time; + // return duration > 0 && Math.Abs(duration - time) < 1000; // } // catch (Exception ex) - // { + // { // Console.WriteLine(ex.Message); + // return true; // } - // } + public bool IsAtEnd() + { + if (_mediaPlayer.State == VLCState.Ended) + { + return true; + } + return false; + } + public void LoadMedia(string filePath, int audioTrackIndex = 0) { try { - Console.WriteLine($"LoadMedia. in"); + // Console.WriteLine($"LoadMedia. in"); + // _media?.ParseStop(); + // Console.WriteLine($"LoadMedia. ParseStop"); _mediaPlayer.Stop(); - _mediaPlayer.Media = null; - Console.WriteLine($"LoadMedia. Stop"); + // Console.WriteLine($"LoadMedia. Stop"); _media?.Dispose(); - _media= null; - Console.WriteLine($"LoadMedia. Dispose"); + // Console.WriteLine($"LoadMedia. Dispose"); _media = new Media(_libVLC, filePath, FromType.FromPath); + _media.AddOption(":avcodec-hw=dxva2"); + _media.AddOption(":vout=gl"); _media.AddOption(":audio-output=directsound"); _media.AddOption($":audio-track={audioTrackIndex}"); + // _media.AddOption(":start-time=0.5"); + _mediaPlayer.Media = _media; _mediaPlayer.Play(_media); } catch (Exception ex) - { + { Console.WriteLine(ex.Message); } diff --git a/VideoPlayerForm.cs b/VideoPlayerForm.cs index 654bf7b..5d04de3 100644 --- a/VideoPlayerForm.cs +++ b/VideoPlayerForm.cs @@ -232,28 +232,36 @@ namespace DualScreenDemo public async Task PlayNextSong() { - // 等待初始化完成(例如播放器、串口等資源尚未就緒時) - Console.WriteLine("開始播放下一首歌曲..."); - var songToPlay = SongList.Next(); - if (!songToPlay.isPublicSong) + try { - // 若是使用者點播模式,先送出升Key的串口指令 - if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen) + // 等待初始化完成(例如播放器、串口等資源尚未就緒時) + Console.WriteLine("開始播放下一首歌曲..."); + var songToPlay = SongList.Next(); + if (!songToPlay.isPublicSong) { - byte[] commandBytesIncreasePitch1 = new byte[] { 0xA2, 0x7F, 0xA4 }; - SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch1, 0, commandBytesIncreasePitch1.Length); + // 若是使用者點播模式,先送出升Key的串口指令 + if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen) + { + byte[] commandBytesIncreasePitch1 = new byte[] { 0xA2, 0x7F, 0xA4 }; + SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch1, 0, commandBytesIncreasePitch1.Length); + } } + // 更新畫面上顯示的下一首歌資訊 + SongList.UpdateNextSongLabel(); + + // 顯示 QRCode(可能是點歌頁用) + overlayForm.DisplayQRCodeOnOverlay(HttpServer.randomFolderPath); + + // 隱藏「暫停中」標籤 + overlayForm.HidePauseLabel(); + + await _InitializeAndPlayMedia(songToPlay); + + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); } - // 更新畫面上顯示的下一首歌資訊 - SongList.UpdateNextSongLabel(); - - // 顯示 QRCode(可能是點歌頁用) - overlayForm.DisplayQRCodeOnOverlay(HttpServer.randomFolderPath); - - // 隱藏「暫停中」標籤 - overlayForm.HidePauseLabel(); - - await _InitializeAndPlayMedia(songToPlay); } @@ -347,7 +355,7 @@ namespace DualScreenDemo // 音量處理 //SetVolume(isMuted ? 0 : previousVolume); - if(isMuted){ Mute(true); } + if (isMuted) { Mute(true); } SetVolume(100 + song.getBasic().getDbChange()); if (isSyncToPrimaryMonitor) SyncToPrimaryMonitor(); return Task.CompletedTask; @@ -379,7 +387,7 @@ namespace DualScreenDemo { try { - if (_mediaService0.IsAtEnd() || _mediaService1.IsAtEnd()) + if (_mediaService1.IsAtEnd()) { BeginInvoke(new Action(async () => { @@ -498,7 +506,7 @@ namespace DualScreenDemo } private bool _ToggleVocalRemoval(bool isVocal) { - _mediaService0.Mute(isVocal); + _mediaService0.Mute(isVocal); _mediaService1.Mute(!isVocal); return isVocal; }