下载期间在Windows Media Player上播放大文件

时间:2009-03-15 08:56:30

标签: c# fileshare media-player

我的问题是将视频文件写入正在从网络下载并使用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以共享模式打开它们,一切都按预期工作。

3 个答案:

答案 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,这将成功。