mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-24 03:49:14 -05:00
add album_artist and bits_per_sample, bumping db version. Collect album_artist from flac, aac, wma, and iTunes xml. Collect sample_count and bits_per_sample for flac
This commit is contained in:
parent
22f6fd34bd
commit
e02f0774ec
@ -30,7 +30,6 @@
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
@ -35,6 +35,9 @@
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "db-generic.h"
|
||||
#include "err.h"
|
||||
|
@ -44,7 +44,11 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "db-generic.h"
|
||||
#include "db-sql.h"
|
||||
@ -465,7 +469,9 @@ char *db_sqlite2_initial1 =
|
||||
" codectype VARCHAR(5) DEFAULT NULL,\n"
|
||||
" idx INTEGER NOT NULL,\n"
|
||||
" has_video INTEGER DEFAULT 0,\n"
|
||||
" contentrating INTEGER DEFAULT 0\n" /* 40 */
|
||||
" contentrating INTEGER DEFAULT 0,\n" /* 40 */
|
||||
" bits_per_sample INTEGER DEFAULT 0,\n"
|
||||
" album_artist VARCHAR(1024)\n"
|
||||
");\n"
|
||||
"create table playlistitems (\n"
|
||||
" id INTEGER PRIMARY KEY NOT NULL,\n"
|
||||
@ -477,7 +483,7 @@ char *db_sqlite2_initial1 =
|
||||
" subterm VARCHAR(255) DEFAULT NULL,\n"
|
||||
" value VARCHAR(1024) NOT NULL\n"
|
||||
");\n"
|
||||
"insert into config values ('version','','12');\n";
|
||||
"insert into config values ('version','','13');\n";
|
||||
|
||||
char *db_sqlite2_initial2 =
|
||||
"create table playlists (\n"
|
||||
|
@ -41,11 +41,14 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sqlite3.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "conf.h"
|
||||
#include "err.h"
|
||||
#include "db-generic.h"
|
||||
#include "db-sql.h"
|
||||
@ -67,7 +70,7 @@ static char **db_sqlite3_row = NULL;
|
||||
|
||||
static char db_sqlite3_path[PATH_MAX + 1];
|
||||
|
||||
#define DB_SQLITE3_VERSION 12
|
||||
#define DB_SQLITE3_VERSION 13
|
||||
|
||||
|
||||
/* Forwards */
|
||||
@ -504,7 +507,9 @@ char *db_sqlite3_initial1 =
|
||||
" codectype VARCHAR(5) DEFAULT NULL,\n"
|
||||
" idx INTEGER NOT NULL,\n"
|
||||
" has_video INTEGER DEFAULT 0,\n"
|
||||
" contentrating INTEGER DEFAULT 0\n"
|
||||
" contentrating INTEGER DEFAULT 0,\n"
|
||||
" bits_per_sample INTEGER DEFAULT 0,\n"
|
||||
" album_artist VARCHAR(1024)\n"
|
||||
");\n"
|
||||
"create table playlistitems (\n"
|
||||
" id INTEGER PRIMARY KEY NOT NULL,\n"
|
||||
@ -516,7 +521,7 @@ char *db_sqlite3_initial1 =
|
||||
" subterm VARCHAR(255) DEFAULT NULL,\n"
|
||||
" value VARCHAR(1024) NOT NULL\n"
|
||||
");\n"
|
||||
"insert into config values ('version','','12');\n";
|
||||
"insert into config values ('version','','13');\n";
|
||||
|
||||
char *db_sqlite3_initial2 =
|
||||
"create table playlists (\n"
|
||||
|
@ -361,5 +361,59 @@ char *db_sqlite_updates[] = {
|
||||
/* version 11 -> version 12 */
|
||||
"REPLACE INTO config VALUES('rescan',NULL,1);\n"
|
||||
"UPDATE config SET value=12 WHERE term='version';\n",
|
||||
/* version 12 -> version 13 */
|
||||
"create temp table tempsongs as select * from songs;\n"
|
||||
"drop table songs;\n"
|
||||
"CREATE TABLE songs (\n"
|
||||
" id INTEGER PRIMARY KEY NOT NULL,\n"
|
||||
" path VARCHAR(4096) NOT NULL,\n"
|
||||
" fname VARCHAR(255) NOT NULL,\n"
|
||||
" title VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" artist VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" album VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" genre VARCHAR(255) DEFAULT NULL,\n"
|
||||
" comment VARCHAR(4096) DEFAULT NULL,\n"
|
||||
" type VARCHAR(255) DEFAULT NULL,\n"
|
||||
" composer VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" orchestra VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" conductor VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" grouping VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" url VARCHAR(1024) DEFAULT NULL,\n"
|
||||
" bitrate INTEGER DEFAULT 0,\n"
|
||||
" samplerate INTEGER DEFAULT 0,\n"
|
||||
" song_length INTEGER DEFAULT 0,\n"
|
||||
" file_size INTEGER DEFAULT 0,\n"
|
||||
" year INTEGER DEFAULT 0,\n"
|
||||
" track INTEGER DEFAULT 0,\n"
|
||||
" total_tracks INTEGER DEFAULT 0,\n"
|
||||
" disc INTEGER DEFAULT 0,\n"
|
||||
" total_discs INTEGER DEFAULT 0,\n"
|
||||
" bpm INTEGER DEFAULT 0,\n"
|
||||
" compilation INTEGER DEFAULT 0,\n"
|
||||
" rating INTEGER DEFAULT 0,\n"
|
||||
" play_count INTEGER DEFAULT 0,\n"
|
||||
" data_kind INTEGER DEFAULT 0,\n"
|
||||
" item_kind INTEGER DEFAULT 0,\n"
|
||||
" description INTEGER DEFAULT 0,\n"
|
||||
" time_added INTEGER DEFAULT 0,\n"
|
||||
" time_modified INTEGER DEFAULT 0,\n"
|
||||
" time_played INTEGER DEFAULT 0,\n"
|
||||
" db_timestamp INTEGER DEFAULT 0,\n"
|
||||
" disabled INTEGER DEFAULT 0,\n"
|
||||
" sample_count INTEGER DEFAULT 0,\n"
|
||||
" force_update INTEGER DEFAULT 0,\n"
|
||||
" codectype VARCHAR(5) DEFAULT NULL,\n"
|
||||
" idx INTEGER NOT NULL,\n"
|
||||
" has_video INTEGER DEFAULT 0,\n"
|
||||
" contentrating INTEGER DEFAULT 0,\n"
|
||||
" bits_per_sample INTEGER DEFAULT 0,\n"
|
||||
" album_artist VARCHAR(1024)\n"
|
||||
");\n"
|
||||
"begin transaction;\n"
|
||||
"insert into songs select *,0,'' from tempsongs;\n"
|
||||
"commit transaction;\n"
|
||||
"drop table tempsongs;\n"
|
||||
"update config set value=13 where term='version';\n",
|
||||
NULL /* No more versions! */
|
||||
|
||||
};
|
||||
|
29
src/db-sql.c
29
src/db-sql.c
@ -34,6 +34,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "err.h"
|
||||
#include "mp3-scanner.h"
|
||||
@ -777,6 +780,7 @@ int db_sql_add(char **pe, MP3FILE *pmp3, int *id) {
|
||||
int insertid;
|
||||
char *query;
|
||||
char *path;
|
||||
char sample_count[40];
|
||||
|
||||
DPRINTF(E_SPAM,L_DB,"Entering db_sql_add\n");
|
||||
|
||||
@ -809,6 +813,7 @@ int db_sql_add(char **pe, MP3FILE *pmp3, int *id) {
|
||||
pmp3->play_count=0;
|
||||
pmp3->time_played=0;
|
||||
|
||||
sprintf(sample_count,"%lld",pmp3->sample_count);
|
||||
err=db_sql_exec_fn(pe,E_DBG,"INSERT INTO songs VALUES "
|
||||
"(NULL," // id
|
||||
"'%q'," // path
|
||||
@ -845,12 +850,14 @@ int db_sql_add(char **pe, MP3FILE *pmp3, int *id) {
|
||||
"%d," // time_played
|
||||
"%d," // db_timestamp
|
||||
"%d," // disabled
|
||||
"%d," // sample_count
|
||||
"%s," // sample_count
|
||||
"0," // force_update
|
||||
"'%q'," // codectype
|
||||
"%d," // index
|
||||
"%d," // has_video
|
||||
"%d)", // contentrating
|
||||
"%d," // contentrating
|
||||
"%d," // bits_per_sample
|
||||
"'%q')", // albumartist
|
||||
path,
|
||||
STR(pmp3->fname),
|
||||
STR(pmp3->title),
|
||||
@ -884,11 +891,13 @@ int db_sql_add(char **pe, MP3FILE *pmp3, int *id) {
|
||||
pmp3->time_played,
|
||||
pmp3->db_timestamp,
|
||||
pmp3->disabled,
|
||||
pmp3->sample_count,
|
||||
sample_count,
|
||||
STR(pmp3->codectype),
|
||||
pmp3->index,
|
||||
pmp3->has_video,
|
||||
pmp3->contentrating);
|
||||
pmp3->contentrating,
|
||||
pmp3->bits_per_sample,
|
||||
STR(pmp3->album_artist));
|
||||
|
||||
free(path);
|
||||
if(err != DB_E_SUCCESS)
|
||||
@ -919,12 +928,14 @@ int db_sql_update(char **pe, MP3FILE *pmp3, int *id) {
|
||||
int err;
|
||||
char query[1024];
|
||||
char *path;
|
||||
char sample_count[40];
|
||||
|
||||
if(!pmp3->time_modified)
|
||||
pmp3->time_modified = (int)time(NULL);
|
||||
|
||||
pmp3->db_timestamp = (int)time(NULL);
|
||||
|
||||
sprintf(sample_count,"%lld",pmp3->sample_count);
|
||||
strcpy(query,"UPDATE songs SET "
|
||||
"title='%q'," // title
|
||||
"artist='%q'," // artist
|
||||
@ -952,8 +963,9 @@ int db_sql_update(char **pe, MP3FILE *pmp3, int *id) {
|
||||
"disabled=%d," // disabled
|
||||
"compilation=%d," // compilation
|
||||
"rating=%d," // rating
|
||||
"sample_count=%d," // sample_count
|
||||
"codectype='%q'" // codec
|
||||
"sample_count=%s," // sample_count
|
||||
"codectype='%q'," // codec
|
||||
"album_artist='%q',"
|
||||
" WHERE path='%q' and idx=%d");
|
||||
|
||||
path = _db_proper_path(pmp3->path);
|
||||
@ -985,8 +997,9 @@ int db_sql_update(char **pe, MP3FILE *pmp3, int *id) {
|
||||
pmp3->disabled,
|
||||
pmp3->compilation,
|
||||
pmp3->rating,
|
||||
pmp3->sample_count,
|
||||
sample_count,
|
||||
STR(pmp3->codectype),
|
||||
STR(pmp3->album_artist),
|
||||
path,
|
||||
pmp3->index);
|
||||
|
||||
@ -1440,6 +1453,8 @@ void db_sql_build_mp3file(SQL_ROW valarray, MP3FILE *pmp3) {
|
||||
pmp3->index=db_sql_atoi(valarray[38]);
|
||||
pmp3->has_video=db_sql_atoi(valarray[39]);
|
||||
pmp3->contentrating=db_sql_atoi(valarray[40]);
|
||||
pmp3->bits_per_sample=db_sql_atoi(valarray[41]);
|
||||
pmp3->album_artist=db_sql_strdup(valarray[42]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,5 +57,6 @@
|
||||
#define SG_IDX 38
|
||||
#define SG_HAS_VIDEO 39
|
||||
#define SG_CONTENTRATING 40
|
||||
|
||||
#define SG_BITS_PER_SAMPLE 41
|
||||
#define SG_ALBUM_ARTIST 42
|
||||
#endif /* _FF_DBSTRUCT_H_ */
|
||||
|
@ -30,7 +30,6 @@
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#define _POSIX_PTHREAD_SEMANTICS
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@ -735,6 +734,7 @@ int scan_freetags(MP3FILE *pmp3) {
|
||||
MAYBEFREE(pmp3->grouping);
|
||||
MAYBEFREE(pmp3->description);
|
||||
MAYBEFREE(pmp3->codectype);
|
||||
MAYBEFREE(pmp3->album_artist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
typedef struct tag_mp3file {
|
||||
char *path;
|
||||
int index;
|
||||
uint32_t index;
|
||||
char *fname;
|
||||
char *title; /* TIT2 */
|
||||
char *artist; /* TPE1 */
|
||||
@ -40,54 +40,60 @@ typedef struct tag_mp3file {
|
||||
char *grouping; /* TIT1 */
|
||||
char *url; /* daap.songdataurl (asul) */
|
||||
|
||||
int bitrate;
|
||||
int samplerate;
|
||||
int song_length;
|
||||
int file_size;
|
||||
int year; /* TDRC */
|
||||
uint32_t bitrate;
|
||||
uint32_t samplerate;
|
||||
uint32_t song_length;
|
||||
uint32_t file_size; /* ?? */
|
||||
uint32_t year; /* TDRC */
|
||||
|
||||
int track; /* TRCK */
|
||||
int total_tracks;
|
||||
uint32_t track; /* TRCK */
|
||||
uint32_t total_tracks;
|
||||
|
||||
int disc; /* TPOS */
|
||||
int total_discs;
|
||||
uint32_t disc; /* TPOS */
|
||||
uint32_t total_discs;
|
||||
|
||||
int time_added;
|
||||
int time_modified;
|
||||
int time_played;
|
||||
int play_count;
|
||||
int rating;
|
||||
int db_timestamp;
|
||||
int disabled;
|
||||
int bpm; /* TBPM */
|
||||
uint32_t time_added; /* really should be a time_t */
|
||||
uint32_t time_modified;
|
||||
uint32_t time_played;
|
||||
|
||||
int got_id3;
|
||||
unsigned int id;
|
||||
uint32_t play_count;
|
||||
uint32_t rating;
|
||||
uint32_t db_timestamp;
|
||||
|
||||
uint32_t disabled;
|
||||
uint32_t bpm; /* TBPM */
|
||||
|
||||
uint32_t got_id3;
|
||||
uint32_t id;
|
||||
|
||||
char *description; /* long file type */
|
||||
char *codectype; /* song.codectype */
|
||||
int item_kind; /* song or movie */
|
||||
int data_kind; /* dmap.datakind (asdk) */
|
||||
int force_update;
|
||||
int sample_count;
|
||||
|
||||
uint32_t item_kind; /* song or movie */
|
||||
uint32_t data_kind; /* dmap.datakind (asdk) */
|
||||
uint32_t force_update;
|
||||
uint64_t sample_count;
|
||||
char compilation;
|
||||
|
||||
/* iTunes 5+ */
|
||||
int contentrating;
|
||||
uint32_t contentrating;
|
||||
|
||||
/* iTunes 6.0.2 */
|
||||
int has_video;
|
||||
uint32_t has_video;
|
||||
uint32_t bits_per_sample;
|
||||
|
||||
char *album_artist;
|
||||
} MP3FILE;
|
||||
|
||||
typedef struct tag_m3ufile {
|
||||
int id; /**< integer id (miid) */
|
||||
uint32_t id; /**< integer id (miid) */
|
||||
char *title; /**< playlist name as displayed in iTunes (minm) */
|
||||
int type; /**< 0=static webmanaged, 1=smart, 2=static m3u (aeSP/MPTY) */
|
||||
int items; /**< number of items (mimc) */
|
||||
uint32_t type; /**< 0=static webmanaged, 1=smart, 2=static m3u (aeSP/MPTY) */
|
||||
uint32_t items; /**< number of items (mimc) */
|
||||
char *query; /**< where clause if type 1 (MSPS) */
|
||||
int db_timestamp; /**< time last updated */
|
||||
uint32_t db_timestamp; /**< time last updated */
|
||||
char *path; /**< path of underlying playlist (if type 2) */
|
||||
int index; /**< index of playlist for paths with multiple playlists */
|
||||
uint32_t index; /**< index of playlist for paths with multiple playlists */
|
||||
} M3UFILE;
|
||||
|
||||
typedef struct tag_packed_m3ufile {
|
||||
@ -143,6 +149,7 @@ typedef struct tag_packed_mp3file {
|
||||
char *idx;
|
||||
char *has_video;
|
||||
char *contentrating;
|
||||
char *bits_per_sample;
|
||||
} PACKED_MP3FILE;
|
||||
|
||||
#define PL_STATICWEB 0
|
||||
|
@ -32,6 +32,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -231,6 +231,8 @@ int scan_get_aacinfo(char *filename, MP3FILE *pmp3) {
|
||||
|
||||
if(!memcmp(current_atom,"\xA9" "nam",4)) { /* Song name */
|
||||
pmp3->title=strdup((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"aART",4)) {
|
||||
pmp3->album_artist=strdup((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"\xA9" "ART",4)) {
|
||||
pmp3->artist=strdup((char*)¤t_data[16]);
|
||||
} else if(!memcmp(current_atom,"\xA9" "alb",4)) {
|
||||
|
@ -107,6 +107,8 @@ int scan_get_flacinfo(char *filename, MP3FILE *pmp3) {
|
||||
pmp3->song_length = (sec * 1000) + ms;
|
||||
pmp3->bitrate = (pmp3->file_size) / (((sec * 1000) + ms) / 8);
|
||||
pmp3->samplerate = block->data.stream_info.sample_rate;
|
||||
pmp3->bits_per_sample = block->data.stream_info.bits_per_sample;
|
||||
pmp3->sample_count = block->data.stream_info.total_samples;
|
||||
|
||||
found |= 1;
|
||||
if(found == 3)
|
||||
@ -123,6 +125,10 @@ int scan_get_flacinfo(char *filename, MP3FILE *pmp3) {
|
||||
"TITLE", &len))) {
|
||||
if ((pmp3->title = calloc(len + 1, 1)) != NULL)
|
||||
strncpy(pmp3->title, val, len);
|
||||
} else if ((val = GET_VORBIS_COMMENT(block->data.vorbis_comment.comments[i],
|
||||
"ALBUMARTIST", &len))) {
|
||||
if ((pmp3->album_artist = calloc(len + 1, 1)) != NULL)
|
||||
strncpy(pmp3->album_artist, val, len);
|
||||
} else if ((val = GET_VORBIS_COMMENT(block->data.vorbis_comment.comments[i],
|
||||
"ALBUM", &len))) {
|
||||
if ((pmp3->album = calloc(len + 1, 1)) != NULL)
|
||||
|
@ -642,8 +642,8 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3, int e
|
||||
}
|
||||
} else if(strcasecmp(descriptor_name,"wm/albumartist")==0) {
|
||||
/* get first one only */
|
||||
if(!pmp3->orchestra) {
|
||||
pmp3->orchestra = descriptor_byte_value;
|
||||
if(!pmp3->album_artist) {
|
||||
pmp3->album_artist = descriptor_byte_value;
|
||||
descriptor_byte_value = NULL;
|
||||
}
|
||||
} else if(strcasecmp(descriptor_name,"author") == 0) {
|
||||
|
@ -83,6 +83,7 @@ static char *scan_xml_track_tags[] = {
|
||||
"Date Added",
|
||||
"Comments",
|
||||
"Composer",
|
||||
"Album Artist",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -108,6 +109,7 @@ static char *scan_xml_track_tags[] = {
|
||||
#define SCAN_XML_T_DATE_ADDED 17
|
||||
#define SCAN_XML_T_COMMENTS 18
|
||||
#define SCAN_XML_T_COMPOSER 19
|
||||
#define SCAN_XML_T_ALBUM_ARTIST 20
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
@ -715,6 +717,7 @@ int scan_xml_tracks_section(int action, char *info) {
|
||||
MAYBECOPY(total_discs);
|
||||
MAYBECOPY(time_added);
|
||||
MAYBECOPY(disabled);
|
||||
MAYBECOPYSTRING(album_artist);
|
||||
|
||||
/* must add to the red-black tree */
|
||||
scan_xml_add_lookup(current_track_id,pmp3->id);
|
||||
@ -757,6 +760,7 @@ int scan_xml_tracks_section(int action, char *info) {
|
||||
MAYBECOPY(rating);
|
||||
MAYBECOPY(time_added);
|
||||
MAYBECOPY(disabled);
|
||||
MAYBECOPYSTRING(album_artist);
|
||||
|
||||
make_composite_tags(pmp3);
|
||||
if(db_add(NULL,pmp3,&added_id) == DB_E_SUCCESS) {
|
||||
@ -775,7 +779,9 @@ int scan_xml_tracks_section(int action, char *info) {
|
||||
MAYBEFREE(mp3.album);
|
||||
MAYBEFREE(mp3.genre);
|
||||
MAYBEFREE(mp3.comment);
|
||||
MAYBEFREE(mp3.album_artist);
|
||||
MAYBEFREE(song_path);
|
||||
|
||||
memset((void*)&mp3,0,sizeof(MP3FILE));
|
||||
} else {
|
||||
return XML_STATE_ERROR;
|
||||
@ -823,6 +829,8 @@ int scan_xml_tracks_section(int action, char *info) {
|
||||
mp3.comment = strdup(info);
|
||||
} else if(current_field == SCAN_XML_T_COMPOSER) {
|
||||
mp3.composer = strdup(info);
|
||||
} else if(current_field == SCAN_XML_T_ALBUM_ARTIST) {
|
||||
mp3.album_artist = strdup(info);
|
||||
}
|
||||
} else if(action == RXML_EVT_END) {
|
||||
state = XML_TRACK_ST_TRACK_INFO;
|
||||
|
@ -97,6 +97,7 @@ void dump_mp3(MP3FILE *pmp3) {
|
||||
printf("fname.........: %s\n",pmp3->fname);
|
||||
printf("title.........: %s\n",pmp3->title);
|
||||
printf("artist........: %s\n",pmp3->artist);
|
||||
printf("album_artist..: %s\n",pmp3->album_artist);
|
||||
printf("album.........: %s\n",pmp3->album);
|
||||
printf("genre.........: %s\n",pmp3->genre);
|
||||
printf("comment.......: %s\n",pmp3->comment);
|
||||
|
Loading…
x
Reference in New Issue
Block a user