Meine Frage besteht darin, eine Videodatei auf die Festplatte zu schreiben, die aus dem Netzwerk heruntergeladen und gleichzeitig mit Windows Media Player abgespielt wird. Die Datei ist ziemlich groß und wird eine Weile dauern. Es ist notwendig, es herunterzuladen, anstatt es direkt in Windows Media Player zu streamen.Wiedergabe großer Dateien auf Windows Media Player während des Downloads
Was passiert ist, dass, während ich in die Videodatei schreiben und gleichzeitig von meinem eigenen Testcode lesen kann, kann es nicht mit Windows Media Player getan werden (zumindest habe ich es nicht herausgefunden). Ich weiß, dass es möglich ist, weil Amazon Unbox Downloads es tut. Mit Unbox können Sie WMVs abspielen, während sie heruntergeladen werden. Und Unbox ist in .NET so geschrieben ...
Ich habe die "C# file read/write fileshare doesn’t appear to work" Frage und Antworten zum Öffnen einer Datei mit den FileShare-Flags gelesen. Aber es funktioniert nicht für mich. Process Monitor sagt, dass Media Player die Datei mit Fileshare-Flags öffnet, aber es ist fehlgeschlagen.
// 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);
}
Dies scheint zu funktionieren:
In dem Puffer Thread ich zum Lesen der Datei aus dem Netz diesen Code habe und es in eine Datei (keine Fehlerbehandlung oder andere Dinge, die es besser lesbar zu machen) zu schreiben fein. Die Datei schreibt auf den Datenträger und verfügt über die richtigen Berechtigungen.
Aber dann here die Event-Handler in dem anderen Thread zum Abspielen des Videos
// the playback thread
private void OnBufferingComplete(object sender, BufferingCompleteEventArgs e)
{
axWindowsMediaPlayer1.URL = e.MediaFile.FullName;
}
Windows Media Player zeigt wieder, dass seine Öffnen die Datei und stoppt dann nur mit einem Fehler, dass die Datei nicht geöffnet werden kann "bereits in einem anderen Prozess geöffnet."
Ich habe alles versucht, was mir einfällt. Was vermisse ich? Wenn die Amazon-Jungs das können, dann kann ich das auch, oder?
bearbeiten: Dieser Code funktioniert mit MPlayer, VLC und Media Player Classic; nur nicht Windows Media Player oder Windows Media Center-Player. IOW, die einzigen Spieler, mit denen ich arbeiten muss. Pfui!
edit2: Ich ging so weit, MiniHttp zu verwenden, um das Video zu Windows Media Player zu streamen, um zu sehen, ob das "WMP" in das Abspielen eines Videos, das heruntergeladen wird, "täuschen" würde. Nichts zu tun. Während WMP die Datei geöffnet hat, hat sie gewartet, bis die mpeg-Datei vollständig kopiert wurde, bevor sie abgespielt wurde. Woher weiß es das?
edit3: Nach etwas graben entdeckte ich das Problem. Ich arbeite mit MPEG2-Dateien. Das Problem liegt nicht unbedingt beim Windows Media Player, sondern beim Microsoft MPEG2 DirectShow Splitter, mit dem WMP die MPEG2-Dateien öffnet, die ich gleichzeitig wiedergeben und herunterladen möchte. Der Splitter öffnet die Dateien im Nicht-Shared-Modus. Nicht so bei WMV-Dateien. WMP öffnet sie im freigegebenen Modus und alles funktioniert wie erwartet.
@Bevan, wenn FileShare.Write beim Erstellen der Datei angegeben wird, bedeutet dies, dass der Media Player die Datei nie zum Lesen öffnen kann. –
@darin - danke für die Köpfe hoch. FileShare hat nicht gemeint, was ich dachte. Ich habe meine Antwort aktualisiert, um meinem besseren Verständnis zu entsprechen. – Bevan