音乐视频盒 (WPF)





4.00/5 (4投票s)
本文解释了如何使用 Windows Presentation Foundation 3D 几何和媒体类创建音乐视频盒,以播放用户选择的音乐专辑。
引言
本文解释了如何使用 Windows Presentation Foundation 3D 几何和媒体类创建音乐视频盒,以播放用户选择的音乐专辑。
引言
这款音乐视频盒的设计方式是存储了三张不同专辑的音乐曲目,用户可以选择一张专辑和他们想播放的曲目。 专辑列表显示在左侧面板上,每张专辑的曲目以图片形式显示在 3D 立方体的侧面,该立方体旋转,方便用户选择他们喜欢的曲目。
最初,屏幕看起来像这样
该应用程序的中心是 3D 立方体,它显示当前专辑的曲目图片,并以顺时针方向旋转。
选择一张专辑(例如:印度灵修音乐)后,立方体呈现不同的外观,带有代表专辑中曲目的图片,如下所示
点击图片后,会打开另一个窗口,为您播放相应的视频,如下所示
WPF – 3D 几何和材质
立方体的侧面是使用 MeshGeometry3D
类单独创建的,该类构建 3D 形状。 它允许我们指定位置、法线和纹理坐标信息。
<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 " />
立方体的侧面由 Material
组成,在本例中为 DiffuseMaterial
,它允许应用程序应用 2D 画笔,例如 SolidColorBrush
或 TileBrush
,用于漫反射光照的 3D 模型。 对于列表中选择的专辑,此 Material
被动态地应用于侧面,ImageBrush
用于包含视频曲目的专辑(灵修和 Taare Zameen Par),LinearGradientBrush
用于未选择或只有一首视频的专辑(流行/摇滚)。
<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>
几何和材质的细节都在 app.xaml 中编码为应用程序资源。
用于 3D 图形的 XAML
<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
HitTest 是用户点击 3D 立方体侧面时采取的操作。 这在 ChooseTrack
方法中实现,其中鼠标位置参数从 MouseButtonEventArgs
中检索,我们在 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);
}
HitTest 方法将 ViewPort
对象作为参数以及回调方法 HTResult
和位置参数。 在回调方法 HTResult
中,我们使用 RayMeshGeometry3DHitTestResult
对象并调用 ModelHit
以获取用户点击鼠标的三维形状的 GeometryModel3D
对象。
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;
}
有两个辅助方法,SetTrack
用于选择曲目,PlayTrack
用于在窗口中打开 MediaElement
以播放视频。 在 SetTrack
方法中,创建一个 MusicPlayer
实例,并通过调用 FindAlbum
和 FindTrack
方法分别设置属性 CurrentAlbum
和 CurrentTrackPath
。
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);
}
}
在 PlayTrack
方法中,MusicPlayer
显示为一个对话框,如下所示
public void PlayTrack()
{
mplayer.ShowDialog();
}
选择专辑后,立方体侧面的图片会发生变化,SetMaterial
方法用于此目的。 例如,如下调用此方法
setSideMaterial("TaareMaterial");
将为立方体的每一侧应用在 App.xaml 中定义的相应材质资源。
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"];
}
音乐视频盒的 Album 类
随此应用程序提供的音乐视频存储在应用程序文件夹内的子文件夹中。 视频文件的名称被检索并存储在 AlbumCollection
类的实例中。 AlbumCollection
类是一个泛型类,类型为 Album
,包含两个属性,即 AlbumName
和 TrackPath
,以及一个字符串数组。
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;
}
结论
这个带有三张专辑的音乐视频盒是使用 WPF 的 3D 技术创建的。