|
Página 1 de 1
|
¿como Extraer Fotogramas De Un Video?
Autor |
Mensaje |
jsbsan
Analista Programador
Registrado: Septiembre 2009
Mensajes: 4175
Edad: 51 Ubicación: dos hermanas, sevilla
|
¿como Extraer Fotogramas De Un Video?
Sabeis alguna forma de ir extrayendo fotogramas de un video e irlos mostrando en un drawingArea?
Se que ffmeg, lo puede hacer, creando los archivos gráficos de cada fotogramas.
Pero creo que el proceso seria mucho más rápido si se pudiera hacer directamente llamando a alguna libreria de C, para pasar el dibujo al drawinArea.
A ver que me contais...
Saludos
|
#1 Jueves, 18 Febrero 2016, 11:42 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: ¿como Extraer Fotogramas De Un Video?
|
#2 Jueves, 18 Febrero 2016, 14:29 |
|
|
v3ctor
Analista Programador
Registrado: May 2013
Mensajes: 1786
Edad: 44 Ubicación: Uruguay
|
Re: ¿como Extraer Fotogramas De Un Video?
acá el sensei de las librerías externas y sobre todo de c es el sapo jajajajajaj
=================== Software libre, programación libre, vida libre es la Public function Libertad()as Invendible
Proyectos: VisorRV1960,Taller2015,Tanteador
https://sourceforge.net/u/v3ctor-full/profile/
Blog: http://novatocodegambas.blogspot.com.uy/
|
#3 Jueves, 18 Febrero 2016, 15:23 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: ¿como Extraer Fotogramas De Un Video?
Vamos a crear un archivo de tipo .png de un frame del video, utilizando la libreria de GStreamer:
Public Struct GstMapInfo
GstMemory As Pointer
flags As Integer
data As Pointer
size As Long
maxsize As Long
End Struct
Library "libgstreamer-1.0"
Private Enum GST_STATE_VOID_PENDING = 0, GST_STATE_NULL, GST_STATE_READY, GST_STATE_PAUSED, GST_STATE_PLAYING
Private Enum GST_STATE_CHANGE_FAILURE = 0, GST_STATE_CHANGE_SUCCESS, GST_STATE_CHANGE_ASYNC, GST_STATE_CHANGE_NO_PREROLL
Private Const GST_SECOND As Long = 1000000000
Private Const GST_FORMAT_TIME As Integer = 3
Private Const GST_SEEK_FLAG_FLUSH As Integer = 1
Private Const GST_SEEK_FLAG_KEY_UNIT As Integer = 4
Private Const GST_MAP_READ As Integer = 1
Private Const GDK_COLORSPACE_RGB As Integer = 0
' gst_init (int *argc, char **argv[])
' Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
Private Extern gst_init(argc As Pointer, argv As Pointer)
' GstElement * gst_parse_launch (const gchar *pipeline_description, GError **error)
' Create a new pipeline based on command line syntax.
Private Extern gst_parse_launch(description As String, GError As Pointer) As Pointer
' GstElement * gst_bin_get_by_name (GstBin *bin, const gchar *name)
' Gets the element with the given name from a bin.
Private Extern gst_bin_get_by_name(bin As Pointer, name As String) As Pointer
' GstStateChangeReturn gst_element_set_state(GstElement *element, GstState state)
' Sets the state of the element.
Private Extern gst_element_set_state(element As Pointer, state As Integer) As Integer
' GstStateChangeReturn gst_element_get_state (GstElement *element, GstState *state, GstState *pending, GstClockTime timeout)
' Gets the state of the element.
Private Extern gst_element_get_state(element As Pointer, state As Pointer, pending As Pointer, timeout As Long) As Integer
' gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration)
' Queries an element (usually top-level pipeline or playbin element) for the total stream duration in nanoseconds.
Private Extern gst_element_query_duration(element As Pointer, GstFormat As Integer, duration As Pointer) As Boolean
' gboolean gst_element_seek_simple (GstElement *element, GstFormat format, GstSeekFlags seek_flags, gint64 seek_pos)
' Simple API to perform a seek on the given element.
Private Extern gst_element_seek_simple(element As Pointer, GstFormat As Integer, seek_flags As Integer, seek_pos As Long) As Boolean
' void g_signal_emit_by_name (gpointer instance, const gchar *detailed_signal, ...)
' Emits a signal.
Private Extern g_signal_emit_by_name(instance As Pointer, detailed_signal As String, GstSample As Pointer)
' GstCaps * gst_sample_get_caps (GstSample *sample)
' Get the caps associated with sample.
Private Extern gst_sample_get_caps(GstSample As Pointer) As Pointer
' GstStructure * gst_caps_get_structure (const GstCaps *caps, guint index)
' Finds the structure in caps that has the index index , and returns it.
Private Extern gst_caps_get_structure(GstCaps As Pointer, index As Integer) As Pointer
' gboolean gst_structure_get_int (const GstStructure *structure, const gchar *fieldname, gint *value)
' Sets the int pointed to by value corresponding to the value of the given field.
Private Extern gst_structure_get_int(structure As Pointer, fieldname As String, value As Pointer) As Boolean
' GstBuffer * gst_sample_get_buffer (GstSample *sample)
' Get the buffer associated with sample.
Private Extern gst_sample_get_buffer(GstSample As Pointer) As Pointer
' gboolean gst_buffer_map (GstBuffer *buffer, GstMapInfo *info, GstMapFlags flags)
' Fills info with the GstMapInfo of all merged memory blocks in buffer .
Private Extern gst_buffer_map(GstBuffer As Pointer, info As GstMapInfo, flags As Integer) As Boolean
' void gst_buffer_unmap (GstBuffer *buffer, GstMapInfo *info)
' Release the memory previously mapped with gst_buffer_map().
Private Extern gst_buffer_unmap(GstBuffer As Pointer, info As GstMapInfo)
' void gst_object_unref(gpointer object)
' Decrements the reference count on object.
Private Extern gst_object_unref(gobject As Pointer)
Library "libgdk_pixbuf-2.0:0.3000.7"
' GdkPixbuf * gdk_pixbuf_new_from_data (const guchar *data, GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, int width, int height, int rowstride, GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data)
' Creates a new GdkPixbuf out of in-memory image data. '
Private Extern gdk_pixbuf_new_from_data(data As GstMapInfo, colorspace As Integer, has_alpha As Boolean, bits_per_sample As Integer, width As Integer, height As Integer, rowstride As Integer, destroy_fn As Pointer, destroy_fn_data As Pointer) As Pointer
' gboolean gdk_pixbuf_save (GdkPixbuf *pixbuf, const char *filename, const char *type, GError **error, ...)
' Saves pixbuf to a file in format type. By default, "jpeg", "png", "ico" and "bmp" are possible file formats to save in.
Private Extern gdk_pixbuf_save(GdkPixbuf As Pointer, filename As String, type As String, GError As Pointer, altro As String) As Boolean
Public Sub Main()
Dim uri, caps, linea, imagen As String
Dim pipeline, sink, sample As Pointer
Dim capsP, s, buffer, pixbuf As Pointer
Dim rit, width, height As Integer
Dim dur, pos As Long
Dim tempus As Float
Dim bo As Boolean
Dim map As New GstMapInfo
uri = "file://" & "/ruta/del/archivo/video"
caps = "\x22video/x-raw,format=RGB,width=480,pixel-aspect-ratio=1/1\x22" ' El tamaño de la imagen .png será 480x360 (es possible modificarlo)
imagen = "/ruta/del/futuro/archivo/imagen.png"
tempus = 44.33 ' Extrae el frame que encontramos en la posición = 44,33% del video total
' Inicializa la libreria Gstreamer:
gst_init(0, 0)
' Crea una nueva pipeline:
linea = "uridecodebin uri=" & uri & " ! videoconvert ! videoscale ! appsink name=sink caps=" & caps
pipeline = gst_parse_launch(linea, 0)
If IsNull(pipeline) Then Error.Raise("Impossible crear una pipeline !")
sink = gst_bin_get_by_name(pipeline, "sink")
rit = gst_element_set_state(pipeline, GST_STATE_PAUSED)
If rit = GST_STATE_CHANGE_FAILURE Then Error.Raise("Impossible ejecutar el archivo !")
rit = gst_element_get_state(pipeline, 0, 0, 5 * GST_SECOND)
If rit = GST_STATE_CHANGE_FAILURE Then Error.Raise("Impossible ejecutar el archivo !")
' Obtiene la duración del video:
gst_element_query_duration(pipeline, GST_FORMAT_TIME, VarPtr(dur))
If dur <> -1 Then
pos = dur * tempus / 100
Else
pos = 1 * GST_SECOND
Endif
gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_KEY_UNIT Or GST_SEEK_FLAG_FLUSH, pos)
g_signal_emit_by_name(sink, "pull-preroll", VarPtr(sample))
gst_object_unref(sink)
If IsNull(sample) = False Then
capsP = gst_sample_get_caps(sample)
If IsNull(capsP) Then Error.Raise("Impossible obtener el formato del frame !")
s = gst_caps_get_structure(capsP, 0)
bo = gst_structure_get_int(s, "width", VarPtr(width))
bo = bo Or gst_structure_get_int(s, "height", VarPtr(height))
If bo = False Then Error.Raise("Impossible obtener el tamaño del frame !")
' Crea un pixmap de el buffer y lo guarda:
buffer = gst_sample_get_buffer(sample)
gst_buffer_map(buffer, map, GST_MAP_READ)
pixbuf = gdk_pixbuf_new_from_data(map.data, GDK_COLORSPACE_RGB, False, 8, width, height, ((width * 3) + 3) Xor 3, Null, Null)
If IsNull(pixbuf) Then Error.Raise("Impossible crear un nuevo pixbuf de los datos !")
gdk_pixbuf_save(pixbuf, imagen, "png", 0, Null)
gst_buffer_unmap(buffer, map)
Else
Error.Raise("Impossible guardar el archivo imagen !")
Endif
' Terminando...
gst_element_set_state(pipeline, GST_STATE_NULL)
gst_object_unref(pipeline)
End
última edición por vuott el Jueves, 18 Febrero 2016, 20:41; editado 8 veces
|
#4 Jueves, 18 Febrero 2016, 20:13 |
|
|
jsbsan
Analista Programador
Registrado: Septiembre 2009
Mensajes: 4175
Edad: 51 Ubicación: dos hermanas, sevilla
|
Re: ¿como Extraer Fotogramas De Un Video?
vuott:
Gracias, lo voy a probar en mi sistema de 32 bits, a ver si hay suerte.
Ya os cuento...
|
#5 Jueves, 18 Febrero 2016, 20:56 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: ¿como Extraer Fotogramas De Un Video?
lo voy a probar en mi sistema de 32 bits, a ver si hay suerte.
...... 32-bit ?
|
#6 Jueves, 18 Febrero 2016, 21:20 |
|
|
|
Temas parecidos
Temas parecidos
|
Página 1 de 1
|
Usuarios navegando en este tema: 0 registrados, 0 ocultos y 0 invitados Usuarios registrados conectados: Ninguno
|
No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas No puede adjuntar archivos Puede descargar archivos No puede publicar eventos en el calendario
|
|
|
|
|