Custom Media Player in WPF (Part 1)

First of all I would like to welcome everyone to my new blog and wish you all a happy new year… Through this blog I hope I can provide help, tips and some useful information about common problems we’ve all faced in programming, as well as some sample applications... In my first post I’m going to show you how you can easily create your own custom Media Player which can automatically search for lyrics for the song you’re listening.

To begin, we are going to create a new WPF application (in this demo I am going to use the .NET 4 Framework and Visual Studio 2010, but most of the functions mentioned in this post are also available on .NET 3.5).

The next thing we are going to do is to add 4 buttons and a mediaElement to our MainWindow by dragging them from the toolbox we have available here. These 4 buttons cover the main 4 functions of a media player, play, pause, stop, open. I am not going to give you any instructions on how to “reshape” them as I believe the best GUI is the one you make yourself, so this is up to you.

Let’s open the MainWindow.xaml.cs file now and create the play, pause and stop functions.

1.bool fileIsPlaying;   
2.//play the file   
3.private void playButton__Click(object sender, RoutedEventArgs e)   
4.{   
5.    mediaElement.Play();   
6.    fileIsPlaying = true;   
7.}   
8.  
9.  
10.//pause the file   
11.private void pauseButton_Click(object sender, RoutedEventArgs e)   
12.{   
13.    mediaElement.Pause();   
14.    fileIsPlaying = false;   
15.}   
16.  
17.  
18.//stop the file   
19.private void stopButton_Click(object sender, RoutedEventArgs e)   
20.{   
21.    mediaElement.Stop();   
22.    fileIsPlaying = false;   
23.}

The code behind the open button is a little bit more complex

1.private void openFileButton_Click(object sender, RoutedEventArgs e)   
2.        {   
3.            Stream checkStream = null;   
4.            OpenFileDialog dlg = new OpenFileDialog();   
5.            dlg.Filter = "All Supported File Types(*.mp3,*.wav,*.mpeg,*.wmv,*.avi)|*.mp3;*.wav;*.mpeg;*.wmv;*.avi";   
6.            // Show open file dialog box    
7.            if ((bool)dlg.ShowDialog())   
8.            {   
9.                try  
10.                {   
11.                    // check if something is selected   
12.                    if ((checkStream = dlg.OpenFile()) != null)   
13.                    {   
14.                        mediaElement.Source = new Uri(dlg.FileName);   
15.                    }   
16.                }   
17.                catch (Exception ex)   
18.                {   
19.                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);   
20.                }   
21.              }   
22.      }

You can easily change the file types allowed by users in the OpenFileDialog just by changing this value.

            dlg.Filter = "All Supported File Types (*.mp3,*.wav,*.mpeg,*.wmv,*.avi)|*.mp3;*.wav;*.mpeg;*.wmv;*.avi";

You can also create 2 sliders in order to control the volume and the speed ratio of the playback. You should add these properties into your XAML file :

  • for the speedRatioSlider
    Value="1" Maximum="3" SmallChange="0.25"
  • for the volumeSlider
    Value="0.5" Maximum="1" SmallChange="0.01" LargeChange="0.1"

    So now we’re finally able to edit our c# code and create the events.

    1.//change the speed of the playback   
    2.void speedRatioSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double /> e)   
    3.{   
    4.    mediaElement.SpeedRatio = speedRatioSlider.Value;   
    5.  
    6.}   
    7.  
    8.//turn volume up-down   
    9.private void volumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double /> e)   
    10.{   
    11.    mediaElement.Volume = volumeSlider.Value;   
    12.}

    Now there’s one more thing we need to do. We have to create a slide bar attached to this mediaElement to show the progress made. For this task we’re going to need a slider, a progress bar and a Timer to periodically change the values of these elements. First of all we need to create a DispatcherTimer and an event that will occur every 1 second, in order to change the value of the textbox displaying the current progress of the playback.

    1.DispatcherTimer timer;   
    2.  
    3.public delegate void timerTick();   
    4.timerTick tick;   
    5.  
    6.public MainWindow()   
    7.        {   
    8.            InitializeComponent();   
    9.  
    10.            timer = new DispatcherTimer();   
    11.            timer.Interval = TimeSpan.FromSeconds(1);   
    12.            timer.Tick += new EventHandler(timer_Tick);   
    13.            tick = new timerTick(changeStatus);   
    14.  
    15.        }   
    16.  
    17.  
    18.void timer_Tick(object sender, EventArgs e)   
    19.        {   
    20.            Dispatcher.Invoke(tick);   
    21.        }

    We’ll use the Position property of the mediaElement (which is, though, available only after the mediaElement_MediaOpened event occurs) to change the value of the textbox that displays the current time of the playback.

    1.//visualize progressBar    
    2.//the fileIsPlaying variable is true when the media is playing    
    3.//and false when the media is paused or stopped   
    4. void changeStatus()   
    5.        {   
    6.            if (fileIsPlaying)   
    7.            {   
    8.                string sec, min, hours;  
    9. 
    10.                #region customizeTime   
    11.                if (mediaElement.Position.Seconds < 10)   
    12.                    sec = "0" + mediaElement.Position.Seconds.ToString();   
    13.                else  
    14.                    sec = mediaElement.Position.Seconds.ToString();   
    15.  
    16.  
    17.                if (mediaElement.Position.Minutes < 10)   
    18.                    min = "0" + mediaElement.Position.Minutes.ToString();   
    19.                else  
    20.                    min = mediaElement.Position.Minutes.ToString();   
    21.  
    22.                if (mediaElement.Position.Hours < 10)   
    23.                    hours = "0" + mediaElement.Position.Hours.ToString();   
    24.                else  
    25.                    hours = mediaElement.Position.Hours.ToString();  
    26. 
    27.                #endregion customizeTime   
    28.  
    29.                seekSlider.Value = mediaElement.Position.TotalMilliseconds;   
    30.                progressBar.Value = mediaElement.Position.TotalMilliseconds;   
    31.  
    32.                if (mediaElement.Position.Hours == 0)   
    33.                {   
    34.  
    35.                    currentTimeTextBlock.Text = min + ":" + sec;   
    36.                }   
    37.                else  
    38.                {   
    39.                    currentTimeTextBlock.Text = hours + ":" + min + ":" + sec;   
    40.                }   
    41.            }   
    42.        }

    So now we have the current time displayed on the textbox and the progress of the playback. We have to create the events for the following functions of the seekSlider

    1.//seek to desirable position of the file   
    2.//you will also have to set the moveToPosition property of the seekSlider to    
    3.//true   
    4.private void seekSlider_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)   
    5.        {   
    6.            TimeSpan ts = new TimeSpan(0, 0, 0, 0, (int)seekSlider.Value);   
    7.  
    8.            changePostion(ts);   
    9.        }   
    10.  
    11.//mouse down on slide bar in order to seek   
    12.        private void seekSlider_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)   
    13.        {   
    14.            isDragging = true;   
    15.        }   
    16.  
    17.private void seekSlider_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)   
    18.        {   
    19.            if (isDragging)   
    20.            {   
    21.                TimeSpan ts = new TimeSpan(0, 0, 0, 0, (int)seekSlider.Value);   
    22.                changePostion(ts);   
    23.            }   
    24.            isDragging = false;   
    25.        }   
    26.  
    27.//change position of the file   
    28.void changePostion(TimeSpan ts)   
    29.{   
    30.      mediaElement.Position = ts;   
    31.}  

    Finally we need to implement the mediaElement_MediaOpened and mediaElement_MediaEnded functions.

    1.    
    2.     
    3.  
    4.        //occurs when the file is opened   
    5.        public void mediaElement_MediaOpened(object sender, RoutedEventArgs e)   
    6.        {   
    7.            timer.Start();   
    8.            fileIsPlaying = true;   
    9.            openMedia();   
    10.        }   
    11.  
    12.  
    13.        //opens media,adds file to playlist and gets file info   
    14.        public void openMedia()   
    15.        {   
    16.            ......   
    17.        }   
    18.  
    19.  
    20.  
    21.//occurs when the file is done playing   
    22.private void mediaElement_MediaEnded(object sender, RoutedEventArgs e)   
    23.        {   
    24.            mediaElement.Stop();   
    25.            volumeSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double />(volumeSlider_ValueChanged);   
    26.            speedRatioSlider.ValueChanged -= new RoutedPropertyChangedEventHandler<double />(speedRatioSlider_ValueChanged);   
    27.                }   

    That’s all for now…We have created our own, fully functional media Player.. You can download the sample code here...I would be happy to read any thoughts or suggestions you might have…

  • 原文链接
原文地址:https://www.cnblogs.com/Events/p/3470769.html