如何在源为https uri时播放wpf MediaElement

时间:2014-08-01 13:59:05

标签: c# wpf nullreferenceexception mediaelement

在wpf独立应用程序(.exe)中,我在MainWindow中包含了一个MediaElement

<Window x:Class="Media.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Main Window" Height="350" Width="525">
    <Grid>
        <MediaElement x:Name="Player" Stretch="Uniform" LoadedBehavior="Manual" UnloadedBehavior="Stop"/>
    </Grid>
</Window>

从后面的代码我将Source设置为任何https Uri:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var source = new Uri("https://stream_which_can_be_opened_with_windows_media_player.com", UriKind.Absolute);
        Player.Source = source;
        Player.Play();
    }
}

调用Play()方法时,会抛出NullReferenceException而不是播放媒体内容。 MediaElement已初始化,NullReferenceExceptionPlay()方法抛出,请参见下文。

可以在Windows Media Player(文件 - &gt;打开网址)中打开视频的相同Uri。

问题似乎出现在MediaPlayerState.OpenMedia方法(MediaElement内部使用的对象)中,该方法试图检查从SecurityHelper.ExtractUriForClickOnceDeployedApp检索到的appDeploymentUri是否具有HTTPS方案。该应用程序未与ClickOnce一起部署(它有一个独立的安装程序),appDeploymentUri为null,因此为NullReferenceException

这是来自PresentationFramework.dll,System.Windows.Media.MediaPlayerState.OpenMedia

    if (SecurityHelper.AreStringTypesEqual(uriToOpen.Scheme, Uri.UriSchemeHttps))
    {
        // target is HTTPS. Then, elevate ONLY if we are NOT coming from HTTPS (=XDomain HTTPS app to HTTPS media disallowed)

        //source of the issue
        Uri appDeploymentUri = SecurityHelper.ExtractUriForClickOnceDeployedApp();
        //appDeploymentUri is null
        if (!SecurityHelper.AreStringTypesEqual(appDeploymentUri.Scheme, Uri.UriSchemeHttps))

有没有人有任何解决方案/解决方案才能使其正常工作?

1 个答案:

答案 0 :(得分:5)

我一直在使用MediaElement很多次,我可以说老实说这是一个糟糕的错误,并且比我遇到的任何其他WPF组件都有更多错误。它不仅存在缺陷,而且缺少Silverlight的许多功能。 HTTPS适用于Silverlight。

我通过了代码,但我没有看到改变它的方法。也许有一些MAD反射黑客会允许你这样做,但这是黑客攻击,我不建议这样做。 Ps,它似乎是一个真正的错误,也许让微软的人知道它。

最简单的解决方案是使用OWIN制作“内存网络服务器”。然后,您可以流式传输http://localhost:1337并打包基础https://内容。 https内容仍然是安全的,因为您从“内存网络服务器”流式传输,并且没有“真正的”网络请求。它应该仍然是有效的&amp;安全