Cómo generar un archivo de video a partir de una secuencia de QImage usando QMediaRecorder en Qt5 C++

3 minutos de lectura

avatar de usuario
Lennart Rolland

Básicamente, lo que quiero es codificar un video usando QMediaRecorder proporcionando como fuente una secuencia de QImages que genero en código personalizado en tiempo de ejecución.

Hasta ahora no he encontrado una manera fácil de hacer esto, y todo apunta a la solución donde tengo que implementar de alguna manera mi propia subclase de QMediaService y/o QMediaControl eso toma QImage como entrada, registrarlos y de alguna manera hacer QMediaRecorder usalos, usalos a ellos. pero de acuerdo a esto página en la documentación oficial de Qt sobre el tema, este es un camino menos transitado y estoy solo:

En general, la implementación de un QMediaService está fuera del alcance de esta documentación y se debe buscar soporte en las listas de correo o canales de IRC relevantes.

Estoy con esta publicación esperando que alguien que posea este conocimiento pueda arrojar algo de luz sobre cómo se haría esto. Creo que documentar este conjunto de funciones abrirá muchas posibilidades útiles para los usuarios de Qt5.

Actualización 2020-06-16: Han pasado casi 4 años y todavía no hay una sola respuesta. Ofreceré una recompensa por esta pregunta y aceptaré la mejor respuesta con código de ejemplo de trabajo para Qt5 reciente.

  • Hola, @Lennart, creo que el nombre de la clase puede haberte engañado, ya que QMedios de comunicaciónRecorder puede llevar a considerar que se trata de una base cercana que podría utilizarse para grabar vídeo. Sin embargo, puedes ver en Documentación qt esta clase tiene métodos solo de audio (como AudioCodecDescripción()) y solo lo hereda QAudioRecorder. Te sugiero que le eches un vistazo QVideoProbeque le permiten sondear fotogramas desde un QMediaPlayer.

    – diogoslima

    19/09/2018 a las 21:35

  • Podría intentar simplemente usar ffmpeg, es bastante portátil. Simplemente ejecútelo como una aplicación externa desde su código. Debería ser bastante fácil generar un video a partir de imágenes fijas con eso. Pregunta si necesitas ayuda con eso.

    – 0xbaadf00d

    10 de abril de 2019 a las 12:14

  • 0xbaadf00d – Gracias, pero creo que te perdiste el punto de la pregunta. Soy perfectamente capaz de manejar video. He usado ffmpeg durante mucho tiempo. Lo que busco es cómo usar Qt para hacer lo mismo. Esto tiene la ventaja de que tendría una dependencia menos de la que preocuparme. Para videos simples, podría confiar en el soporte de video en Qt en lugar de tener que agrupar ffmpeg.

    –Lennart Rolland

    14 de abril de 2019 a las 11:51

  • @LennartRolland Parece que QMediaRecorder solo funciona en macOS, Linux, plataformas móviles y Windows XP. ¿Está abierto a otras soluciones usando Qt?

    – karlphillip

    20 de junio de 2020 a las 23:56

  • @ Doch88: No vi eso, creo que no era el caso cuando hice la pregunta por primera vez. ¡Gracias!

    –Lennart Rolland

    22 de junio de 2020 a las 14:11

Es bastante simple hacer esto directamente con ffmpeg. Puede guardar las imágenes en el disco y luego usar un filtro ffmpeg desde la línea de comando, a través de QProcess. También puede crear una transmisión de video en el código, evitando así la pérdida de tiempo y rendimiento debido a que las imágenes se guardan en el disco, guarde las imágenes en esa transmisión.

  • Sé que es fácil en ffmpeg, he estado usando ffmpeg desde 2002, esperaba evitar la dependencia

    –Lennart Rolland

    3 de julio de 2020 a las 17:04

Puedes probar libqtavi. Es un envoltorio alrededor de libgwavi. API que parece simple y buena integración con las clases de Qt. Pero solo es compatible con el códec MJPG y el formato avi y su tamaño de salida es más grande que mpeg/mp4, hevc/mkv…

QAviWriter writer("demo.avi", QSize(800, 600), 24, "MJPG");// set framerate to 24 fps and 'MJPG' codec 
writer.setAudioFileName("audio.wav"); // set audio track
writer.open();
writer.addFrame(QImage("file.png"));
//...add all other video frames here
writer.close();

¿Ha sido útil esta solución?