|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionFew days ago I have been post an article about how creating a Silverlight 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:
BackgroundYou already know I have been create a Silverlight V2 control named Key Features
Using the ControlUsing the 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 <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 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 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. How It WorksIn here I don't repeat how the <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 But in code, something need to say. The first is how tracking the current position of the media. If you have been study the Create a globe /// <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 // 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 // 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 /// <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 HistoryCurrentMediaStateChnaged and SelectedItemChanged. AutoTurn to false, the turnning button not appear.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||