From 385f31b09a621d9d120af3e30e41d9a0473cfa91 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Wed, 3 Sep 2014 13:18:58 +0100 Subject: [PATCH] Add extra option -t/--timeout to vary the time to wait for more audio before giving up. Zero to disable timeout, default 120 seconds. --- common.h | 1 + player.c | 7 ++++--- shairport.c | 17 +++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/common.h b/common.h index 97f55ae4..43a19d70 100644 --- a/common.h +++ b/common.h @@ -44,6 +44,7 @@ typedef struct { uint8_t hw_addr[6]; int port; int resyncthreshold; // if it get's out of whack my more than this, resync. Zero means never resync. + uint64_t timeout; // while in play mode, exit if no packets of audio come in for more than this number of seconds . Zero means never exit. char *output_name; audio_output *output; char *mdns_name; diff --git a/player.c b/player.c index 0cf6d1db..857d50ef 100644 --- a/player.c +++ b/player.c @@ -347,9 +347,10 @@ static abuf_t *buffer_get_frame(void) { // get the time local_time_now = get_absolute_time_in_ns(); - // if 120 seconds have elapsed since the last audio packet was received, then we should stop - if ((time_of_last_audio_packet!=0) && (shutdown_requested==0)) { - if (local_time_now-time_of_last_audio_packet>=(uint64_t)120<<32) { + // if config.timeout (default 120) seconds have elapsed since the last audio packet was received, then we should stop. + // config.timeout of zero means don't check..., but iTunes may be confused by a long gap followed by a resumption... + if ((time_of_last_audio_packet!=0) && (shutdown_requested==0) && (config.timeout!=0)) { + if (local_time_now-time_of_last_audio_packet>=config.timeout<<32) { debug(1,"As Yeats almost said, \"Too long a silence / can make a stone of the heart\""); rtsp_request_shutdown_stream(); shutdown_requested=1; diff --git a/shairport.c b/shairport.c index 2b0f8511..c6ac3f1a 100644 --- a/shairport.c +++ b/shairport.c @@ -164,6 +164,7 @@ void usage(char *progname) { printf(" if no mdns provider is specified,\n"); printf(" shairport tries them all until one works.\n"); printf(" -r, --resync=THRESHOLD resync if error exceeds this number of frames. Set to 0 to stop resyncing.\n"); + printf(" -t, --timeout=SECONDS go back to idle mode from play mode after a break in communications of this many seconds (default 120). Set to 0 never to exit play mode.\n"); printf("\n"); mdns_ls_backends(); @@ -193,19 +194,23 @@ int parse_options(int argc, char **argv) { {"AirPlayLatency", required_argument, NULL, 'A'}, {"iTunesLatency", required_argument, NULL, 'i'}, {"resync", required_argument, NULL, 'r'}, + {"timeout", required_argument, NULL, 't'}, {NULL, 0, NULL, 0} }; int opt; while ((opt = getopt_long(argc, argv, - "+hdvVkp:a:o:b:B:E:wm:L:S:A:i:r:", + "+hdvVkp:a:o:b:B:E:wm:L:S:A:i:r:t:", long_options, NULL)) > 0) { switch (opt) { // Note -- Version, Kill and Help done separately default: + case 't': + config.timeout = atoi(optarg); + break; case 'r': - config.resyncthreshold = atoi(optarg); - break; + config.resyncthreshold = atoi(optarg); + break; case 'd': config.daemonise = 1; break; @@ -359,7 +364,8 @@ int main(int argc, char **argv) { config.userSuppliedLatency = 0; // zero means none supplied config.iTunesLatency = 99400; // this seems to work pretty well for iTunes -- two left-ear headphones, one from the iMac jack, one from an NSLU2 running a cheap "3D Sound" USB Soundcard config.AirPlayLatency = 88200; // this seems to work pretty well for AirPlay -- Syncs sound and vision on AppleTV, but also used for iPhone/iPod/iPad sources - config.resyncthreshold = 441*5; // this number of frames is 50 ms. + config.resyncthreshold = 441*5; // this number of frames is 50 ms + config.timeout = 120; // this number of seconds to wait for [more] audio before switching to idle. config.buffer_start_fill = 220; config.port = 5000; config.packet_stuffing = ST_basic; // simple interpolation or deletion @@ -374,8 +380,7 @@ int main(int argc, char **argv) { // mDNS supports maximum of 63-character names (we append 13). if (strlen(config.apname) > 50) die("Supplied name too long (max 50 characters)"); - - + /* here, daemonise with libdaemon */ if (config.daemonise) {