Difference between revisions of "LibVLC SampleCode Thumbnailer"
Jump to navigation
Jump to search
(retry if libvlc is too slow) |
(use libvlc events) |
||
Line 9: | Line 9: | ||
#include <unistd.h> | #include <unistd.h> | ||
+ | /* position to seek to (out of 1.) */ | ||
+ | #define POS 0.3 | ||
+ | |||
+ | /* for the callback to notify the main thread that the position changed */ | ||
+ | static int fini = 0; | ||
+ | |||
+ | /* to catch problems */ | ||
static libvlc_exception_t ex; | static libvlc_exception_t ex; | ||
+ | |||
+ | /* "position changed" callback */ | ||
+ | static void callback( const libvlc_event_t *ev, void *param ) | ||
+ | { | ||
+ | if( ev->type == libvlc_MediaInstancePositionChanged ) | ||
+ | { | ||
+ | /* XXX: add a tolerance ? (POS +/- 10%) */ | ||
+ | if( ev->u.media_instance_position_changed.new_position >= POS ) | ||
+ | fini = 1; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | fprintf( stderr, "Error: catched event %s\n", | ||
+ | libvlc_event_type_name( ev->type ) ); | ||
+ | } | ||
+ | } | ||
static void catch (void) | static void catch (void) | ||
Line 49: | Line 72: | ||
if( argc == 5 ) | if( argc == 5 ) | ||
{ | { | ||
− | if( | + | if( strncmp( argv[1], "-s", 3 ) ) |
{ | { | ||
usage(); | usage(); | ||
Line 63: | Line 86: | ||
const char* const args[] = { | const char* const args[] = { | ||
"-I", "dummy", /* no interface */ | "-I", "dummy", /* no interface */ | ||
− | "--vout", "dummy", /* we don't want video */ | + | "--vout", "dummy", /* we don't want video (output) */ |
"--no-audio", /* we don't want audio */ | "--no-audio", /* we don't want audio */ | ||
"--verbose=1", /* show only errors & warnings */ | "--verbose=1", /* show only errors & warnings */ | ||
Line 69: | Line 92: | ||
"--services-discovery", "", /* nor that */ | "--services-discovery", "", /* nor that */ | ||
"--no-video-title-show", /* nor the filename displayed */ | "--no-video-title-show", /* nor the filename displayed */ | ||
+ | "--no-stats", /* no stats */ | ||
"--no-sub-autodetect", /* don't want subtitles */ | "--no-sub-autodetect", /* don't want subtitles */ | ||
− | "--control", "", /* don't want interface */ | + | "--control", "", /* don't want interface (again) */ |
− | "--extraintf", "" /* | + | "--no-inhibit", /* i say no interface ! */ |
+ | "--no-disable-screensaver", /* wanna fight ? */ | ||
+ | "--extraintf", "" /* ok, it will be a piece of cake */ | ||
}; | }; | ||
Line 92: | Line 118: | ||
catch(); | catch(); | ||
− | /* | + | /* avoid introduction */ |
− | libvlc_media_instance_set_position( mi, | + | libvlc_media_instance_set_position( mi, POS, &ex ); |
catch(); | catch(); | ||
− | int | + | libvlc_event_manager_t *em; |
− | while( | + | em = libvlc_media_instance_event_manager( mi, &ex ); |
− | + | catch(); | |
− | + | ||
− | sleep(1); | + | libvlc_event_attach( em, libvlc_MediaInstancePositionChanged, |
+ | callback, NULL, &ex ); | ||
+ | catch(); | ||
+ | |||
+ | int max = 10; /* don't wait more than 10s */ | ||
+ | while( !fini && max-- ) /* wait for the event */ | ||
+ | sleep( 1 ); | ||
+ | |||
+ | libvlc_event_detach( em, libvlc_MediaInstancePositionChanged, | ||
+ | callback, NULL, &ex ); | ||
+ | catch(); | ||
− | + | libvlc_video_take_snapshot( mi, TEMP, i_width, i_height, &ex ); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
catch(); | catch(); | ||
− | /* wait | + | sleep( 1 ); /* wait for the snapshot to be written */ |
− | |||
char *mv; | char *mv; | ||
Line 130: | Line 158: | ||
return 0; | return 0; | ||
− | } | + | }</pre> |
− | </pre> |
Revision as of 10:29, 16 January 2008
This sample code will generate a thumbnail from any media. It can be used by nautilus instead of totem-video-thumbnailer
/* Copyright Rafaël Carré (licence WTFPL) */
#include <stdio.h> #include <vlc/libvlc.h> #include <stdlib.h> #include <string.h> #include <unistd.h> /* position to seek to (out of 1.) */ #define POS 0.3 /* for the callback to notify the main thread that the position changed */ static int fini = 0; /* to catch problems */ static libvlc_exception_t ex; /* "position changed" callback */ static void callback( const libvlc_event_t *ev, void *param ) { if( ev->type == libvlc_MediaInstancePositionChanged ) { /* XXX: add a tolerance ? (POS +/- 10%) */ if( ev->u.media_instance_position_changed.new_position >= POS ) fini = 1; } else { fprintf( stderr, "Error: catched event %s\n", libvlc_event_type_name( ev->type ) ); } } static void catch (void) { if (libvlc_exception_raised (&ex)) { fprintf (stderr, "Exception: %s\n", libvlc_exception_get_message (&ex)); exit(1); } libvlc_exception_clear (&ex); } #define TEMP "/tmp/vlc-video-thumbnailer.png" #define usage() \ fprintf( stderr, \ "Usage: %s input output\n" \ "input being any video VLC can read, and output a png file\n" \ , argv[0] ) int main( int argc, const char **argv ) { if( argc != 3 && argc != 5 ) { usage(); if( argc == 2 && ( !strcmp( argv[1], "-h" ) || strcmp( argv[1], "--help") ) ) return 0; else return 1; } const char *input = argv[1]; const char *output = argv[2]; int i_width = 0; int i_height = 0; if( argc == 5 ) { if( strncmp( argv[1], "-s", 3 ) ) { usage(); return 1; } i_width = atoi( argv[2] ); input = argv[3]; output = argv[4]; } libvlc_exception_init( &ex ); const char* const args[] = { "-I", "dummy", /* no interface */ "--vout", "dummy", /* we don't want video (output) */ "--no-audio", /* we don't want audio */ "--verbose=1", /* show only errors & warnings */ "--no-media-library", /* don't want that */ "--services-discovery", "", /* nor that */ "--no-video-title-show", /* nor the filename displayed */ "--no-stats", /* no stats */ "--no-sub-autodetect", /* don't want subtitles */ "--control", "", /* don't want interface (again) */ "--no-inhibit", /* i say no interface ! */ "--no-disable-screensaver", /* wanna fight ? */ "--extraintf", "" /* ok, it will be a piece of cake */ }; int nargs = sizeof(args) / sizeof(args[0]); libvlc_instance_t *libvlc = libvlc_new( nargs, args, &ex ); catch(); libvlc_media_instance_t *mi; libvlc_media_descriptor_t *md; md = libvlc_media_descriptor_new( libvlc, input, &ex ); catch(); mi = libvlc_media_instance_new_from_media_descriptor( md, &ex ); catch(); libvlc_media_descriptor_release( md ); libvlc_media_instance_play( mi, &ex ); catch(); /* avoid introduction */ libvlc_media_instance_set_position( mi, POS, &ex ); catch(); libvlc_event_manager_t *em; em = libvlc_media_instance_event_manager( mi, &ex ); catch(); libvlc_event_attach( em, libvlc_MediaInstancePositionChanged, callback, NULL, &ex ); catch(); int max = 10; /* don't wait more than 10s */ while( !fini && max-- ) /* wait for the event */ sleep( 1 ); libvlc_event_detach( em, libvlc_MediaInstancePositionChanged, callback, NULL, &ex ); catch(); libvlc_video_take_snapshot( mi, TEMP, i_width, i_height, &ex ); catch(); sleep( 1 ); /* wait for the snapshot to be written */ char *mv; if( asprintf( &mv, "mv %s %s", TEMP, output ) == -1 ) return 1; system( mv ); free( mv ); libvlc_media_instance_stop( mi, &ex ); catch(); libvlc_media_instance_release( mi ); libvlc_release( libvlc, &ex ); catch(); return 0; }