![]() |
Web Development »
Silverlight »
Controls
Beginner
License: The Microsoft Public License (Ms-PL)
A Silverlight Video Player Carousel ControlBy cokkiyVideoCarousel is a Silverlight V2 control can play media in an interactive carousel. |
C# (C# 2.0, C# 3.0), .NET (.NET 2.0, .NET 3.0), Silverlight, Dev, Design
|
||||||||
|
Advanced Search |
|
|
|
||||||||||||||||
Few days ago I have been post an article about how creating a Silverlight Carousel control, you can read here. In this article I'll creating a new Carousel which can be used to playing video or audio. I named it VideoCarousel. The VideoCarousel very similar to the Carousel except it can play video or audio. If you have been try the Carousel control, maybe you already know the Carousel has a Panel display the user selected picture (with title). In the VideoCarousel the Panel replaced by a video player control. If you want to know how the Carousel working, you may need to read this article.
You may use the VideoCarousel control as a video player in your web page. It's support dynamic add/ remove media (video or audio) info to it's collection. The media info can include a picture (you can capture a frame from the film), a Uri where the media located, a title, the name of the director, the name of the main actors and the name of the producer.
When the user move the Mouse over the CarouselItem, the media info will be appear. When the user select the CarouselItem, the select video picture will be appear in the selected item panel and the media will be auto buffer. If the media ready, user can play it or if you set the AutoPlay property to true, the media will be auto play. The Carousel menu auto disappear when the media palying.
Display media info when mouse over:
The carousel hide when video playing:

You already know I have been create a Silverlight V2 control named Carousel which can display a collection of picture in an interactive carousel. I like the control so I made some upgrade for it, now it can use as a video player.
Using the VideoCarousel control is very simple. In your Silverlight application, add a reference of the assembly (the name of the assembly is Cokkiy.Display.VideoCarousel). Then in your page's XAML file, do like following:
In the beginning of the page, add a xmlns reference.
<UserControl x:Class="VideoCarouselTest.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:display="clr-namespace:Cokkiy.Display;assembly=Cokkiy.Display.VideoCarousel"
>
Then, place the VideoCarousel control inside to your layout control, such as Grid or StackPanel:
<Grid x:Name="LayoutRoot" Background="White">
<display:VideoCarousel x:Name="carousel" TurnDirection="Counterclockwise" Padding="5,5,5,5" >
Also, you can set it's background like this:
<display:VideoCarousel.Background>
<LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush>
</display:VideoCarousel.Background>
If you want set the media info static in your XAML file, you can do as following:
<display:VideoCarousel.ItemSources>
<display:ItemSource Title="Sample Video" Director="Unknown" Actors="Unknown"
Producer="Microsoft"
ImageSource="Images/01.jpg" MediaSource="Videos/SampleVideo.wmv"/>
<display:ItemSource Title="Sample" ImageSource="Images/02.jpg"
MediaSource="Videos/Sample.wmv"/>
<display:ItemSource Title="SL VC1 Video" ImageSource="Images/03.jpg"
MediaSource="Videos/sl.wmv"/>
<display:ItemSource Title="silverlight" ImageSource="Images/04.jpg"
MediaSource="Videos/silverlight.wmv"/>
<display:ItemSource Title="SampleVideo" ImageSource="Images/05.jpg"
MediaSource="Videos/SampleVideo.wmv"/>
<display:ItemSource Title="Sample" ImageSource="Images/06.jpg"
MediaSource="Videos/Sample.wmv"/>
<display:ItemSource Title="sl" ImageSource="Images/07.jpg"
MediaSource="Videos/sl.wmv"/>
<display:ItemSource Title="silverlight" ImageSource="Images/08.jpg"
MediaSource="Videos/silverlight.wmv"/>
<display:ItemSource Title="SampleVideo" ImageSource="Images/09.jpg"
MediaSource="Videos/SampleVideo.wmv"/>
<display:ItemSource Title="silverlight" ImageSource="Images/10.jpg"
MediaSource="silverlight.wmv"/>
<display:ItemSource Title="Error created" ImageSource="Images/11.jpg"/>
</display:VideoCarousel.ItemSources>
In the end, close the tag.
</display:VideoCarousel>
</Grid>
But in most situation, you want dynamic add media info into the collection based on user selection or film just watched. You can subscribe the SelectedItemChanged or the CurrentMediaStateChnaged event.The SelectedItemChanged event occurs when user selected an item and the CurrentMediaStateChnaged event occurs when the media playing, paused or stoped. The following code add a film to the control.
carousel.ItemSources.Add(
new Uri("Images/25.jpg", UriKind.Relative), // a picture from the film
new Uri("Videos/sl.wmv",UriKind.Relative), // the media Uri addresss
"Dynamic added SL VC1 Video", // Film title
"Jo Coco", // the director
"Tom Crausel", // the main actor
"the Disney Product"); // the producer
You also want remove the media the user just watched when the meida ended.
void carousel_CurrentMediaStateChnaged(object sender, MediaStateChangedEventArgs e)
{
if (e.MediaState == MediaState.Ended)
{
// remove the media user just watched
carousel.ItemSources.Remove(e.Title);
}
}
In some times, you may want the Carousel part not auto turnning. You can simple set the AutoTurn to false gets this effects. When the Carousel not auto turnning, a button will auto appear in each side of the Carousel, the user can use the buttons to turns left or right.
In XAML file you can do like this:
<display:VideoCarousel x:Name="carousel" AutoTurn="False"
TurnDirection="Counterclockwise" Padding="5,5,5,5" >
Or you can set it in code.
In here I don't repeat how the Carousel works (you can read how it works here). The main point of here is the video player. The video player is a UserControl. Here is the XAML (note here I omits all the control template):
<UserControl x:Class="Cokkiy.Display.VideoPlayer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
xmlns:mwc="clr-namespace:Microsoft.Windows.Controls;assembly=Cokkiy.Common.Controls"
xmlns:cc="clr-namespace:Cokkiy.Common.Controls;assembly=Cokkiy.Common.Controls"
xmlns:resources="clr-namespace:Cokkiy.Display.Resources"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
>
<Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MouseLeave="LayoutRoot_MouseLeave" MouseMove="LayoutRoot_MouseMove"
Opacity="1" Background="Transparent">
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="PositionStates">
<vsm:VisualState x:Name="SetPositionState">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000"
Storyboard.TargetName="positionSlider"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000"
Storyboard.TargetName="_base"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000"
Storyboard.TargetName="position"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Duration="00:00:00.0010000"
Storyboard.TargetName="bufferPosition"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="ShowPositionState"/>
</vsm:VisualStateGroup>
<vsm:VisualStateGroup x:Name="ControlStates">
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransition GeneratedDuration="00:00:02" To="ShowControlPanelState"/>
<vsm:VisualTransition From="ShowControlPanelState" GeneratedDuration="00:00:02"/>
</vsm:VisualStateGroup.Transitions>
<vsm:VisualState x:Name="ShowControlPanelState">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="controlBorder"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="0.8"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="HideControlPanelState"/>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Image x:Name="frameImage" HorizontalAlignment="Center" VerticalAlignment="Center"
Stretch="Uniform" />
<Grid x:Name="mediaBackground" Background="Black" Visibility="Collapsed">
<StackPanel MouseLeftButtonUp="mediaPlace_MouseLeftButtonUp" x:Name="mediaPlace"
VerticalAlignment="Center" HorizontalAlignment="Center">
<MediaElement AutoPlay="False" x:Name="mediaPlayer"/>
</StackPanel>
</Grid>
<Border CornerRadius="30,30,0,30" VerticalAlignment="Bottom" Background="Black"
x:Name="controlBorder" Opacity="0">
<Grid x:Name="controlGrid" Opacity="0.7" HorizontalAlignment="Stretch"
VerticalAlignment="Bottom" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<cc:PlayPauseButton x:Name="playPauseButton" IsEnabled="False" Width="60" Height="60"
Click="playPauseButton_Click"/>
<StackPanel Grid.Column="1">
<TextBlock x:Name="titleTextBlock" HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16" Foreground="White" Text="Video Tile" TextWrapping="Wrap"/>
<mwc:DockPanel LastChildFill="True">
<Button Margin="0,0,5,0" mwc:DockPanel.Dock="Left" x:Name="stopButton"
Click="stopButton_Click" Style="{StaticResource StopButtonStyle}"/>
<StackPanel Orientation="Horizontal" mwc:DockPanel.Dock="Right">
<Slider Width="100" Maximum="1" Value="0.5" LargeChange="0.05" SmallChange="0.01"
Style="{StaticResource EllipseSliderStyle}" x:Name="volumeSlider"
ValueChanged="volumeSlider_ValueChanged"/>
<ToggleButton Margin="0,0,5,0" VerticalAlignment="Center"
Style="{StaticResource muteToggleButtonStyle}" x:Name="muteButton"
Checked="muteButton_Checked" Unchecked="muteButton_Unchecked"/>
</StackPanel>
<!--Position TraackBar and Text-->
<StackPanel x:Name="positionPanel" MouseEnter="positionPanel_MouseEnter"
MouseLeave="positionPanel_MouseLeave" HorizontalAlignment="Stretch">
<Grid>
<Rectangle Fill="#FF7C7A7A" Height="5" VerticalAlignment="Center"
x:Name="_base"
SizeChanged="_base_SizeChanged"
HorizontalAlignment="Stretch"/>
<Rectangle Fill="#FFD7F90E" x:Name="bufferPosition"
VerticalAlignment="Center"
HorizontalAlignment="Left" Height="5" Width="0"/>
<Rectangle Fill="#FFFAFAFB" Height="5" VerticalAlignment="Center"
HorizontalAlignment="Left" Width="0" x:Name="position"/>
<Slider Maximum="1" LargeChange="0.05" SmallChange="0.01"
mwc:DockPanel.Dock="Right" Style="{StaticResource EllipseSliderStyle}"
IsEnabled="False" x:Name="positionSlider"
ValueChanged="positionSlider_ValueChanged"
Opacity="0"/>
</Grid>
<mwc:DockPanel LastChildFill="False">
<TextBlock Foreground="White" mwc:DockPanel.Dock="Right"
x:Name="mediaDurantionTextBlock" Text="unknown"/>
<TextBlock Foreground="White" mwc:DockPanel.Dock="Right" Text="/"/>
<TextBlock Foreground="White" mwc:DockPanel.Dock="Right"
x:Name="mediaPositionTextBlock" Text="00:00:00"/>
</mwc:DockPanel>
</StackPanel>
</mwc:DockPanel>
</StackPanel>
</Grid>
</Border>
<Grid HorizontalAlignment="Center" x:Name="loadingInfo" VerticalAlignment="Center"
Visibility="Collapsed">
<-- Omit the loading animation control -->
</Grid>
</Grid>
The main part of the video player is a control panel, which controls the MediaElement to play, pause or stop the media and indicating the position of the media. The visual state controls the appear or disappear of the control panel. There no more interesting thing to say in this XAML file.
But in code, something need to say. The first is how tracking the current position of the media. If you have been study the MediaElement control you may notice there no notify when the playing position changed. So I create a Timer object to track the positon at specified intervals.
Create a globe Timer object.
/// <summary>
/// A timer object to set the current position
/// </summary>
private Timer setPositionTimer;
When the media play, start the timer.
/// <summary>
/// Play the media
/// </summary>
private void PlayMedia()
{
mediaPlayer.Play();
// omit other code here
// if can seek, show play position
if (mediaPlayer.CanSeek)
{
if (setPositionTimer == null)
{
setPositionTimer = new Timer(this.UpdatePosition, null, 0, 500);
}
}
}
The TimerCallback function called by the Timer object. It's uses a anonymous delegate to update the position of the track bar.
// Update the play position
private void UpdatePosition(object state)
{
positionSlider.Dispatcher.BeginInvoke(
delegate()
{
double value = mediaPlayer.Position.TotalSeconds
/ mediaPlayer.NaturalDuration.TimeSpan.TotalSeconds;
position.Width = value * _base.ActualWidth;
mediaPositionTextBlock.Text = mediaPlayer.Position.TotalMinutes.ToString("F2"); ;
});
}
The second interesting thing is when user move the mouse over the player, the control panel will appear and then disappear if the user hold the mouse still.
When user move the mouse, we use the VisualState make the control panel appear. And we start the downcount to hide the control panel.
// Mouse move in the layout root panel
private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
{
// If mouse move, we show the control panel, then wait a minute
// we hide the control panel
VisualStateManager.GoToState(this, "ShowControlPanelState", true);
this.Cursor = null;
HideControlPanel();
}
The HideControlPanel use a DispatcherTimer object. Here uses DispatcherTimer object because we want direct update the Visual.
/// <summary>
/// A timer when it's occured, the control panel will be hide
/// </summary>
private DispatcherTimer hideControlPanelTimer;
/// <summary>
/// Hide the control panel when a time out
/// </summary>
private void HideControlPanel()
{
if (hideControlPanelTimer == null)
{
hideControlPanelTimer = new DispatcherTimer();
hideControlPanelTimer.Interval = TimeSpan.FromSeconds(10);
}
hideControlPanelTimer.Stop();
hideControlPanelTimer.Tick += delegate(object s, EventArgs args)
{
// when the time out, hide the control panel
VisualStateManager.GoToState(this, "HideControlPanelState", true);
this.Cursor = Cursors.None;
hideControlPanelTimer.Stop();
};
hideControlPanelTimer.Start();
}
I say so much about the VideoCarousel control. If you have any problem or advice, please contact me.
CurrentMediaStateChnaged and SelectedItemChanged. AutoTurn to false, the turnning button not appear. | You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 26 Nov 2008 Editor: Sean Ewington |
Copyright 2008 by cokkiy Everything else Copyright © CodeProject, 1999-2009 Web13 | Advertise on the Code Project |