diff --git a/DBObj/SongData.cs b/DBObj/SongData.cs index fc297d4..34ad183 100644 --- a/DBObj/SongData.cs +++ b/DBObj/SongData.cs @@ -1,17 +1,18 @@ using DualScreenDemo; using System; using System.IO; +using System.Net; using System.Windows.Markup; namespace DBObj { public class SongData { private Song basic; - private Artist A ; - private Artist B ; + private Artist A; + private Artist B; public bool isPublicSong { get; set; } public PlayState state; - + public SongData() { basic = new("", "", "", "", 0, 1, ""); @@ -24,46 +25,47 @@ namespace DBObj basic = new(songNumber, song, "", filename, humanVoice, 0, ""); isPublicSong = isPublic; } - public SongData(string songNumber, string song, string artistA, string artistB, string filename, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice,int dbChange,string situation) + public SongData(string songNumber, string song, string artistA, string artistB, string filename, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice, int dbChange, string situation) { - basic=new(songNumber,song,songSimplified,filename,humanVoice,dbChange,situation); + basic = new(songNumber, song, songSimplified, filename, humanVoice, dbChange, situation); A = new Artist(artistA, artistASimplified); B = !artistB.Equals("") ? new Artist(artistB, artistBSimplified) : null; isPublicSong = false; } - public SongData(SongData value,PlayState s){ + public SongData(SongData value, PlayState s) + { basic = value.getBasic(); A = value.getA(); B = value.getB(); - state =s; + state = s; } public Song getBasic() => basic; public Artist getA() => A; public Artist getB() => B; public string getNumber() => basic.getNumber(); - public string getName(bool IsSimplified=false) => basic.getName(IsSimplified); + 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 int getNameLength() => basic.getName().Length; public string getFileName() => basic.getFileName(); public string next_song_text() { var str = (state == PlayState.InsertPlayback) ? GetStateTxt(false) : ""; - return String.Format("下一首:{0} {1}", basic.getName(false),str); + return String.Format("下一首:{0} {1}", basic.getName(false), str); } public string artist_text() { - return B!=null + return B != null ? $"{A.getName(false)} - {B.getName(false)}" : A.getName(false); } public string name_text() { - return B!=null + 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)); } @@ -73,12 +75,13 @@ namespace DBObj { try { - string fullPath = Path.Combine(server, basic.getFileName()); - if (File.Exists(fullPath)) - { - Console.WriteLine($"找到檔案: {fullPath}"); - return true; - } + // string fullPath = Path.Combine(server, basic.getFileName()); + Uri fullUri = new Uri(new Uri(server), basic.getFileName()); + // if (File.Exists(fullPath)) + // { + // Console.WriteLine($"找到檔案: {fullPath}"); + return true; + // } } catch (Exception ex) { @@ -89,7 +92,7 @@ namespace DBObj Console.WriteLine($"全部 server 都找不到檔案: {basic.getFileName()}"); return false; } - + public string getFile() { return FindExistingPath(basic.getFileName()); @@ -103,24 +106,76 @@ namespace DBObj } return null; // 找不到就回原本的 filename,不加路徑 } + public Uri getFileUrl() + { + return GetUri(basic.getFileName()); + } + private Uri GetUri(string filename) + { + + foreach (var server in Utils.Env.GetSongServers()) + { + var check = IsFtpUriReachable(new Uri(server).ToString()); + if (!string.IsNullOrWhiteSpace(server) && check != false) + { + return new Uri(new Uri(server), filename); + } + } + + // throw new InvalidOperationException("No valid server found."); + Console.WriteLine("No valid server found."); + return null; + } + public Color GetStateColor() => state switch { - PlayState.Played => Color.Gray, - PlayState.Skipped => Color.Gray, - PlayState.NoFile => Color.Gray, - PlayState.Playing => Color.LimeGreen, + PlayState.Played => Color.Gray, + PlayState.Skipped => Color.Gray, + PlayState.NoFile => Color.Gray, + PlayState.Playing => Color.LimeGreen, PlayState.InsertPlayback => Color.Gold, - _ => Color.White + _ => Color.White }; - public string GetStateTxt(bool IsSimplified) => (state==PlayState.NotPlayed)?"":$"({state.GetDescription(IsSimplified)})"; + public string GetStateTxt(bool IsSimplified) => (state == PlayState.NotPlayed) ? "" : $"({state.GetDescription(IsSimplified)})"; public void SetState(PlayState s) => state = s; public PlayState GetState() => state; - + public int getHumanVoice() => basic.getHumanVoice(); public override string ToString() { - return String.Format("{0} {1}", basic.getName(),state.GetDescription() ); + return String.Format("{0} {1}", basic.getName(), state.GetDescription()); + } + public static bool IsFtpUriReachable(string ftpUri) + { + try + { + #pragma warning disable SYSLIB0014 // 類型或成員已經過時 + var request = (FtpWebRequest)WebRequest.Create(ftpUri); + #pragma warning restore SYSLIB0014 // 類型或成員已經過時 + request.Method = WebRequestMethods.Ftp.ListDirectory; // Lightweight check + // request.Credentials = new NetworkCredential("svr", "svr"); // Replace with actual username/password + request.Timeout = 5000; + + using var response = (FtpWebResponse)request.GetResponse(); + return response.StatusCode == FtpStatusCode.OpeningData || response.StatusCode == FtpStatusCode.DataAlreadyOpen; + } + catch (WebException ex) + { + if (ex.Response is FtpWebResponse ftpResponse) + { + Console.WriteLine($"FTP error: {ftpResponse.StatusDescription}"); + return false; + } + + Console.WriteLine($"Connection error: {ex.Message}"); + return false; + } + catch (Exception ex) + { + Console.WriteLine($"Unexpected error: {ex.Message}"); + return false; + } } } } \ No newline at end of file diff --git a/Env.cs b/Env.cs index 715ab8b..8093219 100644 --- a/Env.cs +++ b/Env.cs @@ -60,7 +60,7 @@ namespace Utils // .Select(s => s.Trim('\'', '"').TrimEnd('\\')) // 清理 // .ToArray(); - return new string[] { @"\\svr01", @"\\svr02" }; + return new string[] { @"ftp://svr:svr@svr",@"ftp://song1:song1@svr01", @"ftp://song2:song2@svr02",@"ftp://song3:song3@svr03" }; } diff --git a/HttpServer.cs b/HttpServer.cs index 0a8239e..98b404c 100644 --- a/HttpServer.cs +++ b/HttpServer.cs @@ -34,13 +34,13 @@ namespace DualScreenDemo private static string _baseDirectory = @"themes\superstar\_www"; // 根據實際情況設定 private static TaskCompletionSource _qrReadyTcs; - + public static async Task StartServer(string baseDirectory, int port, SQLManager manager, CancellationToken token) { songListManager = manager; string randomFolderName = CreateRandomFolderAndRedirectHTML(baseDirectory); randomFolderPath = randomFolderName; - + // 安裝包更新 string localAddress = GetLocalIPAddress(); string externalAddress = Utils.Env.Get("PhoneIP", "").Trim(); @@ -58,16 +58,16 @@ namespace DualScreenDemo //_listener.Prefixes.Add($"http://{host}:{externalPort}/"); } string localQrContent = String.Format("http://{0}:{1}/{2}/windows.html", localAddress, port, randomFolderName); - - + + // 修改外网二维码内容生成 - - string externalQrContent = !string.IsNullOrEmpty(externalAddress) ? + + string externalQrContent = !string.IsNullOrEmpty(externalAddress) ? String.Format("http://{0}:{1}/{2}/windows.html", externalAddress, externalPort, randomFolderName) : localQrContent; - + GenerateQRCode(externalQrContent, Path.Combine(baseDirectory, randomFolderName, "qrcode.png")); - + _qrReadyTcs?.TrySetResult(randomFolderName); // safe call,null-safe try { @@ -84,7 +84,7 @@ namespace DualScreenDemo { try { - HttpListenerContext context = await _listener.GetContextAsync(); + HttpListenerContext context = await _listener.GetContextAsync(); await ProcessRequestAsync(context, baseDirectory, randomFolderName); } catch (HttpListenerException) @@ -97,7 +97,7 @@ namespace DualScreenDemo _listener.Close(); Console.WriteLine("Server stopped."); } - + public static async Task RestartServer() { Console.WriteLine("Restarting server..."); @@ -115,7 +115,7 @@ namespace DualScreenDemo _cts = new CancellationTokenSource(); - + // ✅ 等 QR code 跑完 _qrReadyTcs = new TaskCompletionSource(); _serverTask = StartServer(_baseDirectory, _port, songListManager, _cts.Token); @@ -245,7 +245,7 @@ namespace DualScreenDemo // 添加基本的缓存控制 context.Response.Headers.Add("Cache-Control", "public, max-age=3600"); - + if (context.Request.HttpMethod == "POST") { string relativePath = context.Request.Url.AbsolutePath.Replace($"/{randomFolderName}", ""); @@ -289,7 +289,7 @@ namespace DualScreenDemo { // 获取请求的完整URL路径 string requestPath = context.Request.Url.AbsolutePath; - + // 如果是根路径访问,直接返回404 if (requestPath == "/" || requestPath == "/windows.html") { @@ -298,7 +298,7 @@ namespace DualScreenDemo } string requestedFile = context.Request.Url.LocalPath.Replace($"/{randomFolderName}/", ""); - + if (string.IsNullOrEmpty(requestedFile.Trim('/'))) { requestedFile = "windows.html"; @@ -321,6 +321,28 @@ namespace DualScreenDemo { try { + var request = context.Request; + var user = context.User; + + Console.WriteLine("Headers:"); + foreach (string key in request.Headers.AllKeys) + { + Console.WriteLine($" {key}: {request.Headers[key]}"); + } + + Console.WriteLine("Query String:"); + foreach (string key in request.QueryString.AllKeys) + { + Console.WriteLine($" {key}: {request.QueryString[key]}"); + } + + Console.WriteLine("Body:"); + using (var reader = new StreamReader(request.InputStream, request.ContentEncoding)) + { + string body = reader.ReadToEnd(); + Console.WriteLine(body); + } + context.Response.Close(); } catch { } @@ -337,7 +359,7 @@ namespace DualScreenDemo context.Response.StatusCode = statusCode; context.Response.ContentType = "application/json; charset=utf-8"; context.Response.ContentLength64 = buffer.Length; - + await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length); } catch (Exception ex) @@ -377,7 +399,7 @@ namespace DualScreenDemo .Select(song => new { Song = song.getName(), - ArtistA =song.getArtist_A(), + ArtistA = song.getArtist_A(), SongNumber = song.getNumber(), }) .ToList(); @@ -421,7 +443,7 @@ namespace DualScreenDemo private static async Task HandleSoundControlRequest(HttpListenerContext context) { - + string requestBody; using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding)) { @@ -465,14 +487,14 @@ namespace DualScreenDemo // 执行音量增大操作 OverlayForm.MainForm.Invoke(new System.Action(() => { - OverlayForm.MainForm.ShowTopRightLabelTime("音量 ↑","a2 b3 a4"); + OverlayForm.MainForm.ShowTopRightLabelTime("音量 ↑", "a2 b3 a4"); })); break; case "mic_up": // 执行麦克风增大操作 OverlayForm.MainForm.Invoke(new System.Action(() => { - OverlayForm.MainForm.ShowTopRightLabelTime("麥克風 ↑","a2 b5 a4"); + OverlayForm.MainForm.ShowTopRightLabelTime("麥克風 ↑", "a2 b5 a4"); })); break; case "mute": @@ -501,20 +523,20 @@ namespace DualScreenDemo // 执行音量减小操作 OverlayForm.MainForm.Invoke(new System.Action(() => { - OverlayForm.MainForm.ShowTopRightLabelTime("音量 ↓","a2 b4 a4"); + OverlayForm.MainForm.ShowTopRightLabelTime("音量 ↓", "a2 b4 a4"); })); break; case "mic_down": // 执行麦克风减小操作 OverlayForm.MainForm.Invoke(new System.Action(() => { - OverlayForm.MainForm.ShowTopRightLabelTime("麥克風 ↓","a2 b6 a4"); + OverlayForm.MainForm.ShowTopRightLabelTime("麥克風 ↓", "a2 b6 a4"); })); break; case "original_song": if (PrimaryForm.Instance.InvokeRequired) { - PrimaryForm.Instance.Invoke(new System.Action(() => + PrimaryForm.Instance.Invoke(new System.Action(() => { PrimaryForm.Instance.videoPlayerForm.ToggleVocalRemoval(); })); @@ -524,12 +546,13 @@ namespace DualScreenDemo PrimaryForm.Instance.videoPlayerForm.ToggleVocalRemoval(); } // 执行原唱操作 - + break; case "service": // 执行服务操作 - OverlayForm.MainForm.Invoke(new System.Action(() => { - OverlayForm.MainForm.ShowTopRightLabel("服務鈴","a2 53 a4"); + OverlayForm.MainForm.Invoke(new System.Action(() => + { + OverlayForm.MainForm.ShowTopRightLabel("服務鈴", "a2 53 a4"); })); break; case "replay": @@ -539,7 +562,7 @@ namespace DualScreenDemo // 在这里执行按钮点击后的操作 // 比如切歌操作 PrimaryForm.Instance.videoPlayerForm.ReplayCurrentSong(); - })); + })); break; case "male_key": // 执行男调操作 @@ -578,7 +601,7 @@ namespace DualScreenDemo case "cut": // 执行切歌操作 if (PrimaryForm.Instance.InvokeRequired) - PrimaryForm.Instance.Invoke(new System.Action(() => { PrimaryForm.Instance.videoPlayerForm.PlayNextSong();})); + PrimaryForm.Instance.Invoke(new System.Action(() => { PrimaryForm.Instance.videoPlayerForm.PlayNextSong(); })); else PrimaryForm.Instance.videoPlayerForm.PlayNextSong(); break; @@ -668,16 +691,16 @@ namespace DualScreenDemo playingSongList = SongList.GetHistory() .Select((song, index) => new { - Song=song.getName(), - ArtistA=song.getArtist_A(), + Song = song.getName(), + ArtistA = song.getArtist_A(), PlayState = song.GetState().GetDescription() }) .ToList() }; - + jsonResponse = JsonConvert.SerializeObject(response); context.Response.StatusCode = (int)HttpStatusCode.OK; - + } catch (Exception ex) { @@ -690,7 +713,7 @@ namespace DualScreenDemo } // 生成播放状态 - + private static async Task HandleOrderSongRequest(HttpListenerContext context) { try @@ -704,19 +727,22 @@ namespace DualScreenDemo Console.WriteLine("Received order song request: " + requestBody); // 解析 JSON 为 Song 对象 var json = JObject.Parse(requestBody); - SongData song =songListManager.SearchSongByNumber(json["SongNumber"]?.ToString()); - - if (song != null) { + SongData song = songListManager.SearchSongByNumber(json["SongNumber"]?.ToString()); + + if (song != null) + { Console.WriteLine($"Ordering Song: {song.getName()} by {song.getArtist_A()}"); // 这里可以添加处理逻辑,例如将歌曲加入到播放列表或数据库中 song.getBasic().setNameTest("*"); SongList.Add(song); - + var response = new { status = "success", message = "Song ordered successfully" }; string jsonResponse = JsonConvert.SerializeObject(response); await SendResponseAsync(context, jsonResponse); - } else { + } + else + { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; await SendResponseAsync(context, "{\"status\": \"error\", \"message\": \"Invalid song data\"}"); } @@ -743,9 +769,10 @@ namespace DualScreenDemo // 解析 JSON 为 Song 对象 var json = JObject.Parse(requestBody); - SongData song =songListManager.SearchSongByNumber(json["SongNumber"]?.ToString()); + SongData song = songListManager.SearchSongByNumber(json["SongNumber"]?.ToString()); - if (song != null){ + if (song != null) + { Console.WriteLine($"Inserting Song: {song.getName()} by {song.getArtist_A()}"); // 这里可以添加插播歌曲的处理逻辑 song.getBasic().setNameTest("*"); @@ -753,7 +780,9 @@ namespace DualScreenDemo var response = new { status = "success", message = "Song inserted successfully" }; string jsonResponse = JsonConvert.SerializeObject(response); await SendResponseAsync(context, jsonResponse); - } else { + } + else + { context.Response.StatusCode = (int)HttpStatusCode.BadRequest; await SendResponseAsync(context, "{\"status\": \"error\", \"message\": \"Invalid song data\"}"); } @@ -822,11 +851,13 @@ namespace DualScreenDemo } // 封装响应代码以避免重复 - async static Task SendResponseAsync(HttpListenerContext context, string jsonResponse) { + async static Task SendResponseAsync(HttpListenerContext context, string jsonResponse) + { context.Response.ContentType = "application/json"; context.Response.ContentLength64 = Encoding.UTF8.GetByteCount(jsonResponse); context.Response.StatusCode = (int)HttpStatusCode.OK; - using (var streamWriter = new StreamWriter(context.Response.OutputStream)) { + using (var streamWriter = new StreamWriter(context.Response.OutputStream)) + { await streamWriter.WriteAsync(jsonResponse); await streamWriter.FlushAsync(); } @@ -843,7 +874,7 @@ namespace DualScreenDemo } } private static async Task HandleMessageRequest(HttpListenerContext context) - { + { try { using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding)) @@ -852,11 +883,11 @@ namespace DualScreenDemo if (!string.IsNullOrEmpty(json)) { context.Response.StatusCode = 200; - context.Response.ContentType = "application/json"; + context.Response.ContentType = "application/json"; int startIndex = json.IndexOf("\"message\":\"") + 11; int endIndex = json.IndexOf("\"", startIndex); if (startIndex >= 0 && endIndex >= 0) - OnDisplayBarrage?.Invoke( json.Substring(startIndex, endIndex - startIndex) ); + OnDisplayBarrage?.Invoke(json.Substring(startIndex, endIndex - startIndex)); } else { @@ -948,7 +979,7 @@ namespace DualScreenDemo } }*/ - + private static string GetMimeType(string filePath) { @@ -985,7 +1016,7 @@ namespace DualScreenDemo case ".json": mimeType = "application/json"; break; - // Add more cases for other file types as needed + // Add more cases for other file types as needed } return mimeType; @@ -1016,25 +1047,25 @@ namespace DualScreenDemo //SongListManager.Instance.UserLogin(phone); // 获取用户的收藏歌曲 - var favoriteSongs=new List(); //= SongListManager.Instance.GetFavoriteSongsByPhoneNumber(); - - string query =PrimaryForm.Instance.SearchFavoriteSongs_Mysql(); + var favoriteSongs = new List(); //= SongListManager.Instance.GetFavoriteSongsByPhoneNumber(); + + string query = PrimaryForm.Instance.SearchFavoriteSongs_Mysql(); var searchResults = PrimaryForm.Instance.SearchSongs_Mysql(query); // 创建响应数据 var response = new { isLoggedIn = true, - + favoriteSongList = searchResults .Select(song => new { Name = song.getName(), - ArtistA =song.getArtist_A(), + ArtistA = song.getArtist_A(), Number = song.getNumber(), ArtistAFull = song.getArtist_A(true), ArtistBFull = song.getArtist_B(true), NameFull = song.getName(true), - HumanVoice =song.getHumanVoice(), + HumanVoice = song.getHumanVoice(), FileName = song.getFileName() }) .ToList(), @@ -1088,7 +1119,7 @@ namespace DualScreenDemo } // 异步响应发送方法 - + private static async Task SendResponseAsyncs(HttpListenerContext context, string responseContent) { try @@ -1103,14 +1134,14 @@ namespace DualScreenDemo Console.WriteLine("Error sending response: " + ex.Message); } } - + private static async Task HandleGetRequest(HttpListenerContext context, string baseDirectory, string requestedFile) { try { // 获取请求的完整URL路径 string requestPath = context.Request.Url.AbsolutePath; - + // 检查URL是否包含随机文件夹名 if (!requestPath.Contains("/" + randomFolderPath + "/")) { @@ -1120,7 +1151,7 @@ namespace DualScreenDemo } string filePath = Path.Combine(baseDirectory, requestedFile.TrimStart('/')); - + if (!File.Exists(filePath)) { context.Response.StatusCode = (int)HttpStatusCode.NotFound; @@ -1129,7 +1160,7 @@ namespace DualScreenDemo string contentType = GetMimeType(filePath); context.Response.ContentType = contentType; - + // 对于静态文件使用缓存 if (_fileCache.TryGetValue(filePath, out byte[] cachedContent)) { @@ -1145,7 +1176,7 @@ namespace DualScreenDemo buffer = new byte[fileStream.Length]; await fileStream.ReadAsync(buffer, 0, buffer.Length); } - + // 缓存静态文件 if (contentType.StartsWith("text/") || contentType.Contains("javascript") || contentType.Contains("json")) { diff --git a/PrimaryFormParts/PrimaryForm.OrderedSongs.cs b/PrimaryFormParts/PrimaryForm.OrderedSongs.cs index ae54021..729a0db 100644 --- a/PrimaryFormParts/PrimaryForm.OrderedSongs.cs +++ b/PrimaryFormParts/PrimaryForm.OrderedSongs.cs @@ -2,7 +2,7 @@ namespace DualScreenDemo { public partial class PrimaryForm { - private Button orderedSongsButton; + public Button orderedSongsButton; private Bitmap orderedSongsNormalBackground; private Bitmap orderedSongsActiveBackground; } diff --git a/Program.cs b/Program.cs index 99b0d65..70eaaa4 100644 --- a/Program.cs +++ b/Program.cs @@ -14,7 +14,7 @@ namespace DualScreenDemo private static PrimaryForm primaryForm; // 儲存實例的參考 public static Room room = new Room(); - public static string verSion = "Server V2.10 202509010938"; + public static string verSion = "Server V2.10 202509031254"; [STAThread] static void Main() diff --git a/Services/MediaService.cs b/Services/MediaService.cs index b5d981d..48502c4 100644 --- a/Services/MediaService.cs +++ b/Services/MediaService.cs @@ -85,15 +85,16 @@ namespace DualScreenDemo.Services _media?.Dispose(); _media = new Media(filePath, FromType.FromPath); - _media.ParseAsync(_libVLC); - _media.ParsedChanged += (sender, args) => - { - // if (args.ParsedStatus != MediaParsedStatus.Failed) - // { + _media.ParseAsync(_libVLC); + _media.ParsedChanged += (sender, args) => + { + // if (args.ParsedStatus != MediaParsedStatus.Failed) + // { _mediaPlayer.Media = addMediaOption(_media, audioTrackIndex); _mediaPlayer.Play(); - // } - }; + // } + }; + _mediaPlayer.Fullscreen = true; _mediaPlayer.Mute = false; } @@ -103,7 +104,27 @@ namespace DualScreenDemo.Services Program.WriteLog(ex.ToString()); } } + public void LoadMedia(Uri url, int audioTrackIndex = 0) + { + try + { + _mediaPlayer.Pause(); + _media?.Dispose(); + _media = new Media(url); + + _mediaPlayer.Media = addMediaOption(_media, audioTrackIndex); + _mediaPlayer.Play(); + + _mediaPlayer.Fullscreen = true; + _mediaPlayer.Mute = false; + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + Program.WriteLog(ex.ToString()); + } + } private Media addMediaOption(Media media, int audioTrackIndex) { media.AddOption(":avcodec-hw=dxva2"); diff --git a/VideoPlayerForm.cs b/VideoPlayerForm.cs index 433b9cc..007666f 100644 --- a/VideoPlayerForm.cs +++ b/VideoPlayerForm.cs @@ -347,12 +347,15 @@ namespace DualScreenDemo try { string pathToPlay = song.getFile(); + Uri url = song.getFileUrl(); + if (pathToPlay == null) _mediaService0.LoadMedia(url, 0); //同步畫面播放器載入media設置參數 - _mediaService0.LoadMedia(pathToPlay, 0); + else _mediaService0.LoadMedia(pathToPlay, 0); // _mediaService0.Player.Media.AddOption(":no-audio"); _mediaService0.Player.AspectRatio = "8:5"; + if(pathToPlay==null)_mediaService1.LoadMedia(url, song.isPublicSong ? 0 : 1); //影片畫面播放器載入media設置聲道 - _mediaService1.LoadMedia(pathToPlay, song.isPublicSong ? 0 : 1); + else _mediaService1.LoadMedia(pathToPlay, song.isPublicSong ? 0 : 1); isVocalRemoved = true; if (isMuted) { Mute(true); } @@ -361,6 +364,7 @@ namespace DualScreenDemo SetVolume(100 + song.getBasic().getDbChange()); Task.Run(() => Thread.Sleep(100)); if (isSyncToPrimaryMonitor) SyncToPrimaryMonitor(); + if (url == null&&!song.isPublicSong) PlayNextSong(); return Task.CompletedTask; } catch (Exception ex) @@ -403,6 +407,7 @@ namespace DualScreenDemo BeginInvoke(new Action(async () => { await PlayNextSong(); + if (PrimaryForm.Instance.isOnOrderedSongsPage) PrimaryForm.Instance.orderedSongsButton.PerformClick(); })); } }