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)
- Download the project or the dll (zip format).
- Add the project or dll as a reference. (This example adds the dll.)
- 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.
- 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: <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>
1: public partial class Page : UserControl2: {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 events25: 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: else37: {38: positionTimer.Stop();39: }40: }41:42: void MainVideo_DownloadProgressChanged(object sender, RoutedEventArgs e)43: {44: this.Scrubber.DownloadProgress = this.MainVideo.DownloadProgress;45: }46: #endregion47:48: #region Scrubber events49: 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: #endregion65: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: }



October 14th, 2008 at 1:02 am
[...] Corey Schuman Implements the Video Slider control [...]
October 22nd, 2008 at 6:08 am
Does it’s still work in the RC1 of silverlight?
Because I tried and I didn’t find a way to make it work…
October 22nd, 2008 at 7:18 am
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.
January 18th, 2010 at 4:47 pm
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.
January 19th, 2010 at 6:32 am
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?
March 3rd, 2010 at 11:38 pm
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