我的问题是将视频文件写入正在从网络下载并使用Windows Media Player同时播放的硬盘驱动器。该文件非常大,需要一段时间才能下载。有必要下载它,而不是直接将其直接流式传输到Windows Media Player。
虽然我可以写入视频文件并从我自己的测试代码同时读取它,但是使用Windows Media Player无法完成(至少我没有想到)。我知道这是可能的,因为Amazon Unbox下载会这样做。 Unbox允许您在下载WMV时播放它们。 Unbox是用.NET编写的......
我已阅读使用FileShare标记打开文件的“C# file read/write fileshare doesn’t appear to work”问题和答案。但这对我不起作用。 Process Monitor表示Media Player正在使用Fileshare标志打开文件,但它出错了。
在缓冲线程中,我有这个代码,用于从网络读取文件并将其写入文件(没有错误处理或其他东西,使其更具可读性):
// the download thread
void StartStreaming(Stream webStream, int bufferFullByteCount)
{
int bytesRead;
var buffer = new byte[4096];
var fileStream = new FileStream(MediaFile.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
var writer = new BinaryWriter(fileStream);
var totalBytesRead = 0;
do
{
bytesRead = webStream.Read(buffer, 0, 4096);
if (bytesRead != 0)
{
writer.Write(buffer, 0, (int)bytesRead);
writer.Flush();
totalBytesRead += bytesRead;
}
if (totalBytesRead >= bufferFullByteCount)
{
// fire an event to a different thread to tell
// Windows Media Player to start playing
OnBufferingComplete(this, new BufferingCompleteEventArgs(this, MediaFile));
}
} while (bytesRead != 0);
}
这似乎工作正常。该文件写入磁盘并具有正确的权限。
然后继承了另一个线程中用于播放视频的事件处理程序
// the playback thread
private void OnBufferingComplete(object sender, BufferingCompleteEventArgs e)
{
axWindowsMediaPlayer1.URL = e.MediaFile.FullName;
}
Windows Media Player指示它打开文件,然后停止并显示“无法打开文件”的错误“已在另一个进程中打开。”
我已经尝试了所有我能想到的东西。我错过了什么?如果亚马逊人能做到这一点那么我也可以,对吧?
编辑: 此代码适用于mplayer,VLC和Media Player Classic;只是没有Windows Media Player或Windows Media Center播放器。 IOW,我需要他们合作的唯一玩家。啊!
EDIT2: 我甚至使用MiniHttp将视频流式传输到Windows Media Player,看看是否会“愚弄”WMP播放正在下载的视频。无所事事。当WMP确实打开文件时,它等待mpeg文件在开始播放之前完全复制。怎么知道?
EDIT3: 经过一番挖掘,我发现了这个问题。我正在使用MPEG2文件。问题不一定是Windows Media Player,而是使用WMP用于打开我试图播放和下载的MPEG2文件的Microsoft MPEG2 DirectShow Splitter。 Splitter以非共享模式打开文件。 WMV文件不是这样。 WMP以共享模式打开它们,一切都按预期工作。
答案 0 :(得分:2)
我决定回答我自己的问题,以防其他人遇到这种罕见的情况。
简短的回答是这样的:Windows Media Player(在撰写本文时)将允许同时下载和播放文件,只要该文件在渲染文件时受到CODECS的支持即可。
引用问题的最后一次编辑:
经过一番挖掘后,我发现了这个问题。我正在使用MPEG2文件。问题不一定是Windows Media Player,而是使用WMP用于打开我试图播放和下载的MPEG2文件的Microsoft MPEG2 DirectShow Splitter。 Splitter以非共享模式打开文件。 WMV文件不是这样。 WMP以共享模式打开它们,一切都按预期工作。
答案 1 :(得分:0)
@darin发表评论后,3月16日更新:
您在编写文件时指定FileShare.ReadWrite
,理论上允许其他进程打开文档进行编写。
尝试将代码更改为仅请求FileShare.Read
:
var fileStream
= new FileStream(
MediaFile.FullName,
FileMode.Create,
FileAccess.Write,
FileShare.Read); // Instead of ReadWrite
引用MSDN:
FileShare.Read:允许后续 打开文件进行阅读。
FileShare.ReadWrite:允许后续 打开文件进行阅读或 写入。
答案 2 :(得分:0)
当您打开文件进行编写时,不应使用FileShare.ReadWrite。您应该使用FileShare.Read:
var fileStream = new FileStream(
MediaFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read);
当mplayer.exe进程打开文件进行读取时,它将首先尝试使用FileShare.Read打开它,这将失败,但随后它将重新尝试使用FileShare.ReadWrite,这将成功。