Click here to Skip to main content
Email Password   helpLost your password?

Contents

Introduction

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

So those were my basic ideas. What ill do is talk about each item in turn as the article progresses.

How it Works

OK first of all ill just mention what files are involved, these are as follows

So thats it. Shall we carry on and see how each part was done. I wont explain it all as a lot of it is standard WPF stuff like Styles/Templates/Binding but sometimes there will even be something there that needs to be mentioned. So lets carry on shall we.

Play Videos

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

Control media playback (pause / stop / play)

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

Control media volume

All I do here is use a Slider WPF control to alter the MediaElements Volume property

Control media position

All I do here is use a Slider WPF control to alter the MediaElements Position property

Scale media

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

Rate each media item

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 stuff

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.

How To Use It

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.

That's it

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.

So What Do You Think ?

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.

Conclusion

Theres not to much to mention here as I think the rest of the article pretty much covers it.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralCool, but how to play the file on the network?
smallrui
17:36 27 Jan '10  
thanks Wink
GeneralRe: Cool, but how to play the file on the network?
smallrui
17:59 27 Jan '10  
I tried to use following code,
mediaPlayerMain.Source = new Uri("http://www.sample.com:8080/myfile.WMV", UriKind.Absolute);

and it works, thanks Poke tongue
GeneralRe: Cool, but how to play the file on the network?
Sacha Barber
22:43 27 Jan '10  
cool

Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralRe: Cool, but how to play the file on the network?
Sacha Barber
22:44 27 Jan '10  
Actually you may like my better media player Sonic Sonic : A WPF (hybrid smart client) searchable media library[^] a bit better, its a nicer media player

Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralRe: Cool, but how to play the file on the network?
smallrui
23:28 31 Jan '10  
Thanks for your replay. Nice, saw it. Big Grin

By the way, Is there anyway to display with its default control buttons or
other method can achieve? Confused

I tried to imitate WMP12 effect and floating some buttons on this,
but it will become flash when the mouse over the control-button.
Anyway to solve it plase.

Thanks again. Poke tongue
QuestionWhat kind of license
Krzysiek.Staszak
12:23 1 Jun '09  
Hi,

can you provide information about license for this project?
AnswerRe: What kind of license
Sacha Barber
22:34 1 Jun '09  
You can use it any way you want.

Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralAccess Violation Errors.
Jammer
12:18 27 May '09  
Hi Sacha,

Sorry for hijacking this message board but I've just started seeing this error with WPF and WMP:

Unhandled exception at 0x1d1c1b30 in App.exe: 0xC0000005: Access violation writing location 0x3d0c3360.


I've taken all the usual try{} catch{} steps to isolate the problem but I fear the issue lies with either WPF or the MediaPlayer class itself. Did you encounter anything like this on your journeys?

Thanks for any pointers.

How's the book coming along? Smile

Cheers,


GeneralRe: Access Violation Errors.
Sacha Barber
0:37 28 May '09  
Hey man, I have downloaded code again and tried it both at home and at work on several PCs/laptops and cant see any issues.

Frown

Book is in the waiting stage, where we have done full proposal and are just waiting for the red/green light.

Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralRe: Access Violation Errors.
Jammer
3:27 28 May '09  
Excellent news on the book. Progress at the very least, really good to hear that.

Hmm ... I'm going to have to do some more exploring to see what the problem is. It works fine for the first 100 ish plays (different files) and then it just blows up.

I'm thinking that I might need to create a new instance of MediaPlayer every 30 files or something and see how it performs then.

Thanks Sacha.

Cheers,


GeneralNeed to play mov, mp4 and avi using MediaElement
Member 2409888
12:28 11 May '09  
Any help with this will be appreciated.

Thanks,
GeneralRe: Need to play mov, mp4 and avi using MediaElement
Sacha Barber
0:01 13 May '09  
See my reply below to rohan_puranik, Jerimiah is the man, he has full support for this using his own MediaKit WPF library written using WPF / C++ / C# ask him

Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralRe: Need to play mov, mp4 and avi using MediaElement
SangwookPark
19:42 14 May '09  
Very Nice Program

After ffdshow(ffdshow_rev2649_20090201_clsid.exe) installed, you can play mp4,avi.
GeneralRe: Need to play mov, mp4 and avi using MediaElement
Sacha Barber
22:43 14 May '09  
SangwookPark wrote:
Very Nice Program


This one or Jers MediaKit, Jer is the Media WPF MAN

Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralRe: Need to play mov, mp4 and avi using MediaElement
soft2buy
19:06 27 Sep '09  
I've downloaded and installed ffdshow,but still can not play mp4,avi? I used ffdshow default setting. Anything else needs to do? :(
GeneralCan We Replicate Windows Media Player's Behavior?
rohan_puranik
2:51 5 May '09  
Hi Sacha
I was going through your articles on WPF especially on Media Element. Very informative and nicely written.
Meanwhile I am trying to develop a user control which provides all the functionalities similar to the Windows Media Player using Mediaelement alongwith the current status of video playback.
I have been able to develop the video playback functionalities such as Play,Pause,Stop (using Mediaelement methods). Also i have designed a slider which moves as the video progresses in the mediaelement and you can drag the thumb and "click to point" to advance the media element's position.
But i am unable to capture the current status of media (such as Isplaying,Isstopped etc.) as mediaelemnt does not expose any method directly for this purpose. I surfed some sites and they suggested me to use Storyboard and its trigger events. But the problem is that after attaching clock control (i.e storyboard) to mediaelement it does not allow to update mediaelement's position property. I am findiing it difficult to handle the animation and timeline properties as well.
So i was wondering if you have worked on this and it would be very nice if you could give some workaround for this problem in your next article.

Thank You.
GeneralRe: Can We Replicate Windows Media Player's Behavior?
Sacha Barber
0:00 13 May '09  
One of my good buddies Jermiah Morrill has written some great media stuff, I think you may be better of asking him, You can contact him over at http://jmorrill.hjtcentral.com/Home/tabid/428/Default.aspx[^]

Sacha Barber
  • Microsoft Visual C# MVP 2008/2009
  • Codeproject MVP 2008/2009
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

QuestionPlease Help !!!!
Men Bahalemeh
4:52 3 May '09  
I have a big problem with MediaElement and it's that sometimes when i play some mp3 or wmv with MediaElment its NaturalDuration became Automatic !!!Frown and i can not get its Play time or anything of that media .
Please help me because my Application is finish and this problem is killing me .
Cry
AnswerRe: Please Help !!!!
soft2buy
20:07 27 Sep '09  
I guess this is what you are looking for:
http://msdn.microsoft.com/en-us/library/system.windows.media.mediatimeline.aspx[^]
Generalthis code is not working. What are the basic requirements to run this code?
Behlim
7:00 25 Mar '09  
i have VS 2008 with SP1 but i cannot play any movie through any WPF video player?
why
GeneralMedia Items added more than once
Member 3743453
9:49 25 Jan '09  
I add a media item. Then I add a second, different item, and the first one gets added again.

I think it's because of the line

foreach (MediaItem mi in mediaItems.Values)
lstMediaItems.Items.Add(mi);

In the media_drop(..) method.

The items are being added twice.

Adding a
lstMediaItems.Items.Clear();

Before that code seemed to do the trick for me.

Good work though matey.
GeneralRe: Media Items added more than once
Sacha Barber
22:44 25 Jan '09  
Fair enough its not perfect then. Frown

Glad you like it though

Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralRe: Media Items added more than once
Member 3743453
5:07 26 Jan '09  
Dont give me the sad face. It is perfect. Maybe I wanted the videos to be added twice... Smile

Seriously, good work. This application alone has helped me understand customising listboxs and parsing XML files, better than anything else.
GeneralRe: Media Items added more than once
Sacha Barber
5:47 26 Jan '09  
OK cool. have a Smile instead.

Sacha Barber
  • Microsoft Visual C# MVP 2008
  • Codeproject MVP 2008
Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My Blog : sachabarber.net

GeneralScreen Grab
cbm
14:21 5 Jan '09  
Is it possible to make a button and make it screen grab from the playing video?

how would that be done if the button has been added. What would the code look like?

thanks,
Christian

cbm.dk



Last Updated 13 Sep 2007 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010