Merge pull request #752 from whatdoineed2do/db-queue-quality

db queue to incl media quality info
This commit is contained in:
Christian Meffert 2019-07-09 20:19:10 +02:00 committed by GitHub
commit e608b763ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 104 additions and 4 deletions

View File

@ -1997,6 +1997,10 @@ curl --include \
| path | string | Path |
| uri | string | Resource identifier |
| artwork_url | string | *(optional)* [Artwork url](#artwork-urls) |
| type | string | file (codec) type (ie mp3/flac/...) |
| bitrate | string | file bitrate (ie 192/128/...) |
| samplerate | string | file sample rate (ie 44100/48000/...) |
| channel | string | file channel (ie mono/stereo/xx ch)) |
### `playlist` object

View File

@ -213,6 +213,7 @@ static const struct col_type_map mfi_cols_map[] =
{ "album_sort", mfi_offsetof(album_sort), DB_TYPE_STRING, DB_FIXUP_ALBUM_SORT },
{ "album_artist_sort", mfi_offsetof(album_artist_sort), DB_TYPE_STRING, DB_FIXUP_ALBUM_ARTIST_SORT },
{ "composer_sort", mfi_offsetof(composer_sort), DB_TYPE_STRING, DB_FIXUP_COMPOSER_SORT },
{ "channels", mfi_offsetof(channels), DB_TYPE_INT },
};
/* This list must be kept in sync with
@ -273,6 +274,10 @@ static const struct col_type_map qi_cols_map[] =
{ "queue_version", qi_offsetof(queue_version), DB_TYPE_INT },
{ "composer", qi_offsetof(composer), DB_TYPE_STRING, DB_FIXUP_COMPOSER },
{ "songartistid", qi_offsetof(songartistid), DB_TYPE_INT64 },
{ "type", qi_offsetof(type), DB_TYPE_STRING, DB_FIXUP_CODECTYPE },
{ "bitrate", qi_offsetof(bitrate), DB_TYPE_INT },
{ "samplerate", qi_offsetof(samplerate), DB_TYPE_INT },
{ "chanenls", qi_offsetof(channels), DB_TYPE_INT },
};
/* This list must be kept in sync with
@ -343,6 +348,7 @@ static const ssize_t dbmfi_cols_map[] =
dbmfi_offsetof(album_sort),
dbmfi_offsetof(album_artist_sort),
dbmfi_offsetof(composer_sort),
dbmfi_offsetof(channels),
};
/* This list must be kept in sync with
@ -704,6 +710,7 @@ free_queue_item(struct db_queue_item *queue_item, int content_only)
free(queue_item->album_sort);
free(queue_item->album_artist_sort);
free(queue_item->artwork_url);
free(queue_item->type);
if (!content_only)
free(queue_item);
@ -4640,12 +4647,14 @@ queue_add_file(struct db_media_file_info *dbmfi, int pos, int shuffle_pos, int q
"pos, shuffle_pos, path, virtual_path, title, " \
"artist, composer, album_artist, album, genre, songalbumid, songartistid," \
"time_modified, artist_sort, album_sort, album_artist_sort, year, " \
"type, bitrate, samplerate, channels, " \
"track, disc, queue_version)" \
"VALUES" \
"(NULL, %s, %s, %s, %s, " \
"%d, %d, %Q, %Q, %Q, " \
"%Q, %Q, %Q, %Q, %Q, %s, %s," \
"%s, %Q, %Q, %Q, %s, " \
"%Q, %s, %s, %s, " \
"%s, %s, %d);"
char *query;
@ -4656,6 +4665,7 @@ queue_add_file(struct db_media_file_info *dbmfi, int pos, int shuffle_pos, int q
pos, shuffle_pos, dbmfi->path, dbmfi->virtual_path, dbmfi->title,
dbmfi->artist, dbmfi->composer, dbmfi->album_artist, dbmfi->album, dbmfi->genre, dbmfi->songalbumid, dbmfi->songartistid,
dbmfi->time_modified, dbmfi->artist_sort, dbmfi->album_sort, dbmfi->album_artist_sort, dbmfi->year,
dbmfi->type, dbmfi->bitrate, dbmfi->samplerate, dbmfi->channels,
dbmfi->track, dbmfi->disc, queue_version);
ret = db_query_run(query, 1, 0);
@ -4672,12 +4682,14 @@ queue_add_item(struct db_queue_item *item, int pos, int shuffle_pos, int queue_v
"pos, shuffle_pos, path, virtual_path, title, " \
"artist, composer, album_artist, album, genre, songalbumid, songartistid, " \
"time_modified, artist_sort, album_sort, album_artist_sort, year, " \
"type, bitrate, samplerate, channels, " \
"track, disc, artwork_url, queue_version)" \
"VALUES" \
"(NULL, %d, %d, %d, %d, " \
"%d, %d, %Q, %Q, %Q, " \
"%Q, %Q, %Q, %Q, %Q, %" PRIi64 ", %" PRIi64 "," \
"%d, %Q, %Q, %Q, %d, " \
"%Q, %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", " \
"%d, %d, %Q, %d);"
char *query;
@ -4688,6 +4700,7 @@ queue_add_item(struct db_queue_item *item, int pos, int shuffle_pos, int queue_v
pos, shuffle_pos, item->path, item->virtual_path, item->title,
item->artist, item->composer, item->album_artist, item->album, item->genre, item->songalbumid, item->songartistid,
item->time_modified, item->artist_sort, item->album_sort, item->album_artist_sort, item->year,
item->type, item->bitrate, item->samplerate, item->channels,
item->track, item->disc, item->artwork_url, queue_version);
ret = db_query_run(query, 1, 0);
@ -5116,6 +5129,10 @@ queue_enum_fetch(struct query_params *qp, struct db_queue_item *queue_item, int
queue_item->artwork_url = strdup_if((char *)sqlite3_column_text(qp->stmt, 22), keep_item);
queue_item->composer = strdup_if((char *)sqlite3_column_text(qp->stmt, 24), keep_item);
queue_item->songartistid = sqlite3_column_int64(qp->stmt, 25);
queue_item->type = strdup_if((char *)sqlite3_column_text(qp->stmt, 26), keep_item);
queue_item->bitrate = sqlite3_column_int(qp->stmt, 27);
queue_item->samplerate = sqlite3_column_int(qp->stmt, 28);
queue_item->channels = sqlite3_column_int(qp->stmt, 29);
return 0;
}

View File

@ -163,6 +163,7 @@ struct media_file_info {
uint32_t bitrate;
uint32_t samplerate;
uint32_t channels;
uint32_t song_length;
int64_t file_size;
uint32_t year; /* TDRC */
@ -367,6 +368,7 @@ struct db_media_file_info {
char *album_sort;
char *album_artist_sort;
char *composer_sort;
char *channels;
};
#define dbmfi_offsetof(field) offsetof(struct db_media_file_info, field)
@ -469,6 +471,11 @@ struct db_queue_item {
char *composer;
char *type;
uint32_t bitrate;
uint32_t samplerate;
uint32_t channels;
int64_t songartistid;
/* Not saved in queue table */

View File

@ -95,7 +95,8 @@
" artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
" album_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
" album_artist_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
" composer_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP" \
" composer_sort VARCHAR(1024) DEFAULT NULL COLLATE DAAP," \
" channels INTEGER DEFAULT 0" \
");"
#define T_PL \
@ -192,7 +193,11 @@
" artwork_url VARCHAR(4096) DEFAULT NULL," \
" queue_version INTEGER DEFAULT 0," \
" composer VARCHAR(1024) DEFAULT NULL," \
" songartistid INTEGER NOT NULL" \
" songartistid INTEGER NOT NULL," \
" type VARCHAR(8) DEFAULT NULL," \
" bitrate INTEGER DEFAULT 0," \
" samplerate INTEGER DEFAULT 0," \
" channels INTEGER DEFAULT 0" \
");"
#define Q_PL1 \

View File

@ -26,7 +26,7 @@
* is a major upgrade. In other words minor version upgrades permit downgrading
* forked-daapd after the database was upgraded. */
#define SCHEMA_VERSION_MAJOR 21
#define SCHEMA_VERSION_MINOR 00
#define SCHEMA_VERSION_MINOR 01
int
db_init_indices(sqlite3 *hdl);

View File

@ -995,6 +995,31 @@ static const struct db_upgrade_query db_upgrade_v2100_queries[] =
{ U_V2100_SCVER_MINOR, "set schema_version_minor to 00" },
};
#define U_v2101_ALTER_QUEUE_ADD_TYPE \
"ALTER TABLE queue ADD COLUMN type VARCHAR(8) DEFAULT NULL;"
#define U_v2101_ALTER_QUEUE_ADD_BITRATE \
"ALTER TABLE queue ADD COLUMN bitrate INTEGER DEFAULT 0;"
#define U_v2101_ALTER_QUEUE_ADD_SAMPLERATE \
"ALTER TABLE queue ADD COLUMN samplerate INTEGER DEFAULT 0;"
#define U_v2101_ALTER_QUEUE_ADD_CHANNELS \
"ALTER TABLE queue ADD COLUMN channels INTEGER DEFAULT 0;"
#define U_v2101_ALTER_FILES_ADD_CHANNELS \
"ALTER TABLE files ADD COLUMN channels INTEGER DEFAULT 0;"
#define U_v2101_SCVER_MINOR \
"UPDATE admin SET value = '01' WHERE key = 'schema_version_minor';"
static const struct db_upgrade_query db_upgrade_v2101_queries[] =
{
{ U_v2101_ALTER_QUEUE_ADD_TYPE, "alter table queue add column type" },
{ U_v2101_ALTER_QUEUE_ADD_BITRATE, "alter table queue add column bitrate" },
{ U_v2101_ALTER_QUEUE_ADD_SAMPLERATE, "alter table queue add column samplerate" },
{ U_v2101_ALTER_QUEUE_ADD_CHANNELS, "alter table queue add column channels" },
{ U_v2101_ALTER_FILES_ADD_CHANNELS, "alter table files add column channels" },
{ U_v2101_SCVER_MINOR, "set schema_version_minor to 01" },
};
int
db_upgrade(sqlite3 *hdl, int db_ver)
@ -1143,6 +1168,13 @@ db_upgrade(sqlite3 *hdl, int db_ver)
if (ret < 0)
return -1;
/* FALLTHROUGH */
case 2100:
ret = db_generic_upgrade(hdl, db_upgrade_v2101_queries, ARRAY_SIZE(db_upgrade_v2101_queries));
if (ret < 0)
return -1;
break;
default:

View File

@ -231,6 +231,11 @@ track_to_json(struct db_media_file_info *dbmfi)
safe_json_add_time_from_string(item, "date_released", dbmfi->date_released, false);
safe_json_add_int_from_string(item, "seek_ms", dbmfi->seek);
safe_json_add_string(item, "type", dbmfi->type);
safe_json_add_int_from_string(item, "samplerate", dbmfi->samplerate);
safe_json_add_int_from_string(item, "bitrate", dbmfi->bitrate);
safe_json_add_int_from_string(item, "channels", dbmfi->channels);
ret = safe_atoi32(dbmfi->media_kind, &intval);
if (ret == 0)
safe_json_add_string(item, "media_kind", db_media_kind_label(intval));
@ -1664,6 +1669,8 @@ queue_item_to_json(struct db_queue_item *queue_item, char shuffle)
json_object *item;
char uri[100];
char artwork_url[100];
char chbuf[6];
const char *ch;
int ret;
item = json_object_new_object();
@ -1721,6 +1728,19 @@ queue_item_to_json(struct db_queue_item *queue_item, char shuffle)
json_object_object_add(item, "artwork_url", json_object_new_string(artwork_url));
}
safe_json_add_string(item, "type", queue_item->type);
json_object_object_add(item, "bitrate", json_object_new_int(queue_item->bitrate));
json_object_object_add(item, "samplerate", json_object_new_int(queue_item->samplerate));
switch (queue_item->channels)
{
case 1: ch = "mono"; break;
case 2: ch = "stereo"; break;
default:
snprintf(chbuf, sizeof(chbuf), "%d ch", queue_item->channels);
ch = chbuf;
}
safe_json_add_string(item, "channels", ch);
return item;
}

View File

@ -1712,6 +1712,10 @@ map_media_file_to_queue_item(struct db_queue_item *queue_item, struct media_file
queue_item->track = mfi->track;
queue_item->disc = mfi->disc;
//queue_item->artwork_url
queue_item->type = safe_strdup(mfi->type);
queue_item->channels = mfi->channels;
queue_item->samplerate = mfi->samplerate;
queue_item->bitrate = mfi->bitrate;
}
static int

View File

@ -373,6 +373,7 @@ scan_metadata_ffmpeg(const char *file, struct media_file_info *mfi)
char *path;
int mdcount;
int sample_rate;
int channels;
int i;
int ret;
@ -442,6 +443,7 @@ scan_metadata_ffmpeg(const char *file, struct media_file_info *mfi)
codec_id = ctx->streams[i]->codecpar->codec_id;
sample_rate = ctx->streams[i]->codecpar->sample_rate;
sample_fmt = ctx->streams[i]->codecpar->format;
channels = ctx->streams[i]->codecpar->channels;
switch (codec_type)
{
case AVMEDIA_TYPE_VIDEO:
@ -478,6 +480,7 @@ scan_metadata_ffmpeg(const char *file, struct media_file_info *mfi)
mfi->bits_per_sample = 8 * av_get_bytes_per_sample(sample_fmt);
if (mfi->bits_per_sample == 0)
mfi->bits_per_sample = av_get_bits_per_sample(codec_id);
mfi->channels = channels;
}
break;
@ -503,7 +506,7 @@ scan_metadata_ffmpeg(const char *file, struct media_file_info *mfi)
else if (ctx->duration > AV_TIME_BASE) /* guesstimate */
mfi->bitrate = ((mfi->file_size * 8) / (ctx->duration / AV_TIME_BASE)) / 1000;
DPRINTF(E_DBG, L_SCAN, "Duration %d ms, bitrate %d kbps\n", mfi->song_length, mfi->bitrate);
DPRINTF(E_DBG, L_SCAN, "Duration %d ms, bitrate %d kbps, samplerate %d channels %d\n", mfi->song_length, mfi->bitrate, mfi->samplerate, mfi->channels);
/* Try to extract ICY metadata if http stream */
if (mfi->data_kind == DATA_KIND_HTTP)

View File

@ -51,6 +51,10 @@
<span class="heading">Type</span>
<span class="title is-6">{{ item.media_kind }} - {{ item.data_kind }} <span class="has-text-weight-normal" v-if="item.data_kind === 'spotify'">(<a @click="open_spotify_artist">artist</a>, <a @click="open_spotify_album">album</a>)</span></span>
</p>
<p>
<span class="heading">Quality</span>
<span class="title is-6">{{ item.type}} | {{ item.samplerate }} Hz | {{ item.channels }} | {{ item.bitrate }} Kb/s</span>
</p>
</div>
</div>
<footer class="card-footer">

View File

@ -57,6 +57,10 @@
<span class="heading">Type</span>
<span class="title is-6">{{ track.media_kind }} - {{ track.data_kind }} <span class="has-text-weight-normal" v-if="track.data_kind === 'spotify'">(<a @click="open_spotify_artist">artist</a>, <a @click="open_spotify_album">album</a>)</span></span>
</p>
<p>
<span class="heading">Quality</span>
<span class="title is-6">{{ track.type}} | {{ track.samplerate}} Hz | {{ track.channels }} channels | {{ track.bitrate}} Kb/s</span>
</p>
<p>
<span class="heading">Added at</span>
<span class="title is-6">{{ track.time_added | time('L LT') }}</span>