diff --git a/README.html b/README.html index b774c73..e0daf1d 100644 --- a/README.html +++ b/README.html @@ -1,29 +1,30 @@ -
This project is a GPLv3 unix AirPlay2 server which now also works on macOS. Its main use is to act like an AppleTV for screen-mirroring (with audio) of iOS/macOS clients (iPads, iPhones, MacBooks) in a window on the server display (with the possibility of sharing that window on screen-sharing applications such as Zoom) on a host running Linux, macOS, or other unix, using Apple’s AirPlay Mirror protocol first available in iOS 5. (Details of what is known about the AirPlay2 protocol can be found here and here). Note that Apple DRM (as in Apple TV app content) cannot be decrypted by UxPlay.
-The UxPlay server and its client must be on the same local area network, on which a Bonjour/Zeroconf mDNS/DNS-SD server is also running (only DNS-SD “Service Discovery” service is necessary, it is not necessary that the local network also be of the “.local” mDNS-based type). On Linux and BSD Unix servers, this is usually provided by Avahi, through the avahi-daemon service, and is included in most Linux distributions (this service can also be provided by macOS, iOS or Windows servers).
-Since v1.38, UxPlay now also supports the Airplay audio-only protocol as well as AirPlay Mirror protocol, and (when the client screen is not being mirrored) can play Apple Lossless (ALAC) audio streamed from the client without video (the accompanying cover-art and metadata is not displayed). The initial connection to the client can be either AirPlay audio or Airplay Mirror mode. An Airplay Mirror connection (with “Advanced Audio Coding” AAC-ELD lossy-compression audio) switches to ALAC if the mirrow window is closed and an AirPlay audio connection is started, and back again to AAC if a new Airplay Mirror connection is made.
-UxPlay is based on https://github.com/FD-/RPiPlay, with GStreamer integration from https://github.com/antimof/UxPlay. (UxPlay only uses GStreamer, and does not contain the alternative Raspberry-Pi-specific audio and video renderers also found in RPiPlay.) Tested on a number of systems, including Ubuntu 20.04, Linux Mint 20.2, OpenSUSE 15.3, macOS 10.15, FreeBSD 13.0.
+This project is a GPLv3 open source unix AirPlay2 Mirror server for Linux, macOS, and *BSD. It is now hosted at the github site https://github.com/FDH2/UxPlay (where development and user-assistance now takes place), although it initially was developed by antimof using code from RPiPlay, which in turn derives from AirplayServer, shairplay, and playfair. (The antimof site is mainly inactive, but periodically posts updates pulled from the main UxPlay site).
+Its main use is to act like an AppleTV for screen-mirroring (with audio) of iOS/iPadOS/macOS clients (iPhones, iPads, MacBooks) in a window on the server display (with the possibility of sharing that window on screen-sharing applications such as Zoom) on a host running Linux, macOS, or other unix. UxPlay supports a “legacy” form of Apple’s AirPlay Mirror protocol introduced in iOS 12; client devices running iOS/iPadOS 12 or later are supported, as is a (nonfree) Windows-based AirPlay-client software emulator, AirMyPC. Older (32-bit) client devices that can only run iOS 9.3 or iOS 10.3 are currently partially supported by UxPlay: reports indicate that screen-mirroring video works, audio is a work in progess. (Details of what is publically known about Apple’s AirPlay2 protocol can be found here and here).
+The UxPlay server and its client must be on the same local area network, on which a Bonjour/Zeroconf mDNS/DNS-SD server is also running (only DNS-SD “Service Discovery” service is strictly necessary, it is not necessary that the local network also be of the “.local” mDNS-based type). On Linux and BSD Unix servers, this is usually provided by Avahi, through the avahi-daemon service, and is included in most Linux distributions (this service can also be provided by macOS, iOS or Windows servers).
+Connections to the UxPlay server by iOS/MacOS clients can be initiated both in AirPlay Mirror mode (which streams lossily-compressed AAC audio while mirroring the client screen, or in the alternative AirPlay Audio mode which streams Apple Lossless (ALAC) audio without screen mirroring (the accompanying metadata and cover art in this mode is not displayed). Switching between these two modes during an active connection is possible: in Mirror mode, close the mirror window and start an Audio mode connection, switch back by initiating a Mirror mode connection. Note that Apple DRM (as in Apple TV app content on the client) cannot be decrypted by UxPlay, and (unlike with a true AppleTV), the client cannot run a http connection on the server instead of streaming content from one on the client.
+UxPlay uses GStreamer Plugins for rendering audio and video, and does not offer the alternative Raspberry-Pi-specific audio and video renderers available in RPiPlay. It is tested on a number of systems, including (among others) Debian 11.2, Ubuntu 20.04 and 21.10, Linux Mint 20.2, OpenSUSE 15.3, macOS 10.15.7, FreeBSD 13.0.
Using Gstreamer means that video and audio are supported “out of the box”, using a choice of plugins. Gstreamer decoding is plugin agnostic, and uses accelerated decoders if available. For Intel integrated graphics, the VAAPI plugin is preferable, (but don’t use it with nVidia).
Some Linux distributions such as Debian do not allow distribution of compiled GPL code linked to OpenSLL-1.1.1 because its “dual OpenSSL/SSLeay” license has some incompatibilites with GPL, unless all code authors have explicitly given an “exception” to allow such linking (the historical origins of UxPlay make this impossible to obtain). Other distributions treat OpenSSL as a “System Library” which the GPL allows linking to.
+Some Linux distributions such as Debian do not allow distribution of compiled GPL code linked to OpenSSL-1.1.1 because its “dual OpenSSL/SSLeay” license has some incompatibilites with GPL, unless all code authors have explicitly given an “exception” to allow such linking (the historical origins of UxPlay make this impossible to obtain). Other distributions treat OpenSSL as a “System Library” which the GPL allows linking to.
For “GPL-strict” distributions, UxPlay can be built using OpenSSL- 3.0.0, which has a new GPLv3-compatible license.
Either download and unzip UxPlay-master.zip, or (if git is installed): “git clone https://github.com/FDH2/UxPlay”.
-*This is also a pull request on the original site https://github.com/antimof/UxPlay ; but is unlikely to ever get committed into the codebase there, as that project appears to be inactive.
+*This is also a pull request on the original site https://github.com/antimof/UxPlay ; that original project is inactive, but the pull request with changes up to 2021-12-10 were recently merged with the antimof tree (thank you antimof!).
(Instructions for Debian/Ubuntu; adapt these for other Linuxes; for macOS, see below).
You need a C/C++ compiler (e.g. g++) with the standard development libraries installed.
Make sure that cmake>=3.4.1 and pkg-config are also installed: “sudo apt-get install cmake pkg-config”. In a terminal window, change directories to the source directory of the downloaded source code (“UxPlay-master” for zipfile downloads, “UxPlay” for “git clone” downloads), then do
sudo apt-get install libssl-dev libplist-dev libavahi-compat-libdnssd-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-libav gstreamer1.0-plugins-badsudo apt-get install gstreamer1.0-vaapi (For Intel graphics, but not nVidia graphics)sudo apt-get install gstreamer1.0-vaapi (For hardware-accelerated Intel graphics, but not nVidia graphics)sudo apt-get install libx11-dev (for the “ZOOMFIX” X11_display name fix for screen-sharing with e.g., ZOOM)cmake . (or “cmake -DZOOMFIX=ON .” to get a screen-sharing fix to make X11 mirror display windows visible to screen-sharing applications such as Zoom, see below).makesudo make install (you can afterwards uninstall with sudo make uninstall in the same directory in which this was run)If you intend to modify the code, use a separate “build” directory: replace “cmake [ ] .” by “mkdir build ; cd build ; cmake [ ] ..”; you can then clean the build directory with “rm -rf build/*” (run from within the UxPlay source directory) without affecting the source directories which contain your modifications.
The above script installs the executable file “uxplay” to /usr/local/bin, (and installs a manpage to /usr/local/man/man1 and README files to /usr/local/share/doc/uxplay). It can also be found in the build directory after the build processs. Run uxplay in a terminal window.
The above script installs the executable file “uxplay” to /usr/local/bin, (and installs a manpage to somewhere like /usr/local/share/man/man1 and README files to somewhere like /usr/local/share/doc/uxplay). It can also be found in the build directory after the build processs. Run uxplay in a terminal window.
Note libplist-dev (version 2.0 or greater) is a new dependency (the original antimof version UxPlay-1.2 supplied it). Older Linux distributions may only supply libplist 1.x, which is too old. [Installing libplist-dev (with libplist3) from ubuntu 18.04 solves this problem on ubuntu 16.04.] If you cannot find a libplist-2.x package that installs on your older distribution, you can get it at https://github.com/libimobiledevice/libplist and build it from source. _(You will need build tools autoconf, automake, libtool, and may need to also install some libpython*-dev package). By default, libplist installs in /usr/local/lib. If this is not in the library path (as in ubuntu), create a file /etc/ld.so.conf.d/libplist.conf containing the text “/usr/local/lib”, and run “sudo ldconfig” to permanently add /usr/local/lib to the library path._
Red Hat, Fedora, CentOS: (sudo yum install) openssl-devel libplist-devel avahi-compat-libdns_sd-devel (+libX11-devel for ZOOMFIX). The required GStreamer packages are: gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-libav gstreamer1-plugins-bad-free ( + gstreamer1-vaapi for intel graphics).
OpenSUSE: (sudo zypper install) libopenssl-devel libplist-devel avahi-compat-mDNSResponder-devel (+ libX11-devel for ZOOMFIX). The required GStreamer packages are: gstreamer-devel gstreamer-plugins-base-devel gstreamer-plugins-libav gstreamer-plugins-bad (+ gstreamer-plugins-vaapi for Intel graphics).
@@ -35,7 +36,7 @@First get the latest macOS release of GStreamer-1.0 from https://gstreamer.freedesktop.org/download/. Install both the macOS runtime and development installer packages. Assuming that the latest release is 1.18.5 they are gstreamer-1.0-1.18.5-x86_64.pkg and gstreamer-1.0-devel-1.18.5-x86_64.pkg. Click on them to install (they install to /Library/FrameWorks/GStreamer.framework). It is recommended you use GStreamer.framework rather than install Gstreamer with Homebrew or MacPorts (see later).
Next install OpenSSL and libplist: these can be built from source (see below) but it is easier to get them using MacPorts “sudo port install openssl libplist-devel” or Homebrew “brew install openssl libplist”. Only the static forms of the two libraries will used for the macOS build, so they do not need to remain installed after you have built uxplay: if you don’t have MacPorts or Homebrew installed, you can just install one of these package-managers before building uxplay, and uninstall it afterwards if you do not want to keep it. Unfortunately, Fink’s openssl11-dev package currently doesn’t supply the static (libcrypto.a) form of the needed OpenSLL library libcrypto, and its libplist1 package is too old.
Finally, build and install uxplay (without ZOOMFIX): open a terminal and change into the UxPlay source directory (“UxPlay-master” for zipfile downloads, “UxPlay” for “git clone” downloads) and build/install with “cmake . ; make ; sudo make install” (same as for Linux).
-The macOS build uses OpenGL, not X11, to create the mirror display window. This has some “quirks”: the window title is “OpenGL renderer” instead of the Airplay server name, but it is visible to screen-sharing apps (e.g., Zoom). The option -t timeout cannot be used because if the GStreamer pipeline is destroyed while the OpenGL window is still open, and uxplay is left running, a segfault occurs (this is an issue with the glimagesink GStreamer OpenGL plugin, not UxPlay). Also, the resolution settings “-s wxh” do not affect the (small) initial mirror window size, but the window can be expanded using the mouse or trackpad.
+On the macOS build, autovideosink uses OpenGL, not X11, to create the mirror display window (equivalent to “-vs glimagesink”; “-vs osxvideosink” can also be used). The window title does not show the Airplay server name, but it is visible to screen-sharing apps (e.g., Zoom). On macOS, The option -t timeout cannot be used because if the GStreamer pipeline is destroyed while the mirror window is still open, a segfault occurs (this is an issue with the GStreamer plugins, not UxPlay). Also, the resolution settings “-s wxh” do not affect the (small) initial OpenGL mirror window size, but the window can be expanded using the mouse or trackpad. In contrast, a window created with “-vs osxvideosink” is initially big, but has the wrong aspect ratio (stretched image); in this case the aspect ratio changes when the window width is changed by dragging its side.
Building OpenSSL and libplist from source on macOS
If you have have the standard GNU toolset (autoconf, automake, libtool, etc.) installed, you can also download and compile the source code for these libraries from https://www.openssl.org/source/, https://github.com/libimobiledevice/libplist. Install the downloaded openssl by opening a terminal in your Downloads directory, and unpacking the source distribution openssl-3.0.0.tar.gz , (“tar -xvzf openssl-3.0.0.tar.gz ; cd openssl-3.0.0”). Then build/install with “./config ; make ; sudo make install_dev” and clean up after building uxplay with “sudo make uninstall” in the same directory. Similarly, for libplist, download the source as a zipfile from github as libplist-master.zip, then unpack (“unzip libplist-master.zip ; cd libplist-master”), build/install (“./autogen.sh ; make ; sudo make install”) and clean up after uxplay is built with “sudo make uninstall” in the same directory.
Other ways (Homebrew, MacPorts) to install GStreamer on macOS (not recommended):
@@ -45,18 +46,26 @@with MacPorts: “sudo port install gstreamer1-gst-plugins-base gstreamer1-gst-plugins-good gstreamer1-gst-plugins-bad gstreamer1-gst-libav”. The MacPorts GStreamer is built to use X11, so must be run from an XQuartz terminal, can use ZOOMFIX, and needs option “-vs ximagesink”. On an older unibody MacBook Pro, the default resolution wxh = 1920x1080 was too large for the non-retina display, but using option “-s 800x600” worked; However, the GStreamer pipeline is fragile against attempts to change the X11 window size, or to rotations that switch a connected client between portrait and landscape mode while uxplay is running. Using the MacPorts X11 GStreamer is only viable if the image size is left unchanged from the initial “-s wxh” setting (also use the iPad/iPhone setting that locks the screen orientation against switching between portrait and landscape mode as the device is rotated).
If uxplay starts, but stalls after “Initialized server socket(s)” appears, it is probably because a firewall is blocking access to the server on which it is running. If possible, either turn off the firewall to see if that is the problem, or get three consecutive network ports, starting at port n, all three in the range 1024-65535, opened for both tcp and udp, and use “uxplay -p n” (or open UDP 6000, 6001, 6011 TCP 7000,7001,7100 and use “uxplay -p”).
-Stalling after “Initialize server socket(s)”, with the server showing as available on the client iPad/iPhone, is almost certainly a firewall problem: one user was unaware that two firewalls (ufw and firewalld) were both active on their system.
-Stalling this way, but without the server showing as available on the client, probably means that your network does not have a running Bonjour/zeroconf DNS-SD server. On Linux, make sure Avahi is installed, and start the avahi-daemon service (your distribution will document how to do this). Some systems may instead use the mdnsd daemon as an alternative to provide DNS-SD service. (FreeBSD offers both alternatives, but only Avahi was tested: one of the steps needed for getting Avahi running on this system is to edit /usr/local/etc/avahi/avahi-daemon.conf to uncomment a line for airplay support.)
-For other problems after a connection is made, use “uxplay -d” (debug log option) to see what is happening. Such problems are usually due to a GStreamer plugin that doesn’t work on your system: (by default, GStreamer uses an algorithm to guess what is the “best” plugin to use on your system). If you use an nVidia graphics card, make sure that the gstreamer1.0-vaapi plugin for Intel graphics is NOT installed (uninstall it if it is installed!). (You can test for this by explicitly choosing the GStreamer videosink with option “-vs ximagesink” or “-vs xvimagesink”, to see if this fixes the problem, or “-vs vaapisink” to see if this reproduces the problem.)
-There are some reports of GStreamer problems with Intel graphics. One user (on Debian) solved this with “sudo apt install intel-media-va-driver-non-free”. This is a driver for 8’th (or later) generation "*-lake" Intel chips, that seems to be related to VAAPI accelerated graphics.
+Note: uxplay is run from a terminal command line, and informational messages are written to the terminal.
Stalling this way, with no server name showing on the client as available, probably means that your network does not have a running Bonjour/zeroconf DNS-SD server. On Linux, make sure Avahi is installed, and start the avahi-daemon service on the system running uxplay (your distribution will document how to do this). Some systems may instead use the mdnsd daemon as an alternative to provide DNS-SD service. (FreeBSD offers both alternatives, but only Avahi was tested: one of the steps needed for getting Avahi running on a FreeBSD system is to edit /usr/local/etc/avahi/avahi-daemon.conf to uncomment a line for airplay support.)
This shows that a dns_sd service is working, but a firewall on the server is probably blocking the connection request from the client. (One user who insisted that the firewall had been turned off turned out to have had two active firewalls (firewalld and ufw) both running on the server!) If possible, either turn off the firewall to see if that is the problem, or get three consecutive network ports, starting at port n, all three in the range 1024-65535, opened for both tcp and udp, and use “uxplay -p n” (or open UDP 6000, 6001, 6011 TCP 7000,7001,7100 and use “uxplay -p”).
+For such problems, use “uxplay -d” (debug log option) to see what is happening: it will show how far the connection process gets before the failure occurs.
+Most such problems are due to a GStreamer plugin that doesn’t work on your system: (by default, GStreamer uses an algorithm to guess what is the “best” plugin to use on your system). A common case is that the GStreamer VAAPI plugin (for hardware-accelerated intel graphics) is being used on a system with nVidia graphics, If you use an nVidia graphics card, make sure that the gstreamer1.0-vaapi plugin for Intel graphics is NOT installed (uninstall it if it is installed!). (You can test for this by explicitly choosing the GStreamer videosink with option “-vs ximagesink” or “-vs xvimagesink”, to see if this fixes the problem, or “-vs vaapisink” to see if this reproduces the problem.)
+There are some reports of other GStreamer problems with hardware-accelerated Intel graphics. One user (on Debian) solved this with “sudo apt install intel-media-va-driver-non-free”. This is a driver for 8’th (or later) generation "*-lake" Intel chips, that seems to be related to VAAPI accelerated graphics.
You can try to fix audio problems by using the “-as audiosink” option to choose the GStreamer audiosink , rather than have autoaudiosink pick one for you. The command “gst_inspect-1.0 | grep Sink | grep Audio” " will show you which audiosinks are available on your system. (Replace “Audio” by “Video” to see videosinks). Some possible audiosinks are pulsesink, alsasink, osssink, oss4sink, and osxaudiosink (macOS).
If you ran cmake with “-DZOOMFIX=ON”, check if the problem is still there without ZOOMFIX. ZOOMFIX is only applied to the default videosink choice (“autovideosink”) and the two X11 videosinks “ximagesink” and “xvimagesink”. ZOOMFIX is only designed for these last two; if autovideosink chooses a different videosink, ZOOMFIX is now ignored. If you are using the X11 windowing system (standard on Linux), and have trouble with screen-sharing on Zoom, use ZOOMFIX and “-vs xvimagesink” (or “-vs ximagesink” if the previous choice doesn’t work).
As other videosink choices are not affected by ZOOMFIX, they may or may not be visible to screen-sharing apps. Cairo-based windows created on Linux with “-vs gtksink” are visible to screen-sharing aps without ZOOMFIX; windows on macOS created by “-vs glimagesink” (default choice) and “-vs osximagesink” are also visible.
The “OpenGL renderer” window created on Linux by “-vs glimagesink” sometimes does not close properly when its “close” button is clicked. (this is a GStreamer issue). You may need to terminate uxplay with Ctrl-C to close a “zombie” OpenGl window.
-GStreamer issues: To troubleshoot GStreamer execute “export GST_DEBUG=2” to set the GStreamer debug-level environment-variable in the terminal where you will run uxplay, so that you see warning and error messages; (replace “2” by “4” to see much (much) more of what is happening inside GStreamer). Run “gst-inspect-1.0” to see which GStreamer plugins are installed on your system.
+To troubleshoot GStreamer execute “export GST_DEBUG=2” to set the GStreamer debug-level environment-variable in the terminal where you will run uxplay, so that you see warning and error messages; (replace “2” by “4” to see much (much) more of what is happening inside GStreamer). Run “gst-inspect-1.0” to see which GStreamer plugins are installed on your system.
Some extra GStreamer packages for special plugins may need to be installed (or reinstalled: a user using a Wayland display system as an alternative to X11 reported that after reinstalling Lubuntu 18.4, UxPlay would not work until gstreamer1.0-x was installed, presumably for Wayland’s X11-compatibility mode). Different distributions may break up GStreamer 1.x into packages in different ways; the packages listed above in the build instructions should bring in other required GStreamer packages as dependencies, but will not install all possible plugins.
-Use with non-Apple clients: one user tried to use UxPlay with an airmypc client (a non-free commercial Windows application that can mirror a Windows screen on an Apple TV using AirPlay mirror protocol). While airmypc can mirror to a true AppleTV and some other AirPlay receivers, UxPlay appears to correctly pair with this client, but then fails to decrypt both the audio and video streams. Possibly a different variant of the AirPlay encryption/decryption protocol not supported by UxPlay is used by this client. Without further information, there is no obvious fix. UxPlay reports itself to clients as “model appleTV2,1, sourceVersion 220.68”.
+This triggers an error message, and will be due to use of an incorrect protocol for getting the AES decryption key from the client.
+Modern Apple clients use a more-encrypted protocol than older ones. Which protocol is used by UxPlay depends on the client User-Agent string (reported by the client and now shown in the terminal output). iOS 9 and 10 clients only use iTunes FairPlay encryption on the AES decryption key they send to the server. Somewhere around iOS sourceVersion 330 (part of the User-Agent string) Apple started to further encrypt it by a sha-512 hash with a “shared secret” created during the Server-Client pairing process. The sourceVersion 330 above which the extra decryption step is carried out is set in lib/global.h if you need to change it. (This applies only to audio decryption; the AES key used for video decryption has had this extra encryption since iOS 9).
+The third-party non-free Windows software AirMyPC (a commercial AirPlay emulator) uses an unhashed AES key for both audio and video encryption. AirMyPC has a distinctive User-Agent string, which is detected using two other settings in lib/global.h that can be adjusted if necessary. These settings might be useful if other AirPlay-emulators need support. Uxplay declares itself to be an AppleTV2,1 with sourceVersion 220.68; this can also be changed in global.h.
Options:
-n server_name (Default: UxPlay); server_name@_hostname_ will be the name that appears offering AirPlay services to your iPad, iPhone etc, where hostname is the name of the server running uxplay. This will also now be the name shown above the mirror display (X11) window.
@@ -75,8 +84,10 @@-vs 0 suppresses display of streamed video, but plays streamed audio. (The client’s screen is still mirrored at a reduced rate of 1 frame per second, but is not rendered or displayed.) This feature (which streams audio in AAC audio format) is now probably unneeded, as UxPlay can now stream superior-quality Apple Lossless audio without video in Airplay non-mirror mode.
-as audiosink chooses the GStreamer audiosink, instead of letting autoaudiosink pick it for you. Some audiosink choices are: pulsesink, alsasink, osssink, oss4sink, and osxaudiosink (for macOS). Using quotes “…” might allow some parameters to be included with the audiosink name. (Some choices of audiosink might not work on your system.)
-as 0 (or just -a) suppresses playing of streamed audio, but displays streamed video.
--t timeout will cause the server to relaunch (without stopping uxplay) if no connections have been present during the previous timeout seconds. (You may wish to use this because the Server may not be visible to new Clients that were inactive when the Server was launched, and an idle Bonjour registration also eventually becomes unavailable for new connections.) The timer only starts once a Client has first made a mirror connection and then has disconnected with “Stop Mirrroring”. This option should not be used if the display window is an OpenGL window on macOS, as such an OpenGL window created by GStreamer does not terminate correctly (it causes a segfault) if it is still open when the GStreamer pipeline is closed.
+-t timeout will cause the server to relaunch (without stopping uxplay) if no connections have been present during the previous timeout seconds. You may wish to use this if the Server is not visible to new Clients that were inactive when the Server was launched, and an idle Bonjour registration eventually becomes unavailable for new connections (this is a workaround for what may be due to a problem with your dns-sd or Avahi setup).
+This option should not be used on macOS, as a window created by GStreamer does not terminate correctly (it causes a segfault) if it is still open when the GStreamer pipeline is closed.
1.44 2021-12-13 Omit hash of aeskey with ecdh_secret if sourceVersion <= 280.33 (this supports AirMyPC); internal rearrangement of where this hash is done. Replace decodebin by h264-specific elements in the GStreamer video pipeline. Fully report initial communications between client and server in -d debug mode.
1.43 2021-12-07 Various internal changes, such as tests for successful decryption, uniform treatment of informational/debug messages, etc., updated README.
1.42 2021-11-20 Fix MAC detection to work with modern Linux interface naming practices, MacOS and *BSD.
1.41 2021-11-11 Further cleanups of multiple audio format support (internal changes, separated RAOP and GStreamer audio/video startup)
@@ -103,6 +114,7 @@UxPlay now builds on macOS.
The hostname of the server running uxplay is now appended to the AirPlay server name, which is now displayed as name@hostname, where name is “UxPlay”, (or whatever is set with the -n option).
Added support for audio-only streaming with original (non-Mirror) AirPlay protocol, with Apple Lossless (ALAC) audio.
Added suppport for the older AirPlay protocol used by third-party Windows-based AirPlay mirror emulators such as AirMyPC.
All the resources in this repository are written using only freely available information from the internet. The code and related resources are meant for educational purposes only. It is the responsibility of the user to make sure all local laws are adhered to.
@@ -127,7 +139,7 @@When the Apple TV 2nd generation was introduced in 2010, it received support for the AirTunes protocol. However, because this device allowed playback of visual content, the protocol was extended and renamed AirPlay. It was now possible to stream photo slideshows and videos. Shortly after the release of the Apple TV 2nd generation, AirPlay support for iOS was included in the iOS 4.2 update. It seems like at that point, the audio stream was still actually using the same AirTunes 2 protocol as described above. The video and photo streams were added as a whole new protocol based on HTTP, pretty much independent from the audio stream. Soon, the first curious developers began to investigate how it worked. Their conclusion was that visual content is streamed unencrypted.
In April 2011, a talented hacker extracted the AirPlay private key from an AirPort Express. This meant that finally, third-party developers were able to also build AirPlay receiver (server) programs.
For iOS 5, released in 2011, Apple added a new protocol to the AirPlay suite: AirPlay mirroring. Initial investigators found this new protocol used encryption in order to protect the transferred video data.
-By 2012, most of AirPlay’s protocols had been reverse-engineered and documented. At this point, audio still used the AirTunes 2 protocol from around 2008, video, photos and mirroring still used their respective protocols in an unmodified form, so you could still speak of AirPlay 1 (building upon AirTunes 2). The Airplay server running on the Apple TV reported as version 130. The setup of AirPlay mirroring used the xml format, in particular a stream.xml file. Additionally, it seems like the actual audio data is using the ALAC codec for audio-only (AirTunes 2) streaming and AAC for mirror audio. At least these different formats were used in later iOS versions.
+By 2012, most of AirPlay’s protocols had been reverse-engineered and documented (see also updated version). At this point, audio still used the AirTunes 2 protocol from around 2008, video, photos and mirroring still used their respective protocols in an unmodified form, so you could still speak of AirPlay 1 (building upon AirTunes 2). The Airplay server running on the Apple TV reported as version 130. The setup of AirPlay mirroring used the xml format, in particular a stream.xml file. Additionally, it seems like the actual audio data is using the ALAC codec for audio-only (AirTunes 2) streaming and AAC for mirror audio. At least these different formats were used in later iOS versions.
Sometime before iOS 9, the protocol for mirroring was slightly modified: Instead of the “stream.xml” API endpoint, the same information could also be querried in binary plist form, just by changing the API endpoint to “stream”, without any extension. I wasn’t able to figure out which of these was actually used by what specific client / server versions.
For iOS 9, Apple made considerable changes to the AirPlay protocol in 2015, including audio and mirroring. Apparently, the audio protocol was only slightly modified, and a minor change restored compatibility. For mirroring, an additional pairing phase was added to the connection establishment procedure, consisting of pair-setup and pair-verify calls. Seemingly, these were added in order to simplify usage with devices that are connected frequently. Pair-setup is used only the first time an iOS device connects to an AirPlay receiver. The generated cryptographic binding can be used for pair-verify in later sessions. Additionally, the stream / stream.xml endpoint was replaced with the info endpoint (only available as binary plist AFAICT). As of iOS 12, the protocol introduced with iOS 9 was still supported with only slight modifications, albeit as a legacy mode. While iOS 9 used two SETUP calls (one for general connection and mirroring video, and one for audio), iOS 12 legacy mode uses 3 SETUP calls (one for general connection (timing and events), one for mirroring video, one for audio).
The release of tvOS 10.2 broke many third-party AirPlay sender (client) programs in 2017. The reason was that it was now mandatory to perform device verification via a pin in order to stream content to an Apple TV. The functionality had been in the protocol before, but was not mandatory. Some discussion about the new scheme can be found here. A full specification of the pairing and authentication protocol was made available on GitHub. At that point, tvOS 10.2 reported as AirTunes/320.20.
diff --git a/README.md b/README.md index bee85a0..35d3c83 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,50 @@ +# UxPlay 1.44: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix. -# UxPlay 1.43: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix. +This project is a GPLv3 open source unix AirPlay2 Mirror server for Linux, macOS, and \*BSD. +It is now hosted at the +github site [https://github.com/FDH2/UxPlay](https://github.com/FDH2/UxPlay) (where development and user-assistance now takes place), although it initially was developed by +[antimof](http://github.com/antimof/Uxplay) using code +from [RPiPlay](https://github.com/FD-/RPiPlay), which in turn derives from +[AirplayServer](https://github.com/KqsMea8/AirplayServer), +[shairplay](https://github.com/juhovh/shairplay), and [playfair](https://github.com/EstebanKubata/playfair). (The antimof site is +mainly inactive, but periodically posts updates pulled from the [main UxPlay site](https://github.com/FDH2/UxPlay)). -This project is a GPLv3 unix AirPlay2 server which now also works on macOS. -Its main use is to act like an AppleTV for screen-mirroring (with audio) of iOS/macOS clients -(iPads, iPhones, MacBooks) in a window on the server display (with the possibility of +Its main use is to act like an AppleTV for screen-mirroring (with audio) of iOS/iPadOS/macOS clients +(iPhones, iPads, MacBooks) in a window +on the server display (with the possibility of sharing that window on screen-sharing applications such as Zoom) -on a host running Linux, macOS, or other unix, using Apple's AirPlay Mirror protocol first available in iOS 5. -(Details of what is known about the AirPlay2 protocol can be found [here](https://github.com/SteeBono/airplayreceiver/wiki/AirPlay2-Protocol) and -[here](https://emanuelecozzi.net/docs/airplay2)). **Note that Apple DRM (as in Apple TV app content) cannot be decrypted by UxPlay.** +on a host running Linux, macOS, or other unix. UxPlay supports a "legacy" form of Apple's AirPlay Mirror protocol introduced +in iOS 12; client devices running iOS/iPadOS 12 or later are supported, as is a (nonfree) Windows-based +AirPlay-client software emulator, AirMyPC. Older (32-bit) client devices that can only run iOS 9.3 or iOS 10.3 are +currently partially supported by UxPlay: reports indicate that +screen-mirroring video works, audio is a work in progess. +(Details of what is publically known about Apple's AirPlay2 protocol can be found +[here](https://github.com/SteeBono/airplayreceiver/wiki/AirPlay2-Protocol) and +[here](https://emanuelecozzi.net/docs/airplay2)). The UxPlay server and its client must be on the same local area network, on which a **Bonjour/Zeroconf mDNS/DNS-SD server** is also running -(only DNS-SD "Service Discovery" service is necessary, it is not necessary that the local network also be of the ".local" mDNS-based type). +(only DNS-SD "Service Discovery" service is strictly necessary, it is not necessary that the local network also be of the ".local" mDNS-based type). On Linux and BSD Unix servers, this is usually provided by [Avahi](https://www.avahi.org), through the avahi-daemon service, and is included in most Linux distributions (this service can also be provided by macOS, iOS or Windows servers). -_Since v1.38, UxPlay now also supports the Airplay audio-only protocol as well as AirPlay Mirror protocol, and -(when the client screen is not being mirrored) -can play Apple Lossless (ALAC) audio streamed from the client without video (the accompanying cover-art and metadata is not displayed). -The initial connection to the client can be either AirPlay audio or Airplay Mirror mode. An Airplay Mirror connection (with "Advanced Audio Coding" AAC-ELD lossy-compression audio) -switches to ALAC if the mirrow window is closed and an AirPlay audio connection is started, and back again to AAC if a new -Airplay Mirror connection is made_. +Connections to the UxPlay server by +iOS/MacOS clients can be initiated both in AirPlay Mirror mode (which streams +lossily-compressed AAC audio while mirroring the client screen, +or in the alternative AirPlay Audio mode which streams +Apple Lossless (ALAC) audio without screen mirroring (the accompanying metadata and cover art in +this mode is not displayed). _Switching between these two modes during an active connection is +possible: in Mirror mode, close the mirror window and start an Audio mode connection, +switch back by initiating a Mirror mode connection._ **Note that Apple DRM +(as in Apple TV app content on the client) cannot be decrypted by UxPlay, +and (unlike with a true AppleTV), the client cannot run a http connection on the server +instead of streaming content from one on the client.** -UxPlay is based on https://github.com/FD-/RPiPlay, with GStreamer integration from -https://github.com/antimof/UxPlay. -(UxPlay only uses GStreamer, and does not contain the alternative Raspberry-Pi-specific -audio and video renderers also found in RPiPlay.) -Tested on a number of systems, including Ubuntu 20.04, Linux Mint 20.2, OpenSUSE 15.3, macOS 10.15, FreeBSD 13.0. +UxPlay uses GStreamer Plugins for rendering audio and video, +and does not offer the alternative Raspberry-Pi-specific +audio and video renderers available in [RPiPlay](https://github.com/FD-/RPiPlay). +It is tested on a number of systems, including (among others) Debian 11.2, Ubuntu 20.04 and 21.10, Linux Mint 20.2, OpenSUSE 15.3, macOS 10.15.7, FreeBSD 13.0. Using Gstreamer means that video and audio are supported "out of the box", using a choice of plugins. Gstreamer decoding is plugin agnostic, and uses accelerated decoders if @@ -36,7 +53,7 @@ available. For Intel integrated graphics, the VAAPI plugin is preferable, (but d ### Note to packagers: OpenSSL-3.0.0 solves GPL v3 license issues. Some Linux distributions such as Debian do not allow distribution of compiled -GPL code linked to OpenSLL-1.1.1 because its "dual OpenSSL/SSLeay" license +GPL code linked to OpenSSL-1.1.1 because its "dual OpenSSL/SSLeay" license has some incompatibilites with GPL, unless all code authors have explicitly given an "exception" to allow such linking (the historical origins of UxPlay make this impossible to obtain). Other distributions treat OpenSSL as a "System Library" which the GPL allows linking to. @@ -50,9 +67,10 @@ Either download and unzip [UxPlay-master.zip](https://github.com/FDH2/UxPlay/arc or (if git is installed): "git clone https://github.com/FDH2/UxPlay". *This is also a pull request on the -original site https://github.com/antimof/UxPlay ; but is unlikely to ever -get committed into the codebase there, as that -project appears to be inactive. +original site https://github.com/antimof/UxPlay ; that original +project is inactive, but the pull request with +changes up to 2021-12-10 +were recently merged with the antimof tree (thank you antimof!). ## Building UxPlay on Linux (or \*BSD): @@ -65,7 +83,7 @@ In a terminal window, change directories to the source directory of the downloaded source code ("UxPlay-master" for zipfile downloads, "UxPlay" for "git clone" downloads), then do 1. `sudo apt-get install libssl-dev libplist-dev libavahi-compat-libdnssd-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-libav gstreamer1.0-plugins-bad` -2. `sudo apt-get install gstreamer1.0-vaapi` (For Intel graphics, but not nVidia graphics) +2. `sudo apt-get install gstreamer1.0-vaapi` (For hardware-accelerated Intel graphics, but not nVidia graphics) 3. `sudo apt-get install libx11-dev` (for the "ZOOMFIX" X11_display name fix for screen-sharing with e.g., ZOOM) 4. `cmake .` (or "`cmake -DZOOMFIX=ON .`" to get a screen-sharing fix to make X11 mirror display windows visible to screen-sharing applications such as @@ -76,8 +94,8 @@ Zoom, see below). _If you intend to modify the code, use a separate "build" directory: replace_ "```cmake [ ] . ```" _by_ "```mkdir build ; cd build ; cmake [ ] ..```"; _you can then clean the build directory with_ "```rm -rf build/* ```" _(run from within the UxPlay source directory) without affecting the source directories which contain your modifications_. -The above script installs the executable file "`uxplay`" to `/usr/local/bin`, (and installs a manpage to `/usr/local/man/man1` and README -files to `/usr/local/share/doc/uxplay`). +The above script installs the executable file "`uxplay`" to `/usr/local/bin`, (and installs a manpage to somewhere like `/usr/local/share/man/man1` and README +files to somewhere like `/usr/local/share/doc/uxplay`). It can also be found in the build directory after the build processs. Run uxplay in a terminal window. @@ -139,15 +157,16 @@ Finally, build and install uxplay (without ZOOMFIX): open a terminal and change ("UxPlay-master" for zipfile downloads, "UxPlay" for "git clone" downloads) and build/install with "cmake . ; make ; sudo make install " (same as for Linux). -The macOS build uses OpenGL, not X11, to create the mirror display window. This has some "quirks": -the window title is "OpenGL renderer" instead of the Airplay server name, but it is visible to -screen-sharing apps (e.g., Zoom). The option -t _timeout_ -cannot be used because if the GStreamer pipeline is destroyed while the OpenGL window is still open, -and uxplay is left running, a segfault occurs (this is an issue with the glimagesink GStreamer OpenGL -plugin, not UxPlay). -Also, the resolution settings "-s wxh" do not affect -the (small) initial mirror window size, but the window can be expanded using the mouse or trackpad. - +On the macOS build, autovideosink uses OpenGL, not X11, to create the mirror display window (equivalent to +"-vs glimagesink"; "-vs osxvideosink" can also be used). +The window title does not show the Airplay server name, but it is visible to +screen-sharing apps (e.g., Zoom). On macOS, The option -t _timeout_ +cannot be used because if the GStreamer pipeline is destroyed while the mirror window is still open, +a segfault occurs (this is an issue with the GStreamer plugins, not UxPlay). +Also, the resolution settings "-s wxh" do not affect +the (small) initial OpenGL mirror window size, but the window can be expanded using the mouse or trackpad. +In contrast, a window created with "-vs osxvideosink" is initially big, but has the wrong aspect ratio (stretched image); +in this case the aspect ratio changes when the window width is changed by dragging its side. ***Building OpenSSL and libplist from source on macOS*** @@ -184,30 +203,37 @@ as the device is rotated). # **Troubleshooting:** -If uxplay starts, but stalls after "Initialized server socket(s)" appears, -it is probably because a firewall is blocking -access to the server on which it is running. If possible, either turn off the firewall +Note: ```uxplay``` is run from a terminal command line, and informational messages are written to the terminal. + +### 1. uxplay starts, but stalls after "Initialized server socket(s)" appears, *without any server name showing on the client*. + +Stalling this way, with _no_ server name showing _on the client_ as available, +probably means that your network **does not have a running Bonjour/zeroconf DNS-SD server.** +On Linux, make sure Avahi is installed, +and start the avahi-daemon service on the system running uxplay (your distribution will document how to do this). +Some systems may instead use the mdnsd daemon as an alternative to provide DNS-SD service. +_(FreeBSD offers both alternatives, but only Avahi was tested: one of the steps needed for +getting Avahi running on a FreeBSD system is to edit ```/usr/local/etc/avahi/avahi-daemon.conf``` to +uncomment a line for airplay support._) + +### 2. uxplay starts, but stalls after "Initialized server socket(s)" appears, *with the server name showing on the client* (but the client fails to connect when the UxPlay server is selected). + +This shows that a *dns_sd* service is working, but a firewall on the server is probably blocking the connection request from the client. +(One user who insisted that the firewall had been turned off turned out to have had _two_ active firewalls (*firewalld* and *ufw*) +_both_ running on the server!) If possible, either turn off the firewall to see if that is the problem, or get three consecutive network ports, starting at port n, all three in the range 1024-65535, opened for both tcp and udp, and use "uxplay -p n" (or open UDP 6000, 6001, 6011 TCP 7000,7001,7100 and use "uxplay -p"). -Stalling after "Initialize server socket(s)", with the server showing as available on the client iPad/iPhone, -is almost certainly a firewall problem: one user was unaware that -_two_ firewalls (ufw and firewalld) were both active on their system. +### 3. Problems _after_ the client-server connection has been made: -Stalling this way, but _without_ the server showing as available on the client, -probably means that your network **does not have a running Bonjour/zeroconf DNS-SD server.** -On Linux, make sure Avahi is installed, -and start the avahi-daemon service (your distribution will document how to do this). -Some systems may instead use the mdnsd daemon as an alternative to provide DNS-SD service. -(FreeBSD offers both alternatives, but only Avahi was tested: one of the steps needed for -getting Avahi running on this system is to edit /usr/local/etc/avahi/avahi-daemon.conf to -uncomment a line for airplay support.) +For such problems, use "uxplay -d " (debug log option) to see what is happening: it will show how far the connection process gets before +the failure occurs. -For other problems after a connection is made, use "uxplay -d " (debug log option) to see what is happening. -**Such problems are usually due to a GStreamer plugin that doesn't work on your system**: (by default, +**Most such problems are due to a GStreamer plugin that doesn't work on your system**: (by default, GStreamer uses an algorithm to guess what is the "best" -plugin to use on your system). +plugin to use on your system). A common case is that the GStreamer VAAPI plugin +(for hardware-accelerated intel graphics) is being used on a system with nVidia graphics, If you use an nVidia graphics card, make sure that the gstreamer1.0-vaapi plugin for Intel graphics is *NOT* installed (**uninstall it** if it is installed!). @@ -215,7 +241,7 @@ plugin for Intel graphics is *NOT* installed (**uninstall it** if it is installe "-vs ximagesink" or "-vs xvimagesink", to see if this fixes the problem, or "-vs vaapisink" to see if this reproduces the problem.) -There are some reports of GStreamer problems with Intel graphics. One user +There are some reports of other GStreamer problems with hardware-accelerated Intel graphics. One user (on Debian) solved this with "sudo apt install intel-media-va-driver-non-free". This is a driver for 8'th (or later) generation "*-lake" Intel chips, that seems to be related to VAAPI accelerated graphics. @@ -238,7 +264,9 @@ Cairo-based windows created on Linux with "-vs gtksink" are visible to screen-sh The "OpenGL renderer" window created on Linux by "-vs glimagesink" sometimes does not close properly when its "close" button is clicked. (this is a GStreamer issue). You may need to terminate uxplay with Ctrl-C to close a "zombie" OpenGl window. -__GStreamer issues:__ To troubleshoot GStreamer execute "export GST_DEBUG=2" +### 4. GStreamer issues (missing plugins, etc.): + +To troubleshoot GStreamer execute "export GST_DEBUG=2" to set the GStreamer debug-level environment-variable in the terminal where you will run uxplay, so that you see warning and error messages; (replace "2" by "4" to see much (much) more of what is happening inside @@ -250,12 +278,20 @@ reported that after reinstalling Lubuntu 18.4, UxPlay would not work until gstr Different distributions may break up GStreamer 1.x into packages in different ways; the packages listed above in the build instructions should bring in other required GStreamer packages as dependencies, but will not install all possible plugins. -**Use with non-Apple clients**: one user tried to use UxPlay with an *airmypc* client (a non-free commercial -Windows application that can mirror a Windows screen on an Apple TV using AirPlay mirror protocol). While *airmypc* -can mirror to a true AppleTV and some other AirPlay receivers, UxPlay appears to correctly pair with this client, but -then fails to decrypt both the audio and video streams. Possibly a different variant of the AirPlay encryption/decryption -protocol not supported by UxPlay is used by this client. Without further information, there is no obvious fix. -UxPlay reports itself to clients as "model appleTV2,1, sourceVersion 220.68". +### 5. Failure to decrypt ALL video and audio streams from a particular (older) client: + +This triggers an error message, and will be due to use of an incorrect protocol for getting the AES decryption key from the client. + +Modern Apple clients use a more-encrypted protocol than older ones. +Which protocol is used by UxPlay depends on the client _User-Agent_ string (reported by the client and now shown in the terminal output). +iOS 9 and 10 clients only use iTunes FairPlay encryption on the AES decryption key they send to the server. +Somewhere around iOS sourceVersion 330 (part of the User-Agent string) Apple started to further encrypt it by a sha-512 hash with a "shared secret" created +during the Server-Client pairing process. The sourceVersion 330 above which the extra decryption step is carried out is set in lib/global.h if you need to +change it. (This applies only to audio decryption; the AES key used for video decryption has had this extra encryption since iOS 9). + +The third-party non-free Windows software _AirMyPC_ (a commercial AirPlay emulator) uses an unhashed AES key for both audio and video encryption. _AirMyPC_ has a distinctive +_User-Agent_ string, which is detected using two other settings in lib/global.h that can be adjusted if necessary. These settings might be useful if +other AirPlay-emulators need support. Uxplay declares itself to be an AppleTV2,1 with sourceVersion 220.68; this can also be changed in global.h. # **Usage:** @@ -350,17 +386,21 @@ Also: image transforms that had been added to RPiPlay have been ported to UxPlay **-as 0** (or just **-a**) suppresses playing of streamed audio, but displays streamed video. **-t _timeout_** will cause the server to relaunch (without stopping uxplay) if no connections - have been present during the previous _timeout_ seconds. (You may wish to use this because the Server may not be - visible to new Clients that were inactive when the Server was launched, and an idle Bonjour - registration also eventually becomes unavailable for new connections.) The timer only starts once a - Client has first made a mirror connection and then has disconnected with "Stop Mirrroring". - _This option should **not** be - used if the display window is an OpenGL window on macOS, as such an OpenGL window created + have been present during the previous _timeout_ seconds. You may wish to use this if the Server + is not visible to new Clients that were inactive when the Server was launched, and an idle Bonjour + registration eventually becomes unavailable for new connections (this is a workaround for what + may be due to a problem with your dns-sd or Avahi setup). + _This option should **not** be used on macOS, as a window created by GStreamer does not terminate correctly (it causes a segfault) if it is still open when the GStreamer pipeline is closed._ # ChangeLog +1.44 2021-12-13 Omit hash of aeskey with ecdh_secret if sourceVersion <= 280.33 (this supports AirMyPC); + internal rearrangement of where this hash is done. Replace decodebin by h264-specific + elements in the GStreamer video pipeline. Fully report initial communications between + client and server in -d debug mode. + 1.43 2021-12-07 Various internal changes, such as tests for successful decryption, uniform treatment of informational/debug messages, etc., updated README. @@ -465,6 +505,8 @@ is compiled.) On macOS, Avahi is not used. 12. Added support for audio-only streaming with original (non-Mirror) AirPlay protocol, with Apple Lossless (ALAC) audio. +13. Added suppport for the older AirPlay protocol used by third-party Windows-based AirPlay mirror emulators such as AirMyPC. + # Disclaimer All the resources in this repository are written using only freely available information from the internet. The code and related resources are meant for educational purposes only. It is the responsibility of the user to make sure all local laws are adhered to. @@ -511,7 +553,7 @@ In April 2011, a talented hacker [extracted the AirPlay private key](http://www. For iOS 5, released in 2011, Apple added a new protocol to the AirPlay suite: AirPlay mirroring. [Initial investigators](https://www.aorensoftware.com/blog/2011/08/20/exploring-airplay-mirroring-internals/) found this new protocol used encryption in order to protect the transferred video data. -By 2012, most of AirPlay's protocols had been reverse-engineered and [documented](https://nto.github.io/AirPlay.html). At this point, audio still used the AirTunes 2 protocol from around 2008, video, photos and mirroring still used their respective protocols in an unmodified form, so you could still speak of AirPlay 1 (building upon AirTunes 2). The Airplay server running on the Apple TV reported as version 130. The setup of AirPlay mirroring used the xml format, in particular a stream.xml file. +By 2012, most of AirPlay's protocols had been reverse-engineered and [documented](https://nto.github.io/AirPlay.html) (see also [updated version](https://openairplay.github.io/airplay-spec)). At this point, audio still used the AirTunes 2 protocol from around 2008, video, photos and mirroring still used their respective protocols in an unmodified form, so you could still speak of AirPlay 1 (building upon AirTunes 2). The Airplay server running on the Apple TV reported as version 130. The setup of AirPlay mirroring used the xml format, in particular a stream.xml file. Additionally, it seems like the actual audio data is using the ALAC codec for audio-only (AirTunes 2) streaming and AAC for mirror audio. At least these different formats were used in [later iOS versions](https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-372380451). diff --git a/README.txt b/README.txt index a834e2c..785b477 100644 --- a/README.txt +++ b/README.txt @@ -1,44 +1,61 @@ -UxPlay 1.43: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix. +UxPlay 1.44: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix. ====================================================================== -This project is a GPLv3 unix AirPlay2 server which now also works on -macOS. Its main use is to act like an AppleTV for screen-mirroring (with -audio) of iOS/macOS clients (iPads, iPhones, MacBooks) in a window on +This project is a GPLv3 open source unix AirPlay2 Mirror server for +Linux, macOS, and \*BSD. It is now hosted at the github site +