Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF MediaElement-具有自定义扩展名的播放文件_C#_Wpf_Video_Mediaelement - Fatal编程技术网

C# WPF MediaElement-具有自定义扩展名的播放文件

C# WPF MediaElement-具有自定义扩展名的播放文件,c#,wpf,video,mediaelement,C#,Wpf,Video,Mediaelement,我有自定义扩展名的视频文件。它们是正确编码的MP4文件。当我尝试使用MediaElement播放这样的文件时,什么都没有发生: <MediaElement x:Name="UxVideo" Source="D:\111.xyz" /> 但是,当我重命名文件扩展名时,它可以正常工作: <MediaElement x:Name="UxVideo" Source="D:\111.mp4" /> 似乎MediaElement使用文件扩展名来确定视频格式。使用自定义扩展

我有自定义扩展名的视频文件。它们是正确编码的MP4文件。当我尝试使用
MediaElement
播放这样的文件时,什么都没有发生:

<MediaElement x:Name="UxVideo" Source="D:\111.xyz" />

但是,当我重命名文件扩展名时,它可以正常工作:

<MediaElement x:Name="UxVideo" Source="D:\111.mp4" />

似乎
MediaElement
使用文件扩展名来确定视频格式。使用自定义扩展名制作
MediaElement
播放文件是否有解决办法?也许有其他的控制来实现我的需求

我不适合在运行时重命名文件,因为其他应用程序可能会使用它。我不能复制文件,因为它可能有很大的尺寸

更新

我已将文件扩展名与Windows Media Player关联,并且
MediaElement
开始正常工作


好的,但这是我的机器。如何处理客户的电脑?

我会回答这个问题,我不会贬低你的智慧。 只要代码中有不同的文件扩展名,就需要确保文件本身的文件扩展名完全相同

例如:

<MediaElement x:Name="UxVideo" Source="D:\BABYMETAL - Megitsune.Mp4" />
<MediaElement x:Name="UxVideo" Source="D:\BABYMETAL - Megitsune.XYZ" />

在图片中,我有两个文件,除了文件扩展名外,其他文件都是相同的。 对于第一个图像和代码示例,它们都反映了mp4并将正常工作。 第二个图像和代码示例都反映了.xyz扩展,并将正常工作


答案很简单,请确保文件扩展名和代码扩展名匹配。

看起来像是
MediaElement。SetSource()
有一个选项,用于指定源之外的MIME类型。代码逐字逐句地从中删除


我发现的解决方法是在尝试播放视频文件之前注册Windows Media Player的自定义文件扩展名。因此,我们需要在应用程序启动时执行以下代码:

private void RegisterFileExtension(string fileName)
{
    var ext = Path.GetExtension(fileName);
    var key = Registry.CurrentUser.CreateSubKey(
        $@"Software\Microsoft\MediaPlayer\Player\Extensions\{ext}"); // C# 6.0
    key.SetValue("Permissions", 1);
    key.SetValue("Runtime", 1);
}
此代码在注册表中创建所需的键,与使用Windows Media Player手动打开文件时得到的相同

然后,
MediaElement
播放视频:

<MediaElement Source="D:\111.xyz" />

似乎可以使用符号链接欺骗MediaElement。这不会产生大量的存储开销,但创建的任何链接都应该在使用后删除,以保持一切整洁

发件人:

符号链接是指向另一个文件的文件系统对象 系统对象。指向的对象称为目标

符号链接对用户是透明的;链接显示正常 文件或目录,并可由用户或应用程序执行操作 以完全相同的方式

此处给出了如何创建符号链接的示例: . 我已经修改了
symbolicink
fileName
以匹配您的问题:

namespace ConsoleApplication
{
    class Program
    {
        [DllImport("kernel32.dll")]
        static extern bool CreateSymbolicLink(
        string lpSymlinkFileName, string lpTargetFileName, SymbolicLink dwFlags);

        enum SymbolicLink
        {
            File = 0,
            Directory = 1
        }

        static void Main(string[] args)
        {
            string symbolicLink = @"D:\111.mp4";
            string fileName = @"D:\111.xyz";

            using (var writer = File.CreateText(fileName))
            {
                writer.WriteLine("Hello World");
            }

            CreateSymbolicLink(symbolicLink, fileName, SymbolicLink.File);
        }
    }
}

看起来
SetSource
方法仅适用于Silverlight?不,你说得对!WPF的MediaElement没有可用的SetSource。我会暂时把答案放在那里,但建议在正确答案的下方进行向下投票。无论如何,谢谢你的选择。也许WPF也有类似的功能。
MediaElement
利用较低级别的API,这些API依赖于扩展、MIME类型和特定格式处理程序之间的映射。在您的情况下,您应该以编程方式覆盖内容类型,跳过系统范围的设置。显然,像.XYZIll这样的扩展可能没有正确的注册。请将此答案留给那些不知道您需要这样做的人。
namespace ConsoleApplication
{
    class Program
    {
        [DllImport("kernel32.dll")]
        static extern bool CreateSymbolicLink(
        string lpSymlinkFileName, string lpTargetFileName, SymbolicLink dwFlags);

        enum SymbolicLink
        {
            File = 0,
            Directory = 1
        }

        static void Main(string[] args)
        {
            string symbolicLink = @"D:\111.mp4";
            string fileName = @"D:\111.xyz";

            using (var writer = File.CreateText(fileName))
            {
                writer.WriteLine("Hello World");
            }

            CreateSymbolicLink(symbolicLink, fileName, SymbolicLink.File);
        }
    }
}