2

我的问题是关于将视频文件写入从网络下载的硬盘驱动器并同时使用 Windows Media Player 播放它。该文件很大,需要一段时间才能下载。有必要下载它而不是直接将其流式传输到 Windows Media Player。

发生的情况是,虽然我可以从我自己的测试代码中写入视频文件并同时读取它,但使用 Windows Media Player 无法完成(至少我还没有弄清楚)。我知道这是可能的,因为 Amazon Unbox 下载做到了。Unbox 可让您在下载 WMV 时播放它们。Unbox 是用 .NET 编写的,所以......

我已经阅读了“ C# 文件读/写文件共享似乎不起作用”的问题和答案,用于打开带有 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 文件被完全复制后才开始播放。它是怎么知道的?

编辑3:经过一番挖掘,我发现了问题。我正在处理 MPEG2 文件。问题不一定与 Windows Media Player 相关,而是与 Microsoft MPEG2 DirectShow Splitter 相关,WMP 使用它来打开我试图同时播放和下载的 MPEG2 文件。拆分器以非共享模式打开文件。WMV 文件并非如此。WMP 以共享模式打开它们,一切都按预期工作。

4

3 回答 3

2

我决定回答我自己的问题,以防其他人遇到这种罕见的情况。

简短的回答是:Windows Media Player(在撰写本文时)将允许同时下载和播放文件,只要该功能受渲染文件所涉及的 CODECS 支持。

引用对问题的最后编辑:

经过一番挖掘,我发现了问题。我正在处理 MPEG2 文件。问题不一定与 Windows Media Player 相关,而是与 Microsoft MPEG2 DirectShow Splitter 相关,WMP 使用它来打开我试图同时播放和下载的 MPEG2 文件。拆分器以非共享模式打开文件。WMV 文件并非如此。WMP 以共享模式打开它们,一切都按预期工作。

于 2009-04-01T13:36:04.910 回答
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:允许随后打开文件以进行读取或写入。

于 2009-03-15T09:03:31.523 回答
0

当您打开文件进行写入时,您不应使用 FileShare.ReadWrite。您应该改用 FileShare.Read:

var fileStream = new FileStream(
    MediaFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read);

当 mplayer.exe 进程打开文件进行读取时,它将首先尝试使用 FileShare.Read 打开它,这将失败,但它会重新尝试使用 FileShare.ReadWrite 打开它,这将成功。

于 2009-03-15T09:59:25.040 回答