Pregunta

Mi pregunta es acerca de escribir un archivo de video en el disco duro que se está descargando de la red y reproducirlo al mismo tiempo con Windows Media Player. El archivo es bastante grande y tardará un tiempo en descargarse. Es necesario descargarlo en lugar de simplemente transmitirlo directamente al Reproductor de Windows Media.

Lo que sucede es que, si bien puedo escribir en el archivo de video y leerlo al mismo tiempo desde mi propio código de prueba, no se puede hacer con Windows Media Player (al menos no lo he descubierto). Sé que es posible hacerlo porque las descargas de Amazon Unbox lo hacen. Unbox te permite jugar WMVs mientras los descarga. Y Unbox está escrito en .NET, así que ...

He leído el " archivo C # leído / escribir archivos compartidos no parece funcionar " preguntas y respuestas para abrir un archivo con las marcas de FileShare. Pero no está funcionando para mí. Process Monitor dice que Media Player está abriendo el archivo con marcas de Archivos compartidos, pero se produce un error.

En el subproceso de almacenamiento en búfer tengo este código para leer el archivo de la red y escribirlo en un archivo (sin manejo de errores u otras cosas para que sea más legible):

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

Esto parece funcionar bien. El archivo escribe en el disco y tiene los permisos correctos.

Pero luego está el controlador de eventos en el otro hilo para reproducir el video

    // the playback thread

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

Windows Media Player indica que está abriendo el archivo y luego simplemente se detiene con un error de que el archivo no se puede abrir " ya abierto en otro proceso. "

He intentado todo lo que puedo pensar. ¿Qué me estoy perdiendo? Si los chicos de Amazon pueden hacer esto, entonces yo también, ¿no?

editar: este código funciona con mplayer, VLC y Media Player Classic; simplemente no Windows Media Player o Windows Media Center. IOW, los únicos jugadores con los que necesito que trabajen. ugh!

edit2: Llegué al extremo de usar MiniHttp para transmitir el video al Reproductor de Windows Media para ver si eso "engañaría". WMP para reproducir un video que se está descargando. Haciendo nada. Mientras WMP abrió el archivo, esperó hasta que el archivo mpeg se haya copiado completamente antes de comenzar a reproducirse. ¿Cómo lo sabe?

edit3: Después de cavar un poco descubrí el problema. Estoy trabajando con archivos MPEG2. El problema no es necesariamente con Windows Media Player, sino con el Microsoft MPEG2 DirectShow Splitter que WMP usa para abrir los archivos MPEG2 que intento reproducir y descargar al mismo tiempo. El divisor abre los archivos en modo no compartido. No es así con los archivos WMV. WMP los abre en modo compartido y todo funciona como se esperaba.

¿Fue útil?

Solución

He decidido responder mi propia pregunta en caso de que alguien más se encuentre con esta situación rara.

La respuesta breve es esta: Windows Media Player (a partir de este escrito) permitirá que un archivo se descargue y se reproduzca al mismo tiempo, siempre que CODECS participe en la representación del archivo.

Para citar desde la última edición a la pregunta:

Después de cavar un poco descubrí el problema. Estoy trabajando con archivos MPEG2. El problema no es necesariamente con Windows Media Player, sino con el Microsoft MPEG2 DirectShow Splitter que WMP usa para abrir los archivos MPEG2 que intento reproducir y descargar al mismo tiempo. El divisor abre los archivos en modo no compartido. No es así con los archivos WMV. WMP los abre en modo compartido y todo funciona como se esperaba.

Otros consejos

Cuando abre el archivo para escribir, no debe usar FileShare.ReadWrite. En su lugar, debe usar FileShare.Read:

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

Cuando el proceso mplayer.exe abra el archivo para leerlo, primero intentará abrirlo con FileShare.Read, que fallará, pero luego volverá a intentarlo con FileShare.ReadWrite, que tendrá éxito.

Actualizado el 16 de marzo después del comentario de @darin:

Estás especificando FileShare.ReadWrite cuando escribes el archivo, lo que teóricamente permite que otro proceso lo abra para escribir también.

Intente alterar su código para solicitar solo FileShare.Read :

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

Para citar MSDN :

  

FileShare.Read: permite posteriores   apertura del archivo para leer.

     

FileShare.ReadWrite: permite posteriores   apertura del archivo para leer o   escritura.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top