|
|
| (7 intermediate revisions by 3 users not shown) |
| Line 1: |
Line 1: |
| This sample code will generate a thumbnail from any media.
| | {{Lowercase}} |
| It can be used by nautilus instead of totem-video-thumbnailer
| | Moved [http://git.videolan.org/?p=vlc.git;a=blob;f=doc/libvlc/vlc-thumb.c]. |
| /* Copyright [[User:Funman|Rafaël Carré]] (licence [http://en.wikipedia.org/wiki/WTFPL WTFPL]) */
| |
| <pre>
| |
| /* A video thumbnailer compatible with nautilus */
| |
| /* Copyright © 2007-2008 Rafaël Carré <funman@videolanorg> */ | |
|
| |
|
| #include <stdio.h>
| | [[Category:libVLC]] |
| #include <vlc/libvlc.h>
| |
| #include <stdlib.h>
| |
| #include <string.h>
| |
| #include <unistd.h>
| |
| #include <locale.h>
| |
| #include <sys/types.h>
| |
| #include <sys/stat.h>
| |
| | |
| /* gcc -ansi -Wall -Werror -lvlc-control vlc-video-thumbnailer.c */
| |
| | |
| #if 1
| |
| # define DEBUG( s ) fprintf( stderr, s"\n" );
| |
| #else
| |
| # define DEBUG( s )
| |
| #endif
| |
| | |
| /* position to seek to (out of 1.) */
| |
| #define POS 0.3
| |
| | |
| /* delay before aborting ( real delay will be * 2 ) */
| |
| #define MAX_DELAY 5.0
| |
| | |
| /* 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 )
| |
| {
| |
| float new_pos;
| |
| new_pos = ev->u.media_player_position_changed.new_position;
| |
| if( new_pos >= POS - ( POS / 10 ) )
| |
| {
| |
| DEBUG( "Position set" );
| |
| fini = 1; /* now we can take the snapshot */
| |
| }
| |
| }
| |
| else
| |
| {
| |
| fprintf( stderr, "Error: catched event %s\n",
| |
| libvlc_event_type_name( ev->type ) );
| |
| exit(1);
| |
| }
| |
| }
| |
| | |
| 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);
| |
| }
| |
| | |
| /* nautilus doesn't use .png extension, and vlc detects the filetype with the
| |
| * extension, so we use a temporary file to be sure we'll use png */
| |
| #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;
| |
| }
| |
| | |
| /* mandatory to support UTF-8 filenames (provided the locale is well set)*/
| |
| setlocale( LC_ALL, getenv( "LANG" ) );
| |
| | |
| const char const *input, *output;
| |
| int i_width, i_height = 0;
| |
| | |
| if( argc == 5 )
| |
| {
| |
| if( strcmp( argv[1], "-s" ) )
| |
| {
| |
| usage();
| |
| return 1;
| |
| }
| |
| i_width = atoi( argv[2] );
| |
| input = argv[3];
| |
| output = argv[4];
| |
| }
| |
| else
| |
| {
| |
| input = argv[1];
| |
| output = argv[2];
| |
| i_width = 0;
| |
| }
| |
| | |
| libvlc_exception_init( &ex );
| |
| | |
| /* libvlc settings */
| |
| const char* const args[] = {
| |
| "-I", "dummy", /* no interface */
| |
| "--vout", "dummy", /* we don't want video (output) */
| |
| "--no-audio", /* we don't want audio */
| |
| "--verbose=0", /* show only errors */
| |
| "--no-media-library", /* don't want that */
| |
| "--services-discovery", "", /* nor that */
| |
| "--no-video-title-show", /* nor the filename displayed */
| |
| "--no-stats", /* no stats */
| |
| "--ignore-config", /* don't use/overwrite the config */
| |
| "--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_player_t *m;
| |
| libvlc_media_t *m;
| |
| | |
| | |
| m = libvlc_media_new( libvlc, input, &ex );
| |
| catch();
| |
|
| |
| m = libvlc_media_player_new_from_media( m, &ex );
| |
| catch();
| |
| | |
| libvlc_media_release( m );
| |
| | |
| libvlc_media_player_play( m, &ex );
| |
| catch();
| |
| | |
| /* avoid introduction */
| |
| libvlc_media_player_set_position( m, POS, &ex );
| |
| catch();
| |
| | |
| libvlc_event_manager_t *em;
| |
| em = libvlc_media_player_event_manager( m, &ex );
| |
| catch();
| |
| | |
| libvlc_event_attach( em, libvlc_MediaInstancePositionChanged,
| |
| callback, NULL, &ex );
| |
| catch();
| |
| | |
| float max = MAX_DELAY; /* don't wait more MAX_DELAY seconds */
| |
| while( !fini && ( max -= .2 ) > 0 ) /* wait for the position changed event */
| |
| usleep( 200000 );
| |
| | |
| libvlc_event_detach( em, libvlc_MediaInstancePositionChanged,
| |
| callback, NULL, &ex );
| |
| catch();
| |
| | |
| DEBUG( "Taking snapshot" );
| |
| libvlc_video_take_snapshot( m, TEMP, i_width, i_height, &ex );
| |
| catch();
| |
| | |
| sleep( 1 ); /* be sure that the snapshot has been written */
| |
| | |
| DEBUG( "Stopping" );
| |
| libvlc_media_player_stop( m, &ex );
| |
| catch();
| |
| | |
| max = MAX_DELAY;
| |
| while( ( max -= .2 ) > 0 )
| |
| {
| |
| struct stat st;
| |
| if( stat( TEMP, &st ) == 0 )
| |
| break;
| |
| DEBUG( TEMP" doesn't exist" );
| |
| if( max <= .2 )
| |
| {
| |
| DEBUG( "Snapshot has not been written :(" );
| |
| goto end;
| |
| }
| |
| usleep( 200000 );
| |
| }
| |
| | |
| DEBUG( "Moving snapshot" );
| |
| char *mv;
| |
| if( asprintf( &mv, "mv \"%s\" \"%s\"", TEMP, output ) == -1 )
| |
| return 1;
| |
| system( mv );
| |
| free( mv );
| |
| | |
| end:
| |
| libvlc_media_player_release( m );
| |
| | |
| libvlc_release( libvlc, &ex );
| |
| catch();
| |
| | |
| return 0;
| |
| }</pre>
| |