openairplay/airplay2-receiver

Continue branch-sender from ckdo

Closed this issue ยท 17 comments

Would anyone be interested in the continuation of this branch by ckdo:
https://github.com/ckdo/airplay2-receiver/tree/branch-sender

I feel like it'd be a really good addition if done well.

Noted. The important bit: "if done well" :)

ckdo has done some good work. Have you tested any of those branches?

I'm unable to test those branches easily as they don't have the latest Feature Flags system - HKPairing breaks it for iOS 15 db 2

I'll scour through what CKDO has done and see if I can intertwine it with what we've currently got, then. Thanks.

@systemcrash
Well, the meat of it is there. It's definitely got potential to be usable, though I've been really struggling with RSTP authentication.

I'm currently at the point where I'm getting and even if I implement the HTTP digest auth it rejects it anyway.

----- AUTH SETUP RESPONSE -----
Content-Length: 0
Server: AirTunes/566.25.43
WWW-Authenticate: Digest realm="airplay", nonce="M[...]Q/"
CSeq: 2

401
----- AUTH SETUP RESPONSE ERROR OCCURED -----

I went to look for inspiration and found a lovely package called pyatv - it's designed to interface with Apple TVs.

I thought that surely it must be achievable since I only want to find out what the currently playing song is.
It did manage to connect, and pair, but it failed to perform any actions. I assume this is because the module treats play/pause/play+pause/etc as the same: the play key. So it's sending data to a device which doesn't support an Apple TV remote, and the device subsequently rejects. I'd be more than happy to implement some sort of pyatv wrapper as part of the ap2 module, but even better would be to be able to extract how they're handling RTSP + Auth. Would just like to hear some thoughts before I go and attempt anything major.

As maintainer for pyatv, I can add that it does not support any AirPlay 2 features other than system and transient pairing in order to set up a remote control stream to tunnel the MRP protocol over. This is required in tvOS 15 as the "regular" MRP (which has its own zeroconfs service) is removed. The same functionality also works with the HomePod (which uses transient pairing). The MRP protocol is apple internal so I expect this to not work with any other devices than the Apple TV and HomePod.

Also, pyatv only has very basic AirPlay 1 support for streaming audio. No controls are implemented at all. As far as I know, AirPlay doesn't allow tapping in on someone else's stream. So you can't really see what is streamed by someone else to an AirPlay receiver (or execute any other commands, like play or pause). That is only supported by the sender as it has full control of the stream anyways. An exception is of course events back from the receiver, e.g. when pressing a physical button on the receiver (if supported). I guess that is why they use MRP to deal with this gap and display metadata and audio playback control in iOS via control center. I've documented some parts of that here (scroll down to the AirPlay 2 section, direct linking doesn't work properly). I can probably support any pyatv related questions if needed.

Well then, if you don't mind, I couldn't find anything anywhere explaining which endpoint to send my RTSP data to. It's noted in the explanation that

ID in o= property (4018537194) seems to match what is used for rtsp endpoint (rtsp://xxx/4018537194)

I'd love to know how to get this so I can start testing it on my own devices.

Well then, if you don't mind, I couldn't find anything anywhere explaining which endpoint to send my RTSP data to. It's noted in the explanation that

ID in o= property (4018537194) seems to match what is used for rtsp endpoint (rtsp://xxx/4018537194)

I'd love to know how to get this so I can start testing it on my own devices.

Yes, that seems to generally be the case. I'm not entirely sure what you are trying to do though? What you are referring to is AirPlay v1 stuff, is that what you want to use?

I'm trying to work out all the steps to where ckdo originally got to so I have at least half a clue what's going on. I've been testing this by trying out simple commands, like fetching the speaker info. From what I can see, ckdo was implementing the ap2 authentication over RTSP but it just needs a little tinkering with.

Afterwards, I'd like to make it into a script with command line arguments that people can utilise with relative ease, the same as ap2-recvier

@systemcrash: Have you looked?

I had a look at this myself, and I'm indifferent: this project is the receiver portion. But having the capability is OK. I'm OK without it, however.

Then would it maybe be favourable to, once the current ambitions are complete, call this project finished. Iirc the original intentions of this project are to provide a baseline for a future and more thorough implementation, no?

Calling something complete is a matter of philosophy, I think. I would always be open to more PRs and additions, although it seems the core of this app has largely been successful. It got ported to Go, and was possibly inspiration for other people doing similar ventures. We've not actually implemented PTP fully, yet. So... there's that :)

There seems to be more attention to the C (compiled) version of the receiver: it's a bit more comprehensive, and it has recently implemented the 'open' version of FP crypto. Porting that to Py would be... fun ๐Ÿ˜„ It would actually work. It's just a time-consuming venture, probably better in lib form (see what ckdo did for ALAC lib a while back).

I had fun working on this (and am open to devoting more effort in the future).

I'm not sure - what did you have in mind specifically?

@systemcrash: Nothing to add in current upstream code?