diff --git a/README.html b/README.html index aedb5c7..10ff849 100644 --- a/README.html +++ b/README.html @@ -1046,6 +1046,9 @@ each time the length of the volume slider (or the number of steps above mute, where 16 steps = full volume) is reduced by 50%, the perceived volume is halved (a 10dB attenuation). (This is modified at low volumes, to use the “untapered” volume if it is louder.)

+

-vol v Sets initial audio-streaming volume +(on client): range is [0:1], with 0.0 = mute, 1.0 = full volume +(v is a decimal number).

-s wxh e.g. -s 1920x1080 (= “1080p”), the default width and height resolutions in pixels for h264 video. (The default becomes 3840x2160 (= “4K”) when the -h265 option is used.) This is just @@ -1624,10 +1627,11 @@ an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen, introduced 2017, running tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be.

Changelog

+

1.72 2024-04-22 Add requested options -md <filename> to output +audio metadata text to a file for possible display (complements -ca +option), and -vol option to set initial audio-streaming volume.

1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially -only for YouTube movies. Fix issue with NTP timeout on Windows. Add -requested option -md <filename> to output audio metadata text to a -file for possible display (complements -ca option).

+only for YouTube movies. Fix issue with NTP timeout on Windows.

1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer >= 1.24 when client sleeps, then wakes.

diff --git a/README.md b/README.md index 5ee18f6..3f6db3d 100644 --- a/README.md +++ b/README.md @@ -1054,6 +1054,9 @@ where 16 steps = full volume) is reduced by 50%, the perceived volume is halved (a 10dB attenuation). (This is modified at low volumes, to use the "untapered" volume if it is louder.) +**-vol *v*** Sets initial audio-streaming volume (on client): range is [0:1], +with 0.0 = mute, 1.0 = full volume (*v* is a decimal number). + **-s wxh** e.g. -s 1920x1080 (= "1080p"), the default width and height resolutions in pixels for h264 video. (The default becomes 3840x2160 (= "4K") when the -h265 option is used.) This is just a request made to the @@ -1669,10 +1672,12 @@ what version UxPlay claims to be. # Changelog +1.72 2024-04-22 Add requested options -md \ to output audio +metadata text to a file for possible display (complements -ca option), +and -vol option to set initial audio-streaming volume. + 1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially only for YouTube movies. Fix issue with NTP timeout on Windows. -Add requested option -md \ to output audio metadata text to a file -for possible display (complements -ca option). 1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer \>= 1.24 when client sleeps, then wakes. diff --git a/README.txt b/README.txt index fb71b6e..5a4bca0 100644 --- a/README.txt +++ b/README.txt @@ -1055,6 +1055,9 @@ where 16 steps = full volume) is reduced by 50%, the perceived volume is halved (a 10dB attenuation). (This is modified at low volumes, to use the "untapered" volume if it is louder.) +**-vol *v*** Sets initial audio-streaming volume (on client): range is +\[0:1\], with 0.0 = mute, 1.0 = full volume (*v* is a decimal number). + **-s wxh** e.g. -s 1920x1080 (= "1080p"), the default width and height resolutions in pixels for h264 video. (The default becomes 3840x2160 (= "4K") when the -h265 option is used.) This is just a request made to the @@ -1669,10 +1672,12 @@ what version UxPlay claims to be. # Changelog +1.72 2024-04-22 Add requested options -md \ to output audio +metadata text to a file for possible display (complements -ca option), +and -vol ``{=html} option to set initial audio-streaming volume. + 1.71 2024-12-13 Add support for HTTP Live Streaming (HLS), initially -only for YouTube movies. Fix issue with NTP timeout on Windows. Add -requested option -md \ to output audio metadata text to a -file for possible display (complements -ca option). +only for YouTube movies. Fix issue with NTP timeout on Windows. 1.70 2024-10-04 Add support for 4K (h265) video (resolution 3840 x 2160). Fix issue with GStreamer \>= 1.24 when client sleeps, then wakes. diff --git a/lib/raop.h b/lib/raop.h index 50c9f71..0cb96ac 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -78,6 +78,7 @@ struct raop_callbacks_s { void (*conn_teardown)(void *cls, bool *teardown_96, bool *teardown_110 ); void (*audio_flush)(void *cls); void (*video_flush)(void *cls); + double (*audio_set_client_volume)(void *cls); void (*audio_set_volume)(void *cls, float volume); void (*audio_set_metadata)(void *cls, const void *buffer, int buflen); void (*audio_set_coverart)(void *cls, const void *buffer, int buflen); diff --git a/lib/raop_handlers.h b/lib/raop_handlers.h index 3f34e0d..f760d02 100644 --- a/lib/raop_handlers.h +++ b/lib/raop_handlers.h @@ -903,8 +903,10 @@ raop_handler_get_parameter(raop_conn_t *conn, /* This is a bit ugly, but seems to be how airport works too */ if ((datalen - (current - data) >= 8) && !strncmp(current, "volume\r\n", 8)) { - const char volume[] = "volume: 0.0\r\n"; - + char volume[25] = "volume: 0.0\r\n"; + if (conn->raop->callbacks.audio_set_client_volume) { + snprintf(volume, 25, "volume: %9.6f\r\n", conn->raop->callbacks.audio_set_client_volume(conn->raop->callbacks.cls)); + } http_response_add_header(response, "Content-Type", "text/parameters"); *response_data = strdup(volume); if (*response_data) { diff --git a/uxplay.1 b/uxplay.1 index 6c930d2..6531a2f 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -44,6 +44,8 @@ UxPlay 1.71: An open\-source AirPlay mirroring (+ audio streaming) server: .TP \fB\-taper\fR Use a "tapered" AirPlay volume-control profile. .TP +\fB\-vol\fI v \fR Set initial audio-streaming volume: range [mute=0.0:1.0=full]. +.TP \fB\-s\fR wxh[@r]Request to client for video display resolution [refresh_rate] .IP default 1920x1080[@60] (or 3840x2160[@60] with -h265 option). diff --git a/uxplay.cpp b/uxplay.cpp index 0fd3b60..2ec5708 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -154,6 +154,7 @@ static std::vector registered_keys; static double db_low = -30.0; static double db_high = 0.0; static bool taper_volume = false; +static double initial_volume = 0.0; static bool h265_support = false; static int n_renderers = 0; static bool hls_support = false; @@ -672,6 +673,7 @@ static void print_info (char *name) { printf("-db l[:h] Set minimum volume attenuation to l dB (decibels, negative);\n"); printf(" optional: set maximum to h dB (+ or -) default: -30.0:0.0 dB\n"); printf("-taper Use a \"tapered\" AirPlay volume-control profile\n"); + printf("-vol Set initial audio-streaming volume: range [mute=0.0:1.0=full]\n"); printf("-s wxh[@r]Request to client for video display resolution [refresh_rate]\n"); printf(" default 1920x1080[@60] (or 3840x2160[@60] with -h265 option)\n"); printf("-o Set display \"overscanned\" mode on (not usually needed)\n"); @@ -1240,29 +1242,53 @@ static void parse_arguments (int argc, char *argv[]) { } else if (arg == "-db") { bool db_bad = true; double db1, db2; - char *start = NULL; if ( i < argc -1) { char *end1, *end2; - start = argv[i+1]; - db1 = strtod(start, &end1); - if (end1 > start && *end1 == ':') { + db1 = strtod(argv[i+1], &end1); + if (*end1 == ':') { db2 = strtod(++end1, &end2); if ( *end2 == '\0' && end2 > end1 && db1 < 0 && db1 < db2) { db_bad = false; } - } else if (*end1 =='\0' && end1 > start && db1 < 0 ) { + } else if (*end1 =='\0' && db1 < 0 ) { db_bad = false; db2 = 0.0; } } if (db_bad) { - fprintf(stderr, "invalid %s %s: db value must be \"low\" or \"low:high\", low < 0 and high > low are decibel gains\n", argv[i], start); + fprintf(stderr, "invalid \"-db %s\": db value must be \"low\" or \"low:high\", low < 0 and high > low are decibel gains\n", argv[i+1]); exit(1); } i++; db_low = db1; db_high = db2; - printf("db range %f:%f\n", db_low, db_high); + printf("db range %f:%f\n", db_low, db_high); + } else if (arg == "-vol") { + bool vol_bad = true; + if (i < argc - 1) { + char *end; + double frac = strtod(argv[i+1], &end); + if (*end == '\0' && frac >= 0.0 && frac <= 1.0) { + if (frac == 0.0) { + initial_volume = -144.0; + } else if (frac == 1.0) { + initial_volume = 0.0; + } else { + double db_flat = -30.0 + 30.0*frac; + //double db = 10.0 * (log10(frac) / log10(2.0)); //tapered + //printf("db %f db_flat %f \n", db, db_flat); + //db = (db > db_flat) ? db : db_flat; + initial_volume = db_flat; + } + } + printf("initial_volume attenuation %f db\n", initial_volume); + vol_bad = false; + } + if (vol_bad) { + fprintf(stderr, "invalid \"-vol %s\", value must be between 0.0 (mute) and 1.0 (full volume)\n", argv[i+1]); + exit(1); + } + i++; } else if (arg == "-hls") { hls_support = true; if (i < argc - 1 && *argv[i+1] != '-') { @@ -1789,6 +1815,10 @@ extern "C" void video_flush (void *cls) { } } +extern "C" double audio_set_client_volume(void *cls) { + return initial_volume; +} + extern "C" void audio_set_volume (void *cls, float volume) { double db, db_flat, frac, gst_volume; if (!use_audio) { @@ -2047,6 +2077,7 @@ static int start_raop_server (unsigned short display[5], unsigned short tcp[3], raop_cbs.video_flush = video_flush; raop_cbs.video_pause = video_pause; raop_cbs.video_resume = video_resume; + raop_cbs.audio_set_client_volume = audio_set_client_volume; raop_cbs.audio_set_volume = audio_set_volume; raop_cbs.audio_get_format = audio_get_format; raop_cbs.video_report_size = video_report_size;