fix parsing extended_content_description, better song duration by using preroll
This commit is contained in:
parent
b21d1340c9
commit
1ffd741e50
|
@ -230,6 +230,8 @@ int db_sqlite_init(int reload) {
|
||||||
int items;
|
int items;
|
||||||
int rescan=0;
|
int rescan=0;
|
||||||
|
|
||||||
|
/* make sure we have an index... might not if aborted during scan */
|
||||||
|
db_sqlite_exec(E_DBG,"CREATE INDEX idx_path ON songs(path)");
|
||||||
db_sqlite_update_version(db_sqlite_get_version());
|
db_sqlite_update_version(db_sqlite_get_version());
|
||||||
db_sqlite_get_int(E_DBG,&rescan,"SELECT value FROM config WHERE term='rescan'");
|
db_sqlite_get_int(E_DBG,&rescan,"SELECT value FROM config WHERE term='rescan'");
|
||||||
|
|
||||||
|
@ -899,9 +901,10 @@ int db_sqlite_get_size(DBQUERYINFO *pinfo, char **valarray) {
|
||||||
if(db_wantsmeta(pinfo->meta, metaItunesSmartPlaylist))
|
if(db_wantsmeta(pinfo->meta, metaItunesSmartPlaylist))
|
||||||
size += 9; /* aeSP */
|
size += 9; /* aeSP */
|
||||||
if(db_wantsmeta(pinfo->meta, metaItemName))
|
if(db_wantsmeta(pinfo->meta, metaItemName))
|
||||||
size += (8 + strlen(valarray[1])); /* minm */
|
size += (8 + strlen(valarray[plTitle])); /* minm */
|
||||||
if(valarray[2] && atoi(valarray[2]) && db_wantsmeta(pinfo->meta, metaMPlaylistSpec))
|
if(valarray[plType] && (atoi(valarray[plType])==1) &&
|
||||||
size += (8 + strlen(valarray[4])); /* MSPS */
|
db_wantsmeta(pinfo->meta, metaMPlaylistSpec))
|
||||||
|
size += (8 + strlen(valarray[plQuery])); /* MSPS */
|
||||||
if(db_wantsmeta(pinfo->meta, metaMPlaylistType))
|
if(db_wantsmeta(pinfo->meta, metaMPlaylistType))
|
||||||
size += 9; /* MPTY */
|
size += 9; /* MPTY */
|
||||||
return size;
|
return size;
|
||||||
|
@ -1045,6 +1048,7 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int
|
||||||
unsigned char *current = presult;
|
unsigned char *current = presult;
|
||||||
int transcode;
|
int transcode;
|
||||||
int samplerate=0;
|
int samplerate=0;
|
||||||
|
int smart;
|
||||||
|
|
||||||
switch(pinfo->query_type) {
|
switch(pinfo->query_type) {
|
||||||
case queryTypeBrowseArtists: /* simple 'mlit' entry */
|
case queryTypeBrowseArtists: /* simple 'mlit' entry */
|
||||||
|
@ -1056,16 +1060,21 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int
|
||||||
/* do I want to include the mlit? */
|
/* do I want to include the mlit? */
|
||||||
current += db_dmap_add_container(current,"mlit",len - 8);
|
current += db_dmap_add_container(current,"mlit",len - 8);
|
||||||
if(db_wantsmeta(pinfo->meta,metaItemId))
|
if(db_wantsmeta(pinfo->meta,metaItemId))
|
||||||
current += db_dmap_add_int(current,"miid",atoi(valarray[0]));
|
current += db_dmap_add_int(current,"miid",atoi(valarray[plID]));
|
||||||
current += db_dmap_add_int(current,"mimc",atoi(valarray[3]));
|
current += db_dmap_add_int(current,"mimc",atoi(valarray[plItems]));
|
||||||
if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist))
|
if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist)) {
|
||||||
current += db_dmap_add_char(current,"aeSP",atoi(valarray[2]));
|
smart=0;
|
||||||
|
if(atoi(valarray[plType]) == 1)
|
||||||
|
smart=1;
|
||||||
|
current += db_dmap_add_char(current,"aeSP",smart);
|
||||||
|
}
|
||||||
if(db_wantsmeta(pinfo->meta,metaItemName))
|
if(db_wantsmeta(pinfo->meta,metaItemName))
|
||||||
current += db_dmap_add_string(current,"minm",valarray[1]);
|
current += db_dmap_add_string(current,"minm",valarray[plTitle]);
|
||||||
if((valarray[2]) && atoi(valarray[2]) && db_wantsmeta(pinfo->meta, metaMPlaylistSpec))
|
if((valarray[plType]) && (atoi(valarray[plType])==1) &&
|
||||||
current += db_dmap_add_string(current,"MSPS",valarray[4]);
|
db_wantsmeta(pinfo->meta, metaMPlaylistSpec))
|
||||||
|
current += db_dmap_add_string(current,"MSPS",valarray[plQuery]);
|
||||||
if(db_wantsmeta(pinfo->meta, metaMPlaylistType))
|
if(db_wantsmeta(pinfo->meta, metaMPlaylistType))
|
||||||
current += db_dmap_add_char(current,"MPTY",atoi(valarray[2]));
|
current += db_dmap_add_char(current,"MPTY",atoi(valarray[plType]));
|
||||||
break;
|
break;
|
||||||
case queryTypeItems:
|
case queryTypeItems:
|
||||||
case queryTypePlaylistItems: /* essentially the same query */
|
case queryTypePlaylistItems: /* essentially the same query */
|
||||||
|
@ -1489,6 +1498,23 @@ char *db_sqlite_upgrade_scripts[] = {
|
||||||
"create index idx_path on songs(path);\n"
|
"create index idx_path on songs(path);\n"
|
||||||
"drop table tempsongs;\n"
|
"drop table tempsongs;\n"
|
||||||
"update config set value=3 where term='version';\n",
|
"update config set value=3 where term='version';\n",
|
||||||
|
|
||||||
|
/* version 3 -> version 4 */
|
||||||
|
/* add db_timestamp and path to playlist table */
|
||||||
|
"create temp table tempplaylists as select * from playlists;\n"
|
||||||
|
"drop table playlists;\n"
|
||||||
|
"CREATE TABLE playlists (\n"
|
||||||
|
" id INTEGER PRIMARY KEY NOT NULL,\n"
|
||||||
|
" title VARCHAR(255) NOT NULL,\n"
|
||||||
|
" smart INTEGER NOT NULL,\n"
|
||||||
|
" items INTEGER NOT NULL,\n"
|
||||||
|
" query VARCHAR(1024)\n"
|
||||||
|
" db_timestamp INTEGER NOT NULL,\n"
|
||||||
|
" path VARCHAR(4096)\n"
|
||||||
|
");\n"
|
||||||
|
"insert into playlists select *,0,NULL from tempplaylists;\n"
|
||||||
|
"drop table tempplaylists;\n"
|
||||||
|
"update config set value=4 where term='version';\n",
|
||||||
NULL /* No more versions! */
|
NULL /* No more versions! */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1498,6 +1524,10 @@ char *db_sqlite_upgrade_scripts[] = {
|
||||||
* \param from_version the current version of the database
|
* \param from_version the current version of the database
|
||||||
*/
|
*/
|
||||||
int db_sqlite_update_version(int from_version) {
|
int db_sqlite_update_version(int from_version) {
|
||||||
|
if(from_version > (sizeof(db_sqlite_upgrade_scripts)/sizeof(char*))) {
|
||||||
|
DPRINTF(E_FATAL,L_DB,"Database version too new (time machine, maybe?)\n");
|
||||||
|
}
|
||||||
|
|
||||||
while(db_sqlite_upgrade_scripts[from_version]) {
|
while(db_sqlite_upgrade_scripts[from_version]) {
|
||||||
DPRINTF(E_LOG,L_DB,"Upgrading database from version %d to version %d\n",from_version,
|
DPRINTF(E_LOG,L_DB,"Upgrading database from version %d to version %d\n",from_version,
|
||||||
from_version+1);
|
from_version+1);
|
||||||
|
@ -1508,5 +1538,3 @@ int db_sqlite_update_version(int from_version) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,4 +40,56 @@ extern void db_sqlite_dispose_item(MP3FILE *pmp3);
|
||||||
extern int db_sqlite_add_playlist(char *name, int type, char *clause, int *playlistid);
|
extern int db_sqlite_add_playlist(char *name, int type, char *clause, int *playlistid);
|
||||||
extern int db_sqlite_add_playlist_item(int playlistid, int songid);
|
extern int db_sqlite_add_playlist_item(int playlistid, int songid);
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
songID,
|
||||||
|
songPath,
|
||||||
|
songFname,
|
||||||
|
songTitle,
|
||||||
|
songArtist,
|
||||||
|
songAlbum,
|
||||||
|
songGenre,
|
||||||
|
songComment,
|
||||||
|
songType,
|
||||||
|
songComposer,
|
||||||
|
songOrchestra,
|
||||||
|
songGrouping,
|
||||||
|
songURL,
|
||||||
|
songBitrate,
|
||||||
|
songSampleRate,
|
||||||
|
songLength,
|
||||||
|
songFilesize,
|
||||||
|
songYear,
|
||||||
|
songTrack,
|
||||||
|
songTotalTracks,
|
||||||
|
songDisc,
|
||||||
|
songTotalDiscs,
|
||||||
|
songBPM,
|
||||||
|
songCompilation,
|
||||||
|
songRating,
|
||||||
|
songPlayCount,
|
||||||
|
songDataKind,
|
||||||
|
songItemKind,
|
||||||
|
songDescription,
|
||||||
|
songTimeAdded,
|
||||||
|
songTimeModified,
|
||||||
|
songTimePlayed,
|
||||||
|
songDBTimestamp,
|
||||||
|
songDisabled,
|
||||||
|
songSampleCount,
|
||||||
|
songForceUpdate,
|
||||||
|
songCodecType
|
||||||
|
} SongField_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
plID,
|
||||||
|
plTitle,
|
||||||
|
plType,
|
||||||
|
plItems,
|
||||||
|
plQuery,
|
||||||
|
plDBTimestamp,
|
||||||
|
plPath
|
||||||
|
} PlaylistField_t;
|
||||||
|
|
||||||
|
|
||||||
#endif /* _DBS_SQLITE_H_ */
|
#endif /* _DBS_SQLITE_H_ */
|
||||||
|
|
44
src/wma.c
44
src/wma.c
|
@ -364,7 +364,7 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
|
||||||
switch(descriptor_value_type) {
|
switch(descriptor_value_type) {
|
||||||
case 0x0000: /* string */
|
case 0x0000: /* string */
|
||||||
if(!wma_file_read_utf16(fd,descriptor_value_len,&descriptor_byte_value)) fail=1;
|
if(!wma_file_read_utf16(fd,descriptor_value_len,&descriptor_byte_value)) fail=1;
|
||||||
DPRINTF(E_DBG,L_SCAN,"Type: string, value (%s)\n",descriptor_byte_value);
|
DPRINTF(E_DBG,L_SCAN,"Type: string, value: %s\n",descriptor_byte_value);
|
||||||
break;
|
break;
|
||||||
case 0x0001: /* byte array */
|
case 0x0001: /* byte array */
|
||||||
if(!wma_file_read_bytes(fd,descriptor_value_len,&descriptor_byte_value)) fail=1;
|
if(!wma_file_read_bytes(fd,descriptor_value_len,&descriptor_byte_value)) fail=1;
|
||||||
|
@ -391,33 +391,33 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do stuff with what we found */
|
/* do stuff with what we found */
|
||||||
if(!strcasecmp(descriptor_name,"wm/genre")==0) {
|
if(strcasecmp(descriptor_name,"wm/genre")==0) {
|
||||||
MAYBEFREE(pmp3->genre);
|
MAYBEFREE(pmp3->genre);
|
||||||
pmp3->genre = descriptor_byte_value;
|
pmp3->genre = descriptor_byte_value;
|
||||||
descriptor_byte_value = NULL; /* don't free it! */
|
descriptor_byte_value = NULL; /* don't free it! */
|
||||||
} else if(!strcasecmp(descriptor_name,"wm/albumtitle")==0) {
|
} else if(strcasecmp(descriptor_name,"wm/albumtitle")==0) {
|
||||||
MAYBEFREE(pmp3->album);
|
MAYBEFREE(pmp3->album);
|
||||||
pmp3->album = descriptor_byte_value;
|
pmp3->album = descriptor_byte_value;
|
||||||
descriptor_byte_value = NULL;
|
descriptor_byte_value = NULL;
|
||||||
} else if(!strcasecmp(descriptor_name,"wm/track")==0) {
|
} else if(strcasecmp(descriptor_name,"wm/track")==0) {
|
||||||
pmp3->track = descriptor_int_value + 1;
|
pmp3->track = descriptor_int_value + 1;
|
||||||
} else if(!strcasecmp(descriptor_name,"wm/tracknumber")==0) {
|
} else if(strcasecmp(descriptor_name,"wm/tracknumber")==0) {
|
||||||
pmp3->track = descriptor_int_value;
|
pmp3->track = descriptor_int_value;
|
||||||
} else if(!strcasecmp(descriptor_name,"wm/year")==0) {
|
} else if(strcasecmp(descriptor_name,"wm/year")==0) {
|
||||||
pmp3->track = atoi(descriptor_byte_value);
|
pmp3->year = atoi(descriptor_byte_value);
|
||||||
} else if(!strcasecmp(descriptor_name,"wm/composer")==0) {
|
} else if(strcasecmp(descriptor_name,"wm/composer")==0) {
|
||||||
MAYBEFREE(pmp3->composer);
|
MAYBEFREE(pmp3->composer);
|
||||||
pmp3->composer = descriptor_byte_value;
|
pmp3->composer = descriptor_byte_value;
|
||||||
descriptor_byte_value = NULL;
|
descriptor_byte_value = NULL;
|
||||||
} else if(!strcasecmp(descriptor_name,"wm/albumartist")==0) {
|
} else if(strcasecmp(descriptor_name,"wm/albumartist")==0) {
|
||||||
MAYBEFREE(pmp3->artist);
|
MAYBEFREE(pmp3->artist);
|
||||||
pmp3->artist = descriptor_byte_value;
|
pmp3->artist = descriptor_byte_value;
|
||||||
descriptor_byte_value = NULL;
|
descriptor_byte_value = NULL;
|
||||||
} else if(!strcasecmp(descriptor_name,"wm/contengroupdescription")==0) {
|
} else if(strcasecmp(descriptor_name,"wm/contengroupdescription")==0) {
|
||||||
MAYBEFREE(pmp3->grouping);
|
MAYBEFREE(pmp3->grouping);
|
||||||
pmp3->grouping = descriptor_byte_value;
|
pmp3->grouping = descriptor_byte_value;
|
||||||
descriptor_byte_value = NULL;
|
descriptor_byte_value = NULL;
|
||||||
} else if(!strcasecmp(descriptor_name,"comment")==0) {
|
} else if(strcasecmp(descriptor_name,"comment")==0) {
|
||||||
MAYBEFREE(pmp3->comment);
|
MAYBEFREE(pmp3->comment);
|
||||||
pmp3->comment = descriptor_byte_value;
|
pmp3->comment = descriptor_byte_value;
|
||||||
descriptor_byte_value = NULL;
|
descriptor_byte_value = NULL;
|
||||||
|
@ -506,6 +506,9 @@ int wma_parse_content_description(int fd,int size, MP3FILE *pmp3) {
|
||||||
*/
|
*/
|
||||||
int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) {
|
int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) {
|
||||||
long long play_duration;
|
long long play_duration;
|
||||||
|
long long send_duration;
|
||||||
|
long long preroll;
|
||||||
|
|
||||||
int max_bitrate;
|
int max_bitrate;
|
||||||
|
|
||||||
/* skip guid (16 bytes), filesize (8), creation time (8),
|
/* skip guid (16 bytes), filesize (8), creation time (8),
|
||||||
|
@ -513,17 +516,26 @@ int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) {
|
||||||
*/
|
*/
|
||||||
lseek(fd,40,SEEK_CUR);
|
lseek(fd,40,SEEK_CUR);
|
||||||
|
|
||||||
/* we'll ignore the preroll */
|
|
||||||
if(!wma_file_read_ll(fd, &play_duration))
|
if(!wma_file_read_ll(fd, &play_duration))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pmp3->song_length = (int) (play_duration / 10000);
|
if(!wma_file_read_ll(fd, &send_duration))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(!wma_file_read_ll(fd, &preroll))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* I'm not entirely certain what preroll is, but it seems
|
||||||
|
* to make it match up with what windows thinks is the song
|
||||||
|
* length.
|
||||||
|
*/
|
||||||
|
pmp3->song_length = ((int) (play_duration / 10000)) - preroll;
|
||||||
|
|
||||||
/* skip send_duration (8), preroll (8), flags(4),
|
/* skip flags(4),
|
||||||
* min_packet_size (4), max_packet_size(4)
|
* min_packet_size (4), max_packet_size(4)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lseek(fd,28,SEEK_CUR);
|
lseek(fd,12,SEEK_CUR);
|
||||||
if(!wma_file_read_int(fd,&max_bitrate))
|
if(!wma_file_read_int(fd,&max_bitrate))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -549,7 +561,7 @@ int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) {
|
||||||
*/
|
*/
|
||||||
unsigned char *wma_utf16toutf8(char *utf16, int len) {
|
unsigned char *wma_utf16toutf8(char *utf16, int len) {
|
||||||
char *utf8;
|
char *utf8;
|
||||||
char *src=utf16;;
|
char *src=utf16;
|
||||||
char *dst;
|
char *dst;
|
||||||
unsigned int w1, w2;
|
unsigned int w1, w2;
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
Loading…
Reference in New Issue