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

时间:2015-07-26 00:37:22

标签: c# wpf video 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开始正常运行o_O

好的,但它是我的机器。如何处理客户端的PC?

4 个答案:

答案 0 :(得分:2)

看起来MediaElement.SetSource()除了源之外还有一个指定MIME类型的选项。代码从https://msdn.microsoft.com/en-us/library/windows/apps/br244338.aspx逐字解除。

async private void SetLocalMedia()
{
    var openPicker = new Windows.Storage.Pickers.FileOpenPicker();

    openPicker.FileTypeFilter.Add(".wmv");
    openPicker.FileTypeFilter.Add(".mp4");
    openPicker.FileTypeFilter.Add(".wma");
    openPicker.FileTypeFilter.Add(".mp3");

    var file = await openPicker.PickSingleFileAsync();

    var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);

    // mediaControl is a MediaElement defined in XAML
    if (null != file)
    {
        mediaControl.SetSource(stream, file.ContentType);

        mediaControl.Play();
    }
}

答案 1 :(得分:2)

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

来自https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680%28v=vs.85%29.aspx

  

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

     

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

此处给出了如何创建符号链接的示例: https://stackoverflow.com/a/11156870/1095741。我修改了symbolicLinkfileName以符合您的问题:

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);
        }
    }
}

答案 2 :(得分:0)

我发现的解决方法是在尝试播放视频文件之前注册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" />

答案 3 :(得分:-2)

我会回答这个问题,并且在这个答案中,我并不想贬低你的智慧。 每当您在代码中使用不同的文件扩展名时,您需要确保文件扩展名与文件本身完全相同。

示例:

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

Which one would work?

在图片中,除了文件扩展名外,我有2个相同的文件。 使用第一个图像和代码示例,它们都反映了mp4并且将正常工作。 第二个图像和代码示例都反映了.xyz扩展名,并且可以正常工作。

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