superstar 1.2.1 20250714
歌庫列表 重新調整
This commit is contained in:
parent
7c27380fac
commit
d545c0d8c4
@ -25,8 +25,9 @@ namespace DualScreenDemo
|
||||
/// <summary>
|
||||
/// 遙控器接收資料
|
||||
/// </summary>
|
||||
public async Task ProcessData(string indata)
|
||||
{ AddToHistory(indata);
|
||||
public Task ProcessData(string indata)
|
||||
{
|
||||
AddToHistory(indata);
|
||||
// 遙控器測試
|
||||
// Console.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] 遙控器: {indata}");
|
||||
switch (indata)
|
||||
@ -191,6 +192,7 @@ namespace DualScreenDemo
|
||||
break;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
private void SafeInvokeAction(string commandKey, Action action)
|
||||
{
|
||||
@ -243,18 +245,11 @@ namespace DualScreenDemo
|
||||
private static void SkipToNextSong()
|
||||
{
|
||||
if (PrimaryForm.Instance.InvokeRequired)
|
||||
{
|
||||
PrimaryForm.Instance.Invoke(new System.Action(() => PrimaryForm.Instance.videoPlayerForm.SkipToNextSong()));
|
||||
}
|
||||
PrimaryForm.Instance.Invoke(new System.Action(() => PrimaryForm.Instance.videoPlayerForm.PlayNextSong()));
|
||||
else
|
||||
{
|
||||
PrimaryForm.Instance.videoPlayerForm.SkipToNextSong();
|
||||
}
|
||||
PrimaryForm.Instance.videoPlayerForm.PlayNextSong();
|
||||
|
||||
OverlayForm.MainForm.Invoke(new System.Action(() =>
|
||||
{
|
||||
OverlayForm.MainForm.ShowStandardLabel();
|
||||
}));
|
||||
OverlayForm.MainForm.Invoke(new System.Action(() => { OverlayForm.MainForm.ShowStandardLabel(); } ) );
|
||||
}
|
||||
|
||||
|
||||
@ -352,7 +347,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
ClearDisplay();
|
||||
OverlayForm.MainForm.displayLabel.Text = String.Format("已點歌曲:{0}", song);
|
||||
OverlayForm.MainForm.AddSongToPlaylist(song);
|
||||
SongList.Add(song);
|
||||
OverlayForm.MainForm.nextSongLabel.Visible = false;
|
||||
OverlayForm.displayTimer.Start();
|
||||
}
|
||||
@ -382,7 +377,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
ClearDisplay();
|
||||
OverlayForm.MainForm.displayLabel.Text = String.Format("{0}", song);
|
||||
OverlayForm.MainForm.AddSongToPlaylist(song);
|
||||
SongList.Add(song);
|
||||
OverlayForm.MainForm.nextSongLabel.Visible = false;
|
||||
OverlayForm.displayTimer.Start();
|
||||
}
|
||||
@ -458,7 +453,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
ClearDisplay();
|
||||
OverlayForm.MainForm.displayLabel.Text = String.Format("插播歌曲{0}", song);
|
||||
OverlayForm.MainForm.InsertSongToPlaylist(song);
|
||||
SongList.Insert(song);
|
||||
OverlayForm.MainForm.nextSongLabel.Visible = false;
|
||||
OverlayForm.displayTimer.Start();
|
||||
}
|
||||
@ -592,7 +587,8 @@ namespace DualScreenDemo
|
||||
ClearDisplay();
|
||||
|
||||
// 設定歌曲總數為已播放歌曲的數量
|
||||
OverlayForm.MainForm.totalSongs = PrimaryForm.playedSongsHistory.Count;
|
||||
List<SongData> historySongs = SongList.GetHistory();
|
||||
OverlayForm.MainForm.totalSongs = historySongs.Count;
|
||||
|
||||
// 若無任何播放紀錄,直接顯示訊息並返回,不執行後續動作
|
||||
if (OverlayForm.MainForm.totalSongs == 0)
|
||||
@ -609,45 +605,8 @@ namespace DualScreenDemo
|
||||
int endIndex = Math.Min(startIndex + OverlayForm.MainForm.songsPerPage, OverlayForm.MainForm.totalSongs);
|
||||
|
||||
// 準備要傳給 UpdateHistoryLabel 的兩個清單:歌曲資料與播放狀態
|
||||
List<SongData> historySongs = new List<SongData>();
|
||||
List<PlayState> playStates = new List<PlayState>();
|
||||
|
||||
// 錨點 遙控器
|
||||
// 從播放紀錄中取出當前頁面應顯示的歌曲與狀態
|
||||
int completedCount = PrimaryForm.currentSongIndexInHistory;
|
||||
// 判斷是否正在播放公播歌單 (若用戶點播歌單為空,則播放公播歌單)
|
||||
bool isPlayingPublicList = PrimaryForm.userRequestedSongs.Count == 0 ||
|
||||
(PrimaryForm.currentSongIndexInHistory >= PrimaryForm.userRequestedSongs.Count - 1 );
|
||||
if (isPlayingPublicList)
|
||||
{
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
historySongs.Add(PrimaryForm.playedSongsHistory[i]); // 加入歌曲
|
||||
playStates.Add(PlayState.Played);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
|
||||
historySongs.Add(PrimaryForm.playedSongsHistory[i]); // 加入歌曲
|
||||
if (i < completedCount)
|
||||
{
|
||||
playStates.Add(PlayState.Played);
|
||||
}
|
||||
else if (i == completedCount)
|
||||
{
|
||||
playStates.Add(PlayState.Playing);
|
||||
}
|
||||
else
|
||||
{
|
||||
playStates.Add(PlayState.NotPlayed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 安全更新 UI:若非 UI 執行緒則使用 Invoke 切換
|
||||
if (OverlayForm.MainForm.InvokeRequired)
|
||||
@ -655,7 +614,7 @@ namespace DualScreenDemo
|
||||
OverlayForm.MainForm.Invoke(new System.Action(() =>
|
||||
{
|
||||
// 更新主畫面的歷史播放顯示區
|
||||
OverlayForm.MainForm.UpdateHistoryLabel(historySongs, playStates, OverlayForm.MainForm.currentPage, totalPages);
|
||||
OverlayForm.MainForm.UpdateHistoryLabel(historySongs, OverlayForm.MainForm.currentPage, totalPages);
|
||||
|
||||
// 隱藏下一首提示
|
||||
OverlayForm.MainForm.nextSongLabel.Visible = false;
|
||||
@ -664,7 +623,7 @@ namespace DualScreenDemo
|
||||
else
|
||||
{
|
||||
// 若已在 UI 執行緒,直接操作
|
||||
OverlayForm.MainForm.UpdateHistoryLabel(historySongs, playStates, OverlayForm.MainForm.currentPage, totalPages);
|
||||
OverlayForm.MainForm.UpdateHistoryLabel(historySongs, OverlayForm.MainForm.currentPage, totalPages);
|
||||
OverlayForm.MainForm.nextSongLabel.Visible = false;
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@ namespace DBObj
|
||||
// artist OOP test
|
||||
public class Artist
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string NameSimplified{get;set;}
|
||||
public string Name ;
|
||||
public string NameSimplified ;
|
||||
//public string Phonetic { get; set; }
|
||||
//public string Category { get; set; }
|
||||
//public int Strokes { get; set; }
|
||||
@ -14,6 +14,8 @@ namespace DBObj
|
||||
Name = name;
|
||||
NameSimplified=nameSimplified;
|
||||
}
|
||||
public string getName(bool IsSimplified=false) { return IsSimplified ? NameSimplified : Name; }
|
||||
public string getName() {return Name;}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
26
DBObj/Song.cs
Normal file
26
DBObj/Song.cs
Normal file
@ -0,0 +1,26 @@
|
||||
namespace DBObj
|
||||
{
|
||||
// song OOP test
|
||||
public class Song
|
||||
{
|
||||
private string Number;
|
||||
private string Name;
|
||||
private string Name_Simplified;
|
||||
private string FileName;
|
||||
private int HumanVoice;
|
||||
|
||||
|
||||
public Song(string num,string name,string name_s,string filename,int humanVoice) {
|
||||
Number=num;
|
||||
Name=name;
|
||||
Name_Simplified=name_s;
|
||||
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;}
|
||||
}
|
||||
}
|
@ -1,109 +1,62 @@
|
||||
using DualScreenDemo;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Markup;
|
||||
namespace DBObj
|
||||
{
|
||||
public class SongData
|
||||
{
|
||||
public string Number { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Artist_A { get; set; }
|
||||
private string Artist_B { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string Artist_A_Simplified { get; set; }
|
||||
public string Artist_B_Simplified { get; set; }
|
||||
public string Name_Simplified { get; set; }
|
||||
public int HumanVoice { get; set; }
|
||||
private Song basic;
|
||||
private Artist A ;
|
||||
private Artist B ;
|
||||
public bool isPublicSong { get; set; }
|
||||
|
||||
public PlayState state;
|
||||
|
||||
/*
|
||||
public SongData(string songNumber, string category, string song, double plays, string artistA, string artistB, string artistACategory, string artistBCategory, DateTime addedTime, string songFilePathHost1, string songFilePathHost2, string phoneticNotation, string pinyinNotation, string artistAPhonetic, string artistBPhonetic, string artistASimplified, string artistBSimplified, string songSimplified, string songGenre, string artistAPinyin, string artistBPinyin, int humanVoice)
|
||||
{
|
||||
SongNumber = songNumber;
|
||||
// Category = category;
|
||||
Song = song;
|
||||
// Plays = plays;
|
||||
ArtistA = artistA;
|
||||
ArtistB = artistB;
|
||||
//ArtistACategory = artistACategory;
|
||||
//ArtistBCategory = artistBCategory;
|
||||
//AddedTime = addedTime;
|
||||
SongFilePathHost1 = songFilePathHost1;
|
||||
SongFilePathHost2 = songFilePathHost2;
|
||||
//PhoneticNotation = phoneticNotation;
|
||||
//PinyinNotation = pinyinNotation;
|
||||
//ArtistAPhonetic = artistAPhonetic;
|
||||
//ArtistBPhonetic = artistBPhonetic;
|
||||
ArtistASimplified = artistASimplified;
|
||||
ArtistBSimplified = artistBSimplified;
|
||||
SongSimplified = songSimplified;
|
||||
//SongGenre = songGenre;
|
||||
//ArtistAPinyin = artistAPinyin;
|
||||
//ArtistBPinyin = artistBPinyin;
|
||||
HumanVoice = humanVoice;
|
||||
}
|
||||
|
||||
*/
|
||||
public SongData(string songNumber, string song, string filename, int humanVoice, bool isPublic)
|
||||
{
|
||||
Number = songNumber;
|
||||
Name = song;
|
||||
FileName = filename;
|
||||
HumanVoice = humanVoice;
|
||||
basic=new(songNumber,song,"",filename,humanVoice);
|
||||
isPublicSong = isPublic;
|
||||
}
|
||||
public SongData(string songNumber, string song, string artistA, string artistB, string filename, string artistASimplified, string artistBSimplified, string songSimplified, int humanVoice)
|
||||
{
|
||||
Number = songNumber;
|
||||
Name = song;
|
||||
Artist_A = artistA;
|
||||
Artist_B = artistB;
|
||||
FileName = filename;
|
||||
Artist_A_Simplified = artistASimplified;
|
||||
Artist_B_Simplified = artistBSimplified;
|
||||
Name_Simplified = songSimplified;
|
||||
HumanVoice = humanVoice;
|
||||
basic=new(songNumber,song,songSimplified,filename,humanVoice);
|
||||
A= new Artist(artistA, artistASimplified);
|
||||
if(artistB!=null){
|
||||
B= new Artist(artistB, artistBSimplified);
|
||||
}
|
||||
isPublicSong = false;
|
||||
}
|
||||
public string getName(bool IsSimplified=false)
|
||||
{
|
||||
return IsSimplified ? Name_Simplified : Name;
|
||||
}
|
||||
public int getNameLength()
|
||||
{
|
||||
return Name.Length;
|
||||
}
|
||||
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 next_artist_text()
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(Artist_B)
|
||||
? String.Format("下一首:{0} {1} {2}", Artist_A, Artist_B, Name)
|
||||
: String.Format("下一首:{0} {1}", Artist_A, Name);
|
||||
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));
|
||||
}
|
||||
public string artist_text()
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(Artist_B)
|
||||
? $"{Artist_A} - {Artist_B}"
|
||||
: Artist_A;
|
||||
return B!=null
|
||||
? $"{A.getName(false)} - {B.getName(false)}"
|
||||
: A.getName(false);
|
||||
}
|
||||
public string name_text()
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(Artist_B)
|
||||
? String.Format("{0} - {1} - {2}", Artist_A, Artist_B, Name)
|
||||
: String.Format("{0} - {1}", Artist_A, Name);
|
||||
}
|
||||
public string getArtist_A(bool IsSimplified)
|
||||
{
|
||||
return IsSimplified ? Artist_A_Simplified : Artist_A;
|
||||
}
|
||||
public string getArtist_B(bool IsSimplified)
|
||||
{
|
||||
return IsSimplified ? Artist_B_Simplified : Artist_B;
|
||||
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));
|
||||
}
|
||||
|
||||
public string getFile()
|
||||
{
|
||||
return FindExistingPath(FileName);
|
||||
return FindExistingPath(basic.getFileName());
|
||||
}
|
||||
private string FindExistingPath(string filename)
|
||||
{
|
||||
@ -115,6 +68,28 @@ 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.Playing){
|
||||
c = Color.LimeGreen;
|
||||
}else if (state == PlayState.InsertPlayback){
|
||||
c = Color.Gold;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
public string GetStateTxt(bool IsSimplified){
|
||||
string txt = string.Empty;
|
||||
if (state == PlayState.Played) {
|
||||
txt = IsSimplified ? "(播毕)" : "(播畢)";
|
||||
} else if (state == PlayState.Playing) {
|
||||
txt = IsSimplified ? "(播放中)" : "(播放中)";
|
||||
} else if (state == PlayState.InsertPlayback) {
|
||||
txt = IsSimplified ? "(插播)" : "(插播)";
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
public void SetState(PlayState s) => state = s;
|
||||
|
||||
public PlayState GetState()
|
||||
@ -122,13 +97,13 @@ namespace DBObj
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
public int getHumanVoice() { return basic.getHumanVoice(); }
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
return !string.IsNullOrWhiteSpace(Artist_B)
|
||||
? String.Format("{0} - {1} - {2}", Artist_A, Artist_B, Name)
|
||||
: String.Format("{0} - {1}", Artist_A, Name);
|
||||
return B!=null
|
||||
? String.Format("{0} - {1} - {2} - {3}", state, A.getName(), B.getName(), basic.getName())
|
||||
: String.Format("{0} - {1} - {2}", state, A.getName(), basic.getName());
|
||||
}
|
||||
}
|
||||
}
|
97
DBObj/SongList.cs
Normal file
97
DBObj/SongList.cs
Normal file
@ -0,0 +1,97 @@
|
||||
using DualScreenDemo;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows.Navigation;
|
||||
namespace DBObj
|
||||
{
|
||||
public class SongList
|
||||
{
|
||||
public static SongData welcome ;
|
||||
public static SongData close ;
|
||||
private static SongData publicPlaying=null;
|
||||
private static List<SongData> publicSong = new();
|
||||
private static SongData playing=null;
|
||||
private static List<SongData> not_played = new List<SongData>();
|
||||
private static List<SongData> played = new List<SongData>();
|
||||
public static List<SongData> PublicSong() => publicSong;
|
||||
|
||||
public static SongData Current()
|
||||
{
|
||||
Console.WriteLine(not_played.Count + " Current " + playing);
|
||||
return (playing ==null) ? publicPlaying : playing;
|
||||
}
|
||||
public static SongData Next()
|
||||
{
|
||||
if (playing != null)
|
||||
{
|
||||
playing.SetState(PlayState.Played);
|
||||
played.Add(playing);
|
||||
playing = null;
|
||||
}
|
||||
if (not_played.Count <= 0)
|
||||
return NextPublicSong();
|
||||
else
|
||||
return NextUserSong();
|
||||
}
|
||||
private static SongData NextUserSong()
|
||||
{
|
||||
playing = not_played[0];
|
||||
not_played.RemoveAt(0);
|
||||
playing.SetState(PlayState.Playing);
|
||||
UpdateNextSongLabel();
|
||||
return playing;
|
||||
}
|
||||
private static SongData NextPublicSong()
|
||||
{
|
||||
publicPlaying = publicSong[0];
|
||||
publicSong.RemoveAt(0);
|
||||
publicSong.Add(publicPlaying);
|
||||
return publicPlaying;
|
||||
}
|
||||
|
||||
public static List<SongData> GetHistory()
|
||||
{
|
||||
List<SongData> History = [.. played];
|
||||
if (playing != null) History.Add(playing);
|
||||
History.AddRange(not_played);
|
||||
return History;
|
||||
}
|
||||
|
||||
public static void Add(SongData song)
|
||||
{
|
||||
not_played.Add(song);
|
||||
// PrimaryForm.Instance.AddSongCount(songData.Number);
|
||||
chkCut();
|
||||
}
|
||||
public static void Insert(SongData song)
|
||||
{
|
||||
song.SetState(PlayState.InsertPlayback);
|
||||
not_played.Insert(0, song);
|
||||
chkCut();
|
||||
}
|
||||
private static void chkCut()
|
||||
{
|
||||
if (playing == null)
|
||||
{
|
||||
if (PrimaryForm.Instance.InvokeRequired)
|
||||
PrimaryForm.Instance.Invoke(new System.Action(() => PrimaryForm.Instance.videoPlayerForm.PlayNextSong()));
|
||||
else
|
||||
PrimaryForm.Instance.videoPlayerForm.PlayNextSong();
|
||||
} else {
|
||||
UpdateNextSongLabel();
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateNextSongLabel()
|
||||
{
|
||||
VideoPlayerForm.overlayForm.UpdateNextSongLabel(
|
||||
(not_played.Count > 0) ? not_played[0].next_artist_text() : "目前沒有下一首,請踴躍點歌!!!"
|
||||
);
|
||||
}
|
||||
public static void clearSong()
|
||||
{
|
||||
not_played.Clear();
|
||||
played.Clear();
|
||||
}
|
||||
}
|
||||
}
|
137
HttpServer.cs
137
HttpServer.cs
@ -592,16 +592,9 @@ namespace DualScreenDemo
|
||||
case "cut":
|
||||
// 执行切歌操作
|
||||
if (PrimaryForm.Instance.InvokeRequired)
|
||||
{
|
||||
PrimaryForm.Instance.Invoke(new System.Action(() =>
|
||||
{
|
||||
PrimaryForm.Instance.videoPlayerForm.SkipToNextSong();
|
||||
}));
|
||||
}
|
||||
PrimaryForm.Instance.Invoke(new System.Action(() => { PrimaryForm.Instance.videoPlayerForm.PlayNextSong();}));
|
||||
else
|
||||
{
|
||||
PrimaryForm.Instance.videoPlayerForm.SkipToNextSong();
|
||||
}
|
||||
PrimaryForm.Instance.videoPlayerForm.PlayNextSong();
|
||||
break;
|
||||
case "lower_key":
|
||||
// 执行降调操作
|
||||
@ -691,6 +684,7 @@ namespace DualScreenDemo
|
||||
}
|
||||
private static async Task HandleOrderSongListRequest(HttpListenerContext context)
|
||||
{
|
||||
string jsonResponse = "{\"status\": \"error\", \"message\": \"An error occurred\"}";
|
||||
try
|
||||
{
|
||||
// 读取请求的内容
|
||||
@ -701,94 +695,38 @@ namespace DualScreenDemo
|
||||
}
|
||||
|
||||
Console.WriteLine("Received order song request: " + requestBody);
|
||||
|
||||
// 检查 playedSongsHistory 是否存在且不为空
|
||||
if (PrimaryForm.playedSongsHistory != null && PrimaryForm.playedSongsHistory.Count > 0)
|
||||
{
|
||||
Console.WriteLine("Played Songs History Count: " + PrimaryForm.playedSongsHistory.Count);
|
||||
foreach (var song in PrimaryForm.playedSongsHistory)
|
||||
{
|
||||
Console.WriteLine($"Song: {song.Name}, ArtistA: {song.Artist_A}");
|
||||
}
|
||||
|
||||
// 根据播放历史确定每首歌的播放状态
|
||||
var playStates = DeterminePlayStates(PrimaryForm.playedSongsHistory);
|
||||
var response = new { status = "info", message = "No songs in the played history" };
|
||||
|
||||
// 创建响应数据
|
||||
var response = new
|
||||
/*
|
||||
response = new
|
||||
{
|
||||
playingSongList = PrimaryForm.playedSongsHistory
|
||||
.Select((song, index) => CreateSongResponse(song, playStates[index])) // 使用新的播放状态
|
||||
.ToList(),
|
||||
// 生成播放历史
|
||||
currentSongIndexInHistory = PrimaryForm.currentSongIndexInHistory
|
||||
};
|
||||
|
||||
string jsonResponse = JsonConvert.SerializeObject(response);
|
||||
Console.WriteLine("Serialized JSON Response: " + jsonResponse);
|
||||
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||
await SendResponseAsync(context, jsonResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果播放历史为空,回传一条消息
|
||||
var response = new { status = "info", message = "No songs in the played history" };
|
||||
string jsonResponse = JsonConvert.SerializeObject(response);
|
||||
Console.WriteLine("Sending empty response: " + jsonResponse);
|
||||
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||
await SendResponseAsync(context, jsonResponse);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error handling order song request: " + ex.Message);
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
await SendResponseAsync(context, "{\"status\": \"error\", \"message\": \"An error occurred\"}");
|
||||
}
|
||||
}
|
||||
|
||||
// 确定每首歌的播放状态
|
||||
private static List<PlayState?> DeterminePlayStates(List<SongData> playedSongsHistory)
|
||||
{
|
||||
var playStates = new List<PlayState?>();
|
||||
bool foundPlaying = false; // 标记是否已找到正在播放的歌曲
|
||||
|
||||
for (int i = 0; i < playedSongsHistory.Count; i++)
|
||||
{
|
||||
// 这里可以根据您的业务逻辑来确定每首歌的播放状态
|
||||
if (i == PrimaryForm.currentSongIndexInHistory)
|
||||
{
|
||||
playStates.Add(PlayState.Playing);
|
||||
foundPlaying = true; // 找到正在播放的歌曲
|
||||
}
|
||||
else if (foundPlaying)
|
||||
{
|
||||
playStates.Add(null); // 找到播放中的歌曲后,后面的状态设置为 null
|
||||
}
|
||||
else
|
||||
{
|
||||
playStates.Add(PlayState.NotPlayed); // 未播放状态
|
||||
}
|
||||
}
|
||||
|
||||
return playStates;
|
||||
}
|
||||
|
||||
// 用于创建歌曲响应对象,包括播放状态
|
||||
private static object CreateSongResponse(SongData song, PlayState? playState)
|
||||
{
|
||||
return new
|
||||
.Select((song, index) => new
|
||||
{
|
||||
song.Name,
|
||||
song.Artist_A,
|
||||
song.FileName,
|
||||
PlayState = playState.HasValue ? (playState.Value == PlayState.Playing ? "播放中" : "播放完畢") : null // 如果状态为 null,不返回状态信息
|
||||
State = song.GetState() == PlayState.Playing ? "播放中" : "播放完畢"
|
||||
})
|
||||
.ToList(),
|
||||
// 生成播放历史
|
||||
currentSongIndexInHistory = PrimaryForm.currentSongIndexInHistory
|
||||
};
|
||||
*/
|
||||
jsonResponse = JsonConvert.SerializeObject(response);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.OK;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error handling order song request: " + ex.Message);
|
||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
|
||||
}
|
||||
context.Response.ContentType = "application/json";
|
||||
await SendResponseAsync(context, jsonResponse);
|
||||
}
|
||||
|
||||
// 生成播放状态
|
||||
@ -810,9 +748,9 @@ namespace DualScreenDemo
|
||||
|
||||
if (song != null)
|
||||
{
|
||||
Console.WriteLine($"Ordering Song: {song.Name} by {song.Artist_A}");
|
||||
Console.WriteLine($"Ordering Song: {song.getName()} by {song.getArtist_A()}");
|
||||
// 这里可以添加处理逻辑,例如将歌曲加入到播放列表或数据库中
|
||||
OverlayForm.MainForm.AddSongToPlaylist(song);
|
||||
SongList.Add(song);
|
||||
|
||||
var response = new { status = "success", message = "Song ordered successfully" };
|
||||
string jsonResponse = JsonConvert.SerializeObject(response);
|
||||
@ -849,10 +787,9 @@ namespace DualScreenDemo
|
||||
|
||||
if (song != null)
|
||||
{
|
||||
Console.WriteLine($"Inserting Song: {song.Name} by {song.Artist_A}");
|
||||
Console.WriteLine($"Inserting Song: {song.getName()} by {song.getArtist_A()}");
|
||||
// 这里可以添加插播歌曲的处理逻辑
|
||||
OverlayForm.MainForm.InsertSongToPlaylist(song);
|
||||
|
||||
SongList.Insert(song);
|
||||
var response = new { status = "success", message = "Song inserted successfully" };
|
||||
string jsonResponse = JsonConvert.SerializeObject(response);
|
||||
await SendResponseAsync(context, jsonResponse);
|
||||
@ -1114,14 +1051,14 @@ namespace DualScreenDemo
|
||||
favoriteSongList = searchResults
|
||||
.Select(song => new
|
||||
{
|
||||
song.Name,
|
||||
song.Artist_A,
|
||||
song.Number,
|
||||
song.Artist_A_Simplified,
|
||||
song.Artist_B_Simplified,
|
||||
song.Name_Simplified,
|
||||
song.HumanVoice,
|
||||
song.FileName
|
||||
Name = song.getName(),
|
||||
ArtistA =song.getArtist_A(),
|
||||
Number = song.getNumber(),
|
||||
//song.getArtist_A(true),
|
||||
//song.getArtist_B(true),
|
||||
//song.getName(true),
|
||||
HumanVoice =song.getHumanVoice(),
|
||||
FileName = song.getFileName()
|
||||
})
|
||||
.ToList(),
|
||||
status = "success",
|
||||
|
@ -601,43 +601,6 @@ namespace OverlayFormObj
|
||||
|
||||
|
||||
|
||||
public void UpdateNextSongLabelFromPlaylist( SongData currentPlayingSong)
|
||||
{
|
||||
// 获取播放列表
|
||||
List<SongData> currentPlaylist = VideoPlayerForm.playingSongList ;
|
||||
|
||||
if (currentPlaylist == null || currentPlaylist.Count == 0)
|
||||
{
|
||||
nextSongLabel.Text = "目前沒有下一首,請踴躍點歌!!!";
|
||||
nextSongLabel.Visible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 找到当前歌曲的索引
|
||||
int currentSongIndex = currentPlaylist.IndexOf(currentPlayingSong);
|
||||
|
||||
if (currentSongIndex == -1 || currentSongIndex + 1 >= currentPlaylist.Count)
|
||||
{
|
||||
nextSongLabel.Text = "目前沒有下一首,請踴躍點歌!!!";
|
||||
}
|
||||
else
|
||||
{
|
||||
SongData nextSong = currentPlaylist[currentSongIndex + 1];
|
||||
if (!string.IsNullOrEmpty(nextSong.Artist_A))
|
||||
{
|
||||
nextSongLabel.Text = nextSong.next_artist_text();
|
||||
}
|
||||
else
|
||||
{
|
||||
nextSongLabel.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
nextSongLabel.Visible = !string.IsNullOrEmpty(nextSongLabel.Text); // 僅在有內容時顯示標籤
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 更新 nextSongLabel 標籤的文本
|
||||
public void UpdateNextSongLabel(string text)
|
||||
{
|
||||
|
@ -132,13 +132,13 @@ namespace OverlayFormObj
|
||||
};
|
||||
}
|
||||
|
||||
private void AddCenteredPicture(Bitmap bitmap, int y)
|
||||
{
|
||||
private void AddCenteredPicture(Bitmap bitmap, int y)
|
||||
{
|
||||
int x = (this.Width - bitmap.Width) / 2;
|
||||
AddPicture(bitmap, x, y);
|
||||
}
|
||||
private void AddPicture(Bitmap bitmap, int x, int y)
|
||||
{
|
||||
}
|
||||
private void AddPicture(Bitmap bitmap, int x, int y)
|
||||
{
|
||||
PictureBox pictureBox = new PictureBox
|
||||
{
|
||||
Image = bitmap,
|
||||
@ -148,9 +148,9 @@ private void AddPicture(Bitmap bitmap, int x, int y)
|
||||
};
|
||||
this.Controls.Add(pictureBox);
|
||||
pictureBox.BringToFront();
|
||||
}
|
||||
private Bitmap GenerateTextImage(string text, Font font, Color textColor, Color backgroundColor)
|
||||
{
|
||||
}
|
||||
private Bitmap GenerateTextImage(string text, Font font, Color textColor, Color backgroundColor)
|
||||
{
|
||||
SizeF textSize;
|
||||
using (Bitmap tempBitmap = new Bitmap(1, 1))
|
||||
using (Graphics tempGraphics = Graphics.FromImage(tempBitmap))
|
||||
@ -193,10 +193,10 @@ private Bitmap GenerateTextImage(string text, Font font, Color textColor, Color
|
||||
|
||||
// 修剪圖片邊緣空白
|
||||
return TrimBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap TrimBitmap(Bitmap source)
|
||||
{
|
||||
private Bitmap TrimBitmap(Bitmap source)
|
||||
{
|
||||
Rectangle rect = FindContentBounds(source);
|
||||
|
||||
if (rect.Width == 0 || rect.Height == 0)
|
||||
@ -209,10 +209,10 @@ private Bitmap TrimBitmap(Bitmap source)
|
||||
}
|
||||
|
||||
return trimmedBitmap;
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle FindContentBounds(Bitmap bmp)
|
||||
{
|
||||
private Rectangle FindContentBounds(Bitmap bmp)
|
||||
{
|
||||
int width = bmp.Width;
|
||||
int height = bmp.Height;
|
||||
|
||||
@ -284,7 +284,7 @@ private Rectangle FindContentBounds(Bitmap bmp)
|
||||
}
|
||||
|
||||
return Rectangle.FromLTRB(left, top, right + 1, bottom + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -357,7 +357,6 @@ private Rectangle FindContentBounds(Bitmap bmp)
|
||||
secondLineTimer.Interval = 100;
|
||||
secondLineTimer.Tick += SecondLineTimer_Tick;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@ -370,12 +369,6 @@ private Rectangle FindContentBounds(Bitmap bmp)
|
||||
Console.WriteLine("Error reading marquee text from file: " + ex.Message);
|
||||
marqueeText = "這是跑馬燈文字示例 - 歡迎使用MediaPlayerForm!";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.DoubleBuffered = true;
|
||||
}
|
||||
|
||||
@ -1004,13 +997,8 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
if (songIndex >= 0 && songIndex < totalSongs)
|
||||
{
|
||||
selectedSong = LanguageSongList[songIndex];
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Name + " " + selectedSong.FileName);
|
||||
|
||||
|
||||
// DisplayActionWithSong(currentPage, songIndex, "點播");
|
||||
|
||||
|
||||
AddSongToPlaylist(selectedSong);
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].getName() + " " + selectedSong.getFileName());
|
||||
SongList.Add(selectedSong);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1036,13 +1024,8 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
if (songIndex < totalSongs)
|
||||
{
|
||||
selectedSong = LanguageSongList[songIndex];
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].Name + " " + selectedSong.FileName );
|
||||
|
||||
|
||||
// DisplayActionWithSong(currentPage, songIndex, "插播");
|
||||
|
||||
|
||||
InsertSongToPlaylist(selectedSong);
|
||||
Console.WriteLine("Adding song to playlist: " + LanguageSongList[songIndex].getName() + " " + selectedSong.getFileName() );
|
||||
SongList.Insert(selectedSong);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1120,7 +1103,7 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
if (songIndex < totalSongs)
|
||||
{
|
||||
selectedSong = LanguageSongList[songIndex];
|
||||
Console.WriteLine("Adding song to playlist C: " + LanguageSongList[songIndex].Name + " " + selectedSong.FileName);
|
||||
Console.WriteLine("Adding song to playlist C: " + LanguageSongList[songIndex].getName() + " " + selectedSong.getFileName());
|
||||
|
||||
|
||||
DisplaySongsWithArrows(currentPage, songIndex);
|
||||
@ -1200,7 +1183,7 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
}
|
||||
}
|
||||
}
|
||||
public void UpdateHistoryLabel(List<SongData> historySongs, List<PlayState> playStates, int currentPage, int totalPages)
|
||||
public void UpdateHistoryLabel(List<SongData> historySongs, int currentPage, int totalPages)
|
||||
{
|
||||
|
||||
// 移除畫面上所有現有的 PictureBox(用於刷新內容)
|
||||
@ -1227,37 +1210,15 @@ private static void SongDisplayTimer_Elapsed(object sender, EventArgs e)
|
||||
int rightMargin = this.Width - 100;
|
||||
|
||||
// 逐一繪製歷史歌曲列表
|
||||
|
||||
for (int i = 0; i < historySongs.Count; i++)
|
||||
{
|
||||
var song = historySongs[i]; // 歌曲資料
|
||||
var state = playStates[i]; // 對應的播放狀態
|
||||
|
||||
string status; // 播放狀態文字(如「播放中」)
|
||||
Color textColor; // 對應的顏色
|
||||
|
||||
// 根據播放狀態決定狀態文字與顏色
|
||||
switch (state)
|
||||
{
|
||||
case PlayState.Played:
|
||||
status = "(播畢)";
|
||||
textColor = Color.FromArgb(200, 75, 125); // 播畢顏色:紫紅色
|
||||
break;
|
||||
case PlayState.Playing:
|
||||
status = "(播放中)";
|
||||
textColor = Color.LimeGreen; // 播放中顏色:亮綠
|
||||
break;
|
||||
case PlayState.NotPlayed:
|
||||
status = "";
|
||||
textColor = Color.White; // 尚未播放:白色
|
||||
break;
|
||||
default:
|
||||
status = "";
|
||||
textColor = Color.White;
|
||||
break;
|
||||
}
|
||||
string status=song.GetStateTxt(false); // 播放狀態文字(如「播放中」)
|
||||
Color textColor=song.GetStateColor(); // 對應的顏色
|
||||
|
||||
// 建立顯示的歌曲文字,例如 "1. 我的歌"
|
||||
string songText = $"{i + 1}. {song.Name}";
|
||||
string songText = $"{i + 1}. {song.getName()}";
|
||||
Font songFont = new Font("Microsoft JhengHei", 50, FontStyle.Bold);
|
||||
|
||||
// 將歌名轉成圖片
|
||||
@ -1526,99 +1487,6 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
ClearDisplay();
|
||||
DisplaySongs(currentPage);
|
||||
}
|
||||
// 歌庫路徑調整
|
||||
public void AddSongToPlaylist(SongData songData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 之後還要設計成本地的資料夾位置
|
||||
string pathToPlay = songData.getFile();
|
||||
if (!string.IsNullOrEmpty(pathToPlay))
|
||||
{
|
||||
bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0;
|
||||
|
||||
PrimaryForm.userRequestedSongs.Add(songData);
|
||||
PrimaryForm.playedSongsHistory.Add(songData);
|
||||
PrimaryForm.playStates.Add(wasEmpty ? PlayState.Playing : PlayState.NotPlayed);
|
||||
// 刷新頁面
|
||||
|
||||
if (PrimaryForm.Instance.multiPagePanel.get_currentSongList() == PrimaryForm.playedSongsHistory)
|
||||
PrimaryForm.Instance.multiPagePanel.LoadSongs(PrimaryForm.Instance.currentSongList);
|
||||
if (wasEmpty)
|
||||
{
|
||||
VideoPlayerForm.Instance.SetPlayingSongList(PrimaryForm.userRequestedSongs);
|
||||
PrimaryForm.currentSongIndexInHistory += 1;
|
||||
}
|
||||
VideoPlayerForm.Instance.UpdateNextSongFromPlaylist();
|
||||
PrimaryForm.PrintPlayingSongList();
|
||||
|
||||
// 點播次數+1
|
||||
PrimaryForm.Instance.AddSongCount(songData.Number);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error occurred: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void InsertSongToPlaylist(SongData songData)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 從 songData 中取得兩個可能的檔案路徑(主機1與主機2)
|
||||
var pathToPlay = songData.getFile();
|
||||
|
||||
// 檢查兩個主機上的檔案是否皆不存在
|
||||
if (!string.IsNullOrEmpty(pathToPlay))
|
||||
{
|
||||
// 若其中一個存在,就用第一個存在的那個檔案
|
||||
|
||||
Console.WriteLine("path to play" + pathToPlay);
|
||||
|
||||
// 檢查目前使用者歌單是否為空
|
||||
bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0;
|
||||
|
||||
if (wasEmpty)
|
||||
{
|
||||
// 若是空的,代表是第一首歌,直接加入並設為正在播放
|
||||
PrimaryForm.userRequestedSongs.Add(songData); // 加入播放清單
|
||||
VideoPlayerForm.Instance.SetPlayingSongList(PrimaryForm.userRequestedSongs); // 傳給播放器
|
||||
PrimaryForm.playedSongsHistory.Add(songData); // 加入播放歷史
|
||||
PrimaryForm.playStates.Add(PlayState.Playing); // 設定狀態為正在播放
|
||||
PrimaryForm.currentSongIndexInHistory += 1; // 歷史索引 +1
|
||||
}
|
||||
else if (PrimaryForm.userRequestedSongs.Count == 1)
|
||||
{
|
||||
// 若清單中已有一首,插入新歌在 index 1 (即目前播放之後的位置)
|
||||
PrimaryForm.userRequestedSongs.Insert(1, songData);
|
||||
PrimaryForm.playedSongsHistory.Insert(PrimaryForm.currentSongIndexInHistory + 1, songData);
|
||||
PrimaryForm.playStates.Insert(PrimaryForm.currentSongIndexInHistory + 1, PlayState.NotPlayed); // 尚未播放
|
||||
}
|
||||
else
|
||||
{
|
||||
// 若清單中超過一首,同樣插入在 index 1,也是在當前歌曲之後的位置
|
||||
PrimaryForm.userRequestedSongs.Insert(1, songData);
|
||||
PrimaryForm.playedSongsHistory.Insert(PrimaryForm.currentSongIndexInHistory + 1, songData);
|
||||
PrimaryForm.playStates.Insert(PrimaryForm.currentSongIndexInHistory + 1, PlayState.NotPlayed);
|
||||
}
|
||||
|
||||
// 更新下一首即將播放的資訊(畫面或播放器邏輯用)
|
||||
VideoPlayerForm.Instance.UpdateNextSongFromPlaylist();
|
||||
|
||||
// 印出目前播放清單資訊到畫面或 console
|
||||
PrimaryForm.PrintPlayingSongList();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 捕捉所有例外並印出錯誤訊息(避免整個流程當掉)
|
||||
Console.WriteLine("Error occurred: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 測試
|
||||
public int currentPage = 1;
|
||||
@ -1681,7 +1549,7 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}";
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName(false)}";
|
||||
string artistText = LanguageSongList[i].artist_text();
|
||||
|
||||
maxSongLength = Math.Max(maxSongLength, songText.Length);
|
||||
@ -1701,7 +1569,7 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
// 計算行高
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}";
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName(false)}";
|
||||
string artistText = LanguageSongList[i].artist_text();
|
||||
|
||||
Font songFont = new Font("Microsoft JhengHei", songFontSize, FontStyle.Bold);
|
||||
@ -1718,7 +1586,7 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
{
|
||||
int songNumber = i - startIndex + 1;
|
||||
|
||||
string songText = $"{songNumber}. {LanguageSongList[i].Name}";
|
||||
string songText = $"{songNumber}. {LanguageSongList[i].getName(false)}";
|
||||
string artistText = LanguageSongList[i].artist_text();
|
||||
|
||||
Font songFont = new Font("Microsoft JhengHei", songFontSize, FontStyle.Bold);
|
||||
@ -1791,7 +1659,7 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
int maxArtistLength = 0;
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}";
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName()}";
|
||||
string artistText = LanguageSongList[i].artist_text();
|
||||
|
||||
maxSongLength = Math.Max(maxSongLength, songText.Length);
|
||||
@ -1807,7 +1675,7 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
int rowHeight = 0;
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].Name}";
|
||||
string songText = $"{i - startIndex + 1}. {LanguageSongList[i].getName(false)}";
|
||||
string artistText = LanguageSongList[i].artist_text();
|
||||
|
||||
Font tempSongFont = new Font("Microsoft JhengHei", songFontSize, FontStyle.Bold);
|
||||
@ -1824,7 +1692,7 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
{
|
||||
int songNumber = i - startIndex + 1;
|
||||
|
||||
string songText = $"{songNumber}. {LanguageSongList[i].Name}";
|
||||
string songText = $"{songNumber}. {LanguageSongList[i].getName(false)}";
|
||||
string artistText = LanguageSongList[i].artist_text();
|
||||
|
||||
// 設定顏色,選中的索引顯示為亮綠色
|
||||
@ -1847,67 +1715,6 @@ private void DisplayArtists(List<Artist> artists, int page)//歌星點進去後
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void DisplayActionWithSong(int page, int songIndex, string actionType)
|
||||
{
|
||||
// try
|
||||
// {
|
||||
// if (LanguageSongList == null || LanguageSongList.Count == 0)
|
||||
// {
|
||||
// Console.WriteLine("Error: LanguageSongList is null or empty.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// SongData song = LanguageSongList[songIndex];
|
||||
|
||||
// this.Controls.OfType<PictureBox>().ToList().ForEach(p => this.Controls.Remove(p));
|
||||
|
||||
// int songsPerColumn = 5;
|
||||
// int startIndex = (page - 1) * songsPerPage;
|
||||
// int endIndex = Math.Min(startIndex + songsPerPage, LanguageSongList.Count);
|
||||
|
||||
// int totalPages = (int)Math.Ceiling((double)LanguageSongList.Count / songsPerPage);
|
||||
|
||||
// string headerText = $"{actionType}: {song.ArtistA} - {song.Song} ({page} / {totalPages})";
|
||||
// Font headerFont = new Font("Microsoft JhengHei", 40, FontStyle.Bold);
|
||||
// Color headerColor = actionType == "點播" ? Color.LimeGreen : Color.Yellow;
|
||||
// Bitmap headerBitmap = GenerateTextImage(headerText, headerFont, headerColor, Color.Transparent);
|
||||
// AddCenteredPicture(headerBitmap, 150);
|
||||
|
||||
// int startY = 250;
|
||||
// int verticalSpacing = 10;
|
||||
// int leftColumnX = 200;
|
||||
// int rightColumnX = this.Width / 2 + 150;
|
||||
|
||||
// for (int i = startIndex; i < endIndex; i++)
|
||||
// {
|
||||
// int songNumber = i - startIndex + 1;
|
||||
// string songText = $"{songNumber}. {LanguageSongList[i].Song}";
|
||||
// string artistText = !string.IsNullOrWhiteSpace(LanguageSongList[i].ArtistB)
|
||||
// ? $"{LanguageSongList[i].ArtistA} - {LanguageSongList[i].ArtistB}"
|
||||
// : LanguageSongList[i].ArtistA;
|
||||
|
||||
// Font songFont = new Font("Microsoft JhengHei", 40, FontStyle.Bold);
|
||||
// Bitmap songBitmap = GenerateTextImage(songText, songFont, Color.White, Color.Transparent);
|
||||
|
||||
// Font artistFont = new Font("Microsoft JhengHei", 30, FontStyle.Bold);
|
||||
// Bitmap artistBitmap = GenerateTextImage(artistText, artistFont, Color.White, Color.Transparent);
|
||||
|
||||
// int x = (i - startIndex) < songsPerColumn ? leftColumnX : rightColumnX;
|
||||
// int y = startY + ((i - startIndex) % songsPerColumn) * (songBitmap.Height + verticalSpacing);
|
||||
|
||||
// AddPicture(songBitmap, x, y);
|
||||
// AddPicture(artistBitmap, x + songBitmap.Width + 20, y);
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Error in DisplayActionWithSong: {ex.Message}");
|
||||
// Console.WriteLine(ex.StackTrace);
|
||||
// }
|
||||
}
|
||||
|
||||
public void NextPage()
|
||||
{
|
||||
|
||||
|
10
PlayState.cs
10
PlayState.cs
@ -3,9 +3,11 @@ namespace DualScreenDemo
|
||||
|
||||
public enum PlayState
|
||||
{
|
||||
Playing,
|
||||
Played,
|
||||
NotPlayed,
|
||||
Skipped
|
||||
NotPlayed, // 未播放
|
||||
Playing, // 正在播放
|
||||
Played, // 已播放
|
||||
InsertPlayback, // 插入播放
|
||||
NoFile, // 沒有文件
|
||||
Skipped // 已跳過
|
||||
}
|
||||
}
|
@ -221,11 +221,10 @@ namespace DualScreenDemo
|
||||
var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql());
|
||||
// 重置分頁
|
||||
currentPage = 0;
|
||||
currentSongList = searchResults;
|
||||
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
|
||||
// 更新多頁面面板的內容
|
||||
multiPagePanel.currentPageIndex = 0;
|
||||
multiPagePanel.LoadSongs(currentSongList);
|
||||
multiPagePanel.LoadSongs(searchResults);
|
||||
|
||||
ToggleFavoritePictureBoxButtonsVisibility();
|
||||
}
|
||||
@ -257,11 +256,10 @@ namespace DualScreenDemo
|
||||
var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql());
|
||||
// 重置分頁
|
||||
currentPage = 0;
|
||||
currentSongList = searchResults;
|
||||
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
|
||||
// 更新多頁面面板的內容
|
||||
multiPagePanel.currentPageIndex = 0;
|
||||
multiPagePanel.LoadSongs(currentSongList);
|
||||
multiPagePanel.LoadSongs(searchResults);
|
||||
|
||||
ToggleFavoritePictureBoxButtonsVisibility();
|
||||
}
|
||||
@ -274,11 +272,10 @@ namespace DualScreenDemo
|
||||
var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql());
|
||||
// 重置分頁
|
||||
currentPage = 0;
|
||||
currentSongList = searchResults;
|
||||
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
|
||||
// 更新多頁面面板的內容
|
||||
multiPagePanel.currentPageIndex = 0;
|
||||
multiPagePanel.LoadSongs(currentSongList);
|
||||
multiPagePanel.LoadSongs(searchResults);
|
||||
|
||||
ToggleFavoritePictureBoxButtonsVisibility();
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ namespace DualScreenDemo
|
||||
RefreshDisplayBase_Singer();
|
||||
}
|
||||
|
||||
public void LoadPlayedSongs(List<SongData> songs, List<PlayState> states)
|
||||
public void LoadPlayedSongs(List<SongData> songs)
|
||||
{
|
||||
_isShowingSinger = false;
|
||||
currentSongList = songs;
|
||||
@ -376,76 +376,20 @@ namespace DualScreenDemo
|
||||
{
|
||||
// 創建歌曲標籤
|
||||
Label songLabel = new Label();
|
||||
string statusText = ""; // 狀態文字
|
||||
|
||||
bool isCurrentlyPlaying = false; // 是否正在播放
|
||||
bool hasBeenPlayed = false; // 是否已播放完成
|
||||
bool isLatestInstance = true; // 是否是最新的歌曲
|
||||
|
||||
// 僅在 "已點歌曲" 頁面顯示播放狀態
|
||||
string statusText;
|
||||
Color color;
|
||||
if (PrimaryForm.Instance.isOnOrderedSongsPage)
|
||||
{
|
||||
// 判斷是否正在播放公播歌單 (若用戶點播歌單為空,則播放公播歌單)
|
||||
bool isPlayingPublicList = userRequestedSongs.Count == 0 ||
|
||||
(currentSongIndexInHistory >= userRequestedSongs.Count - 1 );
|
||||
if (isPlayingPublicList)
|
||||
{
|
||||
// 若播放公播歌單,代表已點歌曲皆已播放完畢
|
||||
hasBeenPlayed = true;
|
||||
songLabel.ForeColor = Color.Gray;
|
||||
statusText = IsSimplified ? "(播毕)" : "(播畢)";
|
||||
statusText = song.GetStateTxt(IsSimplified); // 狀態文字
|
||||
color = song.GetStateColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 計算已完成播放的歌曲數量
|
||||
int completedCount = currentSongIndexInHistory;
|
||||
//Console.WriteLine("currentSongIndexInHistory:" + currentSongIndexInHistory);
|
||||
// 遍歷已點歌曲歷史
|
||||
/*for (int i = 0; i <= currentSongIndexInHistory && i < playedSongsHistory.Count; i++) {
|
||||
if (i == currentSongIndexInHistory) {
|
||||
completedCount = i + 1; // 当前播放的歌曲
|
||||
break;
|
||||
}
|
||||
// 检查播放状态
|
||||
if (i < playStates.Count) {
|
||||
if (playStates[i] == PlayState.Played || playStates[i] == PlayState.Playing) {
|
||||
completedCount++;
|
||||
}
|
||||
// 如果是切歌状态,不增加计数
|
||||
}
|
||||
}*/
|
||||
// 計算歌曲在歷史中的位置
|
||||
int songPosition = pageOffset + index;
|
||||
// 判斷歌曲狀態
|
||||
if (songPosition < completedCount)
|
||||
{
|
||||
// 已播放完成
|
||||
hasBeenPlayed = true;
|
||||
songLabel.ForeColor = Color.Gray;
|
||||
statusText = IsSimplified ? "(播毕)" : "(播畢)";
|
||||
}
|
||||
else if (songPosition == completedCount)
|
||||
{
|
||||
// 正在播放
|
||||
isCurrentlyPlaying = true;
|
||||
songLabel.ForeColor = Color.LimeGreen;
|
||||
statusText = IsSimplified ? "(播放中)" : "(播放中)";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未播放
|
||||
songLabel.ForeColor = Color.White;
|
||||
statusText = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未在 "已點歌曲" 頁面顯示白色
|
||||
songLabel.ForeColor = Color.White;
|
||||
color = Color.White;
|
||||
statusText = string.Empty;
|
||||
}
|
||||
|
||||
songLabel.ForeColor = color;
|
||||
// 根據簡繁體設置選擇要顯示的文字
|
||||
string songText = song.getName(IsSimplified);
|
||||
|
||||
@ -507,7 +451,7 @@ namespace DualScreenDemo
|
||||
int artistWidth = (int)(this.Width * ArtistWidth);
|
||||
int artistX = songX + songWidth + 10;
|
||||
// 添加人聲標籤
|
||||
if (song.HumanVoice == 1)
|
||||
if (song.getHumanVoice() == 1)
|
||||
{
|
||||
PictureBox icon = new PictureBox()
|
||||
{
|
||||
@ -542,20 +486,12 @@ namespace DualScreenDemo
|
||||
};
|
||||
|
||||
// 根據文字長度設置字體大小
|
||||
int fold = 14;
|
||||
if (artistText.Length > 6)
|
||||
{
|
||||
artistLabel.Font = new Font("微軟正黑體", 10, FontStyle.Bold);
|
||||
}
|
||||
fold = 10;
|
||||
else if (artistText.Length > 3)
|
||||
{
|
||||
artistLabel.Font = new Font("微軟正黑體", 12, FontStyle.Bold);
|
||||
}
|
||||
else
|
||||
{
|
||||
artistLabel.Font = new Font("微軟正黑體", 14, FontStyle.Bold);
|
||||
}
|
||||
|
||||
//artistLabel.Font = new Font("微軟正黑體", 16, FontStyle.Bold);
|
||||
fold = 12;
|
||||
artistLabel.Font = new Font("微軟正黑體", fold, FontStyle.Bold);
|
||||
|
||||
artistLabel.ForeColor = Color.FromArgb(30,144,255);
|
||||
songLabel.TextAlign = ContentAlignment.MiddleLeft;
|
||||
@ -565,48 +501,15 @@ namespace DualScreenDemo
|
||||
artistLabel.BackColor = Color.Transparent;
|
||||
// 定義滑鼠進入 (MouseEnter) 事件的處理程序
|
||||
EventHandler mouseEnter = (sender, e) => {
|
||||
// 當不在「已點歌曲」頁面,或者該歌曲不是當前正在播放的歌曲,
|
||||
// 且(該歌曲未播放過或不是該歌曲的最新實例)時,改變顯示樣式
|
||||
if (!PrimaryForm.Instance.isOnOrderedSongsPage ||
|
||||
(!isCurrentlyPlaying && (!hasBeenPlayed || !isLatestInstance)))
|
||||
{
|
||||
// 當滑鼠移到歌曲上時,變更歌曲名稱為黃色
|
||||
songLabel.ForeColor = Color.Yellow;
|
||||
// 變更歌手名稱為黃色
|
||||
artistLabel.ForeColor = Color.Yellow;
|
||||
// 增強分隔線的亮度,使其更明顯
|
||||
separatorPanel.BackColor = Color.FromArgb(120, 255, 255, 255);
|
||||
}
|
||||
|
||||
};
|
||||
// 定義滑鼠離開 (MouseLeave) 事件的處理程序
|
||||
EventHandler mouseLeave = (sender, e) => {
|
||||
// 判斷是否處於「已點歌曲」頁面
|
||||
if (PrimaryForm.Instance.isOnOrderedSongsPage)
|
||||
{
|
||||
// 如果當前歌曲正在播放,則維持綠色顯示
|
||||
if (isCurrentlyPlaying)
|
||||
{
|
||||
songLabel.ForeColor = Color.LimeGreen;
|
||||
}
|
||||
// 如果該歌曲已播放完成,且是該歌曲的最新實例,則變為灰色
|
||||
else if (hasBeenPlayed && isLatestInstance)
|
||||
{
|
||||
songLabel.ForeColor = Color.Gray;
|
||||
}
|
||||
// 其他情況,則維持白色
|
||||
else
|
||||
{
|
||||
songLabel.ForeColor = Color.White;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 若不在「已點歌曲」頁面,則默認為白色
|
||||
songLabel.ForeColor = Color.White;
|
||||
}
|
||||
// 恢復歌手名稱的顏色為預設的藍色
|
||||
songLabel.ForeColor = color;
|
||||
artistLabel.ForeColor = Color.FromArgb(30, 144, 255);
|
||||
// 恢復分隔線的顏色為半透明白色
|
||||
separatorPanel.BackColor = Color.FromArgb(80, 255, 255, 255);
|
||||
};
|
||||
// 添加事件处理
|
||||
|
@ -34,67 +34,30 @@ namespace DualScreenDemo
|
||||
this.syncCloseButton = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ResizeAndPositionControl(this.primaryScreenPanel, 0, 0, 1440, 900);
|
||||
this.primaryScreenPanel.TabIndex = 0;
|
||||
this.primaryScreenPanel.BorderStyle = BorderStyle.FixedSingle;
|
||||
this.primaryScreenPanel.BackColor = System.Drawing.Color.Black;
|
||||
|
||||
|
||||
|
||||
// 同步畫面 服務鈴
|
||||
ConfigureButton(this.syncServiceBellButton, 1240, 17, 161, 161,
|
||||
resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen,
|
||||
//(sender, e) => SendCommandThroughSerialPort("a2 53 a4"));
|
||||
(sender,e)=>OnServiceBellButtonClick(sender,e));
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureButton(this.syncCutSongButton, 1218, 195, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, (sender, e) => videoPlayerForm.SkipToNextSong());
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureButton(this.syncCutSongButton, 1218, 195, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, (sender, e) => videoPlayerForm.PlayNextSong());
|
||||
ConfigureButton(this.syncReplayButton, 1218, 265, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, ReplayButton_Click);
|
||||
|
||||
|
||||
|
||||
// 有人聲入口位置
|
||||
ConfigureButton(this.syncOriginalSongButton, 1218, 335, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, (sender,e) => videoPlayerForm.ToggleVocalRemoval());
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureButton(this.syncMuteButton, 1218, 406, 205, 55, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, MuteUnmuteButton_Click);
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureButton(this.syncPauseButton, 1218, 475, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, SyncPauseButton_Click);
|
||||
ConfigureButton(this.syncPlayButton, 1218, 475, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, SyncPlayButton_Click);
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureButton(this.syncVolumeUpButton, 1218, 546, 205, 55, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, null);
|
||||
this.syncVolumeUpButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowVolumeUpLabel(); volumeUpTimer.Start(); };
|
||||
this.syncVolumeUpButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); volumeUpTimer.Stop(); };
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureButton(this.syncVolumeDownButton, 1218, 616, 205, 55, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, null);
|
||||
this.syncVolumeDownButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowVolumeDownLabel(); volumeDownTimer.Start(); };
|
||||
this.syncVolumeDownButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); volumeDownTimer.Stop(); };
|
||||
|
||||
|
||||
|
||||
|
||||
ConfigureButton(this.syncMicUpButton, 1218, 686, 205, 56, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, resizedNormalStateImageForSyncScreen, null);
|
||||
this.syncMicUpButton.MouseDown += (sender, e) => { OverlayForm.MainForm.ShowMicUpLabel(); micControlTimer.Tag = "a2 b5 a4"; micControlTimer.Start(); };
|
||||
this.syncMicUpButton.MouseUp += (sender, e) => { OverlayForm.MainForm.HideAllLabels(); micControlTimer.Stop(); };
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.IO;
|
||||
using DBObj;
|
||||
using OverlayFormObj;
|
||||
|
||||
namespace DualScreenDemo
|
||||
{
|
||||
public partial class PrimaryForm
|
||||
@ -114,26 +114,21 @@ namespace DualScreenDemo
|
||||
this.Controls.Add(favoriteButton);
|
||||
this.Controls.Add(vodScreenCloseButton);
|
||||
}
|
||||
|
||||
|
||||
private async void VodButton_Click(object sender, EventArgs e)
|
||||
private void VodButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
SetVodScreenPictureBoxAndButtonsVisibility(false);
|
||||
await Task.Delay(1000);
|
||||
OverlayForm.MainForm.AddSongToPlaylist(currentSelectedSong);
|
||||
|
||||
SongList.Add(currentSelectedSong);
|
||||
}
|
||||
|
||||
private void InsertButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
SetVodScreenPictureBoxAndButtonsVisibility(false);
|
||||
OverlayForm.MainForm.InsertSongToPlaylist(currentSelectedSong);
|
||||
|
||||
SongList.Insert(currentSelectedSong);
|
||||
}
|
||||
|
||||
private void AlbumButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
string name = currentSelectedSong.Artist_A;
|
||||
string name = currentSelectedSong.getArtist_A(false);
|
||||
string query = $"SELECT * FROM song_library_cache WHERE artistA = '{name}' ORDER BY add_date DESC;";
|
||||
var selectedSongs = SearchSongs_Mysql(query);
|
||||
/*var selectedSongs = allSongs.Where(song => song.ArtistA == currentSelectedSong.ArtistA)
|
||||
@ -146,24 +141,21 @@ namespace DualScreenDemo
|
||||
|
||||
private void FavoriteButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
Console.WriteLine("Favorite Button Clicked");
|
||||
InsertNewFavoriteSong(currentSelectedSong.Number);
|
||||
InsertNewFavoriteSong(currentSelectedSong.getNumber());
|
||||
var searchResults = SearchSongs_Mysql(SearchFavoriteSongs_Mysql());
|
||||
// 重置分頁
|
||||
currentPage = 0;
|
||||
currentSongList = searchResults;
|
||||
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
|
||||
// 更新多頁面面板的內容
|
||||
multiPagePanel.currentPageIndex = 0;
|
||||
multiPagePanel.LoadSongs(currentSongList);
|
||||
multiPagePanel.LoadSongs(searchResults);
|
||||
|
||||
SetVodScreenPictureBoxAndButtonsVisibility(false);
|
||||
}
|
||||
|
||||
private void VodScreenCloseButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
SetVodScreenPictureBoxAndButtonsVisibility(false);
|
||||
}
|
||||
|
||||
@ -171,38 +163,23 @@ namespace DualScreenDemo
|
||||
|
||||
private void SetVodScreenPictureBoxAndButtonsVisibility(bool isVisible)
|
||||
{
|
||||
|
||||
overlayPanel.Visible = isVisible;
|
||||
VodScreenPictureBox.Visible = isVisible;
|
||||
|
||||
|
||||
vodButton.Visible = isVisible;
|
||||
insertButton.Visible = isVisible;
|
||||
albumButton.Visible = isVisible;
|
||||
favoriteButton.Visible = isVisible;
|
||||
vodScreenCloseButton.Visible = isVisible;
|
||||
|
||||
|
||||
|
||||
if (isVisible)
|
||||
{
|
||||
|
||||
if (isLoggedIn)
|
||||
{
|
||||
if (isVisible){
|
||||
if (isLoggedIn){
|
||||
favoriteButton.Enabled = true;
|
||||
favoriteButton.Controls.Remove(disabledPanel);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
favoriteButton.Enabled = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
overlayPanel.BringToFront();
|
||||
VodScreenPictureBox.BringToFront();
|
||||
|
||||
|
||||
vodButton.BringToFront();
|
||||
insertButton.BringToFront();
|
||||
albumButton.BringToFront();
|
||||
|
@ -118,12 +118,7 @@ namespace DualScreenDemo
|
||||
private static Bitmap normalStateImageForLightControl;
|
||||
private static Bitmap resizedNormalStateImageForLightControl;
|
||||
public VideoPlayerForm videoPlayerForm;
|
||||
public List<SongData> currentSongList;
|
||||
public List<Artist> currentArtistList;
|
||||
public static List<SongData> userRequestedSongs;
|
||||
public static List<SongData> playedSongsHistory;
|
||||
public static List<PlayState> playStates;
|
||||
public static int currentSongIndexInHistory = -1;
|
||||
public MultiPagePanel multiPagePanel;
|
||||
private List<Label> songLabels = new List<Label>();
|
||||
private int _currentPage { get; set; }= 0;
|
||||
@ -218,7 +213,6 @@ namespace DualScreenDemo
|
||||
|
||||
InitializeRecording();
|
||||
InitializeMediaPlayer();
|
||||
LoadSongData();
|
||||
LoadImages();
|
||||
InitializeFormAndControls();
|
||||
InitializeMultiPagePanel();
|
||||
@ -989,10 +983,6 @@ namespace DualScreenDemo
|
||||
|
||||
if (status == RecognitionStatus.NoError)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
List<string> candidates = new List<string>();
|
||||
foreach (RecognitionAlternate alternate in result.GetAlternatesFromSelection())
|
||||
{
|
||||
@ -1102,7 +1092,7 @@ namespace DualScreenDemo
|
||||
qieGeButton.Name = "qieGeButton";
|
||||
ConfigureButton(qieGeButton, 28, 755, 92, 132,
|
||||
resizedNormalStateImage, resizedNormalStateImage, resizedNormalStateImage,
|
||||
(sender, e) => videoPlayerForm.SkipToNextSong());
|
||||
(sender, e) => videoPlayerForm.PlayNextSong());
|
||||
this.Controls.Add(qieGeButton);
|
||||
|
||||
|
||||
@ -1438,8 +1428,6 @@ namespace DualScreenDemo
|
||||
}
|
||||
this.Controls.Add(button);
|
||||
}
|
||||
|
||||
|
||||
private void InitializeMultiPagePanel()
|
||||
{
|
||||
// 獲取螢幕尺寸
|
||||
@ -1496,15 +1484,6 @@ namespace DualScreenDemo
|
||||
}
|
||||
}
|
||||
|
||||
public static void PrintPlayingSongList()
|
||||
{
|
||||
Console.WriteLine("當前播放列表:");
|
||||
foreach (var song in userRequestedSongs)
|
||||
{
|
||||
Console.WriteLine(song.name_text());
|
||||
}
|
||||
}
|
||||
|
||||
private void NextPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
multiPagePanel.LoadNextPage();
|
||||
@ -1537,14 +1516,6 @@ namespace DualScreenDemo
|
||||
multiPagePanel.LoadPreviousPage();
|
||||
}
|
||||
|
||||
private void LoadSongData()
|
||||
{
|
||||
userRequestedSongs = new List<SongData>();
|
||||
playedSongsHistory = new List<SongData>();
|
||||
playStates = new List<PlayState>();
|
||||
|
||||
}
|
||||
|
||||
private Bitmap ResizeImage(Image image, int width, int height)
|
||||
{
|
||||
var destRect = new Rectangle(0, 0, width, height);
|
||||
@ -1701,7 +1672,7 @@ namespace DualScreenDemo
|
||||
return bmp;
|
||||
}
|
||||
|
||||
private void DrawTextOnVodScreenPictureBox(string imagePath, SongData songData)
|
||||
private void DrawTextOnVodScreenPictureBox(string imagePath, SongData SongDetail)
|
||||
{
|
||||
Bitmap originalImage = new Bitmap(imagePath);
|
||||
|
||||
@ -1724,11 +1695,11 @@ namespace DualScreenDemo
|
||||
Font font = new Font("微軟正黑體", points, FontStyle.Bold);
|
||||
// 根據文字長度設置字體大小
|
||||
|
||||
if (songData.getNameLength() > 18)
|
||||
if (SongDetail.getNameLength() > 18)
|
||||
{
|
||||
font = new Font("微軟正黑體", 17, FontStyle.Bold);
|
||||
}
|
||||
else if (songData.getNameLength() > 13)
|
||||
else if (SongDetail.getNameLength() > 13)
|
||||
{
|
||||
font = new Font("微軟正黑體", 21, FontStyle.Bold);
|
||||
}
|
||||
@ -1741,7 +1712,7 @@ namespace DualScreenDemo
|
||||
|
||||
Brush textBrush = Brushes.Black;
|
||||
|
||||
string songInfo = songData.Name ?? "未提供歌曲信息";
|
||||
string songInfo = SongDetail.getName() ?? "未提供歌曲信息";
|
||||
|
||||
g.DrawString(songInfo, font, textBrush, new PointF(201, 29));
|
||||
|
||||
@ -1935,7 +1906,7 @@ namespace DualScreenDemo
|
||||
foreach(var song in userRequestedSongs){
|
||||
Console.WriteLine(song.ToString());
|
||||
}*/
|
||||
if( multiPagePanel.get_currentSongList() == playedSongsHistory)
|
||||
if( multiPagePanel.get_currentSongList() == SongList.GetHistory())
|
||||
return;
|
||||
autoRefreshTimer.Stop(); // 停止自动刷新
|
||||
FindFirstNonEmptyText(inputBoxZhuYinSingers
|
||||
@ -2412,8 +2383,8 @@ namespace DualScreenDemo
|
||||
isOnOrderedSongsPage = true;
|
||||
autoRefreshTimer.Start(); // 开始自动刷新
|
||||
// 已點歌曲錨點
|
||||
currentSongList = playedSongsHistory;
|
||||
totalPages = (int)Math.Ceiling((double)playedSongsHistory.Count / itemsPerPage);
|
||||
var List = SongList.GetHistory();
|
||||
totalPages = (int)Math.Ceiling((double)List.Count / itemsPerPage);
|
||||
multiPagePanel.currentPageIndex = 0;
|
||||
|
||||
SetHotSongButtonsVisibility(false);
|
||||
@ -2438,7 +2409,7 @@ namespace DualScreenDemo
|
||||
closeQRCodeButton.Visible = false;
|
||||
}
|
||||
|
||||
multiPagePanel.LoadPlayedSongs(playedSongsHistory, playStates);
|
||||
multiPagePanel.LoadPlayedSongs(List);
|
||||
}
|
||||
}
|
||||
}
|
@ -271,11 +271,10 @@ namespace DualScreenDemo
|
||||
var searchResults = SearchSongs_Mysql(query);
|
||||
// 重置分頁
|
||||
currentPage = 0;
|
||||
currentSongList = searchResults;
|
||||
totalPages = (int)Math.Ceiling((double)searchResults.Count / itemsPerPage);
|
||||
// 更新多頁面面板的內容
|
||||
multiPagePanel.currentPageIndex = 0;
|
||||
multiPagePanel.LoadSongs(currentSongList);
|
||||
multiPagePanel.LoadSongs(searchResults);
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化拼音輸入框 (RichTextBox),並從 config.ini 讀取相關設定。
|
||||
|
92
Program.cs
92
Program.cs
@ -16,31 +16,15 @@ namespace DualScreenDemo
|
||||
public static DataCheck.PublicSongChecker cherker;
|
||||
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
static void Main() {
|
||||
Console.WriteLine("Server V.1.2.0 20250703");
|
||||
if(Utils.Env.GetBool("IsCursor", true))Cursor.Hide();
|
||||
AppDomain.CurrentDomain.ProcessExit += (s, e) =>
|
||||
{
|
||||
Cursor.Show();
|
||||
};
|
||||
//Console.WriteLine("正在喚醒SVR裝置(每3分鐘呼叫一次)...");
|
||||
//_ = Task.Run(async () =>
|
||||
// {
|
||||
// while (true)
|
||||
// {
|
||||
// _ = Directory.Exists(@"\\svr01\video");
|
||||
// _ = Directory.Exists(@"\\svr02\video");
|
||||
// await Task.Delay(180000); // 每3min送一次
|
||||
// }
|
||||
// });
|
||||
|
||||
AppDomain.CurrentDomain.ProcessExit += (s, e) => Cursor.Show();
|
||||
//Console.WriteLine("正在與中控取得聯繫...");
|
||||
var sender = new heartbeatSender();
|
||||
cherker =new DataCheck.PublicSongChecker();
|
||||
cherker =new DataCheck.PublicSongChecker(DBObj.SongList.PublicSong());
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
// COM 初始化
|
||||
int hr = ComInterop.CoInitializeEx(IntPtr.Zero, ComInterop.COINIT_APARTMENTTHREADED);
|
||||
if (hr < 0)
|
||||
@ -74,31 +58,43 @@ namespace DualScreenDemo
|
||||
|
||||
// 創建主窗體
|
||||
primaryForm = new PrimaryForm();
|
||||
//primaryForm.allSongs = songListManager.AllSongs;
|
||||
//primaryForm.allArtists = artistManager.AllArtists;
|
||||
primaryForm.StartPosition = FormStartPosition.Manual;
|
||||
primaryForm.Location = new Point(0, 0);
|
||||
primaryForm.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
|
||||
|
||||
// 在完整初始化後檢查狀態
|
||||
InitializeSecondaryScreen();
|
||||
if (Screen.AllScreens.Length > 1) {
|
||||
var secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary);
|
||||
if (secondaryScreen != null) {
|
||||
// 确保 primaryForm 和 videoPlayerForm 已经正确初始化
|
||||
if (primaryForm.videoPlayerForm == null) {
|
||||
primaryForm.videoPlayerForm = new VideoPlayerForm();
|
||||
}
|
||||
|
||||
// 设置 videoPlayerForm 的位置和大小
|
||||
// primaryForm.videoPlayerForm.StartPosition = FormStartPosition.Manual;
|
||||
// primaryForm.videoPlayerForm.Location = secondaryScreen.WorkingArea.Location;
|
||||
// primaryForm.videoPlayerForm.Size = secondaryScreen.WorkingArea.Size;
|
||||
|
||||
// 显示 videoPlayerForm 在第二显示器
|
||||
primaryForm.videoPlayerForm.Show();
|
||||
|
||||
// 初始化公共播放列表
|
||||
primaryForm.videoPlayerForm.PlayNextSong();
|
||||
}
|
||||
}
|
||||
primaryForm.Show();
|
||||
Application.Run(primaryForm);
|
||||
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
} catch (Exception ex) {
|
||||
WriteLog(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
|
||||
//} finally {
|
||||
//SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
private static bool IsUrlAclExists(string url)
|
||||
{
|
||||
try
|
||||
@ -127,34 +123,7 @@ namespace DualScreenDemo
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitializeSecondaryScreen()
|
||||
{
|
||||
if (Screen.AllScreens.Length > 1)
|
||||
{
|
||||
var secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary);
|
||||
if (secondaryScreen != null)
|
||||
{
|
||||
// 确保 primaryForm 和 videoPlayerForm 已经正确初始化
|
||||
if (primaryForm.videoPlayerForm == null)
|
||||
{
|
||||
primaryForm.videoPlayerForm = new VideoPlayerForm();
|
||||
}
|
||||
|
||||
// 设置 videoPlayerForm 的位置和大小
|
||||
// primaryForm.videoPlayerForm.StartPosition = FormStartPosition.Manual;
|
||||
// primaryForm.videoPlayerForm.Location = secondaryScreen.WorkingArea.Location;
|
||||
// primaryForm.videoPlayerForm.Size = secondaryScreen.WorkingArea.Size;
|
||||
|
||||
// 显示 videoPlayerForm 在第二显示器
|
||||
primaryForm.videoPlayerForm.Show();
|
||||
|
||||
// 初始化公共播放列表
|
||||
primaryForm.videoPlayerForm.PlayPublicPlaylist();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
private static void OnDisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
// UI操作應該放在try-catch塊中
|
||||
@ -174,7 +143,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
primaryForm.videoPlayerForm = new VideoPlayerForm();
|
||||
// primaryForm.primaryMediaPlayerForm = new PrimaryMediaPlayerForm(primaryForm, primaryForm.secondaryMediaPlayerForm);
|
||||
primaryForm.videoPlayerForm.PlayPublicPlaylist();
|
||||
//primaryForm.videoPlayerForm.PlayNextSong();
|
||||
primaryForm.videoPlayerForm.Show();
|
||||
}
|
||||
}
|
||||
@ -213,7 +182,7 @@ namespace DualScreenDemo
|
||||
Console.WriteLine(String.Format("Error writing to log file: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private static Form CreatePrimaryForm()
|
||||
{
|
||||
return new Form
|
||||
@ -234,5 +203,6 @@ namespace DualScreenDemo
|
||||
FormBorderStyle = FormBorderStyle.None
|
||||
};
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -10,22 +10,19 @@ namespace DataCheck
|
||||
public class PublicSongChecker
|
||||
{
|
||||
|
||||
private List<SongData> publicSongList = new();
|
||||
public PublicSongChecker()
|
||||
private List<SongData> publicList;
|
||||
public PublicSongChecker(List<SongData> publicSongList)
|
||||
{
|
||||
publicList = publicSongList;
|
||||
string serverPath = Utils.Env.GetPath("video", "");
|
||||
string localPath = @"D:\video";
|
||||
// 加入你要同步的資料夾
|
||||
SyncFolder(serverPath, localPath, "video", new[] { ".mpg" });
|
||||
}
|
||||
public List<SongData> GetSongs()
|
||||
{
|
||||
return publicSongList;
|
||||
Console.WriteLine($"publicList:{publicList.Count}");
|
||||
}
|
||||
|
||||
private void SyncFolder(string serverPath, string localPath, string label, string[] extensions)
|
||||
{
|
||||
|
||||
if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath);
|
||||
if (!Directory.Exists(serverPath)) {
|
||||
Console.WriteLine($"找不到伺服器資料夾:{serverPath}");
|
||||
@ -57,11 +54,15 @@ namespace DataCheck
|
||||
}
|
||||
}
|
||||
string fileName = Path.GetFileNameWithoutExtension(serverFile.Key);
|
||||
Match match = Regex.Match(fileName, @"^(?<songNumber>\d+)-.*?-(?<songName>[^-]+)-");
|
||||
if (match.Success) {
|
||||
publicSongList.Add(new SongData(
|
||||
match.Groups["songNumber"].Value, // songNumber
|
||||
match.Groups["songName"].Value, // song
|
||||
if (fileName == "welcome") {
|
||||
DBObj.SongList.welcome=new SongData("0", "歡迎光臨", @"D:\video\welcome.mpg", 1 ,true);
|
||||
} else if (fileName == "CLOSE") {
|
||||
DBObj.SongList.close =new SongData("0", "結束播放", @"D:\video\CLOSE.MPG", 1 ,true);
|
||||
} else {
|
||||
//Console.WriteLine($"{fileName} {Path.Combine(localPath, serverFile.Key)}");
|
||||
publicList.Add(new SongData(
|
||||
publicList.Count.ToString(), // songNumber
|
||||
fileName, // song
|
||||
Path.Combine(localPath, serverFile.Key), // songFilePathHost1
|
||||
1, // priority
|
||||
true
|
||||
|
127
SongChecker.cs
127
SongChecker.cs
@ -1,127 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using DBObj;
|
||||
|
||||
namespace DataCheck
|
||||
{
|
||||
public class SongChecker
|
||||
{
|
||||
private static List<SongData> playingSongList= new();
|
||||
//public static List<PlayState> playStates;
|
||||
private static List<SongData> publicSongList = new();
|
||||
private SongData welcome = new SongData("0", "歡迎光臨", @"D:\video\welcome.mpg", 1 ,true);
|
||||
private SongData close = new SongData("0", "結束播放", @"D:\video\CLOSE.MPG", 1 ,true);
|
||||
|
||||
public SongChecker()
|
||||
{
|
||||
string serverPath = Utils.Env.GetPath("video", "");
|
||||
string localPath = @"D:\video";
|
||||
// 加入你要同步的資料夾
|
||||
SyncFolder(serverPath, localPath, "video", new[] { ".mpg" });
|
||||
}
|
||||
public static bool AddSongToPlayList(SongData song)
|
||||
{
|
||||
playingSongList.Add(song);
|
||||
return true;
|
||||
}
|
||||
public static bool isPlayingUserSong()
|
||||
{
|
||||
return playingSongList.Count == 0;
|
||||
}
|
||||
public static SongData GetCurrentSong()
|
||||
{
|
||||
SongData song = null;
|
||||
int count = playingSongList.Count;
|
||||
if (count == 0)
|
||||
{
|
||||
song = publicSongList[0];
|
||||
publicSongList.RemoveAt(0);
|
||||
publicSongList.Add(song);
|
||||
}
|
||||
else
|
||||
{
|
||||
song = playingSongList[0];
|
||||
playingSongList.RemoveAt(0);
|
||||
}
|
||||
return song;
|
||||
}
|
||||
public static SongData GetNextSong()
|
||||
{
|
||||
return playingSongList.Count > 1 ? playingSongList[1] : null;
|
||||
}
|
||||
|
||||
private void SyncFolder(string serverPath, string localPath, string label, string[] extensions)
|
||||
{
|
||||
|
||||
if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath);
|
||||
if (!Directory.Exists(serverPath))
|
||||
{
|
||||
Console.WriteLine($"找不到伺服器資料夾:{serverPath}");
|
||||
return;
|
||||
}
|
||||
|
||||
var serverFiles = Directory.GetFiles(serverPath)
|
||||
.Where(f => extensions.Contains(Path.GetExtension(f), StringComparer.OrdinalIgnoreCase))
|
||||
.Select(f => new FileInfo(f))
|
||||
.ToDictionary(f => f.Name, f => f);
|
||||
|
||||
var localFiles = Directory.GetFiles(localPath)
|
||||
.Where(f => extensions.Contains(Path.GetExtension(f), StringComparer.OrdinalIgnoreCase))
|
||||
.Select(f => new FileInfo(f))
|
||||
.ToDictionary(f => f.Name, f => f);
|
||||
|
||||
// 1. 複製或更新檔案
|
||||
foreach (var serverFile in serverFiles)
|
||||
{
|
||||
string dest = Path.Combine(localPath, serverFile.Key);
|
||||
bool needsCopy = !localFiles.ContainsKey(serverFile.Key) ||
|
||||
serverFile.Value.LastWriteTime > localFiles[serverFile.Key].LastWriteTime;
|
||||
if (needsCopy)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Copy(serverFile.Value.FullName, dest, true);
|
||||
Console.WriteLine($"✅ 更新 {label}: {serverFile.Key}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"❌ 複製 {label} 失敗 {serverFile.Key}: {ex.Message}");
|
||||
continue; // 如果複製失敗就不加入 SongData
|
||||
}
|
||||
}
|
||||
string fileName = Path.GetFileNameWithoutExtension(serverFile.Key);
|
||||
Match match = Regex.Match(fileName, @"^(?<songNumber>\d+)-.*?-(?<songName>[^-]+)-");
|
||||
if (match.Success)
|
||||
{
|
||||
publicSongList.Add(new SongData(
|
||||
match.Groups["songNumber"].Value, // songNumber
|
||||
match.Groups["songName"].Value, // song
|
||||
Path.Combine(localPath, serverFile.Key), // songFilePathHost1
|
||||
1, // priority
|
||||
true
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 刪除多餘的本地檔案
|
||||
foreach (var localFile in localFiles)
|
||||
{
|
||||
if (!serverFiles.ContainsKey(localFile.Key))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(localFile.Value.FullName);
|
||||
Console.WriteLine($"刪除多餘{label}: {localFile.Key}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"刪除{label}失敗 {localFile.Key}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
TCPServer.cs
20
TCPServer.cs
@ -139,21 +139,11 @@ namespace DualScreenDemo
|
||||
if (File.Exists(closePath))
|
||||
{
|
||||
SongData closeSong = new SongData("0", "結束播放",closePath, 1,true);
|
||||
VideoPlayerForm.playingSongList = new List<SongData>();
|
||||
PrimaryForm.playedSongsHistory = new List<SongData>();
|
||||
if (VideoPlayerForm.Instance.currentPlayingSong != null)
|
||||
{
|
||||
VideoPlayerForm.playingSongList.Add(VideoPlayerForm.Instance.currentPlayingSong);
|
||||
}
|
||||
|
||||
VideoPlayerForm.playingSongList.Add(closeSong);
|
||||
|
||||
PrimaryForm.userRequestedSongs = new List<SongData>();
|
||||
SongList.clearSong();
|
||||
SongList.Add(closeSong);
|
||||
|
||||
if (IsFormReady(OverlayForm.MainForm))
|
||||
{
|
||||
OverlayForm.MainForm.nextSongLabel.Visible = false;
|
||||
}
|
||||
|
||||
VideoPlayerForm.Instance.PlayNextSong();
|
||||
PrimaryForm.Instance.logout();
|
||||
@ -187,9 +177,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
// 開台時跳至首頁
|
||||
|
||||
VideoPlayerForm.playingSongList = new List<SongData>();
|
||||
VideoPlayerForm.Instance.PlayPublicPlaylist();
|
||||
PrimaryForm.currentSongIndexInHistory = -1;
|
||||
SongList.clearSong();
|
||||
PrimaryForm.Instance.HotPlayButton_Click(null, EventArgs.Empty);
|
||||
Program.RoomState = "OPEN";
|
||||
PrimaryForm.Instance.HideSendOffScreen();
|
||||
@ -252,7 +240,7 @@ namespace DualScreenDemo
|
||||
*/
|
||||
}
|
||||
|
||||
Console.WriteLine("Connection closed.");
|
||||
//Console.WriteLine("Connection closed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ namespace DualScreenDemo
|
||||
public class VideoPlayerForm : Form
|
||||
{
|
||||
#region 防止閃屏
|
||||
public SongData currentPlayingSong;
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
@ -91,8 +91,6 @@ namespace DualScreenDemo
|
||||
private static bool isInitializationComplete = false;
|
||||
|
||||
public static OverlayForm overlayForm;
|
||||
public static List<SongData> playingSongList;
|
||||
public static int currentSongIndex = 0;
|
||||
public bool isMuted = false;
|
||||
public int previousVolume = -1000;
|
||||
public bool isPaused = false;
|
||||
@ -110,8 +108,6 @@ namespace DualScreenDemo
|
||||
{
|
||||
Instance = this;
|
||||
// this.DoubleBuffered = true;
|
||||
|
||||
InitializeComponent();
|
||||
this.Load += VideoPlayerForm_Load;
|
||||
this.Shown += VideoPlayerForm_Shown;
|
||||
this.FormClosing += VideoPlayerForm_FormClosing;
|
||||
@ -122,11 +118,6 @@ namespace DualScreenDemo
|
||||
MonitorMediaEvents();
|
||||
}
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void VideoPlayerForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
secondMonitor = ScreenHelper.GetSecondMonitor();
|
||||
@ -140,7 +131,7 @@ namespace DualScreenDemo
|
||||
}
|
||||
CheckMonitor();
|
||||
}
|
||||
|
||||
/*
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
@ -159,20 +150,17 @@ namespace DualScreenDemo
|
||||
Console.WriteLine("An error occurred in OnShown: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
private void VideoPlayerForm_Shown(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
int hr = CoInitializeEx(IntPtr.Zero, COINIT.APARTMENTTHREADED);
|
||||
if (hr < 0)
|
||||
{
|
||||
if (hr < 0) {
|
||||
Console.WriteLine("Failed to initialize COM library.");
|
||||
return;
|
||||
}
|
||||
|
||||
InitializeGraphBuilderPrimary();
|
||||
InitializeGraphBuilderSecondary();
|
||||
Task.Run(() => MonitorMediaEvents());
|
||||
}
|
||||
|
||||
private void VideoPlayerForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
@ -296,7 +284,7 @@ namespace DualScreenDemo
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureSampleGrabber(IBaseFilter sampleGrabberFilter)
|
||||
/*private void ConfigureSampleGrabber(IBaseFilter sampleGrabberFilter)
|
||||
{
|
||||
ISampleGrabber sampleGrabber = (ISampleGrabber)sampleGrabberFilter;
|
||||
AMMediaType mediaType = new AMMediaType
|
||||
@ -311,7 +299,7 @@ namespace DualScreenDemo
|
||||
sampleGrabber.SetBufferSamples(false);
|
||||
sampleGrabber.SetOneShot(false);
|
||||
sampleGrabber.SetCallback(new SampleGrabberCallback(this), 1);
|
||||
}
|
||||
}*/
|
||||
|
||||
private int ConnectFilters(IGraphBuilder graphBuilder, IBaseFilter sourceFilter, string sourcePinName, IBaseFilter destFilter, string destPinName)
|
||||
{
|
||||
@ -524,77 +512,12 @@ namespace DualScreenDemo
|
||||
private void DisplayBarrageOnOverlay(string text)
|
||||
{
|
||||
if (overlayForm.InvokeRequired)
|
||||
{
|
||||
overlayForm.Invoke(new System.Action(() => overlayForm.DisplayBarrage(text)));
|
||||
}
|
||||
else
|
||||
{
|
||||
overlayForm.DisplayBarrage(text);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SetPlayingSongList(List<SongData> songList)
|
||||
{
|
||||
// [1] 輸出 debug 訊息,方便開發時追蹤是否有呼叫此方法
|
||||
Console.WriteLine("SetPlayingSongList called");
|
||||
|
||||
// [2] 停止當前播放,釋放資源(例如關閉影片播放器、清除緩衝)
|
||||
StopAndReleaseResources();
|
||||
|
||||
|
||||
// [3] 將新的播放清單指派給 `playingSongList`
|
||||
playingSongList = songList;
|
||||
|
||||
// [6] 若使用者點播清單有歌,就開始播放
|
||||
// [6.1] 設定當前歌曲索引為 -1(意味著即將播放第一首,從 `PlayNextSong` 開始)
|
||||
currentSongIndex = -1;
|
||||
// [6.2] 播放下一首歌(實際會遞增 index 為 0,並播放該首歌)
|
||||
await PlayNextSong();
|
||||
}
|
||||
|
||||
|
||||
public async Task PlayPublicPlaylist()
|
||||
{
|
||||
Console.WriteLine("開始播放公播清單...");
|
||||
|
||||
// 在切换到公播之前,确保最后一首用户歌曲状态正确
|
||||
if (PrimaryForm.currentSongIndexInHistory >= 0 &&
|
||||
PrimaryForm.currentSongIndexInHistory < PrimaryForm.playStates.Count)
|
||||
{
|
||||
PrimaryForm.playStates[PrimaryForm.currentSongIndexInHistory] = PlayState.Played;
|
||||
Console.WriteLine($"切換到公播前更新最後一首歌曲狀態為已播放,索引:{PrimaryForm.currentSongIndexInHistory}");
|
||||
|
||||
// 强制刷新显示
|
||||
if (PrimaryForm.Instance.multiPagePanel != null)
|
||||
{
|
||||
PrimaryForm.Instance.multiPagePanel.LoadPlayedSongs(
|
||||
PrimaryForm.playedSongsHistory,
|
||||
PrimaryForm.playStates
|
||||
);
|
||||
}
|
||||
}
|
||||
currentSongIndex = -1;
|
||||
|
||||
await PlayNextSong();
|
||||
}
|
||||
|
||||
// private static async Task UpdateMarqueeTextForCurrentSong(SongData song)
|
||||
// {
|
||||
// string text;
|
||||
|
||||
// if (string.IsNullOrEmpty(song?.Song))
|
||||
// {
|
||||
// text = string.Empty;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// text = String.Format("正在播放:{0} ", song.Song);
|
||||
// }
|
||||
// overlayForm.UpdateSongDisplayLabel(text);
|
||||
|
||||
// await Task.Delay(5000);
|
||||
// }
|
||||
|
||||
/*
|
||||
public static async Task UpdateMarqueeTextForNextSong(SongData song)
|
||||
{
|
||||
string nextSongText = String.Format("下一首3:{0}", song.Name);
|
||||
@ -625,29 +548,7 @@ namespace DualScreenDemo
|
||||
overlayForm.ResetMarqueeTextToWelcomeMessage();
|
||||
}
|
||||
}
|
||||
public void UpdateNextSongFromPlaylist()
|
||||
{
|
||||
List<SongData> currentPlaylist = playingSongList ;
|
||||
|
||||
if (currentPlaylist == null || currentPlaylist.Count == 0)
|
||||
{
|
||||
overlayForm?.UpdateNextSongLabelFromPlaylist( null);
|
||||
return;
|
||||
}
|
||||
|
||||
int currentSongIndex = currentPlaylist.IndexOf(currentPlayingSong);
|
||||
|
||||
if (currentSongIndex == -1 || currentSongIndex + 1 >= currentPlaylist.Count)
|
||||
{
|
||||
overlayForm?.UpdateNextSongLabelFromPlaylist( null);
|
||||
}
|
||||
else
|
||||
{
|
||||
SongData nextSong = currentPlaylist[currentSongIndex + 1];
|
||||
overlayForm?.UpdateNextSongLabelFromPlaylist( currentPlayingSong);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
public async Task PlayNextSong()
|
||||
{
|
||||
// 等待初始化完成(例如播放器、串口等資源尚未就緒時)
|
||||
@ -655,45 +556,24 @@ namespace DualScreenDemo
|
||||
{
|
||||
await Task.Delay(100);
|
||||
}
|
||||
|
||||
StopAndReleaseResources();
|
||||
await Task.Delay(100);
|
||||
Console.WriteLine("開始播放下一首歌曲...");
|
||||
|
||||
// 根據目前播放模式(點歌 or 公播)決定要播放的清單
|
||||
List<SongData> currentPlaylist = playingSongList ;
|
||||
|
||||
// 若播放清單是空的,直接返回(不執行播放)
|
||||
if (!currentPlaylist.Any()) return;
|
||||
|
||||
var songToPlay = SongList.Next();
|
||||
if (!songToPlay.isPublicSong) {
|
||||
// 若是使用者點播模式,先送出升Key的串口指令
|
||||
if (SerialPortManager.mySerialPort != null && SerialPortManager.mySerialPort.IsOpen)
|
||||
{
|
||||
byte[] commandBytesIncreasePitch1 = new byte[] { 0xA2, 0x7F, 0xA4 };
|
||||
SerialPortManager.mySerialPort.Write(commandBytesIncreasePitch1, 0, commandBytesIncreasePitch1.Length);
|
||||
}
|
||||
|
||||
// 同樣遞增 index 來播放下一首
|
||||
currentSongIndex = (currentSongIndex + 1) % currentPlaylist.Count;
|
||||
|
||||
|
||||
|
||||
// 可以取得 燈控/聲控 的位置
|
||||
var songToPlay = currentPlaylist[currentSongIndex];
|
||||
}
|
||||
|
||||
// pathToPlay 需要調整
|
||||
var pathToPlay = songToPlay.getFile();
|
||||
|
||||
// 若兩個 host 上都找不到檔案就直接結束
|
||||
if (string.IsNullOrEmpty(pathToPlay))
|
||||
{
|
||||
Console.WriteLine($"文件不存在:{songToPlay.Name}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新目前正在播放的歌曲
|
||||
currentPlayingSong = songToPlay;
|
||||
|
||||
// 更新畫面上顯示的下一首歌資訊
|
||||
UpdateNextSongFromPlaylist();
|
||||
SongList.UpdateNextSongLabel();
|
||||
|
||||
// 顯示 QRCode(可能是點歌頁用)
|
||||
overlayForm.DisplayQRCodeOnOverlay(HttpServer.randomFolderPath);
|
||||
@ -706,17 +586,10 @@ namespace DualScreenDemo
|
||||
{
|
||||
// 確保在UI線程上執行COM對象操作
|
||||
if (this.InvokeRequired)
|
||||
{
|
||||
this.Invoke(new Action(async () =>
|
||||
{
|
||||
await InitializeAndPlayMedia(pathToPlay);
|
||||
}));
|
||||
}
|
||||
this.Invoke(new Action(async () => { await InitializeAndPlayMedia(pathToPlay); }));
|
||||
else
|
||||
{
|
||||
await InitializeAndPlayMedia(pathToPlay);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"播放時發生錯誤: {ex.Message}");
|
||||
@ -746,15 +619,8 @@ namespace DualScreenDemo
|
||||
private async Task InitializeAndPlayMedia(string pathToPlay)
|
||||
{
|
||||
|
||||
if (videoWindowPrimary != null)
|
||||
{
|
||||
videoWindowPrimary.put_Visible(OABool.False);
|
||||
}
|
||||
|
||||
if (videoWindowSecondary != null)
|
||||
{
|
||||
videoWindowSecondary.put_Visible(OABool.False);
|
||||
}
|
||||
if (videoWindowPrimary != null) videoWindowPrimary.put_Visible(OABool.False);
|
||||
if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False);
|
||||
|
||||
// 清理並初始化 DirectShow 圖表
|
||||
RemoveAllFilters(graphBuilderPrimary);
|
||||
@ -784,102 +650,21 @@ namespace DualScreenDemo
|
||||
if (mediaControlPrimary != null) mediaControlPrimary.Run();
|
||||
if (mediaControlSecondary != null) mediaControlSecondary.Run();
|
||||
|
||||
if (isSyncToPrimaryMonitor)
|
||||
{
|
||||
SyncToPrimaryMonitor();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 跳至下一首歌曲的方法,會根據目前播放清單(使用者清單或公播清單)做切換與播放邏輯控制。
|
||||
/// </summary>
|
||||
public async Task SkipToNextSong()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 停止當前播放並釋放資源(如播放器、影片檔等)
|
||||
StopAndReleaseResources();
|
||||
|
||||
// 稍作延遲,確保資源已被釋放
|
||||
await Task.Delay(100);
|
||||
|
||||
// 如果目前正在播放使用者點播清單,且清單還有歌曲
|
||||
if ( playingSongList != null && playingSongList.Count > 0)
|
||||
{
|
||||
// 移除目前播放的第一首歌(已經播放過的)
|
||||
playingSongList.RemoveAt(0);
|
||||
|
||||
if (playingSongList.Count <= 0)
|
||||
{
|
||||
lastPlayedIndex = -1;
|
||||
}
|
||||
}
|
||||
currentSongIndex = -1;
|
||||
await PlayNextSong();
|
||||
|
||||
// 如果目前歌曲在播放歷史列表的索引是合法的(防呆)
|
||||
if (PrimaryForm.currentSongIndexInHistory >= 0 && PrimaryForm.currentSongIndexInHistory < PrimaryForm.playedSongsHistory.Count)
|
||||
{
|
||||
var currentSong = PrimaryForm.playedSongsHistory[PrimaryForm.currentSongIndexInHistory];
|
||||
|
||||
// 如果新的播放清單還有歌曲,並且當前歷史記錄中的歌曲與播放清單的第一首一致,則標記為已播畢
|
||||
if (playingSongList.Count > 0 && currentSong == playingSongList[0])
|
||||
{
|
||||
PrimaryForm.playStates[PrimaryForm.currentSongIndexInHistory] = PlayState.Played;
|
||||
}
|
||||
}
|
||||
/*如果當前為公播,不可以+1*/
|
||||
bool isPlayingPublicList = PrimaryForm.userRequestedSongs.Count == 0 ||
|
||||
(PrimaryForm.currentSongIndexInHistory >= PrimaryForm.userRequestedSongs.Count - 1 );
|
||||
if (!isPlayingPublicList)
|
||||
{
|
||||
PrimaryForm.currentSongIndexInHistory += 1;
|
||||
}
|
||||
Console.WriteLine("currentSongIndexInHistory : " + PrimaryForm.currentSongIndexInHistory);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 若有例外錯誤,列印錯誤訊息並切回公播模式
|
||||
Console.WriteLine($"切換歌曲時發生錯誤: {ex.Message}");
|
||||
currentSongIndex = -1;
|
||||
|
||||
await PlayNextSong();
|
||||
}
|
||||
if (isSyncToPrimaryMonitor) SyncToPrimaryMonitor();
|
||||
}
|
||||
|
||||
public void ReplayCurrentSong()
|
||||
{
|
||||
List<SongData> currentPlaylist = playingSongList ;
|
||||
if (!currentPlaylist.Any()) return;
|
||||
var songToPlay = currentPlaylist[currentSongIndex];
|
||||
var songToPlay = SongList.Current();
|
||||
var pathToPlay = songToPlay.getFile();
|
||||
if (string.IsNullOrEmpty(pathToPlay))
|
||||
{
|
||||
MessageBox.Show("File does not exist on both hosts.");
|
||||
return;
|
||||
}
|
||||
// UpdateMarqueeTextForCurrentSong(songToPlay);
|
||||
|
||||
try
|
||||
{
|
||||
if (mediaControlPrimary != null)
|
||||
{
|
||||
mediaControlPrimary.Stop();
|
||||
}
|
||||
if (mediaControlSecondary != null)
|
||||
{
|
||||
mediaControlSecondary.Stop();
|
||||
}
|
||||
|
||||
if (videoWindowPrimary != null)
|
||||
{
|
||||
videoWindowPrimary.put_Visible(OABool.False); // 隐藏主屏幕窗口,避免干扰
|
||||
}
|
||||
|
||||
if (videoWindowSecondary != null)
|
||||
{
|
||||
videoWindowSecondary.put_Visible(OABool.False); // 隐藏副屏幕窗口,避免闪烁
|
||||
}
|
||||
if (mediaControlPrimary != null) mediaControlPrimary.Stop();
|
||||
if (mediaControlSecondary != null) mediaControlSecondary.Stop();
|
||||
if (videoWindowPrimary != null) videoWindowPrimary.put_Visible(OABool.False); // 隐藏主屏幕窗口,避免干扰
|
||||
if (videoWindowSecondary != null) videoWindowSecondary.put_Visible(OABool.False); // 隐藏副屏幕窗口,避免闪烁
|
||||
|
||||
// 清理并初始化 DirectShow 图表
|
||||
RemoveAllFilters(graphBuilderPrimary);
|
||||
@ -902,19 +687,13 @@ namespace DualScreenDemo
|
||||
}
|
||||
|
||||
// 音量处理
|
||||
if (isMuted)
|
||||
{
|
||||
SetVolume(-10000); // 静音
|
||||
}
|
||||
if (isMuted) SetVolume(-10000); // 静音
|
||||
|
||||
// 开始播放
|
||||
mediaControlPrimary?.Run();
|
||||
mediaControlSecondary?.Run();
|
||||
|
||||
if (isSyncToPrimaryMonitor)
|
||||
{
|
||||
SyncToPrimaryMonitor();
|
||||
}
|
||||
if (isSyncToPrimaryMonitor) SyncToPrimaryMonitor();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -985,10 +764,8 @@ namespace DualScreenDemo
|
||||
|
||||
public void RenderMediaFilePrimary(string filePath)
|
||||
{
|
||||
try {
|
||||
int hr;
|
||||
|
||||
try
|
||||
{
|
||||
IBaseFilter sourceFilter;
|
||||
hr = graphBuilderPrimary.AddSourceFilter(filePath, "Source", out sourceFilter);
|
||||
DsError.ThrowExceptionForHR(hr);
|
||||
@ -1007,18 +784,9 @@ namespace DualScreenDemo
|
||||
//Task.Delay(100).Wait();
|
||||
videoWindowPrimary.put_Visible(OABool.True);
|
||||
SaveGraphFile(graphBuilderPrimary, "primary_graph.grf");
|
||||
Console.WriteLine("主檔案 " + ((hr == 0) ? "成功" : "失敗"));
|
||||
|
||||
if (hr == 0)
|
||||
{
|
||||
Console.WriteLine("主檔案 成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("檔案失敗");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
} catch (Exception ex) {
|
||||
Console.WriteLine("主檔案失敗2: " + ex.Message);
|
||||
}
|
||||
}
|
||||
@ -1107,7 +875,6 @@ namespace DualScreenDemo
|
||||
}
|
||||
|
||||
private bool isPlayingNext = false;
|
||||
private int lastPlayedIndex = -1; // 追蹤上一首播放的索引
|
||||
|
||||
public void MonitorMediaEvents()
|
||||
{
|
||||
@ -1119,7 +886,7 @@ namespace DualScreenDemo
|
||||
{
|
||||
try
|
||||
{
|
||||
if (mediaControlSecondary == null || isPlayingNext)
|
||||
if (mediaControlSecondary == null)
|
||||
{
|
||||
await Task.Delay(500);
|
||||
continue;
|
||||
@ -1147,122 +914,14 @@ namespace DualScreenDemo
|
||||
{
|
||||
Console.WriteLine($"檢測到歌曲結束 - 當前位置: {currentSeconds:F2}秒, 總時長: {durationSeconds:F2}秒");
|
||||
|
||||
if (!isPlayingNext)
|
||||
{
|
||||
isPlayingNext = true;
|
||||
|
||||
// 添加额外的保护:确保在切换前停止当前播放
|
||||
if (mediaControlSecondary != null)
|
||||
BeginInvoke(new Action(async () =>
|
||||
{
|
||||
mediaControlSecondary.Stop();
|
||||
}
|
||||
|
||||
this.BeginInvoke(new Action(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// 在切换前释放资源
|
||||
StopAndReleaseResources();
|
||||
await Task.Delay(100); // 给予足够的时间释放资源
|
||||
|
||||
if ( playingSongList != null)
|
||||
{
|
||||
if (playingSongList.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 移除當前播放的歌曲
|
||||
playingSongList.RemoveAt(0);
|
||||
|
||||
// 更新播放状态逻辑
|
||||
if (PrimaryForm.currentSongIndexInHistory >= 0)
|
||||
{
|
||||
// 将当前播放的歌曲标记为已播放
|
||||
PrimaryForm.playStates[PrimaryForm.currentSongIndexInHistory] = PlayState.Played;
|
||||
|
||||
// 如果还有下一首歌
|
||||
if (playingSongList.Count > 0)
|
||||
{
|
||||
PrimaryForm.currentSongIndexInHistory++;
|
||||
// 将下一首歌标记为正在播放
|
||||
if (PrimaryForm.currentSongIndexInHistory < PrimaryForm.playStates.Count)
|
||||
{
|
||||
PrimaryForm.playStates[PrimaryForm.currentSongIndexInHistory] = PlayState.Playing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (playingSongList.Count == 0)
|
||||
{
|
||||
Console.WriteLine("用戶播放列表已播放完畢,切換到公共播放列表");
|
||||
|
||||
// 确保当前歌曲状态更新为已播放
|
||||
if (PrimaryForm.currentSongIndexInHistory >= 0 &&
|
||||
PrimaryForm.currentSongIndexInHistory < PrimaryForm.playStates.Count)
|
||||
{
|
||||
PrimaryForm.playStates[PrimaryForm.currentSongIndexInHistory] = PlayState.Played;
|
||||
Console.WriteLine($"已將最後一首歌曲狀態更新為已播放,索引:{PrimaryForm.currentSongIndexInHistory}");
|
||||
|
||||
// 强制刷新显示
|
||||
if (PrimaryForm.Instance.multiPagePanel != null)
|
||||
{
|
||||
PrimaryForm.Instance.multiPagePanel.LoadPlayedSongs(
|
||||
PrimaryForm.playedSongsHistory,
|
||||
PrimaryForm.playStates
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 重置播放状态但保留历史记录
|
||||
currentSongIndex = -1;
|
||||
|
||||
// 确保所有未播放的歌曲状态被清除
|
||||
for (int i = PrimaryForm.currentSongIndexInHistory + 1;
|
||||
i < PrimaryForm.playStates.Count; i++)
|
||||
{
|
||||
if (PrimaryForm.playStates[i] == PlayState.Playing)
|
||||
{
|
||||
PrimaryForm.playStates[i] = PlayState.NotPlayed;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加延迟以确保状态更新完成
|
||||
await Task.Delay(200);
|
||||
currentSongIndex = -1;
|
||||
|
||||
await PlayNextSong();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSongIndex = -1;
|
||||
await PlayNextSong();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"處理播放列表時發生錯誤: {ex.Message}");
|
||||
lastPlayedIndex = -1;
|
||||
currentSongIndex = -1;
|
||||
|
||||
await PlayNextSong();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"切換歌曲時發生錯誤: {ex.Message}");
|
||||
// 发生错误时重置状态并切换到公播
|
||||
lastPlayedIndex = -1;
|
||||
currentSongIndex = -1;
|
||||
await PlayNextSong();
|
||||
}
|
||||
finally
|
||||
{
|
||||
isPlayingNext = false;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1380,7 +1039,7 @@ namespace DualScreenDemo
|
||||
return -10000;
|
||||
}
|
||||
private bool isVocalRemoved = false;
|
||||
public async void ToggleVocalRemoval()
|
||||
public void ToggleVocalRemoval()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -1500,148 +1159,9 @@ namespace DualScreenDemo
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSongToPlaylist(SongData songData)
|
||||
{
|
||||
try{
|
||||
bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0;
|
||||
// 查找所有相同歌曲的索引
|
||||
var sameNameIndices = new List<int>();
|
||||
for (int i = 0; i < PrimaryForm.playedSongsHistory.Count; i++)
|
||||
{
|
||||
if (PrimaryForm.playedSongsHistory[i].Name == songData.Name)
|
||||
{
|
||||
sameNameIndices.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新歌到播放列表
|
||||
PrimaryForm.userRequestedSongs.Add(songData);
|
||||
PrimaryForm.playedSongsHistory.Add(songData);
|
||||
|
||||
// 更新状态
|
||||
if (wasEmpty)
|
||||
{
|
||||
// 如果是空列表,设置为正在播放
|
||||
PrimaryForm.playStates.Add(PlayState.Playing);
|
||||
PrimaryForm.currentSongIndexInHistory = PrimaryForm.playedSongsHistory.Count - 1;
|
||||
|
||||
// 确保之前相同歌曲的状态为已播放
|
||||
foreach (int index in sameNameIndices)
|
||||
{
|
||||
if (index < PrimaryForm.currentSongIndexInHistory)
|
||||
{
|
||||
PrimaryForm.playStates[index] = PlayState.Played;
|
||||
}
|
||||
}
|
||||
|
||||
VideoPlayerForm.Instance.SetPlayingSongList(PrimaryForm.userRequestedSongs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果不是空列表,设置为未播放
|
||||
PrimaryForm.playStates.Add(PlayState.NotPlayed);
|
||||
|
||||
// 更新所有相同歌曲的状态
|
||||
foreach (int index in sameNameIndices.Where(i => i < PrimaryForm.playedSongsHistory.Count - 1))
|
||||
{
|
||||
if (index < PrimaryForm.currentSongIndexInHistory)
|
||||
{
|
||||
// 之前的相同歌曲标记为已播放
|
||||
PrimaryForm.playStates[index] = PlayState.Played;
|
||||
}
|
||||
else if (index == PrimaryForm.currentSongIndexInHistory)
|
||||
{
|
||||
// 当前播放的歌曲保持Playing状态
|
||||
PrimaryForm.playStates[index] = PlayState.Playing;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 后面的相同歌曲标记为未播放
|
||||
PrimaryForm.playStates[index] = PlayState.NotPlayed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VideoPlayerForm.Instance.UpdateNextSongFromPlaylist();
|
||||
PrimaryForm.PrintPlayingSongList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error occurred: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertSongToPlaylist(SongData songData)
|
||||
{
|
||||
try{
|
||||
bool wasEmpty = PrimaryForm.userRequestedSongs.Count == 0;
|
||||
// 查找所有相同歌曲的索引
|
||||
var sameNameIndices = new List<int>();
|
||||
for (int i = 0; i < PrimaryForm.playedSongsHistory.Count; i++)
|
||||
{
|
||||
if (PrimaryForm.playedSongsHistory[i].Name == songData.Name)
|
||||
{
|
||||
sameNameIndices.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (wasEmpty)
|
||||
{
|
||||
// 如果列表为空,直接添加
|
||||
PrimaryForm.userRequestedSongs.Add(songData);
|
||||
PrimaryForm.playedSongsHistory.Add(songData);
|
||||
PrimaryForm.playStates.Add(PlayState.Playing);
|
||||
PrimaryForm.currentSongIndexInHistory = PrimaryForm.playedSongsHistory.Count - 1;
|
||||
|
||||
// 更新之前相同歌曲的状态
|
||||
foreach (int index in sameNameIndices)
|
||||
{
|
||||
if (index < PrimaryForm.currentSongIndexInHistory)
|
||||
{
|
||||
PrimaryForm.playStates[index] = PlayState.Played;
|
||||
}
|
||||
}
|
||||
|
||||
VideoPlayerForm.Instance.SetPlayingSongList(PrimaryForm.userRequestedSongs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 插入到当前播放歌曲之后
|
||||
int insertIndex = PrimaryForm.currentSongIndexInHistory + 1;
|
||||
|
||||
PrimaryForm.userRequestedSongs.Insert(1, songData);
|
||||
PrimaryForm.playedSongsHistory.Insert(insertIndex, songData);
|
||||
PrimaryForm.playStates.Insert(insertIndex, PlayState.NotPlayed);
|
||||
|
||||
// 更新所有相同歌曲的状态
|
||||
foreach (int index in sameNameIndices)
|
||||
{
|
||||
if (index < PrimaryForm.currentSongIndexInHistory)
|
||||
{
|
||||
// 之前的相同歌曲标记为已播放
|
||||
PrimaryForm.playStates[index] = PlayState.Played;
|
||||
}
|
||||
else if (index == PrimaryForm.currentSongIndexInHistory)
|
||||
{
|
||||
// 当前播放的歌曲保持Playing状态
|
||||
PrimaryForm.playStates[index] = PlayState.Playing;
|
||||
}
|
||||
else if (index > insertIndex)
|
||||
{
|
||||
// 后面的相同歌曲标记为未播放
|
||||
PrimaryForm.playStates[index] = PlayState.NotPlayed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VideoPlayerForm.Instance.UpdateNextSongFromPlaylist();
|
||||
PrimaryForm.PrintPlayingSongList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error occurred: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public VideoStatus GetCurrentVideoStatus()
|
||||
|
Loading…
x
Reference in New Issue
Block a user