From 0473ccdba06935252c22701e00eb59a2ead1516a Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Tue, 17 Sep 2024 18:15:28 -0400 Subject: [PATCH] update to UxPlay-1.70; rename video_renderers_gstreamer.c --- README.html | 54 ++++++++++++------- README.md | 36 ++++++++----- README.txt | 49 +++++++++++------ lib/raop_rtp_mirror.c | 12 ++--- renderers/CMakeLists.txt | 4 +- ..._renderer_gstreamer.c => audio_renderer.c} | 0 ..._renderer_gstreamer.c => video_renderer.c} | 0 uxplay.1 | 5 +- uxplay.cpp | 7 +-- uxplay.spec | 4 +- 10 files changed, 111 insertions(+), 60 deletions(-) rename renderers/{audio_renderer_gstreamer.c => audio_renderer.c} (100%) rename renderers/{video_renderer_gstreamer.c => video_renderer.c} (100%) diff --git a/README.html b/README.html index 3f919e7..4e79404 100644 --- a/README.html +++ b/README.html @@ -1,6 +1,6 @@

UxPlay -1.69: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix +id="uxplay-1.70-airplay-mirror-and-airplay-audio-server-for-linux-macos-and-unix-now-also-runs-on-windows.">UxPlay +1.70: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows).

Now @@ -9,14 +9,13 @@ href="https://github.com/FDH2/UxPlay">https://github.com/FDH2/UxPlay (where ALL user issues should be posted, and latest versions can be found).

@@ -183,8 +182,9 @@ without the accompanying video (there are plans to support HLS video in future releases of UxPlay)

Possibility -for using hardware-accelerated h264 video-decoding, if available.

+id="possibility-for-using-hardware-accelerated-h264h265-video-decoding-if-available.">Possibility +for using hardware-accelerated h264/h265 video-decoding, if +available.

UxPlay uses GStreamer “plugins” for rendering audio and video. This means that video and audio are supported “out of the box”, using a choice of plugins. AirPlay @@ -631,6 +631,13 @@ GPU with the GStreamer OMX plugin (use option “-vd omxh264dec”), but this is broken by Pi 4 Model B firmware. OMX support was removed from Raspberry Pi OS (Bullseye), but is present in Buster.

+
  • H265 (4K) video is supported with hardware +decoding by the Broadcom GPU on Raspberry Pi 5 models, as well as on +Raspberry Pi 4 model B. While GStreamer seem to make use of this +hardware decoding, satisfactory rendering of 4K video by UxPlay on these +Raspberry Pi models has not yet been acheived. The option -h265 +is required, and option “-vsync no” may be preferred. “4K video on +Raspberry Pi is still a work in progress.

  • Even with GPU video decoding, some frames may be dropped by the lower-power models to keep audio and video synchronized using @@ -911,6 +918,14 @@ the mirror display (X11) window.

    -nh Do not append “@_hostname_” at the end of the AirPlay server name.

    +

    -h265 Activate “ScreenMultiCodec” support (AirPlay +“Features” bit 42) for accepting h265 (4K) video in addition to h264 +video (1080p) in screen-mirror mode. When this option is used, two +“video pipelines” (one for h264, one for h265) are created. If any +GStreamer plugins in the pipeline are specific for h264 or h265, the +correct version will be used in each pipeline. A wired Client-Server +ethernet connection is preferred over Wifi for 4K video, and might be +required by the client.

    -pin [nnnn]: (since v1.67) use Apple-style (one-time) “pin” authentication when a new client connects for the first time: a four-digit pin code is displayed on the terminal, and the client @@ -984,10 +999,11 @@ 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.)

    -

    -s wxh (e.g. -s 1920x1080 , which is the default ) -sets the display resolution (width and height, in pixels). (This may be +

    -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 AirPlay client, and perhaps will not be the final -resolution you get.) w and h are whole numbers with four digits or less. +resolution you get. w and h are whole numbers with four digits or less. Note that the height pixel size is the controlling one used by the client for determining the streaming format; the width is dynamically adjusted to the shape of the image (portrait or landscape @@ -1261,13 +1277,13 @@ that your network does not have a running Bonjour/zeroconf DNS-SD server. Before v1.60, UxPlay used to stall silently if DNS-SD service registration failed, but now stops with an error message returned by the DNSServiceRegister function: kDNSServiceErr_Unknown if -no DNS-SD server was found. (A NixOS user found that in NixOS, this +no DNS-SD server was found: (A NixOS user found that in NixOS, this error can also occur if avahi-daemon service IS running with publishing enabled, but reports “the error disappeared on NixOS by setting -services.avahi.openFirewall to true”.) Other mDNS error codes are in the -range FFFE FF00 (-65792) to FFFE FFFF (-65537), and are listed in the -dnssd.h file. An older version of this (the one used by avahi) is found - Other mDNS error codes are +in the range FFFE FF00 (-65792) to FFFE FFFF (-65537), and are listed in +the dnssd.h file. An older version of this (the one used by avahi) is +found here. A few additional error codes are defined in a later version from Apple.

    @@ -1546,6 +1562,8 @@ 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.70 2024-09-17 Add support for 4K (h265) video (resolution 3840 x +2160).

    1.69 2024-08-09 Internal improvements (e.g. in -nohold option, identifying GStreamer videosink selected by autovideosink, finding X11 display) in anticipation of future HLS video support. New -nofreeze diff --git a/README.md b/README.md index 0e03704..e68fd9e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -# UxPlay 1.69: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows). +# UxPlay 1.70: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows). ### **Now developed at the GitHub site [https://github.com/FDH2/UxPlay](https://github.com/FDH2/UxPlay) (where ALL user issues should be posted, and latest versions can be found).** - * _**NEW in v1.69**: minor changes for users: -nofreeze option to NOT leave frozen - video in place when a network failure occurs; internal changes/improvements - needed for planned future HLS video streaming support._ - - * **An experimental ("beta") version of UxPlay with support for HLS streaming of YouTube Videos from the YouTube app on an iOS client is now available at** https://github.com/FDH2/UxPlay/tree/video . + * _**NEW in v1.70**: Support for 4k (h265) video with the new "-h265" option._ + + * **An experimental ("beta") version of UxPlay with support for HLS streaming of YouTube Videos from the YouTube app on an iOS client is now also available at** https://github.com/FDH2/UxPlay/tree/video2, and this feature will be added in a future release of UxPlay. _See the [Wiki page](https://github.com/FDH2/UxPlay/wiki/experimental-version-of-UxPlay-with-support-for-HLS-video-streaming-(you-tube-movies)) for details._ ## Highlights: @@ -136,7 +134,7 @@ using the icon for AirPlay video in apps such as the YouTube app will only send audio (in lossless ALAC format) without the accompanying video (there are plans to support HLS video in future releases of UxPlay)** -### Possibility for using hardware-accelerated h264 video-decoding, if available. +### Possibility for using hardware-accelerated h264/h265 video-decoding, if available. UxPlay uses [GStreamer](https://gstreamer.freedesktop.org) "plugins" for rendering audio and video. This means that video and audio are supported "out of the box", @@ -505,6 +503,11 @@ See [Usage](#usage) for more run-time options. (use option "`-vd omxh264dec`"), but this is broken by Pi 4 Model B firmware. OMX support was removed from Raspberry Pi OS (Bullseye), but is present in Buster. +* **H265 (4K)** video is supported with hardware decoding by the Broadcom GPU on Raspberry Pi 5 models, as well as + on Raspberry Pi 4 model B. **While GStreamer seem to make use of this hardware decoding, satisfactory rendering of + 4K video by UxPlay on these Raspberry Pi models has not yet been acheived.** The option -h265 is required, and + option "-vsync no" may be preferred. "_4K video on Raspberry Pi is still a work in progress._" + Even with GPU video decoding, some frames may be dropped by the lower-power models to keep audio and video synchronized using timestamps. In Legacy Raspberry Pi OS (Bullseye), raspi-config "Performance Options" allows specifying how much memory to allocate to the GPU, but this setting appears to be absent in Bookworm (but it can still be set to e.g. 128MB by adding a line "gpu_mem=128" in /boot/config.txt). @@ -727,6 +730,11 @@ with "`#`" are treated as comments, and ignored. Command line options supersede **-nh** Do not append "@_hostname_" at the end of the AirPlay server name. +**-h265** Activate "ScreenMultiCodec" support (AirPlay "Features" bit 42) for accepting h265 (4K) video in addition to h264 + video (1080p) in screen-mirror mode. When this option is used, two "video pipelines" (one for h264, one for h265) are created. + If any GStreamer plugins in the pipeline are specific for h264 or h265, the correct version will be used in each pipeline. + A wired Client-Server ethernet connection is preferred over Wifi for 4K video, and might be required by the client. + **-pin [nnnn]**: (since v1.67) use Apple-style (one-time) "pin" authentication when a new client connects for the first time: a four-digit pin code is displayed on the terminal, and the client screen shows a login prompt for this to be entered. When "-pin" is used by itself, a new random pin code is chosen for each authentication; if "-pin nnnn" (e.g., "-pin 3939") is used, this will set an unchanging fixed code. Authentication adds the server to the client's list of @@ -773,10 +781,10 @@ using UxPlay as a second monitor for a mac computer, or monitoring a webcam; wit 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.) -**-s wxh** (e.g. -s 1920x1080 , which is the default ) sets the display resolution (width and height, - in pixels). (This may be a +**-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 AirPlay client, and perhaps will not - be the final resolution you get.) w and h are whole numbers with four + be the final resolution you get. w and h are whole numbers with four digits or less. Note that the **height** pixel size is the controlling one used by the client for determining the streaming format; the width is dynamically adjusted to the shape of the image (portrait or landscape @@ -1002,9 +1010,9 @@ Some systems may instead use the mdnsd daemon as an alternative to provide DNS If UxPlay stops with the "No DNS-SD Server found" message, this means that your network **does not have a running Bonjour/zeroconf DNS-SD server.** Before v1.60, UxPlay used to stall silently if DNS-SD service registration failed, but now stops with an error message returned by the -DNSServiceRegister function: kDNSServiceErr_Unknown if no DNS-SD server was found. -(A NixOS user found that in NixOS, this error can also occur if avahi-daemon service IS running with publishing enabled, -but reports "the error disappeared on NixOS by setting services.avahi.openFirewall to true".) +DNSServiceRegister function: kDNSServiceErr_Unknown if no DNS-SD server was found: +_(A NixOS user found that in NixOS, this error can also occur if avahi-daemon service IS running with publishing enabled, but +reports "the error disappeared on NixOS by setting services.avahi.openFirewall to true".)_ Other mDNS error codes are in the range FFFE FF00 (-65792) to FFFE FFFF (-65537), and are listed in the dnssd.h file. An older version of this (the one used by avahi) is found [here](https://github.com/lathiat/avahi/blob/master/avahi-compat-libdns_sd/dns_sd.h). A few additional error codes are defined in a later version @@ -1215,6 +1223,8 @@ tvOS 12.2.1), so it does not seem to matter what version UxPlay claims to be. # Changelog +1.70 2024-09-17 Add support for 4K (h265) video (resolution 3840 x 2160). + 1.69 2024-08-09 Internal improvements (e.g. in -nohold option, identifying GStreamer videosink selected by autovideosink, finding X11 display) in anticipation of future HLS video support. New -nofreeze option to not leave frozen video in place when a network connection is reset. diff --git a/README.txt b/README.txt index aaa2905..b381b09 100644 --- a/README.txt +++ b/README.txt @@ -1,15 +1,14 @@ -# UxPlay 1.69: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows). +# UxPlay 1.70: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix (now also runs on Windows). ### **Now developed at the GitHub site (where ALL user issues should be posted, and latest versions can be found).** -- ***NEW in v1.69**: minor changes for users: -nofreeze option to NOT - leave frozen video in place when a network failure occurs; internal - changes/improvements needed for planned future HLS video streaming - support.* +- ***NEW in v1.70**: Support for 4k (h265) video with the new "-h265" + option.* - **An experimental ("beta") version of UxPlay with support for HLS streaming of YouTube Videos from the YouTube app on an iOS client is - now available at** https://github.com/FDH2/UxPlay/tree/video . *See + now also available at** https://github.com/FDH2/UxPlay/tree/video2, + and this feature will be added in a future release of UxPlay. *See the [Wiki page](https://github.com/FDH2/UxPlay/wiki/experimental-version-of-UxPlay-with-support-for-HLS-video-streaming-(you-tube-movies)) for details.* @@ -174,7 +173,7 @@ stops/restarts as you leave/re-enter* **Audio** *mode.* format) without the accompanying video (there are plans to support HLS video in future releases of UxPlay)** -### Possibility for using hardware-accelerated h264 video-decoding, if available. +### Possibility for using hardware-accelerated h264/h265 video-decoding, if available. UxPlay uses [GStreamer](https://gstreamer.freedesktop.org) "plugins" for rendering audio and video. This means that video and audio are supported @@ -630,6 +629,14 @@ See [Usage](#usage) for more run-time options. this is broken by Pi 4 Model B firmware. OMX support was removed from Raspberry Pi OS (Bullseye), but is present in Buster. +- **H265 (4K)** video is supported with hardware decoding by the + Broadcom GPU on Raspberry Pi 5 models, as well as on Raspberry Pi 4 + model B. **While GStreamer seem to make use of this hardware + decoding, satisfactory rendering of 4K video by UxPlay on these + Raspberry Pi models has not yet been acheived.** The option -h265 is + required, and option "-vsync no" may be preferred. "*4K video on + Raspberry Pi is still a work in progress.*" + Even with GPU video decoding, some frames may be dropped by the lower-power models to keep audio and video synchronized using timestamps. In Legacy Raspberry Pi OS (Bullseye), raspi-config @@ -915,6 +922,14 @@ will also now be the name shown above the mirror display (X11) window. **-nh** Do not append "@_hostname_" at the end of the AirPlay server name. +**-h265** Activate "ScreenMultiCodec" support (AirPlay "Features" bit +42) for accepting h265 (4K) video in addition to h264 video (1080p) in +screen-mirror mode. When this option is used, two "video pipelines" (one +for h264, one for h265) are created. If any GStreamer plugins in the +pipeline are specific for h264 or h265, the correct version will be used +in each pipeline. A wired Client-Server ethernet connection is preferred +over Wifi for 4K video, and might be required by the client. + **-pin \[nnnn\]**: (since v1.67) use Apple-style (one-time) "pin" authentication when a new client connects for the first time: a four-digit pin code is displayed on the terminal, and the client screen @@ -990,10 +1005,11 @@ 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.) -**-s wxh** (e.g. -s 1920x1080 , which is the default ) sets the display -resolution (width and height, in pixels). (This may be a request made to -the AirPlay client, and perhaps will not be the final resolution you -get.) w and h are whole numbers with four digits or less. Note that the +**-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 +AirPlay client, and perhaps will not be the final resolution you get. w +and h are whole numbers with four digits or less. Note that the **height** pixel size is the controlling one used by the client for determining the streaming format; the width is dynamically adjusted to the shape of the image (portrait or landscape format, depending on how @@ -1290,12 +1306,12 @@ that your network **does not have a running Bonjour/zeroconf DNS-SD server.** Before v1.60, UxPlay used to stall silently if DNS-SD service registration failed, but now stops with an error message returned by the DNSServiceRegister function: kDNSServiceErr_Unknown if no DNS-SD server -was found. (A NixOS user found that in NixOS, this error can also occur +was found: *(A NixOS user found that in NixOS, this error can also occur if avahi-daemon service IS running with publishing enabled, but reports "the error disappeared on NixOS by setting services.avahi.openFirewall -to true".) Other mDNS error codes are in the range FFFE FF00 (-65792) to -FFFE FFFF (-65537), and are listed in the dnssd.h file. An older version -of this (the one used by avahi) is found +to true".)* Other mDNS error codes are in the range FFFE FF00 (-65792) +to FFFE FFFF (-65537), and are listed in the dnssd.h file. An older +version of this (the one used by avahi) is found [here](https://github.com/lathiat/avahi/blob/master/avahi-compat-libdns_sd/dns_sd.h). A few additional error codes are defined in a later version from [Apple](https://opensource.apple.com/source/mDNSResponder/mDNSResponder-544/mDNSShared/dns_sd.h.auto.html). @@ -1586,6 +1602,9 @@ what version UxPlay claims to be. # Changelog +1.70 2024-09-17 Add support for 4K (h265) video (resolution 3840 x +2160). + 1.69 2024-08-09 Internal improvements (e.g. in -nohold option, identifying GStreamer videosink selected by autovideosink, finding X11 display) in anticipation of future HLS video support. New -nofreeze diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c index d1c079b..d84e34b 100644 --- a/lib/raop_rtp_mirror.c +++ b/lib/raop_rtp_mirror.c @@ -584,9 +584,9 @@ raop_rtp_mirror_thread(void *arg) printf("h265 detected\n"); h265_video = true; raop_rtp_mirror->callbacks.video_set_codec(raop_rtp_mirror->callbacks.cls, codec); - unsigned char vps_code[] = { 0xa0, 0x00, 0x01, 0x00 }; - unsigned char sps_code[] = { 0xa1, 0x00, 0x01, 0x00 }; - unsigned char pps_code[] = { 0xa2, 0x00, 0x01, 0x00 }; + unsigned char vps_start_code[] = { 0xa0, 0x00, 0x01, 0x00 }; + unsigned char sps_start_code[] = { 0xa1, 0x00, 0x01, 0x00 }; + unsigned char pps_start_code[] = { 0xa2, 0x00, 0x01, 0x00 }; unsigned char *vps; short vps_size; unsigned char *sps; @@ -596,7 +596,7 @@ raop_rtp_mirror_thread(void *arg) unsigned char * ptr = payload + 0x75; - if (memcmp(ptr, vps_code, 4)) { + if (memcmp(ptr, vps_start_code, 4)) { logger_log(raop_rtp_mirror->logger, LOGGER_ERR, "non-conforming HEVC VPS/SPS/PPS payload (VPS)"); raop_rtp_mirror->callbacks.video_pause(raop_rtp_mirror->callbacks.cls); break; @@ -610,7 +610,7 @@ raop_rtp_mirror_thread(void *arg) free(str); } ptr += vps_size; - if (memcmp(ptr, sps_code, 4)) { + if (memcmp(ptr, sps_start_code, 4)) { logger_log(raop_rtp_mirror->logger, LOGGER_ERR, "non-conforming HEVC VPS/SPS/PPS payload (SPS)"); raop_rtp_mirror->callbacks.video_pause(raop_rtp_mirror->callbacks.cls); break; @@ -624,7 +624,7 @@ raop_rtp_mirror_thread(void *arg) free(str); } ptr += sps_size; - if (memcmp(ptr, pps_code, 4)) { + if (memcmp(ptr, pps_start_code, 4)) { logger_log(raop_rtp_mirror->logger, LOGGER_ERR, "non-conforming HEVC VPS/SPS/PPS payload (PPS)"); raop_rtp_mirror->callbacks.video_pause(raop_rtp_mirror->callbacks.cls); break; diff --git a/renderers/CMakeLists.txt b/renderers/CMakeLists.txt index 1fb025d..f844860 100644 --- a/renderers/CMakeLists.txt +++ b/renderers/CMakeLists.txt @@ -47,8 +47,8 @@ endif() add_library( renderers STATIC - audio_renderer_gstreamer.c - video_renderer_gstreamer.c ) + audio_renderer.c + video_renderer.c ) target_link_libraries ( renderers PUBLIC airplay ) diff --git a/renderers/audio_renderer_gstreamer.c b/renderers/audio_renderer.c similarity index 100% rename from renderers/audio_renderer_gstreamer.c rename to renderers/audio_renderer.c diff --git a/renderers/video_renderer_gstreamer.c b/renderers/video_renderer.c similarity index 100% rename from renderers/video_renderer_gstreamer.c rename to renderers/video_renderer.c diff --git a/uxplay.1 b/uxplay.1 index fcfd4e8..419780a 100644 --- a/uxplay.1 +++ b/uxplay.1 @@ -40,7 +40,10 @@ UxPlay 1.70: An open\-source AirPlay mirroring (+ audio streaming) server: .TP \fB\-taper\fR Use a "tapered" AirPlay volume-control profile. .TP -\fB\-s\fR wxh[@r]Set display resolution [refresh_rate] default 1920x1080[@60] +\fB\-s\fR wxh[@r]Request to client for video display resolution [refresh_rate] +.IP + default 1920x1080[@60] (or 3840x2160[@60] with -h265 option). +.PP .TP \fB\-o\fR Set display "overscanned" mode on (not usually needed) .TP diff --git a/uxplay.cpp b/uxplay.cpp index 8654920..5a88353 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -408,9 +408,9 @@ static void main_loop() { guint video_reset_watch_id = g_timeout_add(100, (GSourceFunc) video_reset_callback, (gpointer) loop); guint sigterm_watch_id = g_unix_signal_add(SIGTERM, (GSourceFunc) sigterm_callback, (gpointer) loop); guint sigint_watch_id = g_unix_signal_add(SIGINT, (GSourceFunc) sigint_callback, (gpointer) loop); - printf("********** main_loop_run *******************\n"); + //printf("********** main_loop_run *******************\n"); g_main_loop_run(loop); - printf("********** main_loop_exit *******************\n"); + //printf("********** main_loop_exit *******************\n"); for (int i = 0; i < n_renderers; i++) { if (gst_bus_watch_id[i] > 0) g_source_remove(gst_bus_watch_id[i]); } @@ -594,7 +594,8 @@ 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("-s wxh[@r]Set display resolution [refresh_rate] default 1920x1080[@60]\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"); printf("-fs Full-screen (only works with X11, Wayland, VAAPI, D3D11)\n"); printf("-p Use legacy ports UDP 6000:6001:7011 TCP 7000:7001:7100\n"); diff --git a/uxplay.spec b/uxplay.spec index 07157a7..93fed46 100644 --- a/uxplay.spec +++ b/uxplay.spec @@ -1,5 +1,5 @@ Name: uxplay -Version: 1.69 +Version: 1.70 Release: 1%{?dist} %global gittag v%{version} @@ -135,7 +135,7 @@ cd build %{_docdir}/%{name}/llhttp/LICENSE-MIT %changelog -* Fri Aug 09 2024 UxPlay maintainer +* Tue Sep 17 2024 UxPlay maintainer Initial uxplay.spec: tested on Fedora 38, Rocky Linux 9.2, OpenSUSE Leap 15.5, Mageia 9, OpenMandriva ROME, PCLinuxOS -