From: Mike Brady Date: Sat, 7 Apr 2018 12:22:38 +0000 (+0100) Subject: Improve the scanner to start and stop properly and to release track data when remote... X-Git-Tag: 3.2RC1~7^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4aab0a6f92a097986155cd042c28832928872a79;p=thirdparty%2Fshairport-sync.git Improve the scanner to start and stop properly and to release track data when remote control becomes unavailable. --- diff --git a/common.h b/common.h index 9daacf99..50b7a0fe 100644 --- a/common.h +++ b/common.h @@ -173,10 +173,14 @@ typedef struct { #ifdef HAVE_METADATA_HUB char *cover_art_cache_dir; - int scan_interval_when_active; // number of seconds between DACP server scans when playing something (1) - int scan_interval_when_inactive; // number of seconds between DACP server scans playing nothing (3) - int scan_max_bad_response_count; // number of successive bad results to ignore before giving up (10) - int scan_max_inactive_count; // number of scans to do before stopping if not made active again (about 15 minutes worth) + int scan_interval_when_active; // number of seconds between DACP server scans when playing + // something (1) + int scan_interval_when_inactive; // number of seconds between DACP server scans playing nothing + // (3) + int scan_max_bad_response_count; // number of successive bad results to ignore before giving up + // (10) + int scan_max_inactive_count; // number of scans to do before stopping if not made active again + // (about 15 minutes worth) #endif int disable_resend_requests; // set this to stop resend request being made for missing packets diff --git a/dacp.c b/dacp.c index a7d0679f..16cfe3e0 100644 --- a/dacp.c +++ b/dacp.c @@ -302,7 +302,6 @@ void relinquish_dacp_server_information(rtsp_conn_info *conn) { // the conversation number // Thus, we can keep the DACP port that might have previously been discovered void set_dacp_server_information(rtsp_conn_info *conn) { - debug(1, "set_dacp_server_information."); sps_pthread_mutex_timedlock( &dacp_server_information_lock, 500000, "set_dacp_server_information couldn't get DACP server information lock in 0.5 second!.", 2); @@ -314,6 +313,8 @@ void set_dacp_server_information(rtsp_conn_info *conn) { dacp_server.connection_family = conn->connection_ip_family; dacp_server.scope_id = conn->self_scope_id; strncpy(dacp_server.ip_string, conn->client_ip_string, INET6_ADDRSTRLEN); + debug(1, "set_dacp_server_information set IP to \"%s\" and DACP id to \"%s\".", + dacp_server.ip_string, dacp_server.dacp_id); if (dacp_server.port_monitor_private_storage) // if there's is a monitor already active... mdns_dacp_dont_monitor(dacp_server.port_monitor_private_storage); // let it go. @@ -334,15 +335,18 @@ void set_dacp_server_information(rtsp_conn_info *conn) { metadata_hub_modify_epilog(ch); } else { if (dacp_server.port) { - debug(1,"Enable scanning."); + debug(1, "Enable scanning."); dacp_server.scan_enable = 1; - metadata_hub_modify_prolog(); - int ch = metadata_store.dacp_server_active != dacp_server.scan_enable; - metadata_store.dacp_server_active = dacp_server.scan_enable; - metadata_hub_modify_epilog(ch); + // metadata_hub_modify_prolog(); + // int ch = metadata_store.dacp_server_active != dacp_server.scan_enable; + // metadata_store.dacp_server_active = dacp_server.scan_enable; + // metadata_hub_modify_epilog(ch); } } - dacp_server.active_remote_id = conn->dacp_active_remote; // even if the dacp_id remains the same, the active remote will change. + dacp_server.active_remote_id = conn->dacp_active_remote; // even if the dacp_id remains the same, + // the active remote will change. + debug(1, "set_dacp_server_information set active-remote id to %" PRIu32 ".", + dacp_server.active_remote_id); pthread_cond_signal(&dacp_server_information_cv); pthread_mutex_unlock(&dacp_server_information_lock); } @@ -358,16 +362,18 @@ void dacp_monitor_port_update_callback(char *dacp_id, uint16_t port) { dacp_server.port = port; if (port == 0) dacp_server.scan_enable = 0; - else + else { dacp_server.scan_enable = 1; - metadata_hub_modify_prolog(); - int ch = metadata_store.dacp_server_active != dacp_server.scan_enable; - metadata_store.dacp_server_active = dacp_server.scan_enable; - metadata_hub_modify_epilog(ch); - pthread_cond_signal(&dacp_server_information_cv); + debug(1, "dacp_monitor_port_update_callback enables scan"); + } + // metadata_hub_modify_prolog(); + // int ch = metadata_store.dacp_server_active != dacp_server.scan_enable; + // metadata_store.dacp_server_active = dacp_server.scan_enable; + // metadata_hub_modify_epilog(ch); } else { debug(1, "dacp port monitor reporting on an out-of-use remote."); } + pthread_cond_signal(&dacp_server_information_cv); pthread_mutex_unlock(&dacp_server_information_lock); } void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { @@ -386,346 +392,367 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) { while (dacp_server.scan_enable == 0) { // debug(1, "Wait for a valid DACP port"); pthread_cond_wait(&dacp_server_information_cv, &dacp_server_information_lock); - debug(1,"Wake up with dacp_server.scan_enable == %d.",dacp_server.scan_enable); + // debug(1,"Wake up with dacp_server.scan_enable == %d.",dacp_server.scan_enable); } scan_index++; int32_t the_volume; result = dacp_get_volume(&the_volume); // just want the http code - + if ((result == 496) || (result == 403) || (result == 501)) { bad_result_count++; // debug(1,"Bad Scan : %d.",result); } else - bad_result_count=0; - - if (metadata_store.player_thread_active==0) + bad_result_count = 0; + + if (metadata_store.player_thread_active == 0) idle_scan_count++; else idle_scan_count = 0; - - debug(1,"HTTP Result: %d, Bad Scan Count: %d, Idle Scan Count: %d.",result,bad_result_count,idle_scan_count); - if ((bad_result_count == config.scan_max_bad_response_count) || (idle_scan_count == config.scan_max_inactive_count)) { - debug(1,"DACP server status scanning stopped."); + debug(1, "HTTP Result: %d, Bad Scan Count: %d, Idle Scan Count: %d.", result, bad_result_count, + idle_scan_count); + + if ((bad_result_count == config.scan_max_bad_response_count) || + (idle_scan_count == config.scan_max_inactive_count)) { + debug(1, "DACP server status scanning stopped."); dacp_server.scan_enable = 0; bad_result_count = 0; idle_scan_count = 0; metadata_hub_modify_prolog(); - int ch = metadata_store.dacp_server_active != 0; + int ch = (metadata_store.dacp_server_active != 0) || + (metadata_store.advanced_dacp_server_active != 0); metadata_store.dacp_server_active = 0; - debug(1,"setting dacp_server_active to %d with an update flag value of %d",metadata_store.dacp_server_active,ch); + metadata_store.advanced_dacp_server_active = 0; + debug(1, "setting dacp_server_active and advanced_dacp_server_active to 0 with an update " + "flag value of %d", + ch); metadata_hub_modify_epilog(ch); } pthread_mutex_unlock(&dacp_server_information_lock); // debug(1, "DACP Server ID \"%u\" at \"%s:%u\", scan %d.", dacp_server.active_remote_id, // dacp_server.ip_string, dacp_server.port, scan_index); - int transient_problem = (result == 494) || (result == 495); - if (!transient_problem) { // this just means that it couldn't send the query because something - // else - // was sending a command or something - int adv = (result == 200); - // a result of 200 means the advanced features of, e.g., iTunes, are available - // so, turn the advanced_dacp_server flag on or off and flag if it's changed. - metadata_hub_modify_prolog(); - int diff = metadata_store.advanced_dacp_server_active != adv; - if (diff) { - metadata_store.advanced_dacp_server_active = adv; - debug(1, "Setting dacp_server_active to %d because of a response of %d.", adv, result); + if (dacp_server.scan_enable == + 1) { // if it hasn't been turned off, continue looking for information. + int transient_problem = + (result == 494) || + (result == 495); // this just means that it couldn't send the query because something + // else + // was sending a command or something + if ((!transient_problem) && (bad_result_count == 0) && (idle_scan_count == 0) && + (dacp_server.scan_enable == 1)) { + + // Any other result means that the DACP server is active, but not providing advanced + // features + + metadata_hub_modify_prolog(); + int inactive = metadata_store.dacp_server_active == 0; + if (inactive) { + metadata_store.dacp_server_active = 1; + debug(1, "Setting dacp_server_active to active because of a response of %d.", result); + } + int same = metadata_store.advanced_dacp_server_active == (result == 200); + if (!same) { + metadata_store.advanced_dacp_server_active = (result == 200); + debug(1, "Setting dacp_advanced_server_active to %d because of a response of %d.", (result == 200), + result); + } + metadata_hub_modify_epilog(inactive + (!same)); } - metadata_hub_modify_epilog(diff); - } - if (result == 200) { - metadata_hub_modify_prolog(); - int diff = metadata_store.speaker_volume != the_volume; - if (diff) - metadata_store.speaker_volume = the_volume; - metadata_hub_modify_epilog(diff); - - ssize_t le; - char *response = NULL; - int32_t item_size; - char command[1024] = ""; - snprintf(command, sizeof(command) - 1, "playstatusupdate?revision-number=%d", - revision_number); - // debug(1,"Command: \"%s\"",command); - result = dacp_send_command(command, &response, &le); - // debug(1,"Response to \"%s\" is %d.",command,result); if (result == 200) { - // if (0) { - char *sp = response; - if (le >= 8) { - // here start looking for the contents of the status update - if (dacp_tlv_crawl(&sp, &item_size) == 'cmst') { // status - // here, we know that we are receiving playerstatusupdates, so set a flag - metadata_hub_modify_prolog(); - // debug(1, "playstatusupdate release track metadata"); - // metadata_hub_reset_track_metadata(); - // metadata_store.playerstatusupdates_are_received = 1; - sp -= item_size; // drop down into the array -- don't skip over it - le -= 8; - // char typestring[5]; - // we need to acquire the metadata data structure and possibly update it - while (le >= 8) { - uint32_t type = dacp_tlv_crawl(&sp, &item_size); - le -= item_size + 8; - char *t; - // char u; - // char *st; - int32_t r; - // uint64_t v; - // int i; - - switch (type) { - case 'cmsr': // revision number - t = sp - item_size; - revision_number = ntohl(*(uint32_t *)(t)); - // debug(1," Serial Number: %d", revision_number); - break; - case 'caps': // play status - t = sp - item_size; - r = *(unsigned char *)(t); - switch (r) { - case 2: - if (metadata_store.play_status != PS_STOPPED) { - metadata_store.play_status = PS_STOPPED; - debug(2, "Play status is \"stopped\"."); - } + metadata_hub_modify_prolog(); + int diff = metadata_store.speaker_volume != the_volume; + if (diff) + metadata_store.speaker_volume = the_volume; + metadata_hub_modify_epilog(diff); + + ssize_t le; + char *response = NULL; + int32_t item_size; + char command[1024] = ""; + snprintf(command, sizeof(command) - 1, "playstatusupdate?revision-number=%d", + revision_number); + // debug(1,"Command: \"%s\"",command); + result = dacp_send_command(command, &response, &le); + // debug(1,"Response to \"%s\" is %d.",command,result); + if (result == 200) { + // if (0) { + char *sp = response; + if (le >= 8) { + // here start looking for the contents of the status update + if (dacp_tlv_crawl(&sp, &item_size) == 'cmst') { // status + // here, we know that we are receiving playerstatusupdates, so set a flag + metadata_hub_modify_prolog(); + // debug(1, "playstatusupdate release track metadata"); + // metadata_hub_reset_track_metadata(); + // metadata_store.playerstatusupdates_are_received = 1; + sp -= item_size; // drop down into the array -- don't skip over it + le -= 8; + // char typestring[5]; + // we need to acquire the metadata data structure and possibly update it + while (le >= 8) { + uint32_t type = dacp_tlv_crawl(&sp, &item_size); + le -= item_size + 8; + char *t; + // char u; + // char *st; + int32_t r; + // uint64_t v; + // int i; + + switch (type) { + case 'cmsr': // revision number + t = sp - item_size; + revision_number = ntohl(*(uint32_t *)(t)); + // debug(1," Serial Number: %d", revision_number); break; - case 3: - if (metadata_store.play_status != PS_PAUSED) { - metadata_store.play_status = PS_PAUSED; - debug(2, "Play status is \"paused\"."); + case 'caps': // play status + t = sp - item_size; + r = *(unsigned char *)(t); + switch (r) { + case 2: + if (metadata_store.play_status != PS_STOPPED) { + metadata_store.play_status = PS_STOPPED; + debug(2, "Play status is \"stopped\"."); + } + break; + case 3: + if (metadata_store.play_status != PS_PAUSED) { + metadata_store.play_status = PS_PAUSED; + debug(2, "Play status is \"paused\"."); + } + break; + case 4: + if (metadata_store.play_status != PS_PLAYING) { + metadata_store.play_status = PS_PLAYING; + debug(2, "Play status changed to \"playing\"."); + } + break; + default: + debug(1, "Unrecognised play status %d received.", r); + break; } break; - case 4: - if (metadata_store.play_status != PS_PLAYING) { - metadata_store.play_status = PS_PLAYING; - debug(2, "Play status changed to \"playing\"."); + case 'cash': // shuffle status + t = sp - item_size; + r = *(unsigned char *)(t); + switch (r) { + case 0: + if (metadata_store.shuffle_status != SS_OFF) { + metadata_store.shuffle_status = SS_OFF; + debug(2, "Shuffle status is \"off\"."); + } + break; + case 1: + if (metadata_store.shuffle_status != SS_ON) { + metadata_store.shuffle_status = SS_ON; + debug(2, "Shuffle status is \"on\"."); + } + break; + default: + debug(1, "Unrecognised shuffle status %d received.", r); + break; } break; - default: - debug(1, "Unrecognised play status %d received.", r); - break; - } - break; - case 'cash': // shuffle status - t = sp - item_size; - r = *(unsigned char *)(t); - switch (r) { - case 0: - if (metadata_store.shuffle_status != SS_OFF) { - metadata_store.shuffle_status = SS_OFF; - debug(2, "Shuffle status is \"off\"."); + case 'carp': // repeat status + t = sp - item_size; + r = *(unsigned char *)(t); + switch (r) { + case 0: + if (metadata_store.repeat_status != RS_OFF) { + metadata_store.repeat_status = RS_OFF; + debug(2, "Repeat status is \"none\"."); + } + break; + case 1: + if (metadata_store.repeat_status != RS_ONE) { + metadata_store.repeat_status = RS_ONE; + debug(2, "Repeat status is \"one\"."); + } + break; + case 2: + if (metadata_store.repeat_status != RS_ALL) { + metadata_store.repeat_status = RS_ALL; + debug(2, "Repeat status is \"all\"."); + } + break; + default: + debug(1, "Unrecognised repeat status %d received.", r); + break; } break; - case 1: - if (metadata_store.shuffle_status != SS_ON) { - metadata_store.shuffle_status = SS_ON; - debug(2, "Shuffle status is \"on\"."); + /* + case 'cann': // track name + t = sp - item_size; + if ((metadata_store.track_name == NULL) || + (strncmp(metadata_store.track_name, t, item_size) != 0)) { + if (metadata_store.track_name) + free(metadata_store.track_name); + metadata_store.track_name = strndup(t, item_size); + debug(1, "Track name changed to: \"%s\"", metadata_store.track_name); + metadata_store.track_name_changed = 1; + metadata_store.changed = 1; } break; - default: - debug(1, "Unrecognised shuffle status %d received.", r); + case 'cana': // artist name + t = sp - item_size; + if ((metadata_store.artist_name == NULL) || + (strncmp(metadata_store.artist_name, t, item_size) != 0)) { + if (metadata_store.artist_name) + free(metadata_store.artist_name); + metadata_store.artist_name = strndup(t, item_size); + debug(1, "Artist name changed to: \"%s\"", metadata_store.artist_name); + metadata_store.artist_name_changed = 1; + metadata_store.changed = 1; + } break; - } - break; - case 'carp': // repeat status - t = sp - item_size; - r = *(unsigned char *)(t); - switch (r) { - case 0: - if (metadata_store.repeat_status != RS_OFF) { - metadata_store.repeat_status = RS_OFF; - debug(2, "Repeat status is \"none\"."); + case 'canl': // album name + t = sp - item_size; + if ((metadata_store.album_name == NULL) || + (strncmp(metadata_store.album_name, t, item_size) != 0)) { + if (metadata_store.album_name) + free(metadata_store.album_name); + metadata_store.album_name = strndup(t, item_size); + debug(1, "Album name changed to: \"%s\"", metadata_store.album_name); + metadata_store.album_name_changed = 1; + metadata_store.changed = 1; } break; - case 1: - if (metadata_store.repeat_status != RS_ONE) { - metadata_store.repeat_status = RS_ONE; - debug(2, "Repeat status is \"one\"."); + case 'cang': // genre + t = sp - item_size; + if ((metadata_store.genre == NULL) || + (strncmp(metadata_store.genre, t, item_size) != 0)) { + if (metadata_store.genre) + free(metadata_store.genre); + metadata_store.genre = strndup(t, item_size); + debug(1, "Genre changed to: \"%s\"", metadata_store.genre); + metadata_store.genre_changed = 1; + metadata_store.changed = 1; } break; - case 2: - if (metadata_store.repeat_status != RS_ALL) { - metadata_store.repeat_status = RS_ALL; - debug(2, "Repeat status is \"all\"."); + case 'canp': // nowplaying 4 ids: dbid, plid, playlistItem, itemid (from mellowware + -- + // see reference above) + t = sp - item_size; + if (memcmp(metadata_store.item_composite_id, t, + sizeof(metadata_store.item_composite_id)) != 0) { + memcpy(metadata_store.item_composite_id, t, + sizeof(metadata_store.item_composite_id)); + + char st[33]; + char *pt = st; + int it; + for (it = 0; it < 16; it++) { + sprintf(pt, "%02X", metadata_store.item_composite_id[it]); + pt += 2; + } + *pt = 0; + // debug(1, "Item composite ID set to 0x%s.", st); + metadata_store.item_id_changed = 1; + metadata_store.changed = 1; } break; - default: - debug(1, "Unrecognised repeat status %d received.", r); + */ + case 'astm': + t = sp - item_size; + r = ntohl(*(uint32_t *)(t)); + if (metadata_store.track_metadata) + metadata_store.track_metadata->songtime_in_milliseconds = + ntohl(*(uint32_t *)(t)); break; - } - break; - /* - case 'cann': // track name - t = sp - item_size; - if ((metadata_store.track_name == NULL) || - (strncmp(metadata_store.track_name, t, item_size) != 0)) { - if (metadata_store.track_name) - free(metadata_store.track_name); - metadata_store.track_name = strndup(t, item_size); - debug(1, "Track name changed to: \"%s\"", metadata_store.track_name); - metadata_store.track_name_changed = 1; - metadata_store.changed = 1; - } - break; - case 'cana': // artist name - t = sp - item_size; - if ((metadata_store.artist_name == NULL) || - (strncmp(metadata_store.artist_name, t, item_size) != 0)) { - if (metadata_store.artist_name) - free(metadata_store.artist_name); - metadata_store.artist_name = strndup(t, item_size); - debug(1, "Artist name changed to: \"%s\"", metadata_store.artist_name); - metadata_store.artist_name_changed = 1; - metadata_store.changed = 1; - } - break; - case 'canl': // album name - t = sp - item_size; - if ((metadata_store.album_name == NULL) || - (strncmp(metadata_store.album_name, t, item_size) != 0)) { - if (metadata_store.album_name) - free(metadata_store.album_name); - metadata_store.album_name = strndup(t, item_size); - debug(1, "Album name changed to: \"%s\"", metadata_store.album_name); - metadata_store.album_name_changed = 1; - metadata_store.changed = 1; - } - break; - case 'cang': // genre - t = sp - item_size; - if ((metadata_store.genre == NULL) || - (strncmp(metadata_store.genre, t, item_size) != 0)) { - if (metadata_store.genre) - free(metadata_store.genre); - metadata_store.genre = strndup(t, item_size); - debug(1, "Genre changed to: \"%s\"", metadata_store.genre); - metadata_store.genre_changed = 1; - metadata_store.changed = 1; - } - break; - case 'canp': // nowplaying 4 ids: dbid, plid, playlistItem, itemid (from mellowware -- - // see reference above) - t = sp - item_size; - if (memcmp(metadata_store.item_composite_id, t, - sizeof(metadata_store.item_composite_id)) != 0) { - memcpy(metadata_store.item_composite_id, t, - sizeof(metadata_store.item_composite_id)); - - char st[33]; - char *pt = st; - int it; - for (it = 0; it < 16; it++) { - sprintf(pt, "%02X", metadata_store.item_composite_id[it]); - pt += 2; - } - *pt = 0; - // debug(1, "Item composite ID set to 0x%s.", st); - metadata_store.item_id_changed = 1; - metadata_store.changed = 1; - } - break; - */ - case 'astm': - t = sp - item_size; - r = ntohl(*(uint32_t *)(t)); - if (metadata_store.track_metadata) - metadata_store.track_metadata->songtime_in_milliseconds = ntohl(*(uint32_t *)(t)); - break; - - /* - case 'mstt': - case 'cant': - case 'cast': - case 'cmmk': - case 'caas': - case 'caar': - t = sp - item_size; - r = ntohl(*(uint32_t *)(t)); - printf(" %d", r); - printf(" (0x"); - t = sp - item_size; - for (i = 0; i < item_size; i++) { - printf("%02x", *t & 0xff); - t++; - } - printf(")"); - break; - case 'asai': - t = sp - item_size; - s = ntohl(*(uint32_t *)(t)); - s = s << 32; - t += 4; - v = (ntohl(*(uint32_t *)(t))) & 0xffffffff; - s += v; - printf(" %lu", s); - printf(" (0x"); - t = sp - item_size; - for (i = 0; i < item_size; i++) { - printf("%02x", *t & 0xff); - t++; - } - printf(")"); - break; - */ - default: + /* - printf(" 0x"); - t = sp - item_size; - for (i = 0; i < item_size; i++) { - printf("%02x", *t & 0xff); - t++; - } + case 'mstt': + case 'cant': + case 'cast': + case 'cmmk': + case 'caas': + case 'caar': + t = sp - item_size; + r = ntohl(*(uint32_t *)(t)); + printf(" %d", r); + printf(" (0x"); + t = sp - item_size; + for (i = 0; i < item_size; i++) { + printf("%02x", *t & 0xff); + t++; + } + printf(")"); + break; + case 'asai': + t = sp - item_size; + s = ntohl(*(uint32_t *)(t)); + s = s << 32; + t += 4; + v = (ntohl(*(uint32_t *)(t))) & 0xffffffff; + s += v; + printf(" %lu", s); + printf(" (0x"); + t = sp - item_size; + for (i = 0; i < item_size; i++) { + printf("%02x", *t & 0xff); + t++; + } + printf(")"); + break; */ - break; + default: + /* + printf(" 0x"); + t = sp - item_size; + for (i = 0; i < item_size; i++) { + printf("%02x", *t & 0xff); + t++; + } + */ + break; + } + // printf("\n"); } - // printf("\n"); - } - // finished possibly writing to the metadata hub - metadata_hub_modify_epilog(1); + // finished possibly writing to the metadata hub + metadata_hub_modify_epilog(1); + } else { + debug(1, "Status Update not found.\n"); + } } else { - debug(1, "Status Update not found.\n"); + debug(1, "Can't find any content in playerstatusupdate request"); } - } else { - debug(1, "Can't find any content in playerstatusupdate request"); - } - } /* else { - if (result != 403) - debug(1, "Unexpected response %d to playerstatusupdate request", result); - } */ + } /* else { + if (result != 403) + debug(1, "Unexpected response %d to playerstatusupdate request", result); + } */ + if (response) { + free(response); + response = NULL; + }; + }; + /* + strcpy(command,"nowplayingartwork?mw=320&mh=320"); + debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le)); if (response) { free(response); response = NULL; - }; - }; - /* - strcpy(command,"nowplayingartwork?mw=320&mh=320"); - debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le)); - if (response) { - free(response); - response = NULL; - } - strcpy(command,"getproperty?properties=dmcp.volume"); - debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le)); - if (response) { - free(response); - response = NULL; - } - strcpy(command,"setproperty?dmcp.volume=100.000000"); - debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le)); - if (response) { - free(response); - response = NULL; + } + strcpy(command,"getproperty?properties=dmcp.volume"); + debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le)); + if (response) { + free(response); + response = NULL; + } + strcpy(command,"setproperty?dmcp.volume=100.000000"); + debug(1,"Command: \"%s\", result is %d",command, dacp_send_command(command, &response, &le)); + if (response) { + free(response); + response = NULL; + } + */ + if (metadata_store.player_thread_active) + sleep(config.scan_interval_when_active); + else + sleep(config.scan_interval_when_inactive); } - */ - if (metadata_store.player_thread_active) - sleep(config.scan_interval_when_active); - else - sleep(config.scan_interval_when_inactive); } debug(1, "DACP monitor thread exiting."); pthread_exit(NULL); diff --git a/metadata_hub.c b/metadata_hub.c index 4d67b5ff..7018992b 100644 --- a/metadata_hub.c +++ b/metadata_hub.c @@ -135,6 +135,23 @@ void run_metadata_watchers(void) { void metadata_hub_modify_epilog(int modified) { // always run this after changing an entry or a sequence of entries in the metadata_hub // debug(1, "unlocking metadata hub for writing"); + int m = 0; + if (metadata_store.dacp_server_active==0) { + // debug(1,"player_stop release track metadata and artwork"); + // + if (metadata_store.track_metadata) { + m = 1; + metadata_hub_release_track_metadata(metadata_store.track_metadata); + metadata_store.track_metadata = NULL; + } + if (metadata_store.cover_art_pathname) { + m = 1; + metadata_hub_release_track_artwork(); + } + if (m) + debug(1,"Release track metadata after dacp server goes inactive."); + modified += m; + } pthread_rwlock_unlock(&metadata_hub_re_lock); if (modified) { run_metadata_watchers(); @@ -476,10 +493,6 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin metadata_hub_modify_prolog(); metadata_store.player_thread_active = 0; metadata_store.player_state = PS_STOPPED; - // debug(1,"player_stop release track metadata and artwork"); - //metadata_hub_release_track_metadata(metadata_store.track_metadata); - //metadata_store.track_metadata = NULL; - //metadata_hub_release_track_artwork(); metadata_hub_modify_epilog(1); } break; case 'pfls': { diff --git a/metadata_hub.h b/metadata_hub.h index 85b7354d..3ffc0dc1 100644 --- a/metadata_hub.h +++ b/metadata_hub.h @@ -53,8 +53,8 @@ typedef struct metadata_bundle { // server char *server_ip; // IP number used by Shairport Sync int player_thread_active; // true if a play thread is running - int dacp_server_active; // true if there's a reachable DACP server (assumed to be the Airplay - // client) ; false otherwise + int dacp_server_active; // true if there's a reachable DACP server (assumed to be the Airplay + // client) ; false otherwise int advanced_dacp_server_active; // true if there's a reachable DACP server with iTunes // capabilitiues // ; false otherwise diff --git a/mpris-service.c b/mpris-service.c index 27408972..30a09e01 100644 --- a/mpris-service.c +++ b/mpris-service.c @@ -106,15 +106,15 @@ void mpris_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused) int it; int non_zero = 0; if (argc->track_metadata) { - for (it = 0; it < 16; it++) { - if (argc->track_metadata->item_composite_id[it]) - non_zero = 1; - sprintf(pt, "%02X", argc->track_metadata->item_composite_id[it]); - pt += 2; - } + for (it = 0; it < 16; it++) { + if (argc->track_metadata->item_composite_id[it]) + non_zero = 1; + sprintf(pt, "%02X", argc->track_metadata->item_composite_id[it]); + pt += 2; + } } *pt = 0; - + if (non_zero) { // debug(1, "Set ID using composite ID: \"0x%s\".", st); char trackidstring[1024]; diff --git a/shairport.c b/shairport.c index 87114983..b9fe25b2 100644 --- a/shairport.c +++ b/shairport.c @@ -334,11 +334,17 @@ int parse_options(int argc, char **argv) { config.fixedLatencyOffset = 11025; // this sounds like it works properly. #ifdef HAVE_METADATA_HUB config.cover_art_cache_dir = "/tmp/shairport-sync/.cache/coverart"; - config.scan_interval_when_active = 1; // number of seconds between DACP server scans when playing something - config.scan_interval_when_inactive = 3; // number of seconds between DACP server scans playing nothing - config.scan_max_bad_response_count = 10; // number of successive bad results to ignore before giving up - config.scan_max_inactive_count = (24*60*60)/config.scan_interval_when_inactive; // number of scans to do before stopping if not made active again (24 hours ) -// config.scan_max_inactive_count = 5; // number of scans to do before stopping if not made active again (15 minutes ) + config.scan_interval_when_active = + 1; // number of seconds between DACP server scans when playing something + config.scan_interval_when_inactive = + 3; // number of seconds between DACP server scans playing nothing + config.scan_max_bad_response_count = + 5; // number of successive bad results to ignore before giving up + config.scan_max_inactive_count = + (15 * 60) / config.scan_interval_when_inactive; // number of scans to do before stopping if + // not made active again (15 minutes) +// config.scan_max_inactive_count = 5; // number of scans to do before stopping if not made active +// again (15 minutes ) #endif // config_setting_t *setting;