1
0
mirror of https://github.com/SuperBFG7/ympd synced 2024-12-26 02:50:26 +00:00

Feat: option to select jukebox playlist #37

This commit is contained in:
jcorporation 2018-09-20 17:59:29 +01:00
parent 881567a2bd
commit fb9668b39d
5 changed files with 107 additions and 39 deletions

View File

@ -650,6 +650,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form class="needs-validation" id="settingsFrm" novalidate> <form class="needs-validation" id="settingsFrm" novalidate>
<h4>MPD</h4>
<div class="row"> <div class="row">
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<button data-href='{"cmd":"toggleBtn", "options":["btnRandom"]}' id="btnRandom" type="button" class="btn btn-secondary btn-block" title="Random"> <button data-href='{"cmd":"toggleBtn", "options":["btnRandom"]}' id="btnRandom" type="button" class="btn btn-secondary btn-block" title="Random">
@ -709,14 +710,21 @@
<div class="invalid-feedback">Must be a number.</div> <div class="invalid-feedback">Must be a number.</div>
</div> </div>
</div> </div>
<hr/>
<h4>Jukebox</h4>
<div class="row"> <div class="row">
<div class="form-group col-md-6" data-toggle="buttons"> <div class="form-group col-md-6" data-toggle="buttons">
<button data-href='{"cmd": "toggleBtn", "options": ["btnJukebox"]}' id="btnJukebox" type="button" class="btn btn-secondary btn-block" title="Jukebox"> <button data-href='{"cmd": "toggleBtn", "options": ["btnJukebox"]}' id="btnJukebox" type="button" class="btn btn-secondary btn-block" title="Jukebox">
Jukebox Jukebox
</button> </button>
</div> </div>
<div class="form-group input-group col-md-6 border-secondary">
<select id="jukeboxPlaylist" class="form-control custom-select border-secondary">
</select>
</div>
</div> </div>
<hr/> <hr/>
<h4>Notifications</h4>
<div class="row"> <div class="row">
<div class="form-group col-md-6" data-toggle="buttons"> <div class="form-group col-md-6" data-toggle="buttons">
<button data-href='{"cmd": "toggleBtn", "options": ["btnnotifyPage"]}' type="button" class="btn btn-secondary btn-block" id="btnnotifyPage"> <button data-href='{"cmd": "toggleBtn", "options": ["btnnotifyPage"]}' type="button" class="btn btn-secondary btn-block" id="btnnotifyPage">

View File

@ -31,8 +31,9 @@ var playstate = '';
var settings = {}; var settings = {};
var alertTimeout; var alertTimeout;
var progressTimer; var progressTimer;
let deferredPrompt; var deferredPrompt;
var dragEl; var dragEl;
var playlistEl;
var app = {}; var app = {};
app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 }, app.apps = { "Playback": { "state": "0/-/", "scrollPos": 0 },
@ -850,6 +851,10 @@ function parseSettings(obj) {
} }
settings = obj.data; settings = obj.data;
playlistEl = 'jukeboxPlaylist';
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST", "data": {"offset": 0, "filter": "-"}}, getAllPlaylists);
settings.mpdstream = 'http://'; settings.mpdstream = 'http://';
if (settings.mpdhost == '127.0.0.1' || settings.mpdhost == 'localhost') if (settings.mpdhost == '127.0.0.1' || settings.mpdhost == 'localhost')
settings.mpdstream += window.location.hostname; settings.mpdstream += window.location.hostname;
@ -1504,11 +1509,23 @@ function playlistClear() {
function getAllPlaylists(obj) { function getAllPlaylists(obj) {
var nrItems = obj.data.length; var nrItems = obj.data.length;
var playlists = '<option></option><option>New Playlist</option>'; var playlists = '';
for (var i = 0; i < nrItems; i++) { if (obj.offset == 0) {
playlists += '<option>' + obj.data[i].uri + '</option>'; if (playlistEl == 'addToPlaylistPlaylist')
playlists = '<option></option><option>New Playlist</option>';
else if (playlistEl == 'jukeboxPlaylist')
playlists = '<option>Database</option>';
} }
document.getElementById('addToPlaylistPlaylist').innerHTML += playlists; for (var i = 0; i < nrItems; i++) {
playlists += '<option';
if (playlistEl == 'jukeboxPlaylist' && obj.data[i].uri == settings.jukeboxPlaylist)
playlists += ' selected';
playlists += '>' + obj.data[i].uri + '</option>';
}
if (obj.offset == 0)
document.getElementById(playlistEl).innerHTML = playlists;
else
document.getElementById(playlistEl).innerHTML += playlists;
if (obj.totalEntities > obj.returnedEntities) { if (obj.totalEntities > obj.returnedEntities) {
obj.offset += settings.maxElementsPerPage; obj.offset += settings.maxElementsPerPage;
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST", "data": {"offset": obj.offset, "filter": "-"}}, getAllPlaylists); sendAPI({"cmd": "MPD_API_PLAYLIST_LIST", "data": {"offset": obj.offset, "filter": "-"}}, getAllPlaylists);
@ -1591,6 +1608,7 @@ function showAddToPlaylist(uri) {
document.getElementById('addToPlaylistLabel').innerText = 'Add Stream'; document.getElementById('addToPlaylistLabel').innerText = 'Add Stream';
} }
modalAddToPlaylist.show(); modalAddToPlaylist.show();
playlistEl = 'addToPlaylistPlaylist';
sendAPI({"cmd": "MPD_API_PLAYLIST_LIST","data": {"offset": 0, "filter": "-"}}, getAllPlaylists); sendAPI({"cmd": "MPD_API_PLAYLIST_LIST","data": {"offset": 0, "filter": "-"}}, getAllPlaylists);
} }
@ -1926,6 +1944,7 @@ function confirmSettings() {
if (formOK == true) { if (formOK == true) {
var selectReplaygain = document.getElementById('selectReplaygain'); var selectReplaygain = document.getElementById('selectReplaygain');
var selectJukeboxPlaylist = document.getElementById('jukeboxPlaylist');
sendAPI({"cmd": "MPD_API_SETTINGS_SET", "data": { sendAPI({"cmd": "MPD_API_SETTINGS_SET", "data": {
"consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0), "consume": (document.getElementById('btnConsume').classList.contains('active') ? 1 : 0),
"random": (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0), "random": (document.getElementById('btnRandom').classList.contains('active') ? 1 : 0),
@ -1937,7 +1956,8 @@ function confirmSettings() {
"mixrampdelay": (settings.mixramp == true ? document.getElementById('inputMixrampdelay').value : settings.mixrampdelay), "mixrampdelay": (settings.mixramp == true ? document.getElementById('inputMixrampdelay').value : settings.mixrampdelay),
"notificationWeb": (document.getElementById('btnnotifyWeb').classList.contains('active') ? true : false), "notificationWeb": (document.getElementById('btnnotifyWeb').classList.contains('active') ? true : false),
"notificationPage": (document.getElementById('btnnotifyPage').classList.contains('active') ? true : false), "notificationPage": (document.getElementById('btnnotifyPage').classList.contains('active') ? true : false),
"jukeboxMode": (document.getElementById('btnJukebox').classList.contains('active') ? true : false) "jukeboxMode": (document.getElementById('btnJukebox').classList.contains('active') ? true : false),
"jukeboxPlaylist": selectJukeboxPlaylist.options[selectJukeboxPlaylist.selectedIndex].value
}}, getSettings); }}, getSettings);
modalSettings.hide(); modalSettings.hide();
} else } else

View File

@ -112,18 +112,22 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
n = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.last_song_id, &mpd.queue_version, &mpd.queue_length); n = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.last_song_id, &mpd.queue_version, &mpd.queue_length);
break; break;
case MPD_API_SETTINGS_SET: case MPD_API_SETTINGS_SET:
je = json_scanf(msg.p, msg.len, "{data: {notificationWeb: %B, notificationPage: %B, jukeboxMode: %B}}", je = json_scanf(msg.p, msg.len, "{data: {notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q}}",
&mympd_state.notificationWeb, &mympd_state.notificationWeb,
&mympd_state.notificationPage, &mympd_state.notificationPage,
&mympd_state.jukeboxMode); &mympd_state.jukeboxMode,
if (je == 3) { &mympd_state.jukeboxPlaylist);
if (je == 4) {
char tmp_file[200]; char tmp_file[200];
snprintf(tmp_file, 200, "%s.tmp", config.statefile); snprintf(tmp_file, 200, "%s.tmp", config.statefile);
json_fprintf(tmp_file, "{notificationWeb: %B, notificationPage: %B, jukeboxMode: %B}", json_fprintf(tmp_file, "{notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q}",
mympd_state.notificationWeb, mympd_state.notificationWeb,
mympd_state.notificationPage, mympd_state.notificationPage,
mympd_state.jukeboxMode); mympd_state.jukeboxMode,
mympd_state.jukeboxPlaylist);
rename(tmp_file, config.statefile); rename(tmp_file, config.statefile);
if (mympd_state.jukeboxMode == true)
mympd_jukebox();
} }
je = json_scanf(msg.p, msg.len, "{data: {random: %u}}", &uint_buf1); je = json_scanf(msg.p, msg.len, "{data: {random: %u}}", &uint_buf1);
@ -934,12 +938,14 @@ void mympd_jukebox() {
if (queue_length > 0) if (queue_length > 0)
return; return;
srand((unsigned int)time(NULL));
if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) {
struct mpd_stats *stats = mpd_run_stats(mpd.conn); struct mpd_stats *stats = mpd_run_stats(mpd.conn);
num_songs = mpd_stats_get_number_of_songs(stats); num_songs = mpd_stats_get_number_of_songs(stats);
mpd_stats_free(stats); mpd_stats_free(stats);
num_songs--; num_songs--;
if (num_songs > 0) { if (num_songs > 0) {
srand((unsigned int)time(NULL));
rand_song = rand() % num_songs; rand_song = rand() % num_songs;
mpd_send_list_all(mpd.conn, "/"); mpd_send_list_all(mpd.conn, "/");
i = 0; i = 0;
@ -954,13 +960,42 @@ void mympd_jukebox() {
mpd_response_finish(mpd.conn); mpd_response_finish(mpd.conn);
song = mpd_entity_get_song(entity); song = mpd_entity_get_song(entity);
if (song != NULL) { if (song != NULL) {
printf("Jukebox enabled, playing random song %d/%d\n", rand_song, num_songs); printf("Jukebox enabled, playing random song from database: %d/%d\n", rand_song, num_songs);
mpd_run_add(mpd.conn, mpd_song_get_uri(song)); mpd_run_add(mpd.conn, mpd_song_get_uri(song));
mpd_run_play(mpd.conn); mpd_run_play(mpd.conn);
} }
mpd_entity_free(entity); mpd_entity_free(entity);
} }
} }
else {
mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist);
num_songs = 0;
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
num_songs++;
mpd_entity_free(entity);
}
num_songs--;
if (num_songs > 0) {
rand_song = rand() % num_songs;
mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist);
i = 0;
while ((entity = mpd_recv_entity(mpd.conn)) != NULL) {
if (i == rand_song)
break;
i++;
mpd_entity_free(entity);
}
mpd_response_finish(mpd.conn);
song = mpd_entity_get_song(entity);
if (song != NULL) {
printf("Jukebox enabled, playing random song from %s: %d/%d\n", mympd_state.jukeboxPlaylist, rand_song, num_songs);
mpd_run_add(mpd.conn, mpd_song_get_uri(song));
mpd_run_play(mpd.conn);
}
mpd_entity_free(entity);
}
}
}
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) { int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) {
struct mpd_status *status; struct mpd_status *status;
@ -1051,7 +1086,7 @@ int mympd_put_settings(char *buffer) {
"repeat: %d, single: %d, crossfade: %d, consume: %d, random: %d, " "repeat: %d, single: %d, crossfade: %d, consume: %d, random: %d, "
"mixrampdb: %f, mixrampdelay: %f, mpdhost: %Q, mpdport: %d, passwort_set: %B, " "mixrampdb: %f, mixrampdelay: %f, mpdhost: %Q, mpdport: %d, passwort_set: %B, "
"streamport: %d, coverimage: %Q, stickers: %B, mixramp: %B, maxElementsPerPage: %d, " "streamport: %d, coverimage: %Q, stickers: %B, mixramp: %B, maxElementsPerPage: %d, "
"replaygain: %Q, notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, " "replaygain: %Q, notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q, "
"tags: { Artist: %B, Album: %B, AlbumArtist: %B, Title: %B, Track: %B, Genre: %B, Date: %B," "tags: { Artist: %B, Album: %B, AlbumArtist: %B, Title: %B, Track: %B, Genre: %B, Date: %B,"
"Composer: %B, Performer: %B }" "Composer: %B, Performer: %B }"
"}}", "}}",
@ -1074,6 +1109,7 @@ int mympd_put_settings(char *buffer) {
mympd_state.notificationWeb, mympd_state.notificationWeb,
mympd_state.notificationPage, mympd_state.notificationPage,
mympd_state.jukeboxMode, mympd_state.jukeboxMode,
mympd_state.jukeboxPlaylist,
mpd.tag_artist, mpd.tag_artist,
mpd.tag_album, mpd.tag_album,
mpd.tag_album_artist, mpd.tag_album_artist,

View File

@ -175,6 +175,7 @@ typedef struct {
bool notificationWeb; bool notificationWeb;
bool notificationPage; bool notificationPage;
bool jukeboxMode; bool jukeboxMode;
const char* jukeboxPlaylist;
} t_mympd_state; } t_mympd_state;
t_mympd_state mympd_state; t_mympd_state mympd_state;

View File

@ -236,19 +236,22 @@ int main(int argc, char **argv) {
if (access( config.statefile, F_OK ) != -1 ) { if (access( config.statefile, F_OK ) != -1 ) {
char *content = json_fread(config.statefile); char *content = json_fread(config.statefile);
int je = json_scanf(content, strlen(content), "{notificationWeb: %B, notificationPage: %B, jukeboxMode: %B}", int je = json_scanf(content, strlen(content), "{notificationWeb: %B, notificationPage: %B, jukeboxMode: %B, jukeboxPlaylist: %Q}",
&mympd_state.notificationWeb, &mympd_state.notificationWeb,
&mympd_state.notificationPage, &mympd_state.notificationPage,
&mympd_state.jukeboxMode); &mympd_state.jukeboxMode,
if (je != 3) { &mympd_state.jukeboxPlaylist);
if (je != 4) {
mympd_state.notificationWeb = false; mympd_state.notificationWeb = false;
mympd_state.notificationPage = true; mympd_state.notificationPage = true;
mympd_state.jukeboxMode = false; mympd_state.jukeboxMode = false;
mympd_state.jukeboxPlaylist = "Database";
} }
} else { } else {
mympd_state.notificationWeb = false; mympd_state.notificationWeb = false;
mympd_state.notificationPage = true; mympd_state.notificationPage = true;
mympd_state.jukeboxMode = false; mympd_state.jukeboxMode = false;
mympd_state.jukeboxPlaylist = "Database";
} }
signal(SIGTERM, signal_handler); signal(SIGTERM, signal_handler);