ダウンロード中にWindows Media Playerで大きなファイルを再生する
-
22-07-2019 - |
質問
私の質問は、ネットワークからダウンロードされているハードドライブにビデオファイルを書き込み、Windows Media Playerを使用して同時に再生することです。ファイルはかなり大きく、ダウンロードには時間がかかります。 Windows Media Playerに直接ストリーミングするのではなく、ダウンロードする必要があります。
何が起こるかというと、ビデオファイルへの書き込みと、自分のテストコードからの読み取りを同時に行うことはできますが、Windows Media Playerを使用して実行することはできません(少なくとも、私は理解していません)。 Amazon Unboxのダウンロードがそれを行うので、私はそれが可能であることを知っています。 Unboxでは、ダウンロード中にWMVを再生できます。 Unboxは.NETで書かれているので...
" C#ファイル読み取り/ファイル共有の書き込みが機能していないようです" FileShareフラグを使用してファイルを開くための質問と回答。しかし、それは私のために働いていません。プロセスモニターは、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にあります。スプリッターは非共有モードでファイルを開きます。 WMVファイルではそうではありません。 WMPはそれらを共有モードで開き、すべてが期待どおりに動作します。
解決
他の誰かがこのまれな状況に遭遇した場合に備えて、自分の質問に答えることにしました。
簡単な答えは次のとおりです。WindowsMedia Player(この記事の執筆時点)では、ファイルのレンダリングに関連するCODECSによってその機能がサポートされている限り、ファイルをダウンロードして同時に再生できます。
質問に対する最後の編集から引用するには:
掘り下げて問題を発見しました。 MPEG2ファイルを使用しています。問題は必ずしもWindows Media Playerにあるとは限りませんが、WMPが再生とダウンロードを同時に行っているMPEG2ファイルを開くために使用するMicrosoft MPEG2 DirectShow Splitterにあります。スプリッターは非共有モードでファイルを開きます。 WMVファイルではそうではありません。 WMPはそれらを共有モードで開き、すべてが期待どおりに動作します。
他のヒント
書き込み用にファイルを開く場合、FileShare.ReadWriteを使用しないでください。代わりにFileShare.Readを使用する必要があります。
var fileStream = new FileStream(
MediaFile.FullName, FileMode.Create, FileAccess.Write, FileShare.Read);
mplayer.exeプロセスが読み取り用にファイルを開くと、まずFileShare.Readでファイルを開こうとしますが失敗しますが、FileShare.ReadWriteで再試行します。成功します。
@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:後続の許可 読み取りのためにファイルを開く、または 書きます。