![]() |
Platforms, Frameworks & Libraries »
Windows Presentation Foundation »
General
Intermediate
A simple WPF media player with media item listBy Sacha BarberA simple WPF media player with media item list |
C# 3.0, Windows, .NET 3.0, WPF, VS2005, Dev
|
||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
I used a MediaElement some time ago in one my 1st WPF articles, and thought it may be time to re-visit it and make a simple video player control. That is what this article is all about really. Theres nothing ground breaking here, as Josh Smith is the one to watch for amazing WPF tricks, hes crazy man believe you me he know whats what in WPF. I am a mere underling, showing simpler subjects to beginners of WPF. So thats what we going to do, build a simple media player control that will have the following features
OK first of all ill just mention what files are involved, these are as follows
Styles Templates ItemsControl (ListBox) As the WPF MediaElement relies on the Windows Media Player, I simpy only allow files that are supported by The WMP to be played in the attached control. This is a fairly simple thing to do. I firstly allow the user to drag and drop files on to the control and then check what type the files are. The associated code is shown below
/// <summary>
/// Handles Drop Event for Media Items.
/// </summary>
private void Media_Drop(object sender, DragEventArgs e)
{
string[] fileNames = e.Data.GetData(DataFormats.FileDrop, true)
as string[];
//keep a dictionary of added files
foreach (string f in fileNames)
{
if (IsValidMediaItem(f))
mediaItems.Add(f.Substring(f.LastIndexOf(@"\")+1),
new MediaItem(@f,0));
}
//now add to the list
foreach (MediaItem mi in mediaItems.Values)
lstMediaItems.Items.Add(mi);
// Mark the event as handled, so the control's native Drop handler is not called.
e.Handled = true;
}
/// <summary>
/// check to see if dragged items are valid
/// </summary>
/// <returns>true if filename is valid</returns>
private bool IsValidMediaItem(string filename)
{
bool isValid = false;
string fileExtesion = filename.Substring(filename.LastIndexOf("."));
foreach (string s in MediaItem.allowableMediaTypes)
{
if (s.Equals(fileExtesion,
StringComparison.CurrentCultureIgnoreCase))
isValid = true;
}
return isValid;
}
Thats all there is to that
When dealing with the WPF MediaElement, you can either use Media StoryBoards or use code. To use code you must ensure that the MediaElement.LoadedBehavior="Manual" and if you have that it simply a question of using the following methods on the MediaElement
mediaPlayerMain.Play() mediaPlayerMain.Pause() mediaPlayerMain.Stop() All I do here is use a Slider WPF control to alter the MediaElements Volume property
All I do here is use a Slider WPF control to alter the MediaElements Position property
I wanted to be able to make the MediaElement take up the total available screen real estate. To this end when you click on the main MediaElement it will animate to take up the available screen area by hiding the media list. This uses the excellent article by Christian Graus, Nishant Sivakumar which is available here
I wanted to be able to rate the media items. So I created a special rating button Style which is applied to some ToggleButtons
The Style code for this is as follows, where the stars are actually drawn using the Data property
<!-- Rating Cell-->
<Style x:Key="StarToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Canvas Width="12" Height="12">
<Path Name="star" Fill="Gray"
Data="M 5,0 L 4,4 L 0,4 L 3,7 L 2,11 L 5,9 L 6,9 L 9,11 L 8,
7 L 11,4 L 7,4 L 6,0"/>
</Canvas>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="star" Property="Fill" Value="Gold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This results in the following control
Some other nice bits are that I use some 3D buttons (Taken straight out of Adam Nathans WPF Unleashed book). As the 3D buttons are achieved by using a standard WPF style they can also show content, as I do here where I have a video playing on the 3D buttons.
The style to do all this is shown below. But as I say I stols this from Adam Nathans WPF Unleashed book
<!-- 3D Media Buttons -->
<Style x:Key="btn3DStyle" TargetType="{x:Type Button}">
<Style.Resources>
<Storyboard x:Key="Spin">
<DoubleAnimation
Storyboard.TargetName="CubeRotation"
Storyboard.TargetProperty="Angle" BeginTime="0:0:0"
Duration="0:0:1" From="0" To="360" DecelerationRatio="0.5"
AccelerationRatio="0.5" />
<DoubleAnimation
Storyboard.TargetName="CubeRotation"
Storyboard.TargetProperty="Angle" BeginTime="0:0:1"
Duration="0:0:1" From="360" To="0" DecelerationRatio="0.5"
AccelerationRatio="0.5" />
<DoubleAnimation
Storyboard.TargetName="CubeScale"
Storyboard.TargetProperty="ScaleX"
BeginTime="0:0:0"
Duration="0:0:1" From="0.5" To="0.75" />
<DoubleAnimation
Storyboard.TargetName="CubeScale"
Storyboard.TargetProperty="ScaleX"
BeginTime="0:0:1"
Duration="0:0:1" From="0.75" To="1.0" />
<DoubleAnimation
Storyboard.TargetName="CubeScale"
Storyboard.TargetProperty="ScaleY"
BeginTime="0:0:0"
Duration="0:0:1" From="0.5" To="0.75" />
<DoubleAnimation
Storyboard.TargetName="CubeScale"
Storyboard.TargetProperty="ScaleY"
BeginTime="0:0:1"
Duration="0:0:1" From="0.75" To="1.0" />
<DoubleAnimation
Storyboard.TargetName="CubeScale"
Storyboard.TargetProperty="ScaleZ"
BeginTime="0:0:0"
Duration="0:0:1" From="0.5" To="0.75" />
<DoubleAnimation
Storyboard.TargetName="CubeScale"
Storyboard.TargetProperty="ScaleZ"
BeginTime="0:0:1"
Duration="0:0:1" From="0.75" To="1.0" />
</Storyboard>
</Style.Resources>
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="100"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Spin}"/>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
<Viewport3D>
<Viewport3D.Camera>
<PerspectiveCamera Position="4,4,4" LookDirection="-1,-1,-1" />
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Direction="-0.3,-0.4,-0.5" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D x:Name="Cube">
<ModelVisual3D.Transform>
<Transform3DGroup>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="CubeRotation" Axis="1,2,3" Angle="0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
<ScaleTransform3D x:Name="CubeScale" ScaleX="1" ScaleY="1" ScaleZ="1" CenterX="0" CenterY="0" CenterZ="0" />
</Transform3DGroup>
</ModelVisual3D.Transform>
<ModelVisual3D.Content>
<GeometryModel3D x:Name="OB_Cube">
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<VisualBrush ViewportUnits="Absolute" Transform="1,0,0,-1,0,1">
<VisualBrush.Visual>
<Border Background="{Binding Path=Background, RelativeSource='{RelativeSource TemplatedParent}'}">
<Label Content="{Binding Path=Content, RelativeSource='{RelativeSource TemplatedParent}'}" />
</Border>
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
<GeometryModel3D.Geometry>
<MeshGeometry3D x:Name="ME_Cube"
Positions="1,1,-1 1,-1,-1 -1,-1,-1 -1,1,-1 1,1,1 -1,1,1 -1,-1,1 1,-1,1 1,1,
-1 1,1,1 1,-1,1 1,-1,-1 1,-1,-1 1,-1,1 -1,-1,1 -1,-1,-1 -1,-1,-1 -1,-1,1 -1,1,1 -1,1,
-1 1,1,1 1,1,-1 -1,1,-1 -1,1,1"
TriangleIndices="0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17
18 16 18 19 20 21 22 20 22 23"
TextureCoordinates="0,1 0,0 1,0 1,1 1,1 -0,1 0,-0 1,0 1,1 -0,1 0,-0 1,0 1,0 1,1 -0,1 0,
-0 -0,0 1,-0 1,1 0,1 1,-0 1,1 0,1 -0,0"/>
</GeometryModel3D.Geometry>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
</Viewport3D>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also applying some animations to rotate and size these buttons, nice huh. Oh the media items styles can also be swapped to a more conventional button by using the last button in the media items area. In both the 3D buttons and the standard buttons cases, I also created a nicer tooltip.
Its pretty easy actually (I hope) either drag and drop some media items to the left hand side list box area, or load a previously saved xml media list. When the media items are loaded, just click one and it will start to play in the main window. Where you may control it using the controls provided.
Although there is not that much code in this article, I had fun doing this one, and hope that it will be useful to someone out there.
I would just like to ask, if you liked the article please vote for it, and leave some comments, as it lets me know if the article was at the right level or not, and whether it contained what people need to know.
Theres not to much to mention here as I think the rest of the article pretty much covers it.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 13 Sep 2007 Editor: |
Copyright 2007 by Sacha Barber Everything else Copyright © CodeProject, 1999-2009 Web19 | Advertise on the Code Project |