WPF MediaElement在播放时下载文件
本文关键字:下载 文件 播放 MediaElement WPF | 更新日期: 2023-09-27 18:27:28
是否可以使用MediaElement从服务器播放文件(视频或音频类型),同时将数据保存到特定的文件位置,以便下次可以直接从本地系统加载。在我的项目中,我使用的是WPF Media Element
没有简单的方法。这是可能的——至少有两种方法可以做到。但这并不容易。
MediaElement
处理其源流的方式很棘手,因为它在内部使用Windows Media Player(这意味着它在幕后使用MediaFoundation或DirectShow,这取决于你运行的是哪个版本的Windows)。编写某种拦截器来中继底层流,同时将其保存到磁盘,这种"显而易见"的解决方案是可能的,但你必须离开.NET世界才能做到这一点,因为MediaElement
无法与.NET流一起工作。
这并不是说这是不可能的。您"只需"编写一个自定义源筛选器,并使用自定义协议实现进行设置。http://msdn.microsoft.com/en-us/library/ms787558(VS.85).aspx描述了视频渲染基础结构如何根据传入的URL来决定创建哪种对象来表示视频源。MediaElement
将源URL直接传递到该基础结构中,因此,如果您编写自定义筛选器并将其与myhack:
协议相关联,则如果您将源设置为myhack://whatever
,它最终会加载你的过滤器。然后,如果您将过滤器作为http:
过滤器的包装器,您将能够将传入数据的副本保存到磁盘。
这不是小事。
另一种选择可能是托管本地HTTP服务器。如果您可以选择打开一个可以监听的本地套接字,那么您可以编写一个HTTP实现,该实现使用.NET内置的HTTP客户端类型之一来获取数据,同时保存一个副本并提供该数据。这也很简单,但可能比编写自定义源代码过滤器更容易。
我发现,如果我在开始下载之前设置了下载文件的文件大小,那么MediaElement
将在下载时播放整个视频/音频。
using (var httpClient = new HttpClient() {Timeout = TimeSpan.FromMinutes(25)})
using (var response = await httpClient.GetAsync(theDownloadUrl, HttpCompletionOption.ResponseHeadersRead))
using (var videoFileStream = File.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.Read)) {
videoFileStream.SetLength(response.Content.Headers.ContentLength.GetValueOrDefault());
var copying = response.Content.CopyToAsync(videoFileStream);
//await Task.Delay(1000);
MediaSource = fileName;
await copying;
}