Question

Ma question concerne l'écriture d'un fichier vidéo sur le disque dur en cours de téléchargement à partir du réseau et sa lecture simultanée à l'aide de Windows Media Player. Le fichier est assez gros et va prendre un certain temps à télécharger. Il est nécessaire de le télécharger plutôt que de le diffuser directement vers Windows Media Player.

Ce qui se passe est que, bien que je puisse écrire dans le fichier vidéo et le lire en même temps à partir de mon propre code de test, cela ne peut pas être fait avec Windows Media Player (du moins, je ne l'ai pas compris). Je sais que c'est possible, car Amazon Unbox downloads le fait. Unbox vous permet de lire les WMV pendant son téléchargement. Et Unbox est écrit en .NET donc ...

J'ai lu le " fichier C # lu / écrire des fichiers en partage ne semble pas fonctionner " question et réponses pour ouvrir un fichier avec les drapeaux FileShare. Mais ça ne marche pas pour moi. Process Monitor indique que Media Player ouvre le fichier avec des indicateurs de partage de fichiers, mais il affiche une erreur.

Dans le fil de mise en mémoire tampon, j'ai ce code pour lire le fichier sur le réseau et l'écrire dans un fichier (pas de gestion des erreurs ou autre chose pour le rendre plus lisible):

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

Cela semble bien fonctionner. Le fichier écrit sur le disque et dispose des autorisations appropriées.

Mais alors, voici le gestionnaire d'événements dans l'autre fil pour lire la vidéo

    // the playback thread

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

Windows Media Player indique que le fichier est ouvert puis arrêté avec une erreur indiquant que le fichier ne peut pas être ouvert "déjà ouvert dans un autre processus".

J'ai essayé tout ce à quoi je peux penser. Qu'est-ce que je rate? Si les gars d'Amazon peuvent le faire, alors je le peux aussi, non?

modifier: ce code fonctionne avec mplayer, VLC et Media Player Classic; mais pas les lecteurs Windows Media ou Windows Media Center. IOW, les seuls joueurs avec qui j'ai besoin d'eux. beurk!

edit2: Je suis allé jusqu'à utiliser MiniHttp pour diffuser la vidéo sur Windows Media Player afin de voir si cela pouvait "tromper". WMP pour lire une vidéo en cours de téléchargement. Rien faire. Bien que WMP ait ouvert le fichier, il a attendu que le fichier mpeg soit complètement copié avant de commencer à jouer. Comment sait-il?

edit3: Après quelques recherches, j'ai découvert le problème. Je travaille avec des fichiers MPEG2. Le problème ne vient pas nécessairement de Windows Media Player, mais du Microsoft MPEG2 DirectShow Splitter utilisé par WMP pour ouvrir les fichiers MPEG2 que je tente de lire et de télécharger en même temps. Le séparateur ouvre les fichiers en mode non partagé. Ce n'est pas le cas avec les fichiers WMV. WMP les ouvre en mode partagé et tout fonctionne comme prévu.

Était-ce utile?

La solution

J'ai décidé de répondre à ma propre question au cas où quelqu'un d'autre se retrouverait dans cette situation rare.

La réponse courte est la suivante: Windows Media Player (au moment de l'écriture de cet article) permettra à un fichier d'être téléchargé et lu en même temps, à condition que cette fonctionnalité soit prise en charge par les CODECS impliqués dans le rendu du fichier.

Pour citer la dernière modification à la question:

Après quelques recherches, j'ai découvert le problème. Je travaille avec des fichiers MPEG2. Le problème ne vient pas nécessairement de Windows Media Player, mais du Microsoft MPEG2 DirectShow Splitter utilisé par WMP pour ouvrir les fichiers MPEG2 que je tente de lire et de télécharger en même temps. Le séparateur ouvre les fichiers en mode non partagé. Ce n'est pas le cas avec les fichiers WMV. WMP les ouvre en mode partagé et tout fonctionne comme prévu.

Autres conseils

Lorsque vous ouvrez le fichier en écriture, vous ne devez pas utiliser FileShare.ReadWrite. Vous devriez plutôt utiliser FileShare.Read:

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

Lorsque le processus mplayer.exe ouvre le fichier en lecture, il essaiera d’abord de l’ouvrir avec FileShare.Read, ce qui échouera mais il tentera de nouveau une tentative avec FileShare.ReadWrite qui aboutira.

Mis à jour le 16 mars après le commentaire de @darin:

Vous spécifiez FileShare.ReadWrite lors de l'écriture du fichier, ce qui permet théoriquement à un autre processus de l'ouvrir également pour l'écriture.

Essayez de modifier votre code pour ne demander que FileShare.Read :

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

Pour citer MSDN :

  

FileShare.Read: Permet les suivantes   ouverture du fichier en lecture.

     

FileShare.ReadWrite: Permet des actions ultérieures.   ouverture du fichier pour lecture ou   l'écriture.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top