X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finput%2Fmeta.c;h=4ced9e4887b3094ed462920f24beb12b3acd5005;hb=f188c1f57cf840828fbd34e04818576fd8ca1a46;hp=afb48adf63a7308282f6c92772808d9faf7636d0;hpb=13495399910badd56f947af8c88d07fda997ad3c;p=vlc diff --git a/src/input/meta.c b/src/input/meta.c index afb48adf63..4ced9e4887 100644 --- a/src/input/meta.c +++ b/src/input/meta.c @@ -22,20 +22,27 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include #include #include #include +#include #include "../playlist/playlist_internal.h" #include +#include /* PATH_MAX */ +#include #ifdef HAVE_SYS_STAT_H # include #endif -// FIXME be sure to not touch p_meta without lock on p_item +#include "../libvlc.h" static const char * meta_type_to_string[VLC_META_TYPE_COUNT] = { @@ -43,15 +50,15 @@ static const char * meta_type_to_string[VLC_META_TYPE_COUNT] = [vlc_meta_Artist] = N_("Artist"), [vlc_meta_Genre] = N_("Genre"), [vlc_meta_Copyright] = N_("Copyright"), - [vlc_meta_Album] = N_("Album/movie/show title"), - [vlc_meta_TrackNumber] = N_("Track number/position in set"), + [vlc_meta_Album] = N_("Album"), + [vlc_meta_TrackNumber] = N_("Track number"), [vlc_meta_Description] = N_("Description"), [vlc_meta_Rating] = N_("Rating"), [vlc_meta_Date] = N_("Date"), [vlc_meta_Setting] = N_("Setting"), [vlc_meta_URL] = N_("URL"), [vlc_meta_Language] = N_("Language"), - [vlc_meta_NowPlaying] = N_("Language"), + [vlc_meta_NowPlaying] = N_("Now Playing"), [vlc_meta_Publisher] = N_("Publisher"), [vlc_meta_EncodedBy] = N_("Encoded by"), [vlc_meta_ArtworkURL] = N_("Artwork URL"), @@ -70,7 +77,7 @@ static int __input_FindArtInCache( vlc_object_t *, input_item_t *p_item ); vlc_bool_t input_MetaSatisfied( playlist_t *p_playlist, input_item_t *p_item, uint32_t *pi_mandatory, uint32_t *pi_optional ) { - (void)p_playlist; + VLC_UNUSED(p_playlist); *pi_mandatory = VLC_META_ENGINE_TITLE | VLC_META_ENGINE_ARTIST; uint32_t i_meta = input_CurrentMetaFlags( p_item->p_meta ); @@ -89,7 +96,8 @@ int input_MetaFetch( playlist_t *p_playlist, input_item_t *p_item ) assert( i_mandatory ); /* FIXME: object creation is overkill, use p_private */ - p_me = vlc_object_create( p_playlist, VLC_OBJECT_META_ENGINE ); + p_me = vlc_custom_create( VLC_OBJECT(p_playlist), sizeof( *p_me ), + VLC_OBJECT_GENERIC, "meta engine" ); p_me->i_flags |= OBJECT_FLAGS_NOINTERACT; p_me->i_flags |= OBJECT_FLAGS_QUIET; p_me->i_mandatory = i_mandatory; @@ -99,11 +107,11 @@ int input_MetaFetch( playlist_t *p_playlist, input_item_t *p_item ) p_me->p_module = module_Need( p_me, "meta fetcher", 0, VLC_FALSE ); if( !p_me->p_module ) { - vlc_object_destroy( p_me ); + vlc_object_release( p_me ); return VLC_EGENERIC; } module_Unneed( p_me, p_me->p_module ); - vlc_object_destroy( p_me ); + vlc_object_release( p_me ); input_item_SetMetaFetched( p_item, VLC_TRUE ); @@ -111,7 +119,7 @@ int input_MetaFetch( playlist_t *p_playlist, input_item_t *p_item ) } /* Return codes: - * 0 : Art is in cache + * 0 : Art is in cache or is a local file * 1 : Art found, need to download * -X : Error/not found */ @@ -119,31 +127,37 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item ) { int i_ret = VLC_EGENERIC; module_t *p_module; - char * psz_album = input_item_GetAlbum( p_item ); - char * psz_artist = input_item_GetArtist( p_item ); - char * psz_title = input_item_GetAlbum( p_item ); + char *psz_title, *psz_artist, *psz_album; - if( !p_item->p_meta ) - return VLC_EGENERIC; + psz_artist = input_item_GetArtist( p_item ); + psz_album = input_item_GetAlbum( p_item ); + psz_title = input_item_GetTitle( p_item ); + if(!psz_title) + psz_title = input_item_GetName( p_item ); - if( !p_item->psz_name && !input_item_GetTitle( p_item ) && - (!input_item_GetArtist( p_item ) || !input_item_GetAlbum( p_item )) ) + if( !psz_title && !psz_artist && !psz_album ) return VLC_EGENERIC; + free( psz_title ); + /* If we already checked this album in this session, skip */ - if( input_item_GetArtist( p_item ) && input_item_GetAlbum( p_item ) ) + if( psz_artist && psz_album ) { FOREACH_ARRAY( playlist_album_t album, p_playlist->p_fetcher->albums ) - if( !strcmp( album.psz_artist, input_item_GetArtist( p_item ) ) && - !strcmp( album.psz_album, input_item_GetAlbum( p_item ) ) ) + if( !strcmp( album.psz_artist, psz_artist ) && + !strcmp( album.psz_album, psz_album ) ) { msg_Dbg( p_playlist, " %s - %s has already been searched", - input_item_GetArtist( p_item ), input_item_GetAlbum( p_item ) ); + psz_artist, psz_album ); /* TODO-fenrir if we cache art filename too, we can go faster */ + free( psz_artist ); + free( psz_album ); if( album.b_found ) { - /* Actually get URL from cache */ - input_FindArtInCache( p_playlist, p_item ); + if( !strncmp( album.psz_arturl, "file://", 7 ) ) + input_item_SetArtURL( p_item, album.psz_arturl ); + else /* Actually get URL from cache */ + input_FindArtInCache( p_playlist, p_item ); return 0; } else @@ -153,23 +167,46 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item ) } FOREACH_END(); } + free( psz_artist ); + free( psz_album ); input_FindArtInCache( p_playlist, p_item ); - if( !EMPTY_STR(input_item_GetArtURL( p_item )) ) - return 0; + + char *psz_arturl = input_item_GetArtURL( p_item ); + if( psz_arturl ) + { + /* We already have an URL */ + if( !strncmp( psz_arturl, "file://", strlen( "file://" ) ) ) + { + free( psz_arturl ); + return 0; /* Art is in cache, no need to go further */ + } + + free( psz_arturl ); + + /* Art need to be put in cache */ + return 1; + } PL_LOCK; p_playlist->p_private = p_item; - if( input_item_GetAlbum( p_item ) && input_item_GetArtist( p_item ) ) + psz_album = input_item_GetAlbum( p_item ); + psz_artist = input_item_GetArtist( p_item ); + psz_title = input_item_GetTitle( p_item ); + if( !psz_title ) + psz_title = input_item_GetName( p_item ); + + if( psz_album && psz_artist ) { msg_Dbg( p_playlist, "searching art for %s - %s", - input_item_GetArtist( p_item ), input_item_GetAlbum( p_item ) ); + psz_artist, psz_album ); } else { msg_Dbg( p_playlist, "searching art for %s", - input_item_GetTitle( p_item ) ? input_item_GetTitle( p_item ) : p_item->psz_name ); + psz_title ); } + free( psz_title ); p_module = module_Need( p_playlist, "art finder", 0, VLC_FALSE ); @@ -179,14 +216,20 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item ) msg_Dbg( p_playlist, "unable to find art" ); /* Record this album */ - if( input_item_GetArtist( p_item ) && input_item_GetAlbum( p_item ) ) + if( psz_artist && psz_album ) { playlist_album_t a; - a.psz_artist = strdup( input_item_GetArtist( p_item ) ); - a.psz_album = strdup( input_item_GetAlbum( p_item ) ); + a.psz_artist = psz_artist; + a.psz_album = psz_album; + a.psz_arturl = input_item_GetArtURL( p_item ); a.b_found = (i_ret == VLC_EGENERIC ? VLC_FALSE : VLC_TRUE ); ARRAY_APPEND( p_playlist->p_fetcher->albums, a ); } + else + { + free( psz_artist ); + free( psz_album ); + } if( p_module ) module_Unneed( p_playlist, p_module ); @@ -196,122 +239,150 @@ int input_ArtFind( playlist_t *p_playlist, input_item_t *p_item ) return i_ret; } -#ifndef MAX_PATH -# define MAX_PATH 250 -#endif -#define ArtCacheCreateName(a,b,c,d,e,f) __ArtCacheCreateName(VLC_OBJECT(a),b,c,d,e,f) -static void __ArtCacheCreateName( vlc_object_t *p_obj, - char psz_filename[MAX_PATH+1], - const char *psz_title, - const char *psz_artist, const char *psz_album, - const char *psz_extension ) +static void ArtCacheCreateDir( const char *psz_dir ) { - if( psz_artist && psz_artist ) + char newdir[strlen( psz_dir ) + 1]; + strcpy( newdir, psz_dir ); + char * psz_newdir = newdir; + char * psz = psz_newdir; + + while( *psz ) { - snprintf( psz_filename, MAX_PATH, - "file://%s" DIR_SEP CONFIG_DIR DIR_SEP "art" DIR_SEP "artistalbum" - DIR_SEP "%s" DIR_SEP "%s" DIR_SEP "art%s", - p_obj->p_libvlc->psz_homedir, - psz_artist, psz_album, psz_extension ? psz_extension : "" ); + while( *psz && *psz != DIR_SEP_CHAR) psz++; + if( !*psz ) break; + *psz = 0; + if( !EMPTY_STR( psz_newdir ) ) + utf8_mkdir( psz_newdir, 0700 ); + *psz = DIR_SEP_CHAR; + psz++; } - else + utf8_mkdir( psz_dir, 0700 ); +} + +static char * ArtCacheGetSanitizedFileName( const char *psz ) +{ + char *dup = strdup(psz); + int i; + + filename_sanitize( dup ); + + /* Doesn't create a filename with invalid characters + * TODO: several filesystems forbid several characters: list them all + */ + for( i = 0; dup[i] != '\0'; i++ ) { - /* We will use the psz_title name to store the art */ - snprintf( psz_filename, MAX_PATH, - "file://%s" DIR_SEP CONFIG_DIR DIR_SEP "art" DIR_SEP "title" - DIR_SEP "%s" DIR_SEP "art%s", - p_obj->p_libvlc->psz_homedir, - psz_title, psz_extension ? psz_extension : "" ); + if( dup[i] == DIR_SEP_CHAR ) + dup[i] = ' '; } + return dup; } -#define ArtCacheCreatePath(a,b,c,d) __ArtCacheCreatePath(VLC_OBJECT(a),b,c,d) -static void __ArtCacheCreatePath( vlc_object_t *p_obj, + +#define ArtCacheGetDirPath(a,b,c,d,e) __ArtCacheGetDirPath(VLC_OBJECT(a),b,c,d,e) +static void __ArtCacheGetDirPath( vlc_object_t *p_obj, + char *psz_dir, const char *psz_title, const char *psz_artist, const char *psz_album ) { - char psz_dir[MAX_PATH+1]; - snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR, - p_obj->p_libvlc->psz_homedir ); - utf8_mkdir( psz_dir ); - snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP "art", - p_obj->p_libvlc->psz_homedir ); - utf8_mkdir( psz_dir ); - - if( psz_artist && psz_artist ) + if( !EMPTY_STR(psz_artist) && !EMPTY_STR(psz_album) ) { - snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP - "art" DIR_SEP "artistalbum", - p_obj->p_libvlc->psz_homedir ); - utf8_mkdir( psz_dir ); - snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP - "art" DIR_SEP "artistalbum" DIR_SEP "%s", - p_obj->p_libvlc->psz_homedir, psz_artist ); - utf8_mkdir( psz_dir ); - snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP + char * psz_album_sanitized = ArtCacheGetSanitizedFileName( psz_album ); + char * psz_artist_sanitized = ArtCacheGetSanitizedFileName( psz_artist ); + + snprintf( psz_dir, PATH_MAX, "%s" DIR_SEP "art" DIR_SEP "artistalbum" DIR_SEP "%s" DIR_SEP "%s", - p_obj->p_libvlc->psz_homedir, - psz_artist, psz_album ); - utf8_mkdir( psz_dir ); + p_obj->p_libvlc->psz_cachedir, + psz_artist_sanitized, psz_album_sanitized ); + free( psz_album_sanitized ); + free( psz_artist_sanitized ); } else { - snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP - "art" DIR_SEP "title", - p_obj->p_libvlc->psz_homedir ); - utf8_mkdir( psz_dir ); - snprintf( psz_dir, MAX_PATH, "%s" DIR_SEP CONFIG_DIR DIR_SEP + char * psz_title_sanitized = ArtCacheGetSanitizedFileName( psz_title ); + snprintf( psz_dir, PATH_MAX, "%s" DIR_SEP "art" DIR_SEP "title" DIR_SEP "%s", - p_obj->p_libvlc->psz_homedir, psz_title ); - utf8_mkdir( psz_dir ); + p_obj->p_libvlc->psz_cachedir, + psz_title_sanitized ); + free( psz_title_sanitized ); } } -static char *ArtCacheCreateString( const char *psz ) + + + +#define ArtCacheGetFilePath(a,b,c,d,e,f) __ArtCacheGetFilePath(VLC_OBJECT(a),b,c,d,e,f) +static void __ArtCacheGetFilePath( vlc_object_t *p_obj, + char * psz_filename, + const char *psz_title, + const char *psz_artist, const char *psz_album, + const char *psz_extension ) { - char *dup = strdup(psz); - int i; + char psz_dir[PATH_MAX+1]; + char * psz_ext; + ArtCacheGetDirPath( p_obj, psz_dir, psz_title, psz_artist, psz_album ); - /* Doesn't create a filename with invalid characters - * TODO: several filesystems forbid several characters: list them all - */ - for( i = 0; dup[i] != '\0'; i++ ) + if( psz_extension ) { - if( dup[i] == '/' ) - dup[i] = ' '; + psz_ext = strndup( psz_extension, 6 ); + filename_sanitize( psz_ext ); } - return dup; + else psz_ext = strdup( "" ); + + snprintf( psz_filename, PATH_MAX, "file://%s" DIR_SEP "art%s", + psz_dir, psz_ext ); + + free( psz_ext ); } static int __input_FindArtInCache( vlc_object_t *p_obj, input_item_t *p_item ) { - const char *psz_artist; - const char *psz_album; - const char *psz_title; - char psz_filename[MAX_PATH+1]; - int i; - struct stat a; - const char *ppsz_type[] = { ".jpg", ".png", ".gif", ".bmp", "" }; - - if( !p_item->p_meta ) return VLC_EGENERIC; + char *psz_artist; + char *psz_album; + char *psz_title; + char psz_dirpath[PATH_MAX+1]; + char psz_filepath[PATH_MAX+1]; + char * psz_filename; + DIR * p_dir; psz_artist = input_item_GetArtist( p_item ); psz_album = input_item_GetAlbum( p_item ); psz_title = input_item_GetTitle( p_item ); - if( !psz_title ) psz_title = p_item->psz_name; - - if( (!psz_artist || !psz_album) && !psz_title ) return VLC_EGENERIC; + if( !psz_title ) psz_title = input_item_GetName( p_item ); - for( i = 0; i < 5; i++ ) + if( !psz_title && ( !psz_album || !psz_artist ) ) { - ArtCacheCreateName( p_obj, psz_filename, psz_title /* Used if none artist nor album is defined */, - psz_artist, psz_album, ppsz_type[i] ); + free( psz_artist ); + free( psz_album ); + free( psz_title ); + return VLC_EGENERIC; + } + + ArtCacheGetDirPath( p_obj, psz_dirpath, psz_title, + psz_artist, psz_album ); - /* Check if file exists */ - if( utf8_stat( psz_filename+7, &a ) == 0 ) + free( psz_artist ); + free( psz_album ); + free( psz_title ); + + /* Check if file exists */ + p_dir = utf8_opendir( psz_dirpath ); + if( !p_dir ) + return VLC_EGENERIC; + + while( (psz_filename = utf8_readdir( p_dir )) ) + { + if( !strncmp( psz_filename, "art", 3 ) ) { - input_item_SetArtURL( p_item, psz_filename ); + snprintf( psz_filepath, PATH_MAX, "file://%s" DIR_SEP "%s", + psz_dirpath, psz_filename ); + input_item_SetArtURL( p_item, psz_filepath ); + free( psz_filename ); + closedir( p_dir ); return VLC_SUCCESS; } + free( psz_filename ); } + + /* Not found */ + closedir( p_dir ); return VLC_EGENERIC; } @@ -323,21 +394,20 @@ int input_DownloadAndCacheArt( playlist_t *p_playlist, input_item_t *p_item ) { int i_status = VLC_EGENERIC; stream_t *p_stream; - char psz_filename[MAX_PATH+1]; + char psz_filename[PATH_MAX+1]; char *psz_artist = NULL; char *psz_album = NULL; char *psz_title = NULL; + char *psz_arturl; char *psz_type; - if( input_item_GetArtist( p_item ) ) - psz_artist = ArtCacheCreateString( input_item_GetArtist( p_item ) ); - if( input_item_GetAlbum( p_item ) ) - psz_album = ArtCacheCreateString( input_item_GetAlbum( p_item ) ); - if( input_item_GetTitle( p_item ) ) - psz_title = ArtCacheCreateString( input_item_GetTitle( p_item ) ); - else if( p_item->psz_name ) - psz_title = ArtCacheCreateString( p_item->psz_name ); - - if( !psz_title || ( !psz_artist && !psz_album) ) + + psz_artist = input_item_GetArtist( p_item ); + psz_album = input_item_GetAlbum( p_item ); + psz_title = input_item_GetTitle( p_item ); + if( !psz_title ) + psz_title = input_item_GetName( p_item ); + + if( !psz_title && (!psz_artist || !psz_album) ) { free( psz_title ); free( psz_album ); @@ -345,34 +415,50 @@ int input_DownloadAndCacheArt( playlist_t *p_playlist, input_item_t *p_item ) return VLC_EGENERIC; } - assert( !EMPTY_STR(input_item_GetArtURL( p_item )) ); + psz_arturl = input_item_GetArtURL( p_item ); + assert( !EMPTY_STR( psz_arturl ) ); - psz_type = strrchr( input_item_GetArtURL( p_item ), '.' ); + if( !strncmp( psz_arturl , "file://", 7 ) ) + { + msg_Dbg( p_playlist, "Album art is local file, no need to cache" ); + free( psz_arturl ); + return VLC_SUCCESS; + } + else if( !strncmp( psz_arturl , "APIC", 4 ) ) + { + msg_Warn( p_playlist, "APIC fetch not supported yet" ); + free( psz_arturl ); + return VLC_EGENERIC; + } - /* */ - ArtCacheCreateName( p_playlist, psz_filename, psz_title /* Used only if needed*/, - psz_artist, psz_album, psz_type ); + psz_type = strrchr( psz_arturl, '.' ); + if( psz_type && strlen( psz_type ) > 5 ) + psz_type = NULL; /* remove extension if it's > to 4 characters */ - /* */ - ArtCacheCreatePath( p_playlist, psz_title, psz_artist, psz_album ); + /* Warning: psz_title, psz_artist, psz_album may change in ArtCache*() */ + + ArtCacheGetDirPath( p_playlist, psz_filename, psz_title, psz_artist, + psz_album ); + ArtCacheCreateDir( psz_filename ); + ArtCacheGetFilePath( p_playlist, psz_filename, psz_title, psz_artist, + psz_album, psz_type ); - /* */ free( psz_artist ); free( psz_album ); free( psz_title ); - if( !strncmp( input_item_GetArtURL( p_item ) , "APIC", 4 ) ) - { - msg_Warn( p_playlist, "APIC fetch not supported yet" ); - return VLC_EGENERIC; - } - - p_stream = stream_UrlNew( p_playlist, input_item_GetArtURL( p_item ) ); + p_stream = stream_UrlNew( p_playlist, psz_arturl ); if( p_stream ) { uint8_t p_buffer[65536]; long int l_read; FILE *p_file = utf8_fopen( psz_filename+7, "w" ); + if( p_file == NULL ) { + msg_Err( p_playlist, "Unable write album art in %s", + psz_filename + 7 ); + free( psz_arturl ); + return VLC_EGENERIC; + } int err = 0; while( ( l_read = stream_Read( p_stream, p_buffer, sizeof (p_buffer) ) ) ) { @@ -387,25 +473,29 @@ int input_DownloadAndCacheArt( playlist_t *p_playlist, input_item_t *p_item ) stream_Delete( p_stream ); if( err ) - msg_Err( p_playlist, "%s: %s", psz_filename, strerror( err ) ); + { + errno = err; + msg_Err( p_playlist, "%s: %m", psz_filename ); + } else msg_Dbg( p_playlist, "album art saved to %s\n", psz_filename ); input_item_SetArtURL( p_item, psz_filename ); i_status = VLC_SUCCESS; } + free( psz_arturl ); return i_status; } void input_ExtractAttachmentAndCacheArt( input_thread_t *p_input ) { input_item_t *p_item = p_input->p->input.p_item; - char *psz_arturl; - char *psz_artist = NULL; - char *psz_album = NULL; - char *psz_title = NULL; + const char *psz_arturl; + const char *psz_artist = NULL; + const char *psz_album = NULL; + const char *psz_title = NULL; char *psz_type = NULL; - char psz_filename[MAX_PATH+1]; + char psz_filename[PATH_MAX+1]; FILE *f; input_attachment_t *p_attachment; struct stat s; @@ -414,13 +504,13 @@ void input_ExtractAttachmentAndCacheArt( input_thread_t *p_input ) /* TODO-fenrir merge input_ArtFind with download and make it set the flags FETCH * and then set it here to to be faster */ - psz_arturl = strdup( input_item_GetArtURL( p_item ) ); + psz_arturl = vlc_meta_Get( p_item->p_meta, vlc_meta_ArtworkURL ); + if( !psz_arturl || strncmp( psz_arturl, "attachment://", strlen("attachment://") ) ) { msg_Err( p_input, "internal input error with input_ExtractAttachmentAndCacheArt" ); return; } - input_item_SetArtURL( p_item, NULL ); if( input_item_IsArtFetched( p_item ) ) { @@ -428,7 +518,6 @@ void input_ExtractAttachmentAndCacheArt( input_thread_t *p_input ) * condition */ msg_Warn( p_input, "internal input error with input_ExtractAttachmentAndCacheArt" ); input_FindArtInCache( p_input, p_item ); - free( psz_arturl ); return; } @@ -445,50 +534,51 @@ void input_ExtractAttachmentAndCacheArt( input_thread_t *p_input ) if( !p_attachment || p_attachment->i_data <= 0 ) { msg_Warn( p_input, "internal input error with input_ExtractAttachmentAndCacheArt" ); - goto end; + return; } - if( input_item_GetArtist( p_item ) ) - psz_artist = ArtCacheCreateString( input_item_GetArtist( p_item ) ); - if( input_item_GetAlbum( p_item ) ) - psz_album = ArtCacheCreateString( input_item_GetAlbum( p_item ) ); - if( input_item_GetTitle( p_item ) ) - psz_title = ArtCacheCreateString( input_item_GetTitle( p_item ) ); - else if( p_item->psz_name ) - psz_title = ArtCacheCreateString( p_item->psz_name ); + psz_artist = vlc_meta_Get( p_item->p_meta, vlc_meta_Artist ); + psz_album = vlc_meta_Get( p_item->p_meta, vlc_meta_Album ); + psz_title = vlc_meta_Get( p_item->p_meta, vlc_meta_Title ); + if( !strcmp( p_attachment->psz_mime, "image/jpeg" ) ) + psz_type = strdup( ".jpg" ); + else if( !strcmp( p_attachment->psz_mime, "image/png" ) ) + psz_type = strdup( ".png" ); + + if( !psz_title ) + psz_title = p_item->psz_name; if( (!psz_artist || !psz_album ) && !psz_title ) - goto end; + return; - /* */ - psz_type = strrchr( psz_arturl, '.' ); - ArtCacheCreateName( p_input, psz_filename, psz_title, psz_artist, psz_album, psz_type ); + ArtCacheGetDirPath( p_input, psz_filename, psz_title, psz_artist, psz_album ); + ArtCacheCreateDir( psz_filename ); + ArtCacheGetFilePath( p_input, psz_filename, psz_title, psz_artist, psz_album, psz_type ); + free( psz_type ); /* Check if we already dumped it */ if( !utf8_stat( psz_filename+7, &s ) ) - goto end; - - ArtCacheCreatePath( p_input, psz_title, psz_artist, psz_album ); + { + vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, psz_filename ); + return; + } f = utf8_fopen( psz_filename+7, "w" ); if( f ) { if( fwrite( p_attachment->p_data, p_attachment->i_data, 1, f ) != 1 ) - msg_Err( p_input, "%s: %s", psz_filename, strerror( errno ) ); + msg_Err( p_input, "%s: %m", psz_filename ); else + { msg_Dbg( p_input, "album art saved to %s\n", psz_filename ); + vlc_meta_Set( p_item->p_meta, vlc_meta_ArtworkURL, psz_filename ); + } fclose( f ); } - -end: - if( psz_artist ) free( psz_artist ); - if( psz_album ) free( psz_album ); - if( psz_title ) free( psz_title ); - if( psz_arturl ) free( psz_arturl ); } -uint32_t input_CurrentMetaFlags( vlc_meta_t *p_meta ) +uint32_t input_CurrentMetaFlags( const vlc_meta_t *p_meta ) { uint32_t i_meta = 0;