|
Página 1 de 2
|
Como Mostrar Un Thumbnail De Un Video?
Autor |
Mensaje |
tincho
Analista Programador
Registrado: Noviembre 2014
Mensajes: 2565
Edad: 48 Ubicación:
|
Como Mostrar Un Thumbnail De Un Video?
Hola a todos.
Continuo con la aplicación destornishador, y ahora estoy intentando mostrar en un formulario una pequeña imagen del un video para "previsualizarlo".
Si alguien puede decirme como mostrar un fotograma de un video en un picturebox o algo parecido, me resultaría de gran ayuda, ya que hasta ahora no he dado en la tecla.
Dejo el programa como adjunto, por si al alguno le interesa echar un vistazo.
un saludo.
Descripción de la interfaz
(1) TableView con la propiedad drop activada que mostrara las rutas de los archivos
(2) CheckBox que de acuerdo a si están seleccionadas activaran los procesos.
(3) Boton de proceso de archivos, que acuara de acuerdo a los archivos que encuentre en la lista y según los checks que esten seleccionados para estos.
(4) Limpia la lista.
(5) Muestra los metadatos del archivo seleccionado en la lista (1)
(6) Al seleccionar un archivo de la lista se muestra la imagen o el thumbnail del documento odf.
(7) Acerca de Destornishador.
(8) Salir de la aplicación.
(9) Barra de títulos que cambia de acuerdo al fichero seleccionado en la lista.
Descripción: |
|
Descargar |
Nombre del archivo: |
destornishador-v0.0.47.zip |
Tamaño: |
94.84 KB |
Descargado: |
36 veces |
Descripción: |
|
Descargar |
Nombre del archivo: |
destornishador-v0.0.47.zip |
Tamaño: |
94.84 KB |
Descargado: |
36 veces |
Descripción: |
|
Descargar |
Nombre del archivo: |
destornishador-v0.0.47.zip |
Tamaño: |
94.84 KB |
Descargado: |
36 veces |
|
#1 Sabado, 09 Enero 2016, 22:07 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
..... como mostrar un fotograma de un video en un picturebox o algo parecido
Hooola tincho !
Pregunta muy interesante y compleja !
Vi que en el tu programa usaste avconv con Shell..
Parece que puede extraer tambien uno o más frames de video:
http://ubuntuforums.org/showthread.php?t=2014630
http://www.dototot.com/how-to-extra...vconv-on-linux/
Saludos
última edición por vuott el Domingo, 10 Enero 2016, 21:38; editado 6 veces
|
#2 Domingo, 10 Enero 2016, 00:08 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
Quizas, podrías utilizar un escamotage, usando el Componente gb.media .
Prueba este simple ejemplo:
Private mp As New MediaPlayer
Private salidaVideo As MediaControl
Public Sub Form_Open()
Dim Area As DrawingArea
With Area = New DrawingArea(Me)
.X = 10
.Y = 10
.W = 100
.H = 100
End With
ControlloVideo(Area)
With mp
.URL = Media.URL("/ruta/del/video")
.State = 4
.State = 2
End With
Wait 0.1
' El video serà mostrado en la "DrawingArea":
salidaVideo.SetWindow(Area)
Me.Show
' Ejecuta el video empezando desde el 40° secundo:
With mp
.Audio.Mute = True
.Play()
.Position = 40.00
Wait 0.1
' Pausa el video "ad infinitum" !
mp.Pause()
End With
End
Public Sub ControlloVideo(Drar As DrawingArea)
' Instancia el control de la salida video:
salidaVideo = New MediaControl(mp, "ximagesink")
' Establece el control de la salida video:
mp.Video.Output = salidaVideo
salidaVideo.SetWindow(Drar)
End
Public Sub Form_Close()
mp.Stop()
End
|
#3 Domingo, 10 Enero 2016, 05:36 |
|
|
tincho
Analista Programador
Registrado: Noviembre 2014
Mensajes: 2565
Edad: 48 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
Vi que en el tu programa que usaste avconv con Shell..
Muy buena respuesta he explorado esta opción y efectivamente funciona de manera similar a la extracción del thumbnail de odt que posteaste en el otro post.
Muchas gracias Vuott.
|
#4 Domingo, 10 Enero 2016, 20:21 |
|
|
tincho
Analista Programador
Registrado: Noviembre 2014
Mensajes: 2565
Edad: 48 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
Quizas, podrías utilizar un escamotage, usando el Componente [color=brown]gb.media
Muy interesante opción, porque realmente se puede ver el video.
Tal vez incluya la opción de ver el video en el programa pero, has despertado mi curiosidad, ya que este componente se podría usar para dejar mensajes asociados a un documento o fichero (si se pueden grabar notas de audio), o para escuchar musica mientras se trabaja o para mirar una película etc. etc. etc.
|
#5 Domingo, 10 Enero 2016, 20:28 |
|
|
jguardon
Administrador
Registrado: Septiembre 2009
Mensajes: 2708
Edad: 57 Ubicación: Granada
|
Re: Como Mostrar Un Thumbnail De Un Video?
vuott siempre sorprende
+1
Saludos
=================== Jesús Guardón
Por favor, usemos el corrector ortográfico antes de pulsar el botón "Enviar".
"uo ǝs ʇɐu pıɟıɔıן ɐdɹǝupǝɹ ɐ dɹoƃɹɐɯɐɹ, soןo ɥɐʎ bnǝ dɹodouǝɹsǝןo"
|
#6 Domingo, 10 Enero 2016, 23:52 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
|
#7 Domingo, 10 Enero 2016, 23:56 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
Hooooooola tincho !
Vamos a probar este codigo, que he escrito, mezclando gambas, funciones externas de Libav y de C, codigo en C y tambien un poquito de... Cha Cha Cha
Private Enum AVMEDIA_TYPE_UNKNOWN = -1, AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO,
AVMEDIA_TYPE_DATA, AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_ATTACHMENT, AVMEDIA_TYPE_NB
Private Const PIX_FMT_RGB24 As Integer = 2
Library "libavformat:54.20.4"
' void av_register_all(void)
' Initialize libavformat and register all the muxers, demuxers and protocols.
Private Extern av_register_all()
' int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)
' Open an input stream and read the header. The codecs are not opened.
Private Extern avformat_open_input(ps As Pointer, filename As String, fmt As Pointer, options As Pointer) As Integer
' int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
' Read packets of a media file to get stream information.
Private Extern avformat_find_stream_info(ic As Pointer, options As Pointer) As Integer
' int av_read_frame(AVFormatContext *s, AVPacket *pkt)
' Return the next frame of a stream.
Private Extern av_read_frame(s As Pointer, pkt As Pointer) As Integer
Library "libavcodec:54.35.0"
' int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
' Initialize the AVCodecContext to use the given AVCodec.
Private Extern avcodec_open2(avctx As Pointer, codec As Pointer, options As Pointer) As Integer
' AVFrame *avcodec_alloc_frame(void)
' Allocate an AVFrame and set its fields to default values.
Private Extern avcodec_alloc_frame() As Pointer
' int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
' Calculate the size in bytes that a picture of the given width and height would occupy.
Private Extern avpicture_get_size(pix_fmt As Integer, width As Integer, height As Integer) As Integer
' int avpicture_fill(AVPicture *picture, uint8_t *ptr, enum AVPixelFormat pix_fmt, int width, int height)
' Fill in the AVPicture fields
Private Extern avpicture_fill(AVpicture As Pointer, ptr As Pointer, pix_fmt As Integer, width As Integer, height As Integer) As Integer
' int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt)
' Decode the video frame of size avpkt->size from avpkt->data into picture.
Private Extern avcodec_decode_video2(avctx As Pointer, AVpicture As Pointer, got_picture As Pointer, avpkt As Pointer) As Integer
' void avcodec_free_frame(AVFrame **frame)
' Free the frame and any dynamically allocated objects in it.
Private Extern avcodec_free_frame(AVFrame As Pointer)
' int avcodec_close(AVCodecContext *avctx)
' Close a given AVCodecContext and free all the data associated with it.
Private Extern avcodec_close(avctx As Pointer) As Integer
Library "libswscale:2.1.1"
Private Const SWS_BILINEAR As Integer = 2
' struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat,
' int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param)
' Allocate and return an SwsContext.
Private Extern sws_getContext(srcW As Integer, srcH As Integer, pix As Integer, dstW As Integer, dstH As Integer, dstF As Integer, flags As Integer, srcFilt As Pointer, dstFilt As Pointer, param As Pointer) As Pointer
' int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[])
' Scale the image slice in srcSlice and put the resulting scaled slice in the image in dst. A slice is a sequence of consecutive rows in an image.
Private Extern sws_scale(c As Pointer, srcSlice As Pointer, srcStride As Pointer, srcSliceY As Integer, srcSliceH As Integer, dst As Pointer, dstStride As Integer) As Integer
Library "libc:6"
' FILE *fopen (const char *__filename, const char *__modes)
' Open a file and create a new stream for it.
Private Extern fopen(filename As String, modes As String) As Pointer
' int fclose (FILE *__stream)
' Close STREAM.
Private Extern fclose(filestream As Pointer) As Integer
Library "/tmp/libadhoc"
' int Dim_AVFormatContext()
' Ottiene la dimensione della Struttura 'AVFormatContext'.
Private Extern Dim_AVFormatContext() As Integer
' int PrimoVideo(struct AVFormatContext *p, int type_video)
' Cerca il primo flusso video.
Private Extern PrimoVideo(p As Pointer, type_video As Integer) As Integer
' struct AVCodecContext * OttienePuntatore(struct AVFormatContext *p, int video)
' Ottiene un puntatore al condesto di decodifica.
Private Extern OttienePuntatore(p As Pointer, video As Integer) As Pointer
' AVCodecContex * Decodificatore(struct AVCodecContext *orig)
' Cerca il decodificatore adatto per il flusso video.
Private Extern Decodificatore(orig As Pointer) As Pointer
' struct AVCodecContext * CopiaContesto(struct AVCodec *codec, struct AVCodecContext *orig)
' Copia il contesto video.
Private Extern CopiaContesto(codec As Pointer, orig As Pointer) As Pointer
' int Dim_Packet()
' Ottiene la dimensione della Struttura 'AVPacket'.
Private Extern Dim_Packet() As Integer
' void ScriviFile(AVFrame *pFrame, int width, FILE *pFile)
' Scrive il file immagine ppm.
Private Extern ScriviFile(pFrame As Pointer, width As Integer, height As Integer, pFile As Pointer) As Pointer
Public Sub Main()
Dim rit, video, i, byte As Integer
Dim termineFrame, fotogramma As Integer
Dim ori, cod, codecCtx, frame, rgb As Pointer
Dim context, buffer, sws, packet As Pointer
Dim fileVideo As String
fileVideo = "/ruta/del/file/video"
If Not Exist(fileVideo) Then Error.Raise("File video inesistente !")
fotogramma = 1000
' Crea l'apposita libreria .so per la gestione di alcune risorse complesse di Libav:
CreaSo()
rit = Dim_AVFormatContext()
If rit = 0 Then Error.Raise("Dimensione della Struttura 'AVFormatContext' errata !")
context = Alloc(rit)
av_register_all()
' Apre un file video:
rit = avformat_open_input(VarPtr(context), fileVideo, 0, 0)
If rit <> 0 Then Error.Raise("Impossibile aprire il file video !")
rit = avformat_find_stream_info(context, 0)
If rit <> 0 Then Error.Raise("Impossibile avere informazioni del flusso video !")
video = -1
' Cerca il primo flusso video:
video = PrimoVideo(context, AVMEDIA_TYPE_VIDEO)
If video = -1 Then Error.Raise("Impossibile trovare il primo flusso video !")
' Ottiene un puntatore al contesto codec per il flusso video:
ori = OttienePuntatore(context, video)
If IsNull(ori) Then Error.Raise("Codice non supportato !")
cod = Decodificatore(ori)
If IsNull(cod) Then Error.Raise("Codice non supportato !")
' Copia il contesto di decodificazione:
codecCtx = CopiaContesto(cod, ori)
If IsNull(codecCtx) Then Error.Raise("Impossibile copiare il contesto di decodificazione !")
' Apre il decodificatore:
rit = avcodec_open2(codecCtx, cod, 0)
If rit < 0 Then Error.Raise("Impossibile aprire il decodificatore !")
' Alloca i frame video:
frame = avcodec_alloc_frame()
' Alloca una struttura AVFrame:
rgb = avcodec_alloc_frame()
If IsNull(rgb) Then Error.Raise("Impossibile allocare una struttura 'AVFrame' !")
' Determina la dimensione del buffer richiesto e lo alloca:
byte = avpicture_get_size(PIX_FMT_RGB24, Int@(codecCtx + 148), Int@(codecCtx + 152))
buffer = Alloc(byte)
' Assegna parti appropriate del buffer ai piani di immagine in 'rgb':
avpicture_fill(rgb, buffer, PIX_FMT_RGB24, Int@(codecCtx + 148), Int@(codecCtx + 152))
' Inizializa il contesto SWS:
sws = sws_getContext(Int@(codecCtx + 148), Int@(codecCtx + 152), 0, Int@(codecCtx + 148), Int@(codecCtx + 152), PIX_FMT_RGB24, SWS_BILINEAR, 0, 0, 0)
rit = Dim_Packet()
If rit = 0 Then Error.Raise("Dimensione della Struttura 'AVPacket' errata !")
packet = Alloc(rit)
While av_read_frame(context, packet) >= 0
If Int@(packet + 28) = video Then
avcodec_decode_video2(codecCtx, frame, VarPtr(termineFrame), packet)
If termineFrame Then
' Converte l'immagine dal suo formato nativo in RGB e la salva in un file immagine PPM:
sws_scale(sws, frame, frame + 64, 0, Int@(codecCtx + 152), rgb, rgb + 64)
Inc i
If i = fotogramma Then
SalvaImmagine(rgb, Int@(codecCtx + 148), Int@(codecCtx + 152), i)
Break
Endif
Endif
Endif
Wend
' Va in chiusura:
Free(packet)
Free(buffer)
Free(context)
avcodec_free_frame(VarPtr(rgb))
avcodec_free_frame(VarPtr(frame))
avcodec_close(codecCtx)
avcodec_close(ori)
End
Private Procedure SalvaImmagine(pfr As Pointer, width As Integer, height As Integer, ifr As Integer)
Dim fileimmago As String
Dim fl As Pointer
' Apre il file:
fileimmago = "/tmp/image" & CStr(ifr) & ".ppm"
fl = fopen(fileimmago, "wb")
If IsNull(fl) Then Error.Raise("Impossibile aprire il file video '.ppm' da salvare !")
ScriviFile(pfr, width, height, fl)
' Scrive l'intestazione del nuovo file PPM:
File.Save(fileimmago, "P6\n" & CStr(width) & Chr(32) & CStr(height) & "\n255\n" & File.Load(fileimmago))
' Chiude il file:
fclose(fl)
End
Private Procedure CreaSo()
File.Save("/tmp/libadhoc.c", "#include <libavcodec/avcodec.h>" &
"\n#include <libavformat/avformat.h>" &
"\n#include <libswscale/swscale.h>" &
"\n#include <stdio.h>" &
"\n\n" &
"\n struct AVCodecContext *codecCtx = NULL;" &
"\n struct AVCodec *codec;" &
"\n\n" &
"int Dim_AVFormatContext() {" &
"\n return sizeof(struct AVFormatContext);\n}" &
"\n\n" &
"int PrimoVideo(struct AVFormatContext *p, int type_video) {" &
"\n int i;" &
"\n for(i=0; i<p->nb_streams; i++)" &
"\n if(p->streams[i]->codec->codec_type==type_video) {" &
"\n return i;" &
"\n break;\n }\n}" &
"\n\n" &
"struct AVCodecContext * OttienePuntatore(struct AVFormatContext *p, int video) {" &
"\n struct AVCodecContext *orig = p->streams[video]->codec;\n}" &
"\n\n" &
"struct AVCodec * Decodificatore(struct AVCodecContext *orig) {" &
"\n codec = avcodec_find_decoder(orig->codec_id);" &
"\n return codec;\n}" &
"\n\n" &
"struct AVCodecContext * CopiaContesto(struct AVCodec *codec, struct AVCodecContext *orig) {" &
"\n codecCtx = avcodec_alloc_context3(codec);" &
"\n if(avcodec_copy_context(codecCtx, orig) == 0)" &
"\n return codecCtx;\n}" &
"\n\n" &
"int Dim_Packet() {" &
"\n return sizeof(struct AVPacket);\n}" &
"\n\n" &
"void ScriviFile(AVFrame *pFrame, int width, int height, FILE *pFile) {" &
"\n int y;" &
"\n for(y=0; y<height; y++)" &
"\n fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);" &
"\n\n}")
Shell "gcc -o /tmp/libadhoc.so /tmp/libadhoc.c -shared -fPIC -lavformat -lavcodec -lavutil -lswscale -lz -lbz2" Wait
End
última edición por vuott el Martes, 12 Enero 2016, 02:22; editado 4 veces
|
#8 Martes, 12 Enero 2016, 02:14 |
|
|
tincho
Analista Programador
Registrado: Noviembre 2014
Mensajes: 2565
Edad: 48 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
Vamos a probar este codigo, que he escrito, mezclando gambas, funciones externas de Libav y de C, codigo en C...
Woow!! que super código hiciste!! creo que tiene bastante cha cha cha eh!! jaja
Ahora unas preguntas desde el rincón del aprendiz Este codigo, si no entiendo mal, le pasas un parámetro "archivo-de-video" y genera un "archivo-de-imagen.ppm" en el disco.
En el camino usas magia vudu c usando las librerías "libavformat:54.20.4","libavcodec:54.35.0","libswscale:2.1.1" y "libc:6".
Que es "/tmp/libadhoc"?? es algo así como un enlace o traductor para hablar con las librerias c?
Como uso este código? lo puse en el FMain de un proyecto nuevo (cambie la ruta a un video mp4) y no funciono. que estoy haciendo algo mal?
Nuevamente has despertado mi curiosidad porque hace un tiempo pregunte por el uso de una librería en c++ para manejar ficheros dxf y me comentaste que es muy complicado usar librerias C++.
Por lo que veo en este código que has escrito, supongo que se podrá escribir algo parecido par la librería en C LibreDWG para manejar ficheros dwg en gambas. (voy a poner esto en un post a tal fin)
Muchas gracias Vuott.
|
#9 Viernes, 15 Enero 2016, 12:23 |
|
|
vuott
Analista Programador
Registrado: Agosto 2013
Mensajes: 2086
Edad: 60 Ubicación:
|
Re: Como Mostrar Un Thumbnail De Un Video?
Que es "/tmp/libadhoc"?? es algo así como un enlace o traductor para hablar con las librerias c?
No siempre es posible traducir adecuadamente lineas de codigo de C a gambas; otras veces gambas no siempre es capaz de manejar correctamente Estructuras muy complejas y otros recursos complejos del C.
En estos casos es conveniente manejar con seguridad las Estructuras externas (u otras líneas de código en C) demasiado complejas, usando una adecuada librería esterna, escrita en C por nosotros. Mediante esta librería esterna ad hoc podemos utilizar directamente aquellas líneas de codigo C muy complejas. Es decir que usamos codigo C directamente !
http://www.gambas-it.org/wiki/index...rutture_esterne
De gambas vamos en C y volvemos a gambas del C.
Como uso este código? lo puse en el FMain de un proyecto nuevo (cambie la ruta a un video mp4) y no funciono. que estoy haciendo algo mal?
A mi funciona tambien en FMain.
Precisando:
1) Claramente se necesita tener instaladas en el sistema las librerias de Libav y de libswscale que tú has enumerado.
2) El mi codigo puede funcionar solo en un sistema de 64-bit !
3) Si sigue no funcionando (precisamente, quiero decir, si no crea el archivo imagen PPM), cambia el valor de la variable fotogramma (500 o menos).
última edición por vuott el Viernes, 15 Enero 2016, 13:58; editado 5 veces
|
#10 Viernes, 15 Enero 2016, 13:19 |
|
|
|
Temas parecidos
Temas parecidos
|
Página 1 de 2
|
Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado 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
|
|
|
|
|