使用 MediaElement 从 Stream 播放视频
Posted
技术标签:
【中文标题】使用 MediaElement 从 Stream 播放视频【英文标题】:Using MediaElement to play video from Stream 【发布时间】:2011-10-30 08:41:52 【问题描述】:是否可以使用 WPF MediaElement 从 System.IO.Stream 对象播放流视频?正在从存储媒体文件的 WCF 服务中检索 Stream 对象。
【问题讨论】:
【参考方案1】:在任何人浪费时间自己发现这一点之前:不可能在 WPF 应用程序中托管 Silverlight MediaElement。原因是它是出现在 PresentationFramework.dll(WPF 不可避免)和 System.Windows.dll(Silverlight 版本)中具有相同名称和相同命名空间但类型不同的众多类型之一。 (有人应该解释为什么我们有微软的命名空间!)
【讨论】:
这是真的。不幸的是,我不得不以艰难的方式找到这一点。 :( 我知道这是一个多年前的答案,但“在同一个命名空间中具有相同名称的多个不同类型”不是引用别名存在的原因吗? 始终可以创建 Silverlight 网站并在其中使用 MediaElement,并在 WPF 应用程序中将带有源的 WebBrowser 控件添加到该 Silverlight 网站并完成。 是的 @Damien_The_Unbeliever 我最初的想法 - 但这取决于它如何发挥作用,而且我见过类似技巧不可能的情况。尽管我会说这仍然“可能”是可能的,但需要一些黑客攻击。不过没试过,好像有点麻烦【参考方案2】:可能为时已晚,如果您仍在寻找答案,希望这可能会有所帮助。
是的,您可以使用 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 Player 也是如此。
【讨论】:
【参考方案3】:如果您可以让 WCF 通过 http-URL (GET)
传递媒体对象,那么您只需将该 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/changesets 和http://msdn.microsoft.com/en-us/library/cc190669%28v=vs.95%29.aspx
【讨论】:
【参考方案4】:我知道这不是您要求的,但您可以在 WPF 的窗口内托管 VLC ActiveX 组件,然后使用该 VLC 控件连接到流并显示流。这就是我通过 WPF 进行流式处理的方式。
编辑:this page has an example of how to host an ActiveX control inside WPF
【讨论】:
我可以看到一个 WPF 应用程序的示例,该应用程序将 VLC 作为 ActiveX 组件运行吗?在我真正开始之前,我想看看它的外观以及运行它所涉及的内容。 嗨 Stuart,你能把你的例子用 VLC 贴在某个地方,让我看看。谢谢。【参考方案5】:由于 WPF mediaelement 在内部使用 windows 媒体播放器。如果您将媒体播放器的缓冲区设置从默认缓冲区设置更改为自定义。打开 windows 媒体播放器 工具 选项 性能。
当您选择“缓冲区”选项并将“内容秒数”设置为 2 时,媒体播放器下将添加以下注册表值。 HKEY_CURRENT_USER\Software\Microsoft\MediaPlayer\Preferences 使用默认缓冲时间=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
【讨论】:
以上是关于使用 MediaElement 从 Stream 播放视频的主要内容,如果未能解决你的问题,请参考以下文章
使用 MediaElement 在 Windows Phone 8 上流式传输音频
ViewModel 中的 MediaElement.play()
如何使用 TimedTextSource 在 MediaElement 上查看(srt)字幕