¿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.
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:
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:
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.