【发布时间】:2011-10-30 08:41:52
【问题描述】:
是否可以使用 WPF MediaElement 从 System.IO.Stream 对象播放流视频?正在从存储媒体文件的 WCF 服务中检索 Stream 对象。
【问题讨论】:
标签: c# wpf wcf mediaelement
是否可以使用 WPF MediaElement 从 System.IO.Stream 对象播放流视频?正在从存储媒体文件的 WCF 服务中检索 Stream 对象。
【问题讨论】:
标签: c# wpf wcf mediaelement
在任何人浪费时间自己发现这一点之前:不可能在 WPF 应用程序中托管 Silverlight MediaElement。原因是它是出现在 PresentationFramework.dll(WPF 不可避免)和 System.Windows.dll(Silverlight 版本)中具有相同名称和相同命名空间但类型不同的众多类型之一。 (有人应该解释为什么我们有微软的命名空间!)
【讨论】:
可能为时已晚,如果您仍在寻找答案,希望这可能会有所帮助。
是的,您可以使用 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 也是如此。
【讨论】:
如果您可以让 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
【讨论】:
我知道这不是您要求的,但您可以在 WPF 的窗口内托管 VLC ActiveX 组件,然后使用该 VLC 控件连接到流并显示流。这就是我通过 WPF 进行流式处理的方式。
编辑:this page has an example of how to host an ActiveX control inside WPF
【讨论】:
由于 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
【讨论】: