MediaElement在自定义3D类中不显示

本文关键字:显示 3D 自定义 MediaElement | 更新日期: 2023-09-27 18:05:27

我试图在Viewport3d中显示视频流。当我通过xaml添加MediaElement时,视频播放没有问题;即使我将视频添加为ModelVisual3D后置代码,视频也能正常工作。然而,当我将视频抽象到一个类中时,视频就停止出现了。网络和本地视频文件都会发生这种情况。我尝试用x86和64位编译。有什么方法来解决这个问题吗?为什么会发生这种情况?

我有以下viewport:

<Viewport3D>
    <!-- Camera -->
    <Viewport3D.Camera>
        <PerspectiveCamera Position="0,0,100" LookDirection="0,0,-1" UpDirection="0,1,0" />
    </Viewport3D.Camera>
    <!-- Light -->
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <AmbientLight Color="White" />
        </ModelVisual3D.Content>
    </ModelVisual3D>
    <!-- this doesn't work -->
    <mediaElementTest:VideoControl />
    <!-- but this does? -->
    <!--<ModelVisual3D>
        <ModelVisual3D.Content>
            <GeometryModel3D>
                <GeometryModel3D.Geometry>
                    <MeshGeometry3D 
                        Positions="-100,-100,0 100,-100,0 100,100,0 -100,100,0"
                        TextureCoordinates="0,1 1,1 1,0 0,0"
                        TriangleIndices="0 1 2   0 2 3"
                        />
                </GeometryModel3D.Geometry>
                <GeometryModel3D.Material>
                    <DiffuseMaterial>
                        <DiffuseMaterial.Brush>
                            <VisualBrush>
                                <VisualBrush.Visual>
                                    <MediaElement Source="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" />
                                </VisualBrush.Visual>
                            </VisualBrush>
                        </DiffuseMaterial.Brush>
                    </DiffuseMaterial>
                </GeometryModel3D.Material>
            </GeometryModel3D>
        </ModelVisual3D.Content>
    </ModelVisual3D>-->
</Viewport3D>

VideoControl.xaml

<UIElement3D x:Class="MediaElementTest.VideoControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/>

VideoControl.xaml.cs

public partial class VideoControl
{
    public VideoControl()
    {
        InitializeComponent();
        Visual3DModel = CreateModel();
    }
    private GeometryModel3D CreateModel()
    {
        return new GeometryModel3D
        {
            Geometry = new MeshGeometry3D
            {
                Positions = new Point3DCollection
                {
                    new Point3D(-100, -100, 0),
                    new Point3D(100, -100, 0),
                    new Point3D(100, 100, 0),
                    new Point3D(-100, 100, 0)
                },
                TextureCoordinates = new PointCollection
                {
                    new Point(0, 1),
                    new Point(1, 1),
                    new Point(1, 0),
                    new Point(0, 0)
                },
                TriangleIndices = new Int32Collection
                {
                    0, 1, 2,
                    0, 2, 3
                }
            },
            Material = new DiffuseMaterial(new VisualBrush(new MediaElement
            {
                Source = new Uri("http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", UriKind.RelativeOrAbsolute)
            }))
        };
    }
}

MediaElement在自定义3D类中不显示

回答:自定义3D类中不显示MediaElement

对于你的问题,我认为根本原因是创建VideoControl的方法,我们需要为3D基元创建一个继承自UIElement3D的基类,并创建一个MediaElement实现,作为演示,这是我的示例:

ReusableUIElement3D.cs:

public abstract class ReusableUIElement3D : UIElement3D
{
    public static readonly DependencyProperty ModelProperty = DependencyProperty.Register("Model", typeof (Model3D),
        typeof (ReusableUIElement3D), new PropertyMetadata(ModelPropertyChanged));
    public Model3D Model
    {
        get
        {
            return (Model3D)GetValue(ModelProperty);
        }
        set
        {
            SetValue(ModelProperty, value);
        }
    }
    protected override void OnUpdateModel()
    {
        this.Model = this.CreateElementModel();
    }
    protected virtual Model3D CreateElementModel()
    {
        return null;
    }
    protected static void VisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ReusableUIElement3D reusableElement = (ReusableUIElement3D)d;
        reusableElement.InvalidateModel();
    }
    protected static void ModelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ReusableUIElement3D reusableElement = (ReusableUIElement3D)d;
        reusableElement.Visual3DModel = reusableElement.Model;
    }
}

VideoControl.cs

public class VideoControl : ReusableUIElement3D
{
    protected override Model3D CreateElementModel()
    {
        Model3DGroup cubeModel = new Model3DGroup();
        cubeModel.Children.Add(CreateModel());
        return cubeModel;
    }
    private GeometryModel3D CreateModel()
    {
        return new GeometryModel3D
        {
            Geometry = new MeshGeometry3D
            {
                Positions = new Point3DCollection
            {
                new Point3D(-100, -100, 0),
                new Point3D(100, -100, 0),
                new Point3D(100, 100, 0),
                new Point3D(-100, 100, 0)
            },
                TextureCoordinates = new PointCollection
            {
                new Point(0, 1),
                new Point(1, 1),
                new Point(1, 0),
                new Point(0, 0)
            },
                TriangleIndices = new Int32Collection
            {
                0, 1, 2,
                0, 2, 3
            }
            },
            Material = new DiffuseMaterial(new VisualBrush(new MediaElement
            {
                Source = new Uri("http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", UriKind.RelativeOrAbsolute),
            }))
        };
    }
}

使用VideoControl类,像这样:

<Viewport3D>
    <!-- Camera -->
    <Viewport3D.Camera>
        <PerspectiveCamera Position="0,0,100" LookDirection="0,0,-1" UpDirection="0,1,0" />
    </Viewport3D.Camera>
    <!-- Light -->
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <AmbientLight Color="White" />
        </ModelVisual3D.Content>
    </ModelVisual3D>
    <ModelVisual3D x:Name="UIElement3DContainer">
        <mediaElementTest:VideoControl />
    </ModelVisual3D>
</Viewport3D>