WPF MediaElement - 播放具有自定义扩展名的文件
WPF MediaElement - play file with custom extension
我有自定义扩展名的视频文件。它们是正确编码的 MP4 文件。当我尝试使用 MediaElement
播放此类文件时,没有任何反应:
<MediaElement x:Name="UxVideo" Source="D:1.xyz" />
但是,当我重命名文件扩展名时它工作正常:
<MediaElement x:Name="UxVideo" Source="D:1.mp4" />
似乎MediaElement
使用文件扩展名来确定视频格式。是否有任何解决方法可以让 MediaElement
播放带有自定义扩展名的文件?也许还有其他控件可以实现我的需要?
我不适合在运行时重命名文件,因为其他应用程序可能会使用它。而且我无法复制文件,因为它可能有很大的尺寸。
更新
我已将我的文件扩展名与 Windows 媒体播放器相关联,MediaElement
开始正常工作 o_O
好的,但这是我的机器。如何处理客户的 PC?
我会回答这个问题,并且有了这个答案,我并不是想贬低你的智慧。
每当您在代码中使用不同的文件扩展名时,您都希望确保文件扩展名与文件本身完全相同。
示例:
<MediaElement x:Name="UxVideo" Source="D:\BABYMETAL - Megitsune.Mp4" />
<MediaElement x:Name="UxVideo" Source="D:\BABYMETAL - Megitsune.XYZ" />
在图片中,我有2个文件,除了文件扩展名外都是一样的。
对于第一个图像和代码示例,它们都反映了 mp4 并且可以正常工作。
第二张图片和代码示例都反映了 .xyz 扩展名,并且可以正常工作。
简单回答,确保文件和代码扩展名匹配。
看起来 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();
}
}
我发现的解决方法是在尝试播放视频文件之前为 Windows 媒体播放器注册自定义文件扩展名。因此,我们需要在应用程序启动时执行以下代码:
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 媒体播放器手动打开文件时获得的密钥相同。
然后,MediaElement
可以正常播放视频:
<MediaElement Source="D:1.xyz" />
似乎可以使用符号 link 来欺骗 MediaElement。这不会产生大量的存储开销,但是创建的任何 links 应该在使用后删除以保持一切整洁。
来自 https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680%28v=vs.85%29.aspx :
A symbolic link is a file-system object that points to another file
system object. The object being pointed to is called the target.
Symbolic links are transparent to users; the links appear as normal
files or directories, and can be acted upon by the user or application
in exactly the same manner.
此处给出了如何创建符号 link 的示例:
。我修改了 symbolicLink
和 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:1.mp4";
string fileName = @"D:1.xyz";
using (var writer = File.CreateText(fileName))
{
writer.WriteLine("Hello World");
}
CreateSymbolicLink(symbolicLink, fileName, SymbolicLink.File);
}
}
}
我有自定义扩展名的视频文件。它们是正确编码的 MP4 文件。当我尝试使用 MediaElement
播放此类文件时,没有任何反应:
<MediaElement x:Name="UxVideo" Source="D:1.xyz" />
但是,当我重命名文件扩展名时它工作正常:
<MediaElement x:Name="UxVideo" Source="D:1.mp4" />
似乎MediaElement
使用文件扩展名来确定视频格式。是否有任何解决方法可以让 MediaElement
播放带有自定义扩展名的文件?也许还有其他控件可以实现我的需要?
我不适合在运行时重命名文件,因为其他应用程序可能会使用它。而且我无法复制文件,因为它可能有很大的尺寸。
更新
我已将我的文件扩展名与 Windows 媒体播放器相关联,MediaElement
开始正常工作 o_O
好的,但这是我的机器。如何处理客户的 PC?
我会回答这个问题,并且有了这个答案,我并不是想贬低你的智慧。 每当您在代码中使用不同的文件扩展名时,您都希望确保文件扩展名与文件本身完全相同。
示例:
<MediaElement x:Name="UxVideo" Source="D:\BABYMETAL - Megitsune.Mp4" />
<MediaElement x:Name="UxVideo" Source="D:\BABYMETAL - Megitsune.XYZ" />
在图片中,我有2个文件,除了文件扩展名外都是一样的。 对于第一个图像和代码示例,它们都反映了 mp4 并且可以正常工作。 第二张图片和代码示例都反映了 .xyz 扩展名,并且可以正常工作。
简单回答,确保文件和代码扩展名匹配。
看起来 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();
}
}
我发现的解决方法是在尝试播放视频文件之前为 Windows 媒体播放器注册自定义文件扩展名。因此,我们需要在应用程序启动时执行以下代码:
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 媒体播放器手动打开文件时获得的密钥相同。
然后,MediaElement
可以正常播放视频:
<MediaElement Source="D:1.xyz" />
似乎可以使用符号 link 来欺骗 MediaElement。这不会产生大量的存储开销,但是创建的任何 links 应该在使用后删除以保持一切整洁。
来自 https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680%28v=vs.85%29.aspx :
A symbolic link is a file-system object that points to another file system object. The object being pointed to is called the target.
Symbolic links are transparent to users; the links appear as normal files or directories, and can be acted upon by the user or application in exactly the same manner.
此处给出了如何创建符号 link 的示例:
。我修改了 symbolicLink
和 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:1.mp4";
string fileName = @"D:1.xyz";
using (var writer = File.CreateText(fileName))
{
writer.WriteLine("Hello World");
}
CreateSymbolicLink(symbolicLink, fileName, SymbolicLink.File);
}
}
}