您的位置:首页 > 职场人生

Silverlight实例教程 - Out of Browser音乐播放器 推荐

2010-07-28 04:48 627 查看


上一篇,我们了解了如何在Silverlight的Out of Browser模式下进行Debug调试,另外学习Silverlight OOB应用的一个新特性Notifications窗口。本篇,我们将结合以往的Out of Browser特性,创建一款新的Out of Browser实例, 音乐播放器。 该实例目的比较简单,实现音乐播放,实现音乐文件列表读取,实现音乐文件信息读取,另外音乐播放自动跳转等功能。

在实例开始前,我们仍旧需要了解一些基础知识。Silverlight对音频的支持是使用MediaElement类,该类使用方法非常简单,该类的详细解释,请看MSDN

1 <MediaElement

2 x:Name="media"

3 Source="xbox.wmv"

4 CurrentStateChanged="media_state_changed"

5 Width="300" Height="300"/>

在了解了音频播放类的简单使用后,让我们先看看项目完成后的效果图,



从上面效果图中可以看出整个实例项目UI分5个部分,

1. 音频控制部分,这部分是实例主要功能;

2. 音频文件信息部分,这部分是获取显示当前和下一首音乐文件信息;

3. 唱片图片信息,其实这部分也是属于音频文件信息,不过这里单独列出来,使用独立的类进行处理;

4. 音频文件列表,该列表是载入My Music目录中的音乐文件,并支持用户选择播放功能;

5. UI控制,该部分可以使播放器进入最小化状态。例如:



下面我们开始分别解释以上几个部分的实例设计方法。

我们仍旧使用SilverlightOOBDemo项目,不过为了使代码更清晰易读,这次不再使用OutofBrowserMainPage作为OOB应用主界面,我们重新创建一个新的OOB应用界面OutofBrowserMusicPlayer。

为了修改启动页面为OutofBrowserMusicPlayer,为此,我们需要修改App.xaml中的启动页面代码:

1 private void Application_Startup(object sender, StartupEventArgs e)

2 {

3 if (!Application.Current.IsRunningOutOfBrowser)

4 {

5 this.RootVisual = new MainPage();

6 }

7 else

8 {

9 //this.RootVisual = new OutofBrowserMainPage();

10 this.RootVisual = new OutofBrowserMusicPlayer();

11 }

12

13 }

根据实例需求,我们最主要的功能就是播放音乐,所以,我们第一步首先实现Out of Browser应用音频控制。

1. 创建自定义音频控制控件;



对于音频控制,这里我们使用了自定义控件控制音乐的播放。AudioControl.xaml控件,



这里我仅贴上部分代码,大家可以在文章最后下载完整源代码。

1 <Grid x:Name="LayoutRoot">

2 <Grid.ColumnDefinitions>

3 <ColumnDefinition Width="Auto" />

4 <ColumnDefinition Width="*" />

5 <ColumnDefinition Width="25" />

6 <ColumnDefinition Width="Auto" />

7 <ColumnDefinition Width="Auto" />

8 </Grid.ColumnDefinitions>

9 <Grid Grid.Column="0" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" x:Name="gridCol1">

10 <ToggleButton Cursor="Hand" Margin="0,0,0,0" x:Name="btnPlay" RenderTransformOrigin="0.5,0.5" Template="{StaticResource playControlTemplate}">

11 <ToggleButton.RenderTransform>

12 <TransformGroup>

13 <ScaleTransform ScaleX="1" ScaleY="1"/>

14 <SkewTransform/>

15 <RotateTransform/>

16 <TranslateTransform/>

17 </TransformGroup>

18 </ToggleButton.RenderTransform>

19 </ToggleButton>

20 </Grid>

21 <Grid Grid.Column="1" Margin="0,0,0,0" HorizontalAlignment="Stretch" x:Name="gridCol2" VerticalAlignment="Center">

22 <Grid.ColumnDefinitions>

23 <ColumnDefinition Width="*" />

24 <ColumnDefinition Width="40" />

25 <ColumnDefinition Width="10" />

26 <ColumnDefinition Width="40" />

27 </Grid.ColumnDefinitions>

28 <TextBlock x:Name="tbCurrentTime" Margin="0,1.5,0,0" Height="12" FontFamily="Verdana" FontSize="10" Text="00:00" TextWrapping="Wrap" Foreground="#FFFFFFFF" FontStyle="Normal" HorizontalAlignment="Right" TextAlignment="Right" Grid.Column="1"/>

29 <TextBlock Margin="0,1.5,0,0" Height="12" FontFamily="Verdana" FontSize="10" Text="/" TextWrapping="Wrap" Foreground="#FFFFFFFF" FontStyle="Normal" HorizontalAlignment="Center" TextAlignment="Right" Grid.Column="2"/>

30 <TextBlock x:Name="tbTotalTime" Margin="0,1.5,0,0" Height="12" FontFamily="Verdana" FontSize="10" Text="00:00" TextWrapping="Wrap" Foreground="#FFFFFFFF" FontStyle="Normal" HorizontalAlignment="Left" TextAlignment="Right" Grid.Column="3"/>

31 <local:MediaSlider Margin="0,1.5,0,0" HorizontalAlignment="Stretch" Maximum="100" x:Name="sliderTimeline" Style="{StaticResource progressSliderStyle}" Grid.Column="0" Value="0" Visibility="Visible"/>

32 </Grid>

33 <Grid Grid.Column="2" Margin="4,0,4,0" HorizontalAlignment="Stretch" x:Name="gridCol3" VerticalAlignment="Center">

34 <local:Spinner Margin="0,0,0,0" x:Name="spinner" Width="17" Height="17" HorizontalAlignment="Center" VerticalAlignment="Center"/>

35 </Grid>

36 <Grid Grid.Column="3" Margin="0,10.30,0,10.30" HorizontalAlignment="Stretch" x:Name="gridCol4" Width="70" VerticalAlignment="Stretch" d:LayoutOverrides="Height">

37 <Grid Margin="0,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Center" Width="70">

38 <Grid.ColumnDefinitions>

39 <ColumnDefinition Width="Auto" />

40 <ColumnDefinition Width="*" />

41 </Grid.ColumnDefinitions>

42 <ToggleButton HorizontalAlignment="Left" IsChecked="True" Margin="0,0,0,0" x:Name="btnSpeaker" Template="{StaticResource speakerControlTemplate}"/>

43 <Slider Grid.Column="1" HorizontalAlignment="Stretch" Margin="3,0,0,0" VerticalAlignment="Center" Maximum="1" x:Name="sliderVolume" Style="{StaticResource volumeSliderStyle}" Background="#FF777777"/>

44 </Grid>

45 </Grid>

46 <Grid Grid.Column="4" Margin="0,10.3120002746582,4,10.3120002746582" HorizontalAlignment="Right" x:Name="gridCol5" VerticalAlignment="Stretch" d:LayoutOverrides="Height">

47 <ToggleButton Cursor="Hand" HorizontalAlignment="Left" Margin="0,0,0,0" x:Name="btnFullScreen" Template="{StaticResource fullScreenControlTemplate}"/>

48 </Grid>

49 </Grid>

从以上代码可以看到,在AudioControl中有两个自定义控件local:MediaSlider和local:Spinner。

MediaSlider:



其功能是控制音乐播放进度,支持拖拽前进或者后退音乐播放进度。由于篇幅问题,这里不再列出详细代码,大家可以下载后面的源代码项目参考。

而Spinner控件,是一个载入标识,当音频载入时,会显示该控件。该控件为Path绘制的控件,这里不再贴出代码描述。

2. 获取音频文件信息部分



该部分我们同样也创建一个自定义控件来实现,TrackInfo.xaml,主要是负责在客户端显示音频文件的信息,而Silverlight没有相关API可以实现读取音频文件的标签信息,这里,我们需要引入一个微软开源类库TagLib。该类库的主要功能就是读取和修改音乐文件的标签信息。



其调用方法非常简单:

1 // 获取标签

2 tags = TagLib.File.Create(MediaFile.ID);

3 // 设置标签属性

4 MediaFile.Artist = tags.Tag.FirstPerformer;

5 MediaFile.Title = tags.Tag.Title;

6 MediaFile.Album = tags.Tag.Album;

7 MediaFile.Genre = tags.Tag.FirstGenre;

当音乐标签信息获取成功后,即可将信息绑定到TrackInfo.DataContext。

3. 唱片图片信息

对于唱片的图片信息,这里需要读取Image从本地目录,当没有唱片图片时,则显示默认Music.png图片。这里需要注意的是,读取本地文件,需要OOB应用权限信任。

1 public ImageSource AlbumArtStream

2 {

3 get

4 {

5 BitmapImage image;

6

7 if (string.IsNullOrEmpty(AlbumArtPath))

8 {

9 if (null == _default)

10 {

11 _default = new BitmapImage(new Uri("../Images/Music.png", UriKind.Relative));

12 }

13

14 image = _default;

15 }

16 else

17 {

18 FileStream stream = File.Open(AlbumArtPath, FileMode.Open, FileAccess.Read);

19

20 image = new BitmapImage();

21 image.SetSource(stream);

22 stream.Close();

23 }

24

25 return image;

26 }

27 }

4. 获取音频文件列表

从演示图片可以看出,我们的音频文件列表,是用了一个绑定了音乐播放文件信息的Datagrid。



其代码非常简单,创建两列,分别绑定歌手和歌曲名:

1 <data:DataGrid x:Name="playList"

2 Grid.Row="1"

3 Grid.Column="1"

4 Grid.RowSpan="3"

5 VerticalAlignment="Top"

6 Margin="4"

7 Height="296"

8 Style="{StaticResource DataGridStyle}"

9 AutoGenerateColumns="False"

10 CanUserResizeColumns="True"

11 CanUserSortColumns="False"

12 SelectionChanged="playList_SelectionChanged">

13 <data:DataGrid.Columns>

14 <data:DataGridTextColumn Header="歌手"

15 Binding="{Binding Artist}"

16 FontSize="12" />

17 <data:DataGridTextColumn Header="歌名"

18 Binding="{Binding Title}"

19 FontSize="12"

20 Width="*" />

21 </data:DataGrid.Columns>

22 </data:DataGrid>

而后台,在读取了My Music目录后,将数据集绑定到datagrid.ItemsSource就可以正常实现歌曲列表了。

1 public static List<MediaFile> GetMediaFiles()

2 {

3 List<MediaFile> files = null; ;

4 MediaFile mf;

5 string path = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);

6 IEnumerable<string> list = Directory.EnumerateFiles(path, "*.mp3", SearchOption.AllDirectories);

7 TagLib.File tags;

8 files = GetCachedList(list);

9 if (null == files || files.Count == 0)

10 {

11 files = new List<MediaFile>();

12 foreach (string file in list)

13 {

14 mf = new MediaFile();

15 mf.ID = file;

16 mf.AlbumArtPath = GetAlbumArtPath(file);

17 files.Add(mf);

18 }

19

20 for (int idx = 0; idx < files.Count; idx++)

21 {

22 mf = files[idx];

23 tags = TagLib.File.Create(mf.ID);

24 mf.Artist = tags.Tag.FirstPerformer;

25 mf.Title = tags.Tag.Title;

26 mf.Album = tags.Tag.Album;

27 mf.Genre = tags.Tag.FirstGenre;

28 }

29 SaveCachedList(files);

30 }

31

32 return files;

33 }

在绑定成功后,同时,我们支持用户选择指定音乐播放,使用Datagrid的SelectionChanged事件即可。

1 private void playList_SelectionChanged(object sender, SelectionChangedEventArgs e)

2 {

3 DataGrid dg = (sender as DataGrid);

4

5 if (dg.SelectedIndex != _nowPlaying)

6 {

7 if (dg.SelectedIndex != 0)

8 {

9 me.AutoPlay = true;

10 }

11 OpenAndPlay(dg.SelectedIndex);

12 }

13

14 }

5. UI控制

对于UI的控制,这里我们只是简单的实现了隐藏和显示音乐信息框的功能,其代码实现:

1 private void Minimize_Click(object sender, MouseButtonEventArgs e)

2 {

3 Window main = Application.Current.MainWindow;

4

5 if (!_min)

6 {

7 main.Height = 40;

8 rot.Angle = 0;

9 }

10 else

11 {

12 main.Height = 340;

13 rot.Angle = 180;

14 }

15

16 _min = !_min;

17 }

上面是OOB音乐播放器5个部分的核心功能代码,这里,我想同时将上一篇讲到的Notifications窗口应用到实例中,我们可以仍旧使用NotificationControl文件,在其中对播放音乐Title进行绑定,即当音乐播放完毕后,即弹出消息提示播放下一首“XXX”音乐。效果如下图:



根据上一篇介绍Notifications窗口的代码,我们简单进行修改,即可实现本篇实例需求:

1 NotificationWindow notifyWindow = null;

2 private void ShowToast()

3 {

4 notifyWindow = new NotificationWindow();

5

6 if (notifyWindow.Visibility == Visibility.Visible)

7 notifyWindow.Close();

8

9 NotificationControl myNotify = new NotificationControl();

10 myNotify.DataContext = _playList[_nowPlaying];

11 notifyWindow.Width = 300;

12 notifyWindow.Height = 100;

13 notifyWindow.Content = myNotify;

14 notifyWindow.Show(10000);

15 }

至此,一款基于Silverlight的Out of Browser模式的音乐播放器基本完成了。大家可以根据该实例添加更多自定义功能,例如添加互联网音乐播放功能,音乐搜索功能等,创建属于自己的Silverlight版酷我音乐盒。



本篇源代码下载

欢迎大家加入"专注Silverlight" 技术讨论群:

32679955(六群)
23413513(五群)
32679922(四群)
100844510(三群)
37891947(二群)
22308706(一群)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息