12,753,195 members (36,372 online)
Add your own
alternative version

#### Stats

26.9K views
1.7K downloads
23 bookmarked
Posted 7 Aug 2009

# Music Video Box (WPF)

, 10 Aug 2009 CPOL
 Rate this:
Please Sign up or sign in to vote.
This article explains the creation of a Music Video Box using Windows Presentation Foundation 3D Geometry and Media classes to play music albums as chosen by the user.

## Introduction

This article explains the creation of a Music Video Box using the Windows Presentation Foundation 3D Geometry and Media classes to play music albums as chosen by the user.

## Introduction

This Music Video Box is designed in a way that it stores music tracks of three different albums and the user can select an album and the track he wants to play. While the list of albums appears on the left side panel, the tracks for each album are represented as pictures on the sides of a 3D cube that rotates for easier selection of the track the user prefers.

Initially, the screen looks like this:

The epicenter of this application is the 3D cube that displays pictures of the tracks of the current album, and it rotates in clockwise direction.

Upon selection of an album (e.g.: Hindu Devotional), the cube takes a different look with pictures representing the tracks in the album, as below:

Upon clicking the picture, another window opens up that plays the corresponding video for you, as below:

## WPF – 3D Geometry and Material

The sides of the cubes are created separately using the `MeshGeometry3D` class that builds a 3D shape. It allows us to specify the position, normal, and texture coordinate information.

```<MeshGeometry3D x:Key="CubeSide01"
TriangleIndices="0,1,2 3,4,5"
Normals="-1,0,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 "
TextureCoordinates="0,1 0,0 1,0 1,0 1,1 0,1 "
Positions="-0.5,0.5,-0.5 -0.5,-0.5,-0.5 -0.5,-0.5,0.5 -0.5,
-0.5,0.5 -0.5,0.5,0.5 -0.5,0.5,-0.5 " />```

The sides of the cube compose of a `Material`, `DiffuseMaterial` in this case, that allows the application of a 2-D brush, like a `SolidColorBrush` or `TileBrush`, for a diffusely-lit 3-D model. For the album selected in the list, this `Material` is applied on the sides dynamically, `ImageBrush` for the albums (Devotional and Taare Zameen Par) that contain the video tracks, and `LinearGradientBrush` for no selection or an album (Pop/Rock) that has only one video.

```<MaterialGroup x:Key="TaareMaterial1">
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<ImageBrush Stretch="Fill"
ImageSource="images\Taare\Taare1.jpg"
TileMode="None" ViewportUnits="Absolute"
Viewport="0 0 1 1" AlignmentX="Left"
AlignmentY="Top" Opacity="1.000000" />
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>```

Both the Geometry and Material specifics are coded as Application Resources in app.xaml.

## XAML for 3D Graphics

```<Viewport3D  MouseDown="myViewport_MouseDown"
ClipToBounds="True" Width="600"
Height="400" Name="myViewport" Focusable="True" >
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera"
FarPlaneDistance="15" LookDirection="0,0,1"
UpDirection="0,1,0" NearPlaneDistance="1"
Position="0,0,-3" FieldOfView="50" />
</Viewport3D.Camera>
<ModelVisual3D x:Name="topModelVisual3D">
<ModelVisual3D.Children>
<ModelVisual3D>
<ModelVisual3D.Content>
...............
...............
<ModelVisual3D x:Name="side1ModelVisual">
<ModelVisual3D.Content>
<GeometryModel3D x:Name="side1GeometryModel3D"
Geometry="{StaticResource CubeSide01}"
Material="{StaticResource InitMaterial1}"
BackMaterial="{StaticResource InsideMaterial}"/>
</ModelVisual3D.Content>
</ModelVisual3D>```

## HitTest

The HitTest is the action that is taken when the user clicks on a side of the 3D cube. This is implemented in the `ChooseTrack` method wherein the mouse position parameters are retrieved from the `MouseButtonEventArgs` and we test for a result in the `ViewPort3D`.

```public void ChooseTrack(object sender, System.Windows.Input.MouseButtonEventArgs args)
{
if (listboxAlbum.SelectedIndex <= 0)
return;
Point mouseposition = args.GetPosition(myViewport);
PointHitTestParameters pointparams = new PointHitTestParameters(mouseposition);

//test for a result in the Viewport3D
VisualTreeHelper.HitTest(myViewport, null, HTResult, pointparams);
}```

The HitTest method takes the `ViewPort` object as a parameter along with a callback method `HTResult` and the position parameters. It is in the callback method `HTResult`, we use the `RayMeshGeometry3DHitTestResult` object and calls `ModelHit` to get the `GeometryModel3D` object for the three-dimensional shape where the user hits the mouse.

```public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)
{
RayHitTestResult rayResult = rawresult as RayHitTestResult;
if (rayResult != null)
{
RayMeshGeometry3DHitTestResult rayMeshResult =
rayResult as RayMeshGeometry3DHitTestResult;
if (rayMeshResult != null)
{
GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;
SetTrack(hitgeo);
PlayTrack();
}
}

return HitTestResultBehavior.Stop;
}```

There are two helper methods, `SetTrack` to select the track and `PlayTrack` to open the `MediaElement` in a window to play the video. In the `SetTrack` method, a `MusicPlayer` instance is created, and the properties `CurrentAlbum` and `CurrentTrackPath` are set by calling the `FindAlbum` and `FindTrack` methods, respectively.

```public void SetTrack(GeometryModel3D hitgeo)
{
mplayer = new MusicPlayer();
mplayer.currentAlbum = AvailTracks.FindAlbum(listboxAlbum.SelectedIndex - 1);
// For pop/rock, only one video is placed. On clicking any picture
// on any of the 6 sides, the same video plays.
if (listboxAlbum.SelectedIndex == 2)
{
mplayer.currtrapath = AvailTracks.FindTrack(listboxAlbum.SelectedIndex - 1, 0);
return;
}
if (hitgeo.Geometry==MeshGeometry3D)Application.Current.Resources["CubeSide01"])
{
mplayer.currtrapath =AvailTracks.FindTrack(listboxAlbum.SelectedIndex - 1, 0);
}
else if (hitgeo.Geometry==(MeshGeometry3D)Application.Current.Resources["CubeSide02"])
{
mplayer.currtrapath =AvailTracks.FindTrack(listboxAlbum.SelectedIndex - 1, 1);
}
else if (hitgeo.Geometry == (MeshGeometry3D)Application.Current.Resources["CubeSide03"])
{
mplayer.currtrapath = AvailTracks.FindTrack(listboxAlbum.SelectedIndex - 1, 2);
}
else if (hitgeo.Geometry == (MeshGeometry3D)Application.Current.Resources["CubeSide04"])
{
mplayer.currtrapath = AvailTracks.FindTrack(listboxAlbum.SelectedIndex - 1, 3);
}
else if (hitgeo.Geometry == (MeshGeometry3D)Application.Current.Resources["CubeSide05"])
{
mplayer.currtrapath = AvailTracks.FindTrack(listboxAlbum.SelectedIndex - 1, 4);
}
else if (hitgeo.Geometry == (MeshGeometry3D)Application.Current.Resources["CubeSide06"])
{
mplayer.currtrapath = AvailTracks.FindTrack(listboxAlbum.SelectedIndex - 1, 5);
}
}```

In the `PlayTrack` method, the `MusicPlayer` is shown as a dialog as coded below:

```public void PlayTrack()
{
mplayer.ShowDialog();
}```

On selecting an album, the pictures of the sides of the cube changes, and the method `SetMaterial` is used for this purpose. For example, calling this method as below:

`setSideMaterial("TaareMaterial");`

would apply the corresponding material resource defined in App.xaml for each side of the cube.

```public void setSideMaterial(string materialKey)
{
side1GeometryModel3D.Material =
(MaterialGroup) Application.Current.Resources[materialKey+"1"];
side2GeometryModel3D.Material =
(MaterialGroup) Application.Current.Resources[materialKey+"2"];
side3GeometryModel3D.Material =
(MaterialGroup) Application.Current.Resources[materialKey+"3"];
side4GeometryModel3D.Material =
(MaterialGroup) Application.Current.Resources[materialKey+"4"];
side5GeometryModel3D.Material =
(MaterialGroup) Application.Current.Resources[materialKey+"5"];
side6GeometryModel3D.Material =
(MaterialGroup) Application.Current.Resources[materialKey+"6"];
}```

## Music Video Box’s Album class

The music videos supplied along with this application are stored in a sub-folder inside the application folder. The names of the video files are retrieved and are stored in the instances of the `AlbumCollection` class. The `AlbumCollection` class is a generic class of type `Album` that contains two properties namely `AlbumName` and `TrackPath`, and an array of strings.

```public static class AlbumList
{
public static AlbumCollection CreateAlbums()
{
string[] Devotelist = System.IO.Directory.GetFiles(@"e:\bala\music " +
@"video box\tracks\devotional", "*.wmv");
string[] PopRocklist = System.IO.Directory.GetFiles(@"e:\bala\music " +
@"video box\tracks\poprock", "*.wmv");
string[] Taarelist = System.IO.Directory.GetFiles(
@"e:\bala\music video box\tracks\taaree", "*.wmv");
AlbumCollection ac = new AlbumCollection();
ac.Add(new Album("Devotional", Devotelist));
ac.Add(new Album("Pop/Rock", PopRocklist));
ac.Add(new Album("Taare Zameen Par", Taarelist));
return ac;
}```

## Conclusion

This Music Video Box with three albums is created using WPF’s 3D technologies.

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 Founder BB Systems CIT-GPNP India
No Biography provided

 Pro

## Comments and Discussions

 View All Threads First Prev Next
 Play video so slow! Member 14564661-Nov-09 22:39 Member 1456466 1-Nov-09 22:39
 Last Visit: 31-Dec-99 19:00     Last Update: 21-Feb-17 23:46 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170217.1 | Last Updated 10 Aug 2009
Article Copyright 2009 by Balamurali Balaji
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid