// this code is published under the terms of the GNU GPL2 namespace project01 { using System; using System.IO; using Microsoft.DirectX; using Microsoft.DirectX.AudioVideoPlayback; using System.Windows.Forms; using System.Drawing; using System.Threading; using System.ComponentModel; public class Player08 { private static Audio audio=null; private static Form formPlayer=null; // player window private static ListBox listBox=null; private static Button playButton=null; private static Button stopButton=null; private static Button openButton=null; private static Button prevButton=null; private static Button nextButton=null; private static OpenFileDialog ofd=null; private static TextBox fileNameTextBox=null; private static TrackBar trackPos=null; private static HScrollBar volume=null; private static CheckBox radioButtonLoopList =null; private static CheckBox radioButtonShowList = null; private static Form formList=null; // list window private static Button addFileButton=null; private static Button deleteFileButton=null; private static Button deleteAllButton=null; private static Button openPlayListButton=null; private static Button savePlayListButton=null; private static SaveFileDialog sfd=null; private static Thread t =null; // thread which sets the trackbar private static int volumeValue=0; private static int itemNumber=0; private static bool loop=true; private static string PlayerHome; //directory where the player is started // the filter for the open file dialog private static string filterText = "Audio files (*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd; *.wma)|*.wav; *.mpa; *.mp2; *.mp3; *.au; *.aif; *.aiff; *.snd; *.wma|" + "MIDI Files (*.mid, *.midi, *.rmi)|*.mid; *.midi; *.rmi|" + "All Files (*.*)|*.*"; private static void HandlePauseClick(object sender, System.EventArgs e) { if(audio!=null) { if(audio.Playing) { audio.Pause(); playButton.Text = "play"; t.Suspend(); }else { audio.Play(); //if(listBox.Items.Count>0) HandlePlayFileDoubleClick(null, null); // this was for Winamp like behaviour - but is still bugy playButton.Text = "pause"; t.Resume(); } } } private static void HandleStopClick(object sender, System.EventArgs e) { if(audio!=null) { if(audio.Playing) { t.Suspend();// stop the thread until no file is playing audio.Stop(); playButton.Text = "play"; } } trackPos.Value=0; // set the posittion of the scroll bar to 0 or the left side // this was for Winamp like behaviour - but it is still bugy //if(listBox.Items.Count==0) FileNameTextBox.Text=""; // if there is no file to play in the list delete the file name text box content } private static void HandleOpenClick(object sender, System.EventArgs e) { ofd=new OpenFileDialog(); ofd.InitialDirectory = Directory.GetCurrentDirectory(); ofd.Filter = filterText; ofd.Title = "open audio file"; ofd.ShowDialog(formPlayer); if ((ofd.FileName != null) && (ofd.FileName != string.Empty)) { // only play new file if it is playable if(audio!=null) { if(audio.Playing) { // stop playing a file if a file is playing now audio.Stop(); playButton.Text = "play"; t.Suspend(); // stop the thread until no file is playing } } trackPos.Value=0; // set the posittion of the scroll bar to 0 ->eq. the left side listBox.Items.Clear(); // delete all items from list if ((ofd.FileName != null) && (ofd.FileName != string.Empty)) { // handle only falid files listBox.Items.Add(ofd.FileName); } itemNumber=0; // now only one item is in list listBox.SetSelected(0, true); // select the one file-> for doubel clicked method HandlePlayFileDoubleClick(null, null); // play the file -> is the same result as you double click on the file in the list } } private static void HandleTackMove(object sender, EventArgs e) { if(audio!=null && audio.Playing) audio.CurrentPosition=trackPos.Value;//trackPosition; } private static void HandleVolumeScroll(object sender, ScrollEventArgs se) { volumeValue=-(7000-se.NewValue); // so save volume value at a global variable to set it every time a audio object is created if(audio!=null) audio.Volume=volumeValue; // if a file is playing now } private static void HandleAddFileClick(object sender, System.EventArgs e) { ofd=new OpenFileDialog(); ofd.InitialDirectory = Directory.GetCurrentDirectory(); ofd.Filter = filterText; ofd.Title = "add audio file"; ofd.ShowDialog(formPlayer); if ((ofd.FileName != null) && (ofd.FileName != string.Empty)) { // handle only falid files listBox.Items.Add(ofd.FileName); } } private static void HandleDeleteAllClick(object sender, System.EventArgs e) { itemNumber=0; listBox.Items.Clear(); } private static void HandleDeleteFileClick(object sender, System.EventArgs e) { if(listBox.SelectedIndex<=itemNumber) itemNumber--; listBox.Items.Remove(listBox.SelectedItem); } private static void HandlePlayFileDoubleClick(object sender, System.EventArgs e) { if(listBox.Items.Count!=0 && listBox.SelectedIndex!=-1) { // if the list is empty and you doubel click it a Exception will be thrown if this method is run string fileName=listBox.SelectedItem.ToString(); itemNumber=listBox.SelectedIndex; if ((fileName != null) && (fileName != string.Empty)) { // handle only falid files try { Play(fileName); }catch { // if the file isn't a playable audio file audio=null; // this file isn't playable so set the audio=null fileNameTextBox.Text=""; // if it there no more items in the list MessageBox.Show("This file could not be opened.", "Invalid file.", MessageBoxButtons.OK, MessageBoxIcon.Information); listBox.Items.RemoveAt(itemNumber); playButton.Text = "play"; if(listBox.Items.Count!=0) { itemNumber=itemNumber-1; HandleEndOfPlayedFile(null, null); } } } } } // this method is invoked when the end of a file is reached or the next button is clicked private static void HandleEndOfPlayedFile(object sender, System.EventArgs e) { t.Suspend(); // stop the track position thread at first trackPos.Value=0; // if next is clicked and no item is in list && if last file the loop flag must be true if(listBox.Items.Count>0 && (listBox.Items.Count==itemNumber+1 && loop || listBox.Items.Count!=itemNumber+1)) { if(listBox.Items.Count==itemNumber+1) itemNumber=0; // last file was played so start at the beginning else itemNumber=itemNumber+1; // increment actual itemIndex listBox.SelectedIndex=itemNumber; // Selection to the next item in list Object file=listBox.Items[itemNumber]; // get the next item object string fileName=file.ToString(); // get path from the object if ((fileName != null) && (fileName != string.Empty)) { // handle only falid files try { Play(fileName); // create a new audio instance with the specified file }catch { // if the file isn't a playable audio file fileNameTextBox.Text=""; MessageBox.Show("This file could not be opened.", "Invalid file.", MessageBoxButtons.OK, MessageBoxIcon.Information); listBox.Items.RemoveAt(itemNumber); playButton.Text = "play"; if(listBox.Items.Count!=0) { // if there a items to play in the list - do so itemNumber=itemNumber-1; HandleEndOfPlayedFile(null, null); // if it is a infalied file play the next one } } } } } private static void HandlePrevButtonClick(object sender, System.EventArgs e) { if(listBox.Items.Count>0) { if(listBox.Items.Count==1 && loop) { HandlePlayFileDoubleClick(null, null); // prev item=next item }else if(listBox.Items.Count>1){ // more than one file if(itemNumber==0 && loop) { // the first item is played itemNumber=listBox.Items.Count-1; // prev item is the last in list listBox.SelectedIndex=itemNumber; // Selection to the next item in list HandlePlayFileDoubleClick(null, null); }else if(itemNumber!=0) { itemNumber=itemNumber-1; listBox.SelectedIndex=itemNumber; // Selection to the next item in list HandlePlayFileDoubleClick(null, null); } } } } private static void Play(string fileName) { if(audio!=null ) { if(audio.Playing) audio.Stop(); // if playing a file - so stop now t.Suspend(); audio.Dispose(); //Immediately releases the unmanaged resources used by the object. } audio=new Audio(fileName); // create a new audio instance with the specified file trackPos.Maximum=(int)audio.Duration; // set the maximum of the track Position Scroll Bar to the end of the audio file audio.Volume=volumeValue; audio.Play(); // if a exception occures no handler will be added playButton.Text = "pause"; fileNameTextBox.Text=Path.GetFileNameWithoutExtension(fileName); audio.Ending+=new System.EventHandler(HandleEndOfPlayedFile); t.Resume(); // resume the thread } private static void HandleLoopButtonClick(object sender, System.EventArgs e) { loop=!loop; } // if the checkbox is clicked for showing the file list private static void HandleListShow(object sender, EventArgs e) { if(formList.Visible==false) formList.Visible=true; else formList.Visible=false; } // if the closing icon (right top) on the file list is clicked so uncheck the radioButtonShowList check box private static void HandleCloseListClick(object sender, CancelEventArgs e) { e.Cancel = true; formList.Visible=false; radioButtonShowList.Checked=false; } private static void HandleOpenPlayListClick(object sender, EventArgs e) { ofd=new OpenFileDialog(); ofd.InitialDirectory = Directory.GetCurrentDirectory(); ofd.Filter = "Play List Files (*.m3u)|*.m3u;"; ofd.Title = "open play list"; ofd.ShowDialog(formPlayer); if ((ofd.FileName != null) && (ofd.FileName != string.Empty)) { // only play new file if it is playable FileStream s= new FileStream(ofd.FileName, FileMode.Open); StreamReader r=new StreamReader(s); listBox.Items.Clear(); // remove all items from list String line=r.ReadLine(); itemNumber=-1; string path=ofd.FileName; while(line!=null) { if(!line.StartsWith("#") && line.Length!=0 && !(line.StartsWith(" "))) { // if the line begins with # its not a filepath to playable file if(!Path.IsPathRooted(line)) AddAbsPathToRelativeFilePath(ref line, ref path); // if the path is relative make it absolut listBox.Items.Add(line); itemNumber++; } line=r.ReadLine(); } if(itemNumber==-1) itemNumber=0; // set it back 0 if no file was added s.Close(); // closing the FileStream if(listBox.Items.Count>0) { listBox.SetSelected(0, true); // select the first file-> for doubel clicked method HandlePlayFileDoubleClick(null, null); // play the first file if there is one } } } // the call GetDirectoryName appends the actuell directory to the relative filepath -> where the m3u file was opend public static void AddAbsPathToRelativeFilePath(ref string line, ref String path) { if(Path.GetDirectoryName(path).EndsWith("\\")) line=Path.GetDirectoryName(path)+line; // Path.GetDirectoryName(path) is a partition like "C:\" else line=Path.GetDirectoryName(path)+"\\"+line; // Path.GetDirectoryName(path) is a directory like "C:\MyMusic" Console.WriteLine(line); } private static void HandleSavePlayListClick(object sender, EventArgs e) { sfd=new SaveFileDialog(); sfd.InitialDirectory = Directory.GetCurrentDirectory(); sfd.Filter = "Play List Files (*.m3u)|*.m3u"; sfd.Title = "save play list"; sfd.ShowDialog(formPlayer); if ((sfd.FileName != null) && (sfd.FileName != string.Empty)) { // only play new file if it is playable FileStream s= new FileStream(sfd.FileName, FileMode.Create); StreamWriter r=new StreamWriter(s); for(int i=0; i0) { listBox.SetSelected(0, true); // select the first file-> for doubel clicked method HandlePlayFileDoubleClick(null, null); // play the first file if there is one } } private static void SavePlayListAtClosing(object sender, CancelEventArgs e) { FileStream s= new FileStream(PlayerHome+"\\default.m3u", FileMode.Create); StreamWriter r=new StreamWriter(s); for(int i=0; i0) { listBox.SetSelected(0, true); // select the first file-> for doubel clicked method } */ } } private static void HandleSizeChanged(object sender, EventArgs e) { listBox.Height= formList.Height-50; // is docked on top of the formList so the Width is automatically set addFileButton.Location= new Point (2, formList.Height-46); deleteFileButton.Location= new Point (66, formList.Height-46); deleteAllButton.Location= new Point (130, formList.Height-46); openPlayListButton.Location= new Point (194, formList.Height-46); savePlayListButton.Location= new Point (258, formList.Height-46); } private static void InitializePlayerGUI() { formPlayer=new Form(); formPlayer.MaximizeBox = false; formPlayer.StartPosition = FormStartPosition.CenterScreen; formPlayer.Text = "Audio Player V0.8"; formPlayer.ClientSize = new System.Drawing.Size(305, 115); formPlayer.FormBorderStyle = FormBorderStyle.FixedDialog; // the size is not variable formPlayer.Closing+= new System.ComponentModel.CancelEventHandler(SavePlayListAtClosing); playButton = new Button (); playButton.Text = "play"; playButton.Width=45; playButton.Location = new Point (10, 8); playButton.Click += new System.EventHandler(HandlePauseClick); // when button is pressed so invoke the PauseClick Method ->operator on objects and method as a parameter playButton.FlatStyle = FlatStyle.Flat; formPlayer.Controls.Add(playButton); stopButton = new Button (); stopButton.Text = "stop"; stopButton.Width=42; stopButton.Location = new Point (60, 8); stopButton.Click += new System.EventHandler(HandleStopClick); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter stopButton.FlatStyle = FlatStyle.Flat; formPlayer.Controls.Add(stopButton); prevButton = new Button (); prevButton.Text = "prev"; prevButton.Width=42; prevButton.Location = new Point (110, 8); prevButton.Click += new System.EventHandler(HandlePrevButtonClick); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter prevButton.FlatStyle = FlatStyle.Flat; formPlayer.Controls.Add(prevButton); nextButton = new Button (); nextButton.Text = "next"; nextButton.Width=42; nextButton.Location = new Point (160, 8); nextButton.Click += new System.EventHandler(HandleEndOfPlayedFile); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter nextButton.FlatStyle = FlatStyle.Flat; formPlayer.Controls.Add(nextButton); openButton = new Button (); openButton.Text = "open file"; openButton.Location = new Point (220, 8); openButton.Click += new System.EventHandler(HandleOpenClick); // when button is pressed so invoke the OpenClick Method -> operator on objects and method as a parameter openButton.FlatStyle = FlatStyle.Flat; formPlayer.Controls.Add(openButton); fileNameTextBox = new TextBox(); fileNameTextBox.Location = new Point (110, 37); fileNameTextBox.Width=185; fileNameTextBox.Font = new Font ("Arial" , 8); fileNameTextBox.Height=8; fileNameTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; fileNameTextBox.ReadOnly=true; fileNameTextBox.BackColor=Color.White; formPlayer.Controls.Add(fileNameTextBox); Label posLabel=new Label(); posLabel.Text="pos:"; posLabel.Location=new Point(10, 88); posLabel.Width=26; formPlayer.Controls.Add(posLabel); trackPos = new TrackBar(); trackPos.Location = new Point (32, 85); trackPos.Width=270; trackPos.Minimum=0; trackPos.Maximum=160; trackPos.SmallChange=5; // it equals 5 seconds trackPos.TickStyle=TickStyle.None; trackPos.Scroll+= new EventHandler(HandleTackMove); formPlayer.Controls.Add(trackPos); Label volLabel=new Label(); volLabel.Text="vol:"; volLabel.Location=new Point(10, 65); volLabel.Width=26; formPlayer.Controls.Add(volLabel); volume=new HScrollBar(); volume.Location = new Point (40, 64); volume.Width=255; volume.Minimum=0; volume.Maximum=7000; volume.SmallChange=500; volume.LargeChange=500; volume.Value=3500; volumeValue=-3500; volume.Scroll+= new ScrollEventHandler(HandleVolumeScroll); formPlayer.Controls.Add(volume); Label listLabel=new Label(); listLabel.Text="list:"; listLabel.Location=new Point(10, 40); listLabel.Width=23; formPlayer.Controls.Add(listLabel); radioButtonShowList = new CheckBox(); radioButtonShowList.Location = new Point (34, 35); radioButtonShowList.FlatStyle = FlatStyle.Flat; radioButtonShowList.Checked=false; radioButtonShowList.Width=20; formPlayer.Controls.Add(radioButtonShowList); radioButtonShowList.Click+=new EventHandler(HandleListShow); Label loopLabel=new Label(); loopLabel.Text="loop:"; loopLabel.Location=new Point(60, 40); loopLabel.Width=30; formPlayer.Controls.Add(loopLabel); radioButtonLoopList = new CheckBox(); radioButtonLoopList.Location = new Point (91, 35); radioButtonLoopList.FlatStyle = FlatStyle.Flat; radioButtonLoopList.Checked=true; formPlayer.Controls.Add(radioButtonLoopList); radioButtonLoopList.Click+=new EventHandler(HandleLoopButtonClick); t = new Thread(new ThreadStart(ThreadProc)); t.IsBackground=true; t.Start(); t.Suspend(); // suspend the thread because no file is playing now } private static void InitializeListGUI() { formList=new Form(); formList.Text = "Audio Player - File List"; formList.ClientSize = new System.Drawing.Size(320, 280); formList.FormBorderStyle = FormBorderStyle.SizableToolWindow; // the size is not variable - it does not have any effect formList.Closing+=new CancelEventHandler(HandleCloseListClick); formList.Resize+=new EventHandler(HandleSizeChanged); listBox = new ListBox(); listBox.Size = new System.Drawing.Size(formList.Width-7, formList.Height-50); listBox.HorizontalScrollbar=true; listBox.DoubleClick+=new EventHandler(HandlePlayFileDoubleClick); listBox.Dock=DockStyle.Top; formList.Controls.Add(listBox); addFileButton = new Button (); addFileButton.Text = "add file"; addFileButton.Location= new Point (2, 256); addFileButton.Click += new System.EventHandler(HandleAddFileClick); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter addFileButton.FlatStyle = FlatStyle.Flat; addFileButton.Width=60; addFileButton.Height=20; formList.Controls.Add(addFileButton); deleteFileButton = new Button (); deleteFileButton.Text = "del file"; deleteFileButton.Location= new Point (66, 256); deleteFileButton.Click += new System.EventHandler(HandleDeleteFileClick); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter deleteFileButton.FlatStyle = FlatStyle.Flat; deleteFileButton.Width=60; deleteFileButton.Height=20; formList.Controls.Add(deleteFileButton); deleteAllButton = new Button (); deleteAllButton.Text = "del all"; deleteAllButton.Location= new Point (130, 256); deleteAllButton.Click += new System.EventHandler(HandleDeleteAllClick); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter deleteAllButton.FlatStyle = FlatStyle.Flat; deleteAllButton.Width=60; deleteAllButton.Height=20; formList.Controls.Add(deleteAllButton); openPlayListButton = new Button (); openPlayListButton.Text = "open pl"; openPlayListButton.Location= new Point (194, 256); openPlayListButton.Click += new System.EventHandler(HandleOpenPlayListClick); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter openPlayListButton.FlatStyle = FlatStyle.Flat; openPlayListButton.Width=60; openPlayListButton.Height=20; formList.Controls.Add(openPlayListButton); savePlayListButton = new Button (); savePlayListButton.Text = "save pl"; savePlayListButton.Location= new Point (258, 256); savePlayListButton.Click += new System.EventHandler(HandleSavePlayListClick); // when button is pressed so invoke the StopClick Method -> operator on objects and method as a parameter savePlayListButton.FlatStyle = FlatStyle.Flat; savePlayListButton.Width=60; savePlayListButton.Height=20; formList.Controls.Add(savePlayListButton); } // thread method for updating the track position scroll bar private static void ThreadProc() { for(;;) { if(audio!=null) trackPos.Value=(int)audio.CurrentPosition; Thread.Sleep(500); } } public static void Main(String [] args) { InitializePlayerGUI(); InitializeListGUI(); if(args.Length!=0) HandleOpenFilesAtStart(args); else OpenDefaultPlayList(); Application.Run(formPlayer); } } }