使用MediaElement播放来自流的视频

9

是否可以使用WPF的MediaElement来播放从System.IO.Stream对象中流式传输的视频?该Stream对象是从存储媒体文件的WCF服务中检索的。

5个回答

17

在任何人浪费时间之前,需要指出的是:在WPF应用程序中托管Silverlight MediaElement是不可能的。原因是它是PresentationFramework.dll(WPF不可避免)和System.Windows.dll(Silverlight版本)中一系列具有相同名称和相同命名空间但是却是不同类型的类型之一。

(有人应该向微软解释为什么我们需要命名空间!)


1
这是真的。不幸的是,我不得不通过艰辛的方式发现这一点。:( - rafale
4
我知道这个回答已经一年了,但是"在同一个命名空间中有多个相同名称的不同类型"不正是参考别名存在的原因吗? - Damien_The_Unbeliever
1
始终可以制作Silverlight网站并在其中使用MediaElement,在WPF应用程序中添加WebBrowser控件,并将其源指向Silverlight网站即可完成。 - NoWar
是的@Damien_The_Unbeliever,一开始我也这么想 - 但这取决于它的实际效果,我见过类似技巧不可能实现的情况。虽然我会说这仍然“可能”通过一些黑客手段实现。尽管我还没有尝试过,看起来很麻烦。 - NSGaga-mostly-inactive

14

也许已经有点晚了,但如果你仍在寻找答案,希望这能帮到你。

是的,你可以使用WPF媒体元素从内存流中播放视频。

我使用了一个名为Boxed App的第三方组件,千万感谢BoxedApp - http://www.boxedapp.com/boxedappsdk/

我必须稍微修改一下代码才能让它支持byte[]。将以下构造函数复制到来自BoxedApp的CustomFileStream类中即可。

public CustomFileStream(byte[] data)
{
    _Stream = new MemoryStream(data);
    _Length = _Stream.Length;
    _data = data;
    _Offset = 0;
}

创建一个WPF应用程序,添加一个媒体元素和一个按钮,并复制以下代码:

public MainWindow()
{
    BoxedAppSDK.NativeMethods.BoxedAppSDK_Init();

    InitializeComponent();
}

private void button2_Click(object sender, RoutedEventArgs e)
{
    var MyFileStream = new CustomFileStream(File.ReadAllBytes(@"wildlife.wmv"));

    IntPtr ptr = BoxedAppSDK.NativeMethods.BoxedAppSDK_CreateVirtualFileBasedOnIStream(
            @"1.wmv",
            BoxedAppSDK.NativeMethods.EFileAccess.GenericWrite,
            BoxedAppSDK.NativeMethods.EFileShare.Read,
            IntPtr.Zero,
            BoxedAppSDK.NativeMethods.ECreationDisposition.New,
            BoxedAppSDK.NativeMethods.EFileAttributes.Normal,
            IntPtr.Zero,
            MyFileStream);

    using (new SafeFileHandle(ptr, true))
    {
        mediaElement1.Source = new Uri(Path.GetFullPath("1.wmv"));
        mediaElement1.LoadedBehavior = MediaState.Manual;
        mediaElement1.Play();
    }
}
  • 如果使用封装的应用程序,请按照示例操作,就可以进入快乐的世界了...

对于QT播放器也是同样的情况。


7

如果您可以通过http-URL (GET)使WCF传递媒体对象,那么您只需将该URL分配给MediaElement.Source属性即可 - 参见http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.source.aspx

对于这种URL不可用/不可能的情况:

目前无法分配流 - 尽管有一些黑客技巧可以实现,例如基于DirectShow的示例,请参见http://social.msdn.microsoft.com/forums/en-US/wpf/thread/6191ef1a-0010-4294-a5b4-451bbadca33a/http://jmorrill.hjtcentral.com/Home/tabid/428/EntryId/15/WPF-Hackery-Part-I.aspx

另一个选择是以某种方式托管Silverlight MediaElement并使用SetSource方法,该方法可以接受流并播放...请参见http://silverlightviewport.codeplex.com/SourceControl/list/changesetshttp://msdn.microsoft.com/en-us/library/cc190669%28v=vs.95%29.aspx


5

3
我可以看到一个WPF应用程序运行VLC作为ActiveX组件的示例吗?在实际尝试之前,我想看看它是什么样子以及运行它需要哪些步骤。 - rafale
1
嗨,斯图尔特,你能把使用VLC的示例发布在某个地方让我看看吗?谢谢。 - Toan Nguyen

0

由于WPF媒体元素内部使用Windows Media Player,因此如果您将媒体播放器的缓冲设置从默认缓冲设置更改为自定义,则需要进行以下操作:打开Windows Media Player -> 工具 -> 选项 -> 性能。

当您选择“缓冲”选项并将“内容秒数”设置为2时,将在媒体播放器下添加以下注册表值。 HKEY_CURRENT_USER\Software\Microsoft\MediaPlayer\Preferences UseDefaultBufferTime=0 CustomBufferTime=2000

您可以使用dotnet注册表类进行更改。 请参考此链接: https://social.msdn.microsoft.com/Forums/vstudio/en-US/1b4b8fb9-ff8f-4861-8e99-4a7a4fc75596/setting-windows-media-player-properties-in-wpf?forum=wpf#ac879a7f-37bc-4ccc-854d-ab6e047086e5


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接