python video gstreamer

Cómo crear miniaturas de video con Python y Gstreamer



(4)

Es una vieja pregunta, pero todavía no la he encontrado documentada en ningún lado.
Descubrí que lo siguiente funcionó en un video de reproducción con Gstreamer 1.0

import gi import time gi.require_version(''Gst'', ''1.0'') from gi.repository import Gst def get_frame(): caps = Gst.Caps(''image/png'') pipeline = Gst.ElementFactory.make("playbin", "playbin") pipeline.set_property(''uri'',''file:///home/rolf/GWPE.mp4'') pipeline.set_state(Gst.State.PLAYING) #Allow time for it to start time.sleep(0.5) # jump 30 seconds seek_time = 30 * Gst.SECOND pipeline.seek(1.0, Gst.Format.TIME,(Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE),Gst.SeekType.SET, seek_time , Gst.SeekType.NONE, -1) #Allow video to run to prove it''s working, then take snapshot time.sleep(1) buffer = pipeline.emit(''convert-sample'', caps) buff = buffer.get_buffer() result, map = buff.map(Gst.MapFlags.READ) if result: data = map.data pipeline.set_state(Gst.State.NULL) return data else: return if __name__ == ''__main__'': Gst.init(None) image = get_frame() with open(''frame.png'', ''wb'') as snapshot: snapshot.write(image)

El código debería ejecutarse con Python2 y Python3, espero que ayude a alguien.

Me gustaría crear miniaturas para videos MPEG-4 AVC usando Gstreamer y Python. Esencialmente:

  1. Abra el archivo de video
  2. Busque un cierto punto en el tiempo (por ejemplo, 5 segundos)
  3. Coge el marco en ese momento
  4. Guarde el marco en el disco como un archivo .jpg

He estado viendo esta otra pregunta similar , pero no puedo entender cómo hacer la búsqueda y la captura de cuadros automáticamente sin la intervención del usuario.

Entonces, en resumen, ¿cómo puedo capturar una miniatura de video con Gstreamer y Python según los pasos anteriores?


Para elaborar en la respuesta de Ensonic , aquí hay un ejemplo:

import os import sys import gst def get_frame(path, offset=5, caps=gst.Caps(''image/png'')): pipeline = gst.parse_launch(''playbin2'') pipeline.props.uri = ''file://'' + os.path.abspath(path) pipeline.props.audio_sink = gst.element_factory_make(''fakesink'') pipeline.props.video_sink = gst.element_factory_make(''fakesink'') pipeline.set_state(gst.STATE_PAUSED) # Wait for state change to finish. pipeline.get_state() assert pipeline.seek_simple( gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, offset * gst.SECOND) # Wait for seek to finish. pipeline.get_state() buffer = pipeline.emit(''convert-frame'', caps) pipeline.set_state(gst.STATE_NULL) return buffer def main(): buf = get_frame(sys.argv[1]) with file(''frame.png'', ''w'') as fh: fh.write(str(buf)) if __name__ == ''__main__'': main()

Esto genera una imagen PNG. Puede obtener datos de imágenes en bruto usando gst.Caps("video/x-raw-rgb,bpp=24,depth=24") o algo así.

Tenga en cuenta que en GStreamer 1.0 (en oposición a 0.10), playbin2 ha sido renombrado a playbin y la señal de convert-frame se llama convert-sample .

La mecánica de la búsqueda se explica en este capítulo del Manual de desarrollo de aplicaciones de GStreamer . La documentación de 0.10 playbin2 ya no parece estar en línea, pero la documentación para 1.0 está aquí .


Un ejemplo en Vala, con GStreamer 1.0:

var playbin = Gst.ElementFactory.make ("playbin", null); playbin.set ("uri", "file:///path/to/file"); // some code here. var caps = Gst.Caps.from_string("image/png"); Gst.Sample sample; Signal.emit_by_name(playbin, "convert-sample", caps, out sample); if(sample == null) return; var sample_caps = sample.get_caps (); if(sample_caps == null) return; unowned Gst.Structure structure = sample_caps.get_structure(0); int width = (int)structure.get_value ("width"); int height = (int)structure.get_value ("height"); var memory = sample.get_buffer().get_memory (0); Gst.MapInfo info; memory.map (out info, Gst.MapFlags.READ); uint8[] data = info.data;


Use playbin2. configura el uri en el archivo multimedia, usa gst_element_seek_simple para buscar la posición de tiempo deseada y luego usa g_signal_emit para invocar la señal de acción "convert-frame".