es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo obtener una instantánea de un Video MemoryStream o Byte[] utilizando FFmpegCore en lugar de una ruta de archivo?

Estoy tratando de obtener instantáneas de datos de video que pueden estar en un MemoryStream O Byte[] pero no se encuentran en una ruta de archivo físico. FFMpegCore proporciona la opción de usar Argumentos con PipeSource pero no estoy seguro de cómo usarlos. He actualizado el código para tomar una instantánea desde el Stream como se muestra abajo, pero devuelve un error.

Está dando un error en la función SnapShotAsync en esta línea.

await arguments
            .OutputToPipe(new StreamPipeSink(ms), options => outputOptions(options
                .ForceFormat("rawvideo")))
            .ProcessAsynchronously().ConfigureAwait(false);

A continuación, se muestra el mensaje completo de error.

> ffmpeg exited with non-zero exit-code (1 - ffmpeg version 2021-04-04-git-b1b7cc698b-full build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 10.2.0 (Rev6, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libglslang --enable-vulkan --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      56. 72.100 / 56. 72.100
  libavcodec     58.135.100 / 58.135.100
  libavformat    58. 77.100 / 58. 77.100
  libavdevice    58. 14.100 / 58. 14.100
  libavfilter     7.111.100 /  7.111.100
  libswscale      5. 10.100 /  5. 10.100
  libswresample   3. 10.100 /  3. 10.100
  libpostproc    55. 10.100 / 55. 10.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 000001c78845f040] Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 1280x720, 4716 kb/s): unspecified pixel format
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '.\pipe\FFMpegCore_4599336d-fbf8-430e-ab89-19082c7d3693':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp41isom
    creation_time   : 2021-11-17T11:53:33.000000Z
  Duration: 00:00:03.62, start: 0.000000, bitrate: N/A
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 1280x720, 4716 kb/s, 15.20 fps, 15.08 tbr, 30k tbn, 60k tbc (default)
    Metadata:
      creation_time   : 2021-11-17T11:53:33.000000Z
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : AVC Coding
  Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 170 kb/s (default)
    Metadata:
      creation_time   : 2021-11-17T11:53:33.000000Z
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> png (native))
Press [q] to stop, [?] for help
.\pipe\FFMpegCore_4599336d-fbf8-430e-ab89-19082c7d3693: Invalid argument
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished
Conversion failed!)

Solo estoy pasando un archivo de video.

Hay alguna manera de obtener una instantánea del stream sin almacenar físicamente el archivo.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible obtener capturas de instantáneas de datos de video en un MemoryStream o Byte[] sin almacenar físicamente el archivo. El código que proporcionaste parece estar utilizando FFMpegCore, el cual proporciona una opción para usar Argumentos con PipeSource para la entrada. Para utilizar esta opción, puedes crear un StreamPipeSource desde la transmisión de entrada y pasarla como argumento al método FFMpegArguments.FromPipeInput, el cual creará una fuente de tubería para la entrada.

    En tu caso, parece que ya has actualizado el código para tomar una captura de una transmisión utilizando StreamPipeSource. Sin embargo, el mensaje de error sugiere que FFMpeg tiene problemas para detectar el formato de la transmisión de entrada. Esto puede deberse a la forma en que la transmisión de entrada se está pasando a FFMpegArguments.

    Para solucionar este problema, es posible que necesites establecer las opciones “analyzeduration” y “probesize” para FFMpegArguments para asegurar que FFMpeg tenga suficiente información para detectar el formato de la transmisión de entrada. Puedes hacer esto agregando las siguientes opciones a FFMpegArguments:

    options.AnalyzeDuration(TimeSpan.FromSeconds(10))
           .WithGlobalOptions("-probesize 5000000");
    

    Esto establecerá la “analyzeduration” a 10 segundos y la “probesize” a 5 MB, lo cual debería proporcionar suficiente información para que FFMpeg detecte el formato de la transmisión de entrada.

    Una vez que hayas establecido las opciones, puedes utilizar el método FFMpegArguments.OutputToPipe para enviar la instantánea a una fuente de tubería (en tu caso, un MemoryStream). Luego puedes crear un nuevo Bitmap desde el MemoryStream y devolverlo como salida del método SnapshotAsync.

    Aquí hay una implementación actualizada del método SnapshotAsync:

    public static async Task<bitmap> SnapshotAsync(Stream input, IMediaAnalysis source, Size? size = null, TimeSpan? captureTime = null, int? streamIndex = null, int inputFileIndex = 0)
    {
        input.Seek(0, SeekOrigin.Begin);
        FFMpegCore.Pipes.StreamPipeSource streamPipeSource = new FFMpegCore.Pipes.StreamPipeSource(input);
        var (arguments, outputOptions) = BuildSnapshotArguments(streamPipeSource, source, size, captureTime, streamIndex, inputFileIndex);
        using var ms = new MemoryStream();
    
        await arguments
            .AnalyzeDuration(TimeSpan.FromSeconds(10))
            .WithGlobalOptions("-probesize 5000000")
            .OutputToPipe(new StreamPipeSink(ms), options => outputOptions(options
                .ForceFormat("rawvideo")))
            .ProcessAsynchronously().ConfigureAwait(false);
    
        ms.Position = 0;
        return new Bitmap(ms);
    }
    

    Otra cosa a considerar es el códec de video utilizado en la transmisión de entrada. FFMpeg puede no admitir todos los códecs de video, por lo que es posible que necesites transcodificar la transmisión de entrada a un códec compatible antes de tomar la instantánea. Puedes utilizar el método FFMpegArguments.WithVideoCodec para especificar un códec diferente para la salida.

    ¡Espero que esto ayude! Avísame si tienes alguna otra pregunta.

Comments are closed.