随笔 - 616, 文章 - 0, 评论 - 10492
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
[索引页]
[源码下载]


稳扎稳打Silverlight(18) - 2.0视频之详解MediaElement, 开发一个简易版的全功能播放器


作者:webabcd


介绍
Silverlight 2.0 详解MediaElement:开发一个简易版的全功能播放器
    MediaOpened - 当媒体被成功地打开时所触发的事件
    MediaFailed - 当媒体未能被成功地打开时所触发的事件
    CurrentStateChanged - 播放状态(CurrentState)发生改变时所触发的事件
    DownloadProgressChanged - 下载进度(DownloadProgress)发生变化时所触发的事件
    MediaEnded - 当媒体播放到末尾时所触发的事件
    BufferingProgressChanged - 缓冲进度(BufferingProgress)发生变化时所触发的事件
    Source - 需要播放的媒体地址
    Stretch - 拉伸值
    AutoPlay - 是否自动播放媒体
    CurrentState - 播放状态
    Position - 媒体的位置
    DroppedFramesPerSecond - 媒体每秒正在丢弃的帧数
    BufferingProgress - 缓冲进度
    DownloadProgress - 下载进度
    NaturalDuration - 媒体文件的时长
    Volume - 音量大小
    Balance - 音量平衡
    BufferingTime - 需要缓冲的时间的长度
    CurrentState - 播放状态
    IsMuted - 是否静音
    Play() - 播放媒体
    Pause() - 暂停媒体的播放
    Stop() - 停止媒体的播放


在线DEMO
http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html


示例
VideoPlayer.xaml
<UserControl x:Class="Silverlight20.Video.VideoPlayer"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml">
    
<StackPanel HorizontalAlignment="Left">
    
        
<!--
        Source - 需要播放的媒体地址
        Stretch - 拉伸值 [System.Windows.Media.Stretch 枚举]。参见:本Demo的Shape/Shape.xaml
        AutoPlay - 是否自动播放媒体
        
-->
        
<MediaElement x:Name="mediaElement"
                Width
="400" Height="200"
                Source
="http://download.microsoft.com/download/2/0/5/205d8c39-3d55-4032-8195-7b0e6eda4cb6/WinVideo-SL-InstallExperience.wmv" 
                Stretch
="Fill" 
                AutoPlay
="False">
        
</MediaElement>

        
<Button x:Name="play" Content="播放" Margin="5" Click="play_Click" />
        
<Button x:Name="pause" Content="暂停" Margin="5" Click="pause_Click" />
        
<Button x:Name="stop" Content="停止" Margin="5" Click="stop_Click" />
        
<Button x:Name="mute" Content="静音" Margin="5" Click="mute_Click" />

        
<Slider x:Name="playSlider" Minimum="0" Maximum="1" Margin="5" ToolTipService.ToolTip="播放进度" ValueChanged="playSlider_ValueChanged" />
        
<Slider x:Name="volumeSlider" Minimum="0" Maximum="1" Margin="5" ToolTipService.ToolTip="音量大小" ValueChanged="volumeSlider_ValueChanged" />
        
<Slider x:Name="balanceSlider" Minimum="-1" Maximum="1" Margin="5" ToolTipService.ToolTip="音量平衡" ValueChanged="balanceSlider_ValueChanged" />

        
<TextBlock x:Name="lblPlayTime" Margin="5" />
        
<TextBlock x:Name="lblVolume" Margin="5" />
        
<TextBlock x:Name="lblBalance" Margin="5" />

        
<TextBlock x:Name="lblDownloadProgress" Margin="5" />
        
<TextBlock x:Name="lblBufferingProgress" Margin="5" />
        
<TextBlock x:Name="lblDroppedFramesPerSecond" Margin="5" />
        
<TextBlock x:Name="lblState" Margin="5" />

        
<TextBlock x:Name="lblWidth" Margin="5" />
        
<TextBlock x:Name="lblHeight" Margin="5" />
        
<TextBlock x:Name="lblTotalTime" Margin="5" />
        
<TextBlock x:Name="lblBufferingTime" Margin="5" />

    
</StackPanel>
</UserControl>

VideoPlayer.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Windows.Threading;

namespace Silverlight20.Video
{
    
public partial class VideoPlayer : UserControl
    
{
        
// 媒体的时长
        private TimeSpan _duration;

        
private DispatcherTimer _timer = new DispatcherTimer();

        
public VideoPlayer()
        
{
            InitializeComponent();

            
this.Loaded += new RoutedEventHandler(VideoPlayer_Loaded);

            
/*
             * MediaOpened - 当媒体被成功地打开时所触发的事件
             * MediaFailed - 当媒体未能被成功地打开时所触发的事件
             * CurrentStateChanged - 播放状态(CurrentState)发生改变时所触发的事件
             * DownloadProgressChanged - 下载进度(DownloadProgress)发生变化时所触发的事件(当下载增加量大于等于 0.05 或下载进度增加到 1 时会触发此事件)
             * MediaEnded - 当媒体播放到末尾时所触发的事件
             * BufferingProgressChanged - 缓冲进度(BufferingProgress)发生变化时所触发的事件(当缓冲增加量大于等于 0.05 或缓冲进度增加到 1 时会触发此事件)
             
*/


            mediaElement.MediaOpened 
+= new RoutedEventHandler(mediaElement_MediaOpened);
            mediaElement.CurrentStateChanged 
+= new RoutedEventHandler(mediaElement_CurrentStateChanged);
            mediaElement.DownloadProgressChanged 
+= new RoutedEventHandler(mediaElement_DownloadProgressChanged);
            mediaElement.MediaEnded 
+= new RoutedEventHandler(mediaElement_MediaEnded);
            mediaElement.BufferingProgressChanged 
+= new RoutedEventHandler(mediaElement_BufferingProgressChanged);
        }


        
void VideoPlayer_Loaded(object sender, RoutedEventArgs e)
        
{
            
// 每 500 毫秒调用一次指定的方法
            _timer.Interval = TimeSpan.FromMilliseconds(500);
            _timer.Tick 
+= new EventHandler(_timer_Tick);
            _timer.Start();
        }


        
void _timer_Tick(object sender, EventArgs e)
        
{
            
// CurrentState - 播放状态 [System.Windows.Media.MediaElementState枚举]
            
// Position - 媒体的位置(单位:秒)
            if (mediaElement.CurrentState == MediaElementState.Playing)
            
{
                lblPlayTime.Text 
= string.Format(
                    
"{0}{1:00}:{2:00}:{3:00}",
                    
"播放进度:",
                    mediaElement.Position.Hours,
                    mediaElement.Position.Minutes,
                    mediaElement.Position.Seconds);
            }


            
// DroppedFramesPerSecond - 媒体每秒正在丢弃的帧数
            lblDroppedFramesPerSecond.Text = "每秒正在丢弃的帧数:" + mediaElement.DroppedFramesPerSecond.ToString();
        }


        
void mediaElement_BufferingProgressChanged(object sender, RoutedEventArgs e)
        
{
            
// BufferingProgress - 缓冲进度(0 - 1 之间)
            lblBufferingProgress.Text = string.Format(
                
"缓冲进度:{0:##%}",
                mediaElement.BufferingProgress);
        }


        
void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
        
{
            mediaElement.Stop();
        }


        
void mediaElement_DownloadProgressChanged(object sender, RoutedEventArgs e)
        
{
            
// DownloadProgress - 下载进度(0 - 1 之间)
            lblDownloadProgress.Text = string.Format(
                
"下载进度:{0:##%}",
                mediaElement.DownloadProgress);
        }

        
private void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
        
{
            
/*
             * NaturalVideoWidth - 媒体文件的宽
             * NaturalVideoHeight - 媒体文件的高
             * HasTimeSpan - 是否可取得媒体文件的时长
             * NaturalDuration - 媒体文件的时长
             * Volume - 音量大小(0 - 1 之间)
             * Balance - 音量平衡(-1 - 1 之间)
             * BufferingTime - 需要缓冲的时间的长度
             
*/


            lblWidth.Text 
= "媒体文件的宽:" + mediaElement.NaturalVideoWidth.ToString();
            lblHeight.Text 
= "媒体文件的高:" + mediaElement.NaturalVideoHeight.ToString();

            _duration 
= mediaElement.NaturalDuration.HasTimeSpan ? mediaElement.NaturalDuration.TimeSpan : TimeSpan.FromMilliseconds(0);

            lblTotalTime.Text 
= string.Format(
                
"{0}{1:00}:{2:00}:{3:00}""时长:",
                _duration.Hours,
                _duration.Minutes,
                _duration.Seconds);

            mediaElement.Volume 
= 0.8;
            volumeSlider.Value 
= 0.8;
            lblVolume.Text 
= "音量大小:80%";

            mediaElement.Balance 
= 0;
            balanceSlider.Value 
= 0;
            lblBalance.Text 
= "音量平衡:0%";

            mediaElement.BufferingTime 
= TimeSpan.FromSeconds(30);
            lblBufferingTime.Text 
= "缓冲长度:30秒";
        }


        
private void mediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
        
{
            
/*
             * CurrentState - 播放状态 [System.Windows.Media.MediaElementState枚举]
             *     MediaElementState.Closed - 无可用媒体
             *     MediaElementState.Opening - 尝试打开媒体(此时Play(),Pause(),Stop()命令会被排进队列,等到媒体被成功打开后再依次执行)
             *     MediaElementState.Buffering - 缓冲中
             *     MediaElementState.Playing - 播放中
             *     MediaElementState.Paused - 被暂停(显示当前帧)
             *     MediaElementState.Stopped - 被停止(显示第一帧)
             
*/


            lblState.Text 
= "播放状态:" + mediaElement.CurrentState.ToString();
        }


        
private void play_Click(object sender, RoutedEventArgs e)
        
{
            
// Play() - 播放媒体(在当前 Position 处播放)
            mediaElement.Play();
        }


        
private void pause_Click(object sender, RoutedEventArgs e)
        
{
            
// CanPause - 媒体是否可暂停
            
// Pause() - 暂停媒体的播放
            if (mediaElement.CanPause)
                mediaElement.Pause();
        }


        
private void stop_Click(object sender, RoutedEventArgs e)
        
{
            
// Stop() - 停止媒体的播放
            mediaElement.Stop();
        }


        
void mute_Click(object sender, RoutedEventArgs e)
        
{
            
// IsMuted - 是否静音
            if (mediaElement.IsMuted == true)
            
{
                mute.Content 
= "静音";
                mediaElement.IsMuted 
= false;
            }

            
else
            
{
                mute.Content 
= "有声";
                mediaElement.IsMuted 
= true;
            }

        }


        
private void playSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        
{
            
// CanSeek - 是否可以通过设置 Position 来重新定位媒体
            
// Position - 媒体的位置(单位:秒)
            if (mediaElement.CanSeek)
            
{
                mediaElement.Pause();
                mediaElement.Position 
= TimeSpan.FromSeconds(_duration.TotalSeconds * playSlider.Value);
                mediaElement.Play();
            }

        }


        
private void volumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        
{
            
// Volume - 音量大小(0 - 1 之间)
            mediaElement.Volume = volumeSlider.Value;
            lblVolume.Text 
= string.Format(
                
"音量大小:{0:##%}",
                volumeSlider.Value);
        }


        
private void balanceSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        
{
            
// Balance - 音量平衡(-1 - 1 之间)
            mediaElement.Balance = balanceSlider.Value;
            lblBalance.Text 
= string.Format(
                
"音量平衡:{0:##%}",
                balanceSlider.Value);
        }

    }

}



OK
[源码下载]