Riproduzione di file di grandi dimensioni su Windows Media Player durante il download

StackOverflow https://stackoverflow.com/questions/647501

  •  22-07-2019
  •  | 
  •  

Domanda

La mia domanda riguarda la scrittura di un file video sul disco rigido che viene scaricato dalla rete e la riproduzione allo stesso tempo utilizzando Windows Media Player. Il file è piuttosto grande e richiederà del tempo per il download. È necessario scaricarlo anziché semplicemente trasmetterlo direttamente a Windows Media Player.

Quello che succede è che, mentre posso scrivere sul file video e leggerlo contemporaneamente dal mio codice di prova, non è possibile farlo utilizzando Windows Media Player (almeno non l'ho capito). So che è possibile farlo perché i download di Amazon Unbox lo fanno. Unbox ti consente di giocare a WMV mentre li sta scaricando. E Unbox è scritto in .NET quindi ...

Ho letto " C # file read / scrivere fileshare non sembra funzionare " domande e risposte per l'apertura di un file con i flag FileShare. Ma non funziona per me. Process Monitor afferma che Media Player sta aprendo il file con i flag di condivisione file, ma non funziona correttamente.

Nel thread di buffering ho questo codice per leggere il file dalla rete e scriverlo su un file (nessuna gestione degli errori o altre cose per renderlo più leggibile):

// 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);
}

Questo sembra funzionare bene. Il file scrive sul disco e ha le autorizzazioni corrette.

Ma poi ecco il gestore dell'evento nell'altro thread per la riproduzione del video

    // the playback thread

private void OnBufferingComplete(object sender, BufferingCompleteEventArgs e)
{
    axWindowsMediaPlayer1.URL = e.MediaFile.FullName;
}

Windows Media Player indica che si sta aprendo il file e quindi si interrompe semplicemente con un errore che il file non può essere aperto "già aperto in un altro processo."

Ho provato tutto quello che mi viene in mente. Cosa mi sto perdendo? Se i ragazzi di Amazon possono farlo, lo posso fare anche io, vero?

modifica: questo codice funziona con mplayer, VLC e Media Player Classic; semplicemente non Windows Media Player o Windows Media Center player. IOW, gli unici giocatori con cui ho bisogno di lavorare. ugh!

EDIT2: Sono arrivato al punto di utilizzare MiniHttp per trasmettere in streaming il video su Windows Media Player per vedere se questo avrebbe "ingannato". WMP nella riproduzione di un video che viene scaricato. Niente da fare. Mentre WMP ha aperto il file, ha atteso che il file mpeg fosse completamente copiato prima di iniziare la riproduzione. Come lo sa?

Edit3: Dopo alcuni scavi ho scoperto il problema. Sto lavorando con i file MPEG2. Il problema non è necessariamente con Windows Media Player, ma con Microsoft MPEG2 DirectShow Splitter che WMP utilizza per aprire i file MPEG2 che sto provando a riprodurre e scaricare contemporaneamente. Splitter apre i file in modalità non condivisa. Non così con i file WMV. WMP li apre in modalità condivisa e tutto funziona come previsto.

È stato utile?

Soluzione

Ho deciso di rispondere alla mia domanda nel caso in cui qualcun altro si imbatta in questa rara situazione.

La risposta breve è questa: Windows Media Player (al momento della stesura di questo documento) consentirà il download e la riproduzione di un file contemporaneamente a condizione che tale funzionalità sia supportata dai CODECS coinvolti nel rendering del file.

Per citare dall'ultima modifica alla domanda:

Dopo alcuni scavi ho scoperto il problema. Sto lavorando con i file MPEG2. Il problema non è necessariamente con Windows Media Player, ma con Microsoft MPEG2 DirectShow Splitter che WMP utilizza per aprire i file MPEG2 che sto provando a riprodurre e scaricare contemporaneamente. Splitter apre i file in modalità non condivisa. Non così con i file WMV. WMP li apre in modalità condivisa e tutto funziona come previsto.

Altri suggerimenti

Quando apri il file per la scrittura non dovresti usare FileShare.ReadWrite. Dovresti invece utilizzare FileShare.Read:

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

Quando il processo mplayer.exe apre il file per la lettura, tenterà prima di aprirlo con FileShare.Read che fallirà ma poi tenterà nuovamente con FileShare.ReadWrite che avrà successo.

Aggiornato il 16 marzo dopo il commento di @darin:

Stai specificando FileShare.ReadWrite quando scrivi il file, il che teoricamente consente ad un altro processo di aprirlo anche per scrivere.

Prova a modificare il codice per richiedere solo FileShare.Read :

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

Per citare MSDN :

  

FileShare.Read: consente successivi   apertura del file per la lettura.

     

FileShare.ReadWrite: consente successivi   apertura del file per la lettura o   scrittura.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top