闲来无事,倒腾了一个简单的silverlight视频播放器
近二日闲来无事,把silverlight的官方文档瞅了瞅,倒腾了一个简单的视频播放器,顺便也测试了下能否播放传说中的h.264,最终效果如下:
xaml代码:
后端cs代码:
http://images.24city.com/jimmy/player/default.html
布局思路:
Grid做为最外层容器,分上中下三行
第一行为视频播放窗口,同时单击视频时"暂停"遮罩层也放在这一行,只不过默认不显示而已
第二行为进度条显示区,为了方便布局,在这一行用StackPanel作子容器横向放置了二个控件(进度条和时间显示)
第三行为其它的控制按钮区,也是用StackPanel横向放置其它控件
实现的功能:
1.单击视频,暂停播放,再次单击则继续播放,原则就是利用鼠标单击事件控制Canvas的显示/隐藏以及调用MediaElement的Play(),Pause()方法
2.进度条与播放时间的同步,这里用到了Timer控件,每隔一定时间重新设置进度条的值
3.播放列表采用json字符串解析后绑定实现,同时选择列表的相关视频后,马上播放选择的视频
4.全屏功能
5.静音功能(其实还可以方便左右声道功能,只要不知道界面上怎么放,所以这一块功能没加上去)
6.缓冲以及加载进度的百分比进度显示
7.播放时,预先加载下一段视频(这一块好象效果不明显,主要是对silverlight的缓冲机制不清楚,期待大家共同探讨改进)
另:本示例中用的视频全部为mp4格式的h.264视频
其它不清楚的地方,基本上代码中都有注释
xaml代码:
1
<UserControl x:Class="Test.MainPage"
2
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5
mc:Ignorable="d">
6
<Grid x:Name="LayoutRoot" ShowGridLines="False" >
7
8
<!--Grid布局:分成三行,第一行放视频窗口,第二行为进度条,第三行为其它控制按钮-->
9
<Grid.ColumnDefinitions>
10
<ColumnDefinition Width="*"></ColumnDefinition>
11
</Grid.ColumnDefinitions>
12
13
<Grid.RowDefinitions>
14
<RowDefinition Height="*"></RowDefinition>
15
<RowDefinition Height="22"></RowDefinition>
16
<RowDefinition Height="25"></RowDefinition>
17
</Grid.RowDefinitions>
18
19
20
<!--视频播放控件-->
21
<MediaElement x:Name="media" Source="" Grid.Row="0" Grid.Column="0" CurrentStateChanged="Media_State_Changed" MediaEnded="media_MediaEnded" Cursor="Hand" MouseLeftButtonDown="media_MouseLeftButtonDown" BufferingProgressChanged="media_BufferingProgressChanged" DownloadProgressChanged="media_DownloadProgressChanged"></MediaElement>
22
23
<!--这里用一个Canvas来实现暂停时的遮盖效果-->
24
<Canvas Background="#AAFAEBD7" Grid.Row="0" Grid.Column="0" Cursor="Hand" x:Name="canvas_Pause" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" >
25
<Ellipse Height="200" Width="200" Stroke="AliceBlue" StrokeThickness="10" Canvas.Left="140" Canvas.Top="80"></Ellipse>
26
<Path Stretch="Fill" Stroke="AliceBlue" StrokeThickness="10" Height="98" Width="10" UseLayoutRounding="False" Canvas.Left="203" Canvas.Top="131" Data="M208,136 L208,224"/>
27
<Path Stretch="Fill" Stroke="AliceBlue" StrokeThickness="10" Height="98" Width="10" UseLayoutRounding="False" Canvas.Left="263" Canvas.Top="131" Data="M208,136 L208,224"/>
28
29
<TextBlock Canvas.Left="104" Canvas.Top="296" Foreground="White" >Made by 菩提树下的杨过(http://yjmyzz.cnblogs.com/)</TextBlock>
30
</Canvas>
31
32
<MediaElement x:Name="mediaBuffer" Width="0" Grid.Column="0" Grid.Row="0" BufferingTime="0:0:10" IsMuted="True" AutoPlay="True" ></MediaElement>
33
34
<!--第二行用一个StackPanel横向放了二个子控件,用于显示进度条和当前播放时间-->
35
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" >
36
<Slider Height="20" Width="370" x:Name="sliderProgress" ValueChanged="sliderProgress_ValueChanged" Cursor="Hand" ></Slider>
37
<TextBlock Text="00:00:00/00:00:00" Width="110" x:Name="txtTime"/>
38
</StackPanel>
39
40
<!--第三行同样用StackPanel横向放置其它控制按钮-->
41
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" >
42
<Button Click="PlayMedia" Content="||" Width="25" Height="25" x:Name="btnPlay" Cursor="Hand" />
43
<Button Click="StopMedia" Content="■" Width="25" Height="25" x:Name="btnStop" Cursor="Hand"/>
44
<TextBlock x:Name="txtProgress" FontSize="12" Width="90" Text="缓冲中
100%" Height="25" TextAlignment="Center" Margin="3,0" Padding="0,6,0,0" ></TextBlock>
45
<ComboBox x:Name="cboList" SelectionChanged="cboList_SelectionChanged" Height="25" Width="232">
46
47
</ComboBox>
48
<Button Content="静" Width="25" Height="25" Margin="3,0" x:Name="btnVoice" Click="btnVoice_Click" Cursor="Hand"></Button>
49
<Slider Height="25" Width="50" x:Name="sliderVoice" Maximum="1" Minimum="0" ValueChanged="sliderVoice_ValueChanged" Value="0.5" Cursor="Hand" ></Slider>
50
<Button Content="全" Width="20" Height="25" Cursor="Hand" x:Name="btnFull" Click="btnFull_Click"></Button>
51
</StackPanel>
52
53
</Grid>
54
</UserControl>
55
<UserControl x:Class="Test.MainPage"2
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"4
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5
mc:Ignorable="d">6
<Grid x:Name="LayoutRoot" ShowGridLines="False" >7

8
<!--Grid布局:分成三行,第一行放视频窗口,第二行为进度条,第三行为其它控制按钮-->9
<Grid.ColumnDefinitions>10
<ColumnDefinition Width="*"></ColumnDefinition> 11
</Grid.ColumnDefinitions>12

13
<Grid.RowDefinitions>14
<RowDefinition Height="*"></RowDefinition>15
<RowDefinition Height="22"></RowDefinition>16
<RowDefinition Height="25"></RowDefinition>17
</Grid.RowDefinitions>18

19

20
<!--视频播放控件-->21
<MediaElement x:Name="media" Source="" Grid.Row="0" Grid.Column="0" CurrentStateChanged="Media_State_Changed" MediaEnded="media_MediaEnded" Cursor="Hand" MouseLeftButtonDown="media_MouseLeftButtonDown" BufferingProgressChanged="media_BufferingProgressChanged" DownloadProgressChanged="media_DownloadProgressChanged"></MediaElement>22

23
<!--这里用一个Canvas来实现暂停时的遮盖效果-->24
<Canvas Background="#AAFAEBD7" Grid.Row="0" Grid.Column="0" Cursor="Hand" x:Name="canvas_Pause" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" >25
<Ellipse Height="200" Width="200" Stroke="AliceBlue" StrokeThickness="10" Canvas.Left="140" Canvas.Top="80"></Ellipse>26
<Path Stretch="Fill" Stroke="AliceBlue" StrokeThickness="10" Height="98" Width="10" UseLayoutRounding="False" Canvas.Left="203" Canvas.Top="131" Data="M208,136 L208,224"/>27
<Path Stretch="Fill" Stroke="AliceBlue" StrokeThickness="10" Height="98" Width="10" UseLayoutRounding="False" Canvas.Left="263" Canvas.Top="131" Data="M208,136 L208,224"/>28

29
<TextBlock Canvas.Left="104" Canvas.Top="296" Foreground="White" >Made by 菩提树下的杨过(http://yjmyzz.cnblogs.com/)</TextBlock>30
</Canvas>31
32
<MediaElement x:Name="mediaBuffer" Width="0" Grid.Column="0" Grid.Row="0" BufferingTime="0:0:10" IsMuted="True" AutoPlay="True" ></MediaElement>33

34
<!--第二行用一个StackPanel横向放了二个子控件,用于显示进度条和当前播放时间-->35
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center" >36
<Slider Height="20" Width="370" x:Name="sliderProgress" ValueChanged="sliderProgress_ValueChanged" Cursor="Hand" ></Slider>37
<TextBlock Text="00:00:00/00:00:00" Width="110" x:Name="txtTime"/>38
</StackPanel>39

40
<!--第三行同样用StackPanel横向放置其它控制按钮-->41
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center" >42
<Button Click="PlayMedia" Content="||" Width="25" Height="25" x:Name="btnPlay" Cursor="Hand" />43
<Button Click="StopMedia" Content="■" Width="25" Height="25" x:Name="btnStop" Cursor="Hand"/>44
<TextBlock x:Name="txtProgress" FontSize="12" Width="90" Text="缓冲中
100%" Height="25" TextAlignment="Center" Margin="3,0" Padding="0,6,0,0" ></TextBlock>45
<ComboBox x:Name="cboList" SelectionChanged="cboList_SelectionChanged" Height="25" Width="232">46
47
</ComboBox>48
<Button Content="静" Width="25" Height="25" Margin="3,0" x:Name="btnVoice" Click="btnVoice_Click" Cursor="Hand"></Button>49
<Slider Height="25" Width="50" x:Name="sliderVoice" Maximum="1" Minimum="0" ValueChanged="sliderVoice_ValueChanged" Value="0.5" Cursor="Hand" ></Slider>50
<Button Content="全" Width="20" Height="25" Cursor="Hand" x:Name="btnFull" Click="btnFull_Click"></Button>51
</StackPanel>52

53
</Grid>54
</UserControl>55

后端cs代码:
1
using System;
2
using System.Collections.Generic;
3
using System.Json;
4
using System.Windows;
5
using System.Windows.Controls;
6
using System.Windows.Input;
7
using System.Windows.Interop;
8
using System.Windows.Threading;
9
10
namespace Test
11
{
12
13
14
public partial class MainPage : UserControl
15
{
16
private DispatcherTimer _timerPlay;
17
18
//实际应用中,以下字符串可通过wcf调用获得
19
private string _medialist = "[{src:'http://task.24city.com/video/01.mp4',name:'苹果王手机第1段'},{src:'http://task.24city.com/video/02.mp4',name:'苹果王手机第2段'},{src:'http://task.24city.com/video/03.mp4',name:'苹果王手机第3段'},{src:'http://task.24city.com/video/04.mp4',name:'蔡依林-柠檬草的味道'},{src:'http://task.24city.com/video/05.mp4',name:'我也不知道是啥'},{src:'http://task.24city.com/video/06.mp4',name:'游戏宣传片段'}]";
20
21
List<MediaItem> _listMedia = null;
22
23
int _currentIndex = -1;//正在播放的元素索引
24
25
26
public MainPage()
27
{
28
InitializeComponent();
29
30
//解析Json
31
JsonValue _jsValue = JsonArray.Parse(_medialist);
32
33
if (_jsValue.Count > 0)
34
{
35
_listMedia = new List<MediaItem>(_jsValue.Count);
36
37
for (int i = 0; i < _jsValue.Count; i++)
38
{
39
_listMedia.Add(new MediaItem() { src = _jsValue[i]["src"], name = _jsValue[i]["name"] });
40
}
41
42
_currentIndex = 0;//默认从第一个开始播放
43
media.Source = new Uri(_listMedia[_currentIndex].src);
44
45
cboList.ItemsSource = _listMedia;
46
cboList.DisplayMemberPath = "name";
47
cboList.SelectedIndex = _currentIndex;
48
49
50
this._timerPlay = new DispatcherTimer();
51
this._timerPlay.Interval = new TimeSpan(0, 0, 0, 0, 100);
52
this._timerPlay.Tick += new EventHandler(timer_Tick);
53
this._timerPlay.Start();
54
}
55
56
57
App.Current.Host.Content.FullScreenChanged += new EventHandler(Content_FullScreenChanged);
58
59
60
}
61
62
/// <summary>
63
/// timer触发时,设置进度条与播放时间同步
64
/// </summary>
65
/// <param name="sender"></param>
66
/// <param name="e"></param>
67
void timer_Tick(object sender, EventArgs e)
68
{
69
this.sliderProgress.Maximum = this.media.NaturalDuration.TimeSpan.TotalSeconds;
70
71
this.sliderProgress.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sliderProgress_ValueChanged);
72
73
this.sliderProgress.Value = this.media.Position.TotalSeconds;
74
75
this.sliderProgress.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sliderProgress_ValueChanged);
76
77
this.txtTime.Text = media.Position.Hours.ToString().PadLeft(2, '0') + ":" + media.Position.Minutes.ToString().PadLeft(2, '0') + ":" + media.Position.Seconds.ToString().PadLeft(2, '0') + "/" + media.NaturalDuration.TimeSpan.Hours.ToString().PadLeft(2, '0') + ":" + media.NaturalDuration.TimeSpan.Minutes.ToString().PadLeft(2, '0') + ":" + media.NaturalDuration.TimeSpan.Seconds.ToString().PadLeft(2, '0');
78
}
79
80
/// <summary>
81
/// 显示播放状态
82
/// </summary>
83
/// <param name="sender"></param>
84
/// <param name="e"></param>
85
private void Media_State_Changed(object sender, EventArgs e)
86
{
87
88
if (_currentIndex >= 0)
89
{
90
MediaItem _currentMedia = _listMedia[_currentIndex];
91
92
switch (media.CurrentState)
93
{
94
case System.Windows.Media.MediaElementState.AcquiringLicense:
95
txtProgress.Text = "加载许可证
";
96
97
break;
98
case System.Windows.Media.MediaElementState.Buffering:
99
txtProgress.Text = "缓冲中
";
100
break;
101
case System.Windows.Media.MediaElementState.Closed:
102
txtProgress.Text = "已关闭";
103
break;
104
case System.Windows.Media.MediaElementState.Individualizing:
105
txtProgress.Text = "加载个性化设置
";
106
break;
107
case System.Windows.Media.MediaElementState.Opening:
108
txtProgress.Text = "加载中
";
109
break;
110
case System.Windows.Media.MediaElementState.Paused:
111
txtProgress.Text = "已暂停";
112
break;
113
case System.Windows.Media.MediaElementState.Playing:
114
txtProgress.Text = "正在播放";
115
116
//预选缓冲下一段视频(不过在实际测试中,感觉这么干没啥明显效果,欢迎大家共同探讨如何提前缓冲下一段视频)
117
if (_currentIndex + 1 > _listMedia.Count - 1)
118
{
119
mediaBuffer.Source = new Uri(_listMedia[0].src);
120
}
121
else
122
{
123
mediaBuffer.Source = new Uri(_listMedia[_currentIndex + 1].src);
124
}
125
126
break;
127
case System.Windows.Media.MediaElementState.Stopped:
128
txtProgress.Text = "已停止";
129
break;
130
default:
131
break;
132
}
133
}
134
135
}
136
137
138
/// <summary>
139
/// 停止播放
140
/// </summary>
141
/// <param name="sender"></param>
142
/// <param name="e"></param>
143
private void StopMedia(object sender, System.Windows.RoutedEventArgs e)
144
{
145
media.Stop();
146
btnPlay.Content = ">";
147
148
}
149
150
151
152
/// <summary>
153
/// 播放/暂停
154
/// </summary>
155
/// <param name="sender"></param>
156
/// <param name="e"></param>
157
private void PlayMedia(object sender, System.Windows.RoutedEventArgs e)
158
{
159
160
if (media.CurrentState == System.Windows.Media.MediaElementState.Paused || media.CurrentState == System.Windows.Media.MediaElementState.Stopped)
161
{
162
media.Play();
163
btnPlay.Content = "||";
164
canvas_Pause.Visibility = Visibility.Collapsed;
165
166
}
167
else
168
{
169
media.Pause();
170
btnPlay.Content = ">";
171
canvas_Pause.Visibility = Visibility.Visible;
172
}
173
174
}
175
176
/// <summary>
177
/// 一段播放完毕后,自动跳到下一段
178
/// </summary>
179
/// <param name="sender"></param>
180
/// <param name="e"></param>
181
private void media_MediaEnded(object sender, System.Windows.RoutedEventArgs e)
182
{
183
_currentIndex++;
184
185
if (_currentIndex > _listMedia.Count - 1)
186
{
187
_currentIndex = 0;
188
}
189
190
media.Source = new Uri(_listMedia[_currentIndex].src);
191
192
cboList.SelectedIndex = _currentIndex;
193
}
194
195
/// <summary>
196
/// 下拉列表改变时,播放相关片段
197
/// </summary>
198
/// <param name="sender"></param>
199
/// <param name="e"></param>
200
private void cboList_SelectionChanged(object sender, SelectionChangedEventArgs e)
201
{
202
_currentIndex = cboList.SelectedIndex;
203
if (_currentIndex > _listMedia.Count - 1)
204
{
205
_currentIndex = 0;
206
}
207
208
media.Source = new Uri(_listMedia[_currentIndex].src);
209
canvas_Pause.Visibility = System.Windows.Visibility.Collapsed;
210
media.Position = new TimeSpan(0,0,0,0,0);
211
sliderProgress.Value = 0;
212
}
213
214
/// <summary>
215
/// 暂时Canvas点击后,隐藏Canvas,同时继续播放
216
/// </summary>
217
/// <param name="sender"></param>
218
/// <param name="e"></param>
219
private void Canvas_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
220
{
221
canvas_Pause.Visibility = System.Windows.Visibility.Collapsed;
222
media.Play();
223
}
224
225
/// <summary>
226
/// 视频画面单击时,暂时播放
227
/// </summary>
228
/// <param name="sender"></param>
229
/// <param name="e"></param>
230
private void media_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
231
{
232
canvas_Pause.Visibility = System.Windows.Visibility.Visible;
233
media.Pause();
234
}
235
236
/// <summary>
237
/// 进度条拖动时,跳到相关位置
238
/// </summary>
239
/// <param name="sender"></param>
240
/// <param name="e"></param>
241
private void sliderProgress_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
242
{
243
this.media.Position = new TimeSpan((long)(e.NewValue * 1000 * 1000 * 10));
244
}
245
246
247
//private void media_BufferingProgressChanged(object sender, RoutedEventHandler e)
248
//{
249
// txtTime.Text = "缓冲中
" + media.BufferingProgress.ToString("F0") + "%";
250
//}
251
252
/// <summary>
253
/// 静音按钮的实现
254
/// </summary>
255
/// <param name="sender"></param>
256
/// <param name="e"></param>
257
private void btnVoice_Click(object sender, RoutedEventArgs e)
258
{
259
if (media.IsMuted)
260
{
261
media.IsMuted = false;
262
this.btnVoice.Content = "静";
263
sliderVoice.IsEnabled = true;
264
}
265
else
266
{
267
media.IsMuted = true;
268
this.btnVoice.Content = "音";
269
sliderVoice.IsEnabled = false;
270
}
271
272
}
273
274
/// <summary>
275
/// 调整音量大小
276
/// </summary>
277
/// <param name="sender"></param>
278
/// <param name="e"></param>
279
private void sliderVoice_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
280
{
281
if (sliderVoice == null)
282
{
283
return;
284
}
285
media.Volume = sliderVoice.Value;
286
}
287
288
private void btnFull_Click(object sender, RoutedEventArgs e)
289
{
290
Content contentObj = App.Current.Host.Content;
291
contentObj.IsFullScreen = !contentObj.IsFullScreen;
292
293
294
}
295
296
297
298
private void Content_FullScreenChanged(object sender, EventArgs e)
299
{
300
Content contentObj = App.Current.Host.Content;
301
302
if (contentObj.IsFullScreen)
303
{
304
btnFull.Content = "退";
305
}
306
else
307
{
308
btnFull.Content = "全";
309
}
310
}
311
312
/// <summary>
313
/// 显示缓冲进度
314
/// </summary>
315
/// <param name="sender"></param>
316
/// <param name="e"></param>
317
private void media_BufferingProgressChanged(object sender, RoutedEventArgs e)
318
{
319
this.txtProgress.Text = "缓冲中
" + (media.BufferingProgress*100).ToString("F0") + "%";
320
canvas_Pause.Visibility = Visibility.Visible;
321
if (media.BufferingProgress >= 1.0)
322
{
323
canvas_Pause.Visibility = Visibility.Collapsed;
324
switch (media.CurrentState)
325
{
326
case System.Windows.Media.MediaElementState.Buffering:
327
txtProgress.Text = "缓冲中
";
328
break;
329
case System.Windows.Media.MediaElementState.Closed:
330
txtProgress.Text = "已关闭";
331
break;
332
case System.Windows.Media.MediaElementState.Paused:
333
txtProgress.Text = "已暂停";
334
break;
335
case System.Windows.Media.MediaElementState.Playing:
336
txtProgress.Text = "正在播放";
337
break;
338
case System.Windows.Media.MediaElementState.Stopped:
339
txtProgress.Text = "已停止";
340
break;
341
default:
342
txtProgress.Text = "就绪";
343
break;
344
}
345
}
346
}
347
348
/// <summary>
349
/// 显示加载进度
350
/// </summary>
351
/// <param name="sender"></param>
352
/// <param name="e"></param>
353
private void media_DownloadProgressChanged(object sender, RoutedEventArgs e)
354
{
355
txtProgress.Text = "加载中
" + (media.DownloadProgress * 100).ToString("F0") + "%";
356
if (media.DownloadProgress >= 1)
357
{
358
switch (media.CurrentState)
359
{
360
case System.Windows.Media.MediaElementState.Buffering:
361
txtProgress.Text = "缓冲中
";
362
break;
363
case System.Windows.Media.MediaElementState.Closed:
364
txtProgress.Text = "已关闭";
365
break;
366
case System.Windows.Media.MediaElementState.Paused:
367
txtProgress.Text = "已暂停";
368
break;
369
case System.Windows.Media.MediaElementState.Playing:
370
txtProgress.Text = "正在播放";
371
break;
372
case System.Windows.Media.MediaElementState.Stopped:
373
txtProgress.Text = "已停止";
374
break;
375
default:
376
txtProgress.Text = "就绪";
377
break;
378
}
379
}
380
}
381
382
383
384
385
}
386
387
388
/// <summary>
389
/// 媒体元素Item自定义类
390
/// </summary>
391
public class MediaItem
392
{
393
public string src { set; get; }
394
public string name { set; get; }
395
}
396
}
397
using System;2
using System.Collections.Generic;3
using System.Json;4
using System.Windows;5
using System.Windows.Controls;6
using System.Windows.Input;7
using System.Windows.Interop;8
using System.Windows.Threading;9

10
namespace Test11
{12

13

14
public partial class MainPage : UserControl15
{16
private DispatcherTimer _timerPlay;17

18
//实际应用中,以下字符串可通过wcf调用获得19
private string _medialist = "[{src:'http://task.24city.com/video/01.mp4',name:'苹果王手机第1段'},{src:'http://task.24city.com/video/02.mp4',name:'苹果王手机第2段'},{src:'http://task.24city.com/video/03.mp4',name:'苹果王手机第3段'},{src:'http://task.24city.com/video/04.mp4',name:'蔡依林-柠檬草的味道'},{src:'http://task.24city.com/video/05.mp4',name:'我也不知道是啥'},{src:'http://task.24city.com/video/06.mp4',name:'游戏宣传片段'}]";20

21
List<MediaItem> _listMedia = null;22

23
int _currentIndex = -1;//正在播放的元素索引24

25

26
public MainPage()27
{28
InitializeComponent();29

30
//解析Json31
JsonValue _jsValue = JsonArray.Parse(_medialist);32

33
if (_jsValue.Count > 0)34
{35
_listMedia = new List<MediaItem>(_jsValue.Count);36

37
for (int i = 0; i < _jsValue.Count; i++)38
{39
_listMedia.Add(new MediaItem() { src = _jsValue[i]["src"], name = _jsValue[i]["name"] });40
}41

42
_currentIndex = 0;//默认从第一个开始播放43
media.Source = new Uri(_listMedia[_currentIndex].src); 44

45
cboList.ItemsSource = _listMedia;46
cboList.DisplayMemberPath = "name";47
cboList.SelectedIndex = _currentIndex;48

49

50
this._timerPlay = new DispatcherTimer();51
this._timerPlay.Interval = new TimeSpan(0, 0, 0, 0, 100);52
this._timerPlay.Tick += new EventHandler(timer_Tick);53
this._timerPlay.Start();54
}55

56

57
App.Current.Host.Content.FullScreenChanged += new EventHandler(Content_FullScreenChanged);58

59

60
}61

62
/// <summary>63
/// timer触发时,设置进度条与播放时间同步64
/// </summary>65
/// <param name="sender"></param>66
/// <param name="e"></param>67
void timer_Tick(object sender, EventArgs e)68
{69
this.sliderProgress.Maximum = this.media.NaturalDuration.TimeSpan.TotalSeconds;70

71
this.sliderProgress.ValueChanged -= new RoutedPropertyChangedEventHandler<double>(sliderProgress_ValueChanged);72

73
this.sliderProgress.Value = this.media.Position.TotalSeconds;74

75
this.sliderProgress.ValueChanged += new RoutedPropertyChangedEventHandler<double>(sliderProgress_ValueChanged);76

77
this.txtTime.Text = media.Position.Hours.ToString().PadLeft(2, '0') + ":" + media.Position.Minutes.ToString().PadLeft(2, '0') + ":" + media.Position.Seconds.ToString().PadLeft(2, '0') + "/" + media.NaturalDuration.TimeSpan.Hours.ToString().PadLeft(2, '0') + ":" + media.NaturalDuration.TimeSpan.Minutes.ToString().PadLeft(2, '0') + ":" + media.NaturalDuration.TimeSpan.Seconds.ToString().PadLeft(2, '0');78
}79

80
/// <summary>81
/// 显示播放状态82
/// </summary>83
/// <param name="sender"></param>84
/// <param name="e"></param>85
private void Media_State_Changed(object sender, EventArgs e)86
{87
88
if (_currentIndex >= 0)89
{90
MediaItem _currentMedia = _listMedia[_currentIndex];91

92
switch (media.CurrentState)93
{94
case System.Windows.Media.MediaElementState.AcquiringLicense:95
txtProgress.Text = "加载许可证
";96
97
break;98
case System.Windows.Media.MediaElementState.Buffering:99
txtProgress.Text = "缓冲中
"; 100
break;101
case System.Windows.Media.MediaElementState.Closed:102
txtProgress.Text = "已关闭";103
break;104
case System.Windows.Media.MediaElementState.Individualizing:105
txtProgress.Text = "加载个性化设置
";106
break;107
case System.Windows.Media.MediaElementState.Opening:108
txtProgress.Text = "加载中
";109
break;110
case System.Windows.Media.MediaElementState.Paused:111
txtProgress.Text = "已暂停";112
break;113
case System.Windows.Media.MediaElementState.Playing:114
txtProgress.Text = "正在播放"; 115

116
//预选缓冲下一段视频(不过在实际测试中,感觉这么干没啥明显效果,欢迎大家共同探讨如何提前缓冲下一段视频)117
if (_currentIndex + 1 > _listMedia.Count - 1)118
{119
mediaBuffer.Source = new Uri(_listMedia[0].src);120
}121
else 122
{123
mediaBuffer.Source = new Uri(_listMedia[_currentIndex + 1].src);124
}125
126
break;127
case System.Windows.Media.MediaElementState.Stopped:128
txtProgress.Text = "已停止";129
break;130
default:131
break;132
}133
}134

135
}136

137

138
/// <summary>139
/// 停止播放140
/// </summary>141
/// <param name="sender"></param>142
/// <param name="e"></param>143
private void StopMedia(object sender, System.Windows.RoutedEventArgs e)144
{145
media.Stop();146
btnPlay.Content = ">";147

148
}149

150
151

152
/// <summary>153
/// 播放/暂停154
/// </summary>155
/// <param name="sender"></param>156
/// <param name="e"></param>157
private void PlayMedia(object sender, System.Windows.RoutedEventArgs e)158
{ 159

160
if (media.CurrentState == System.Windows.Media.MediaElementState.Paused || media.CurrentState == System.Windows.Media.MediaElementState.Stopped)161
{162
media.Play();163
btnPlay.Content = "||";164
canvas_Pause.Visibility = Visibility.Collapsed;165
166
}167
else 168
{169
media.Pause();170
btnPlay.Content = ">";171
canvas_Pause.Visibility = Visibility.Visible;172
}173
174
}175

176
/// <summary>177
/// 一段播放完毕后,自动跳到下一段178
/// </summary>179
/// <param name="sender"></param>180
/// <param name="e"></param>181
private void media_MediaEnded(object sender, System.Windows.RoutedEventArgs e)182
{183
_currentIndex++;184

185
if (_currentIndex > _listMedia.Count - 1)186
{187
_currentIndex = 0;188
}189

190
media.Source = new Uri(_listMedia[_currentIndex].src);191

192
cboList.SelectedIndex = _currentIndex;193
}194

195
/// <summary>196
/// 下拉列表改变时,播放相关片段197
/// </summary>198
/// <param name="sender"></param>199
/// <param name="e"></param>200
private void cboList_SelectionChanged(object sender, SelectionChangedEventArgs e)201
{202
_currentIndex = cboList.SelectedIndex;203
if (_currentIndex > _listMedia.Count - 1)204
{205
_currentIndex = 0;206
}207

208
media.Source = new Uri(_listMedia[_currentIndex].src);209
canvas_Pause.Visibility = System.Windows.Visibility.Collapsed;210
media.Position = new TimeSpan(0,0,0,0,0);211
sliderProgress.Value = 0;212
}213

214
/// <summary>215
/// 暂时Canvas点击后,隐藏Canvas,同时继续播放216
/// </summary>217
/// <param name="sender"></param>218
/// <param name="e"></param>219
private void Canvas_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)220
{221
canvas_Pause.Visibility = System.Windows.Visibility.Collapsed;222
media.Play();223
}224

225
/// <summary>226
/// 视频画面单击时,暂时播放227
/// </summary>228
/// <param name="sender"></param>229
/// <param name="e"></param>230
private void media_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)231
{232
canvas_Pause.Visibility = System.Windows.Visibility.Visible;233
media.Pause();234
}235

236
/// <summary>237
/// 进度条拖动时,跳到相关位置238
/// </summary>239
/// <param name="sender"></param>240
/// <param name="e"></param>241
private void sliderProgress_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)242
{243
this.media.Position = new TimeSpan((long)(e.NewValue * 1000 * 1000 * 10));244
}245

246

247
//private void media_BufferingProgressChanged(object sender, RoutedEventHandler e) 248
//{249
// txtTime.Text = "缓冲中
" + media.BufferingProgress.ToString("F0") + "%";250
//}251

252
/// <summary>253
/// 静音按钮的实现254
/// </summary>255
/// <param name="sender"></param>256
/// <param name="e"></param>257
private void btnVoice_Click(object sender, RoutedEventArgs e)258
{259
if (media.IsMuted)260
{261
media.IsMuted = false;262
this.btnVoice.Content = "静";263
sliderVoice.IsEnabled = true;264
}265
else 266
{267
media.IsMuted = true;268
this.btnVoice.Content = "音";269
sliderVoice.IsEnabled = false;270
}271

272
}273

274
/// <summary>275
/// 调整音量大小276
/// </summary>277
/// <param name="sender"></param>278
/// <param name="e"></param>279
private void sliderVoice_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)280
{281
if (sliderVoice == null)282
{283
return;284
}285
media.Volume = sliderVoice.Value;286
}287

288
private void btnFull_Click(object sender, RoutedEventArgs e)289
{290
Content contentObj = App.Current.Host.Content;291
contentObj.IsFullScreen = !contentObj.IsFullScreen;292

293
294
}295

296

297

298
private void Content_FullScreenChanged(object sender, EventArgs e) 299
{300
Content contentObj = App.Current.Host.Content;301
302
if (contentObj.IsFullScreen)303
{304
btnFull.Content = "退";305
}306
else307
{308
btnFull.Content = "全";309
}310
}311

312
/// <summary>313
/// 显示缓冲进度314
/// </summary>315
/// <param name="sender"></param>316
/// <param name="e"></param>317
private void media_BufferingProgressChanged(object sender, RoutedEventArgs e)318
{319
this.txtProgress.Text = "缓冲中
" + (media.BufferingProgress*100).ToString("F0") + "%";320
canvas_Pause.Visibility = Visibility.Visible;321
if (media.BufferingProgress >= 1.0) 322
{323
canvas_Pause.Visibility = Visibility.Collapsed;324
switch (media.CurrentState)325
{326
case System.Windows.Media.MediaElementState.Buffering:327
txtProgress.Text = "缓冲中
";328
break;329
case System.Windows.Media.MediaElementState.Closed:330
txtProgress.Text = "已关闭";331
break;332
case System.Windows.Media.MediaElementState.Paused:333
txtProgress.Text = "已暂停";334
break;335
case System.Windows.Media.MediaElementState.Playing:336
txtProgress.Text = "正在播放";337
break;338
case System.Windows.Media.MediaElementState.Stopped:339
txtProgress.Text = "已停止";340
break;341
default:342
txtProgress.Text = "就绪";343
break;344
}345
}346
}347

348
/// <summary>349
/// 显示加载进度350
/// </summary>351
/// <param name="sender"></param>352
/// <param name="e"></param>353
private void media_DownloadProgressChanged(object sender, RoutedEventArgs e)354
{355
txtProgress.Text = "加载中
" + (media.DownloadProgress * 100).ToString("F0") + "%";356
if (media.DownloadProgress >= 1) 357
{358
switch (media.CurrentState)359
{ 360
case System.Windows.Media.MediaElementState.Buffering:361
txtProgress.Text = "缓冲中
";362
break;363
case System.Windows.Media.MediaElementState.Closed:364
txtProgress.Text = "已关闭";365
break; 366
case System.Windows.Media.MediaElementState.Paused:367
txtProgress.Text = "已暂停";368
break;369
case System.Windows.Media.MediaElementState.Playing:370
txtProgress.Text = "正在播放";371
break;372
case System.Windows.Media.MediaElementState.Stopped:373
txtProgress.Text = "已停止";374
break;375
default:376
txtProgress.Text = "就绪";377
break;378
}379
}380
}381

382
383

384

385
}386

387

388
/// <summary>389
/// 媒体元素Item自定义类390
/// </summary>391
public class MediaItem392
{393
public string src { set; get; }394
public string name { set; get; }395
}396
}397

作者:菩提树下的杨过
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号