微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Silverlight制作音乐播放器

 Silverlight提供了MediaElement控件方便开发者制作音乐或媒体播放器,它可以提供流畅的音乐播放和高清晰度的视频效果. 这里我们来介绍一下如何利用MediaElement控件制作简单的网页音乐播放器. 在这里示例中,在网页中你可以看到一个MediaElement控件,3个Slider控件,一个DataGrid和若干个Button控件. MediaElement用于绑定音乐文件和播放,Slider控件用于绑定音乐的进度过程,平衡度和音量,你可以通过拖拽Slider来控制音乐文件效果.

绑定平衡度和音量时比较简单的,你可以直接通过Binding方法设置ElementName,path和UpdateSourceTrigger属性,或者通过ValueChange事件来绑定. 对于进度条的绑定就稍微要麻烦一点,一般我们有两种方式来实现,第一个是采用Timer控件,定期的去追踪音乐文件的播放事件,并且改变Slider的Value值,还有一种方式是通过创建一个继承IValueConvert接口的类返回Time的秒数,绑定给Slider控件. 用户可以观察音乐的播放进度,并且允许拖拽光标来实现快进或者倒退.

好了,现在来看一下这个简单的媒体的播放器是怎么实现的,首先,确认一个你的电脑是够安装了Silverlight 4 SDK和SIlverlight 4 Toolkit. 运行Silverlight示例一般需要这两个基本程序,它们的下载地址如下:

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=7335

http://www.microsoft.com/download/en/details.aspx?id=18149

 

[本示例完整源码下载(0分)] http://download.csdn.net/source/3448102 

基本准备工作结束了,首先在Visual Studio里面创建一个Silverlight程序,为了更贴近现在的开发环境,在创建Silverlight程序时包括它寄宿的Web应用程序. 因为通常网络音乐播放器的音乐文件和播放列表是存在于Web服务器上的,那么在认存在的Web应用程序中的ClientBin文件夹中放入你的音乐文件(如a.mp3),接着我们放入一个XML文件作为音乐播放列表, XML文件示例如下, 为了方便于测试,这里我们只放进了两个音乐文件:

MusicList.xml

<root>
  <music open="1" path="ClientBin/Mp3/Buddy Joe.mp3" name="Buddy Joe">Buddy Joe</music>
  <music open="1" path="ClientBin/Mp3/Complicated.mp3" name="Complicated">Complicated</music>
</root>


接着, 在SIlverlight项目中创建一个DataItem实体类作为音乐文件实体类,包括音乐文件名称和路径:

DataItem.cs

public class DataItem
    {
        private string nameItem;
        private string pathItem;

        public string NameItem
        {
            get
            {
                return nameItem;
            }
            set
            {
                nameItem = value;
            }
        }

        public string PathItem
        {
            get
            {
                return pathItem;
            }
            set
            {
                pathItem = value;
            }
        }
    }


创建一个类继承IValueConvert接口,用于绑定Process Slider的控件值Value,使得用户能过观测到音乐文件的播放进度,它必须实现两个方法Convert和ConvertBack:

 ProgressConverter.cs

    public class ProgressConverter : IValueConverter
    {
        public object Convert(object value,Type targettype,object parameter,System.Globalization.CultureInfo culture)
        {
            return ((TimeSpan)value).TotalSeconds;
        }

        public object ConvertBack(object value,System.Globalization.CultureInfo culture)
        {
            return TimeSpan.FromSeconds((double)value);
        }
    }

接着修改MainPage.xaml文件,添加必要的MediaElement,Slider,DataGrid等控件,DataGrid用于绑定XML文件的数据, 这里需要在XAML文件中引入ProcessConverter, 这需要在UserControl头文件中加入注册信息 xmlns:yw="clr-namespace:CSSL4MediaPlayer" 并且在Grid容器外引入UserControl的Resource文件  <UserControl.Resources> <yw:ProgressConverter x:Key="progress"></yw:ProgressConverter></UserControl.Resources>   全部代码如下:

MainPage.xaml

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
             x:Class="CSSL4MediaPlayer.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:yw="clr-namespace:CSSL4MediaPlayer"
    mc:Ignorable="d"
    d:DesignHeight="478" d:DesignWidth="604">
    <UserControl.Resources>
        <yw:ProgressConverter x:Key="progress"></yw:ProgressConverter>
    </UserControl.Resources>
        <Grid x:Name="LayoutRoot" HorizontalAlignment="Left" Width="599" Height="474"    ShowGridLines="False" VerticalAlignment="Top" Margin="5,5,5">
        <Grid.RowDeFinitions>
            <RowDeFinition Height="68"/>
            <RowDeFinition Height="53"/>
            <RowDeFinition Height="71"/>
            <RowDeFinition Height="auto"/>
            <RowDeFinition Height="282*" />
        </Grid.RowDeFinitions>
        <MediaElement x:Name="mediaElement" Width="300" Grid.Row="1" Autoplay="True" 
                      IsMuted="False" Stretch="Fill" Volume="0.5" 
                      CurrentStateChanged="mediaElement_CurrentStateChanged" MediaEnded="mediaElement_MediaEnded" MediaOpened="mediaElement_MediaOpened" Margin="44,44,147"></MediaElement>
        <Button x:Name="btnStop" Content="stop" Grid.Row="2" Width="70" Height="25" Click="btnStop_Click" Margin="30,25,499,21"></Button>
        <Button x:Name="btnPlay" Content="play" Grid.Row="2" Width="70" Height="25" Click="btnPlay_Click" Margin="0,430,21" HorizontalAlignment="Right"></Button>
        <Button x:Name="btnPause" Content="pause" Grid.Row="2" Width="70" Height="25" Click="btnPause_Click" Margin="168,361,21"></Button>
        <Button x:Name="btnMuted" Content="muted" Grid.Row="2" Width="70" Height="25" Click="btnMuted_Click" Margin="236,293,21"></Button>
        <Button x:Name="btnFullScreen" Content="full screen" Grid.Row="2" Height="25" Click="btnFullScreen_Click" Margin="305,210,21"></Button>
        <TextBlock Grid.Row="4" Height="23" HorizontalAlignment="Left" Margin="255,9,0" Name="textBlock1" Text="Music Play List" VerticalAlignment="Top" />
        <sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" Grid.Row="4" Height="196" HorizontalAlignment="Left" Margin="196,36,50" Name="girdList" VerticalAlignment="Center" Width="206" SelectionChanged="girdList_SelectionChanged">
            <sdk:DataGrid.Columns >
                <sdk:DataGridTextColumn Header="name" Binding="{Binding NameItem}" Width="204" IsReadOnly="True"></sdk:DataGridTextColumn>
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <TextBlock Height="34" Margin="200,18,197,0" Name="tbTitle" Text="Silverlight Media" VerticalAlignment="Top" FontSize="24" Width="200" />
        <Slider x:Name="sliderProcess" Grid.Row="1" Minimum="0" Value="{Binding ElementName=mediaElement,Path=Position,Mode=TwoWay,Converter={StaticResource progress}}" Maximum="230"  Margin="96,78,0" IsEnabled="False" />
        <TextBlock Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="22,17,0" Name="textBlock2" Text="Process:" VerticalAlignment="Top" />
        <Slider LargeChange="0.1" Margin="466,3,39,46" Maximum="1" SmallChange="0.01" Value="{Binding Volume,ElementName=mediaElement,UpdateSourceTrigger=Default}" Grid.Row="2" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="413,0" Name="tbTag1" Text="Volumn:" VerticalAlignment="Top" Grid.Row="2" />
        <Slider LargeChange="0.1" Margin="466,43,6"  Minimum="-1" Maximum="1" Grid.Row="2" ValueChanged="Slider_ValueChanged" Name="sliderBalance" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="413,45,0" Name="tbTag2" Text="Balance:" VerticalAlignment="Top" Grid.Row="2" />
        <TextBlock Grid.Row="1" Height="16" HorizontalAlignment="Left" Margin="536,6,0" Name="tbTag" Text="Status:" VerticalAlignment="Top" />
        <TextBlock Grid.Row="1" Height="19" HorizontalAlignment="Left" Margin="532,30,0" Name="tbStatus" Text="" VerticalAlignment="Top" />
    </Grid>
</UserControl>


最后添加播放器的基本功能,比如建立播放器的播放,暂停,停止,静音,全屏等功能,实现异步的方法读取XML文件,并且追踪MediaElement播放器的状态并且显示出来:

MainPage.xaml.cs

public partial class MainPage : UserControl
    {
        // Define some public properties of application,include data items,// some signal variables,a TimeSpan class and a timer. 
        public List<DataItem> DataItems;
        public bool blnIsMuted = false;
        public bool blnIsFull = false;
        private TimeSpan timeDuration;

        public MainPage()
        {
            InitializeComponent();
            this.XmlProcessMethod(); 
        }

        /// <summary>
        /// This method used to asynchronous loading data from xml file and 
        /// adds DownLoadXmlComplete method with WebCient,it will add other 
        /// methods to timer and media element.
        /// </summary>
        private void XmlProcessMethod()
        {
            WebClient webClient = new WebClient();
            webClient.DownloadStringAsync(new Uri(HtmlPage.Document.DocumentUri,"ClientBin/MusicList.xml"));
            webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(this.DownLoadXmlComplete);
            mediaElement.MediaEnded += new RoutedEventHandler(mediaElement_MediaEnded);
        }

        private void mediaElement_CurrentStateChanged(object sender,RoutedEventArgs e)
        {
            tbStatus.Text = mediaElement.CurrentState.ToString();
            if (mediaElement.CurrentState != MediaElementState.Playing)
            {
                this.sliderProcess.IsEnabled = false;
            }
            else
            {
                this.sliderProcess.IsEnabled = true;
            }
        }

        private void mediaElement_MediaEnded(object sender,RoutedEventArgs e)
        {
            tbStatus.Text = "complete";
            mediaElement.Stop();
            mediaElement.Position = TimeSpan.Zero;
        }

        private void mediaElement_MediaOpened(object sender,RoutedEventArgs e)
        {
            tbStatus.Text = "start";
            // Retrieve music's total time.
            timeDuration = mediaElement.NaturalDuration.HasTimeSpan ? mediaElement.NaturalDuration.TimeSpan : TimeSpan.FromMilliseconds(0);
            sliderProcess.Maximum = timeDuration.TotalSeconds;
        }

        private void btnStop_Click(object sender,RoutedEventArgs e)
        {
            mediaElement.Pause();
            mediaElement.Position = TimeSpan.Zero;
        }

        private void btnPlay_Click(object sender,RoutedEventArgs e)
        {
            mediaElement.Play();
        }

        private void btnPause_Click(object sender,RoutedEventArgs e)
        {
            mediaElement.Pause();
        }

        /// <summary>
        /// Muted method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMuted_Click(object sender,RoutedEventArgs e)
        {
            if (!blnIsMuted)
            {
                btnMuted.Content = "Unmute";
                mediaElement.IsMuted = true;
                blnIsMuted = true;
            }
            else
            {
                btnMuted.Content = "Muted";
                mediaElement.IsMuted = false;
                blnIsMuted = false;
            }
        }

        /// <summary>
        /// Full screen method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFullScreen_Click(object sender,RoutedEventArgs e)
        {
            if (!blnIsFull)
            {
                btnFullScreen.Content = "Small Screen";
                Application.Current.Host.Content.IsFullScreen = true;
                blnIsFull = true;
            }
            else
            {
                btnFullScreen.Content = "Full Screen";
                Application.Current.Host.Content.IsFullScreen = false;
                blnIsFull = false;
            }
        }

        /// <summary>
        /// Load music data from xml file and convert data to a List of DataItem
        /// instances. Bind DataGrid control's ItemSource with it.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DownLoadXmlComplete(object sender,DownloadStringCompletedEventArgs e)
        {
            using (XmlReader reader = XmlReader.Create(new StringReader(e.Result)))
            {
                DataItems = new List<DataItem>();
                while (reader.Read())
                {
                    if (reader.IsstartElement() && reader.GetAttribute("open") == "1")
                    {
                        string pathMusic = reader.GetAttribute("path").ToString();
                        string nameMusic = reader.GetAttribute("name").ToString();
                        DataItem dataItem = new DataItem();
                        dataItem.NameItem = nameMusic;
                        dataItem.PathItem = pathMusic;
                        DataItems.Add(dataItem);
                    }
                }
                this.DataContext = DataItems;
            }
        }

        /// <summary>
        /// Allow user to change another song.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void girdList_SelectionChanged(object sender,SelectionChangedEventArgs e)
        {
            sliderProcess.IsEnabled = true;
            mediaElement.Position = new TimeSpan(0);
            sliderProcess.Value = 0;
            DataItem selectItem = (DataItem)girdList.SelectedItem;
            mediaElement.source = new Uri(HtmlPage.Document.DocumentUri,selectItem.PathItem);
            mediaElement.Play();
        }

        /// <summary>
        /// Go back to the beginning of slider control when music plays complete
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void mdeMusic_MediaEnded(object sender,RoutedEventArgs e)
        {
            sliderProcess.Value = 0;
        }

        /// <summary>
        /// Balance slider
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Slider_ValueChanged(object sender,RoutedPropertyChangedEventArgs<double> e)
        {
            mediaElement.Balance = sliderBalance.Value;
        }
       
    }

那么这个简单的播放器算是制作完成的,你需要设置Silverlight.Web应用程序为启动项(注意不是Silverlight),如果你从Silverlight程序进入,那么你会在加载Xml文件时收到一个TargetInvocationException错误,这是因为你的Silverlight无法读取Web应用程序中的xml导致的,你当然也可以把XML文件置于Silverlight程序集中.

运行成功后,你可以点击歌曲名称播放它,进行测试.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐