Implement the Video Slider control

Posted by Corey on October 13, 2008 at 8:44 am.

A month ago I released a Slider control specifically geared towards video.  It includes a download progress indicator and the ability to click on the track to navigate.  Unfortunately when I released the code, there was no documentation.  In an effort to correct that, here is how to  implement the VideoSlider.  (And here is the working example)

  1. Download the project or the dll (zip format).
  2. Add the project or dll as a reference. (This example adds the dll.)
    image
    image
  3. Add the VideoSlider control to XAML.  Things to note:
    • First you need to add a reference to the namespace (Line 4).
    • Then add the the Slider to the page (Line 16).
    • Notice line 18, TrackFill and DownloadProgressFill.  These are part properties of the VideoSliderControl.  The TrackFill is the default background of the slider; the DownloadProgressFill is the color of the buffered data.
    •   1: <UserControl x:Class="VideoPlayerExample.Page"
      
        2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      
        3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      
        4:     xmlns:ctrl="clr-namespace:VideoSliderControl;assembly=VideoSliderControl"
      
        5:     xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
      
        6:     Width="400" Height="300">
      
        7:
      
        8:
      
        9:     <Grid x:Name="LayoutRoot" Background="White">
      
       10:         <Grid.RowDefinitions>
      
       11:             <RowDefinition Height="*" />
      
       12:             <RowDefinition Height="30" />
      
       13:         </Grid.RowDefinitions>
      
       14:
      
       15:         <MediaElement x:Name="MainVideo" Grid.Row="0" />
      
       16:         <ctrl:VideoSlider x:Name="Scrubber" MinWidth="200" Margin="5"
      
       17:                 VerticalAlignment="Center" Minimum="0" Maximum="1" Grid.Row="1"
      
       18:                 TrackFill="#FF87CAFE" DownloadProgressFill="#FF2B2B2B" />
      
       19:     </Grid>
      
       20:
      
       21: </UserControl>
  4. Now wire up the controls
    • Set the Media Source (line 46)
    • Register events for the MediaElement (line 10-12)
    • Add a timer to update the position of the slider for the playback (line 3, 9-12, 49-55)
    • When the media opens set the position of the slider to 0 (lines 20-23).
    • TrackClicked – This event fires when you click anywhere on the slider.  Line 19 registers the event and Lines 49-52 handle the event.
    • ThumbDragStarted – This event fires when you click sliders Thumb.  In the event handler you want to lock the thumb so the timer does update the position while you are dragging.  Line 20 registers the event and lines 54-57 handle the event.
    • ThumbDragCompleted – This event fires when you release the mouse button from the Thumb.  In the event handlers you want to unlock the slider and update the position of the MediaElement.  Line 21 registers the event and lines 59-63 handle the event.

  1:     public partial class Page : UserControl
  2:     {
  3:         private DispatcherTimer positionTimer;
  4:         private Boolean IsScrubberLocked = false;
  5:
  6:         public Page()
  7:         {
  8:             InitializeComponent();
  9:
 10:             this.Loaded += new RoutedEventHandler(Page_Loaded);
 11:             positionTimer = new DispatcherTimer();
 12:             positionTimer.Interval = new TimeSpan(0, 0, 0, 0, 100);
 13:             positionTimer.Tick += new EventHandler(positionTimer_Tick);
 14:
 15:             this.MainVideo.MediaOpened += new RoutedEventHandler(MainVideo_MediaOpened);
 16:             this.MainVideo.CurrentStateChanged += new RoutedEventHandler(MainVideo_CurrentStateChanged);
 17:             this.MainVideo.DownloadProgressChanged += new RoutedEventHandler(MainVideo_DownloadProgressChanged);
 18:
 19:             this.Scrubber.TrackClicked += new EventHandler<EventArgs>(Scrubber_TrackClicked);
 20:             this.Scrubber.ThumbDragStarted += new EventHandler<EventArgs>(Scrubber_ThumbDragStarted);
 21:             this.Scrubber.ThumbDragCompleted += new EventHandler<EventArgs>(Scrubber_ThumbDragCompleted);
 22:         }
 23:
 24:         #region Media element events
 25:         void MainVideo_MediaOpened(object sender, RoutedEventArgs e)
 26:         {
 27:             this.Scrubber.Value = 0;
 28:         }
 29:
 30:         void MainVideo_CurrentStateChanged(object sender, RoutedEventArgs e)
 31:         {
 32:             if (this.MainVideo.CurrentState == MediaElementState.Playing)
 33:             {
 34:                 positionTimer.Start();
 35:             }
 36:             else
 37:             {
 38:                 positionTimer.Stop();
 39:             }
 40:         }
 41:
 42:         void MainVideo_DownloadProgressChanged(object sender, RoutedEventArgs e)
 43:         {
 44:             this.Scrubber.DownloadProgress = this.MainVideo.DownloadProgress;
 45:         }
 46:         #endregion
 47:
 48:         #region Scrubber events
 49:         void Scrubber_TrackClicked(object sender, EventArgs e)
 50:         {
 51:             this.MainVideo.Position = TimeSpan.FromSeconds(this.Scrubber.Value * this.MainVideo.NaturalDuration.TimeSpan.TotalSeconds);
 52:         }
 53:
 54:         void Scrubber_ThumbDragStarted(object sender, EventArgs e)
 55:         {
 56:             IsScrubberLocked = true;
 57:         }
 58:
 59:         void Scrubber_ThumbDragCompleted(object sender, EventArgs e)
 60:         {
 61:             IsScrubberLocked = false;
 62:             this.MainVideo.Position = TimeSpan.FromSeconds(this.Scrubber.Value * this.MainVideo.NaturalDuration.TimeSpan.TotalSeconds);
 63:         }
 64:         #endregion
 65:
 66:         void Page_Loaded(object sender, RoutedEventArgs e)
 67:         {
 68:             //this.MainVideo.Source = new Uri("http://quickstarts.asp.net/Futures/Silverlight/samples/media/expressionstudio.wmv", UriKind.Absolute);
 69:             this.MainVideo.Source = new Uri("http://download.microsoft.com/download/8/4/2/8427e8fd-b392-4099-ae1b-d626a71dc617/HaloWars_ESRB_360p30_ST_1500kbps.wmv", UriKind.Absolute);
 70:         }
 71:
 72:         void positionTimer_Tick(object sender, EventArgs e)
 73:         {
 74:             if (this.MainVideo.Position.TotalSeconds > 0 && !IsScrubberLocked)
 75:             {
 76:                 this.Scrubber.Value = (((double)this.MainVideo.Position.Ticks) / ((double)this.MainVideo.NaturalDuration.TimeSpan.Ticks));
 77:             }
 78:         }
 79:     }

The resulting video player.

image

6 Responses to “Implement the Video Slider control”

  •  

    [...] Corey Schuman Implements the Video Slider control [...]

  • Does it’s still work in the RC1 of silverlight?
    Because I tried and I didn’t find a way to make it work…

  • Lénaïc, Are you trying to run it on RTM? You can find the source code here: http://www.codeplex.com/videoslidercontrol/SourceControl/ListDownloadableCommits.aspx.

    Release 4539 works on RTM and the others are Beta 2.

  • Is this video control currently working with the latest release of Silverlight 3?I couldn’t get the control to show up when I was building it.

  • I got it to work with the DLL you provided. One other question, is there a way of changing the thumb style when using the DLL?

  • I referenced the dll. I need to instantiate at runtime and just replaced where I was using the standard Slider with the VideoSlider. So far so good so, I looked at intelisense and saw some of the added properties and methods. I decided to just see how it looked from that point and when I built the project got slammed with this. I don’t have the time to create the controls needed to create cool apps. Something like this would be a great help. Thanks for any help.

    Error 1 The “ValidateXaml” task failed unexpectedly.
    System.IO.FileLoadException: Could not load file or assembly ‘file:///C:\Program Files (x86)\Custom Silverlight Controls\VideoSliderControl\DLL\VideoSliderControl.dll’ or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0×80131515)
    File name: ‘file:///C:\Program Files (x86)\Custom Silverlight Controls\VideoSliderControl\DLL\VideoSliderControl.dll’ —> System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.

    at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
    at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
    at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks)
    at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
    at System.Reflection.Assembly.LoadFrom(String assemblyFile)
    at Microsoft.Silverlight.Build.Tasks.ValidateXaml.XamlValidator.Execute(ITask task)
    at Microsoft.Silverlight.Build.Tasks.ValidateXaml.XamlValidator.Execute(ITask task)
    at Microsoft.Silverlight.Build.Tasks.ValidateXaml.Execute()
    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
    at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult)

    FreeFire

Leave a Reply