openairplay / airplay2-receiver

AirPlay 2 Receiver - Python implementation
2.12k stars 131 forks source link

Can't stream Apple Music to AP2R #86

Closed editinqash closed 9 months ago

editinqash commented 1 year ago

The problem

It connects but when I press play, it disconnects instantly.

What commit exhibits the issue?

main

Was there a last known working commit?

No response

What type of installation are you running?

virtualenv

With which python3 version do you run Receiver?

Pyhton 3.7.9

OS the receiver runs on

Windows 10

OS the sender runs

iOS 17.0 Developer Beta 2

Which sender client was used

Apple Music

Command invocation

python ap2-reciever.py -m vInf -n "GUID HERE"

Please include --debug output which helps to illustrate the problem

debug.txt

Additional information

No response

systemcrash commented 1 year ago

Everything looks normal up to the following:

[09/Jul/2023 23:27:52] code 501, message Unsupported method ('SETMAGICCOOKIE')

You can implement this endpoint yourself and try to figure out what it does. I don't know what behavior is expected here.

The sdk version that we advertise should not include this magic cookie thing, I think. So this could just be an ios17 test thing, a bug, or some new behavior in airplay.

Have a play and see whether you can get this method working.

systemcrash commented 1 year ago

something like this:

diff --git a/ap2-receiver.py b/ap2-receiver.py
index d208f1e..f5f5b00 100644
--- a/ap2-receiver.py
+++ b/ap2-receiver.py
@@ -411,6 +411,7 @@ class AP2Handler(http.server.BaseHTTPRequestHandler):
                          "ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH"
                          "FLUSHBUFFERED, TEARDOWN, OPTIONS, POST, GET, PUT"
                          "SETPEERSX"
+                         "SETMAGICCOOKIE"
                          )
         self.end_headers()

@@ -866,6 +867,21 @@ class AP2Handler(http.server.BaseHTTPRequestHandler):
         self.send_header("CSeq", self.headers["CSeq"])
         self.end_headers()

+    def do_SETMAGICCOOKIE(self):
+        # Appears in iOS 17 betas ( User-Agent: AirPlay/710.66.3 )
+        self.logger.info(f'{self.command}: {self.path}')
+        self.logger.debug(self.headers)
+        content_len = int(self.headers["Content-Length"])
+        if content_len > 0:
+            body = self.rfile.read(content_len)
+
+            plist = readPlistFromString(body)
+            self.logger.info(self.pp.pformat(plist))
+        self.send_response(200)
+        self.send_header("Server", self.version_string())
+        self.send_header("CSeq", self.headers["CSeq"])
+        self.end_headers()
+
     def handle_command(self):
         if self.headers["Content-Type"] == HTTP_CT_BPLIST:
             content_len = int(self.headers["Content-Length"])
systemcrash commented 1 year ago

@xatitive Perhaps you can try the above also.

xatitive commented 1 year ago

Tried the above fix and doesn't work exactly as intended, when ran it outputs the magic cookies hex binary string

[AP2Handler: 192.168.1.184:7000<=>192.168.1.157:56953; Thread-2 (process_request_thread)]: SETMAGICCOOKIE: rtsp://192.168.1.184/9278966137520734488
[AP2Handler: 192.168.1.184:7000<=>192.168.1.157:56953; Thread-2 (process_request_thread)]: {'magicCookie': b'\x00\x00\x01`\x00\x18(\n\x0e\x02\x00\xff\x00\x00\x00\x00'
                b'\x00\x00\x00\x00\x00\x00\xbb\x80',
 'magicCookieID': -4859668389756636041}
[comtypes]: Calling CoUninitialize()
[comtypes]: CoUninitialize() done.
systemcrash commented 1 year ago

You'll need to be more specific than "doesn't work exactly as intended".

The example code I provided does no more than that. We don't know what this endpoint is supposed to do.

The fact that the apple endpoint imposes behavior requirements (cookie) on an older sdk version is concerning. This reads "breaking backwards compatibility".

xatitive commented 1 year ago

True I just didn’t know what more to say

systemcrash commented 1 year ago

Try hacking some more. What happens before and after the cookie bit? On your client (also)?

xatitive commented 1 year ago

Nothing new happens before the cookie bit, after receiving the bit we also get the ID of it too but has nowhere to go rn ofc but now I can "play" music as now it'll say it's playing to the receiver while not receiving anything to play.

After the bit CoUninitialize gets called and nothing more happens when trying to interact with it

systemcrash commented 1 year ago

You could maybe try the streams mode. I added support, but never really figured out what it was supposed to do or how it was supposed to work differently. I see different behaviour in the logs, however.

See commit 723bace76de1b84c94750275cc0ee0913691ae5e

xatitive commented 1 year ago

running python ap2-receiver.py -m myap2 -n "{250B8E87-4420-470E-8B1B-75DD2836809B}" --debug -ftxor 59 did the same thing, (i think thats what u wanted me to run) doesnt do anything new compared to what happened last time. although now im seeing that once connecting to the reciever you have to restart since it just hangs after recieving the cookie

systemcrash commented 1 year ago

Hmm - just taking stabs in the dark here. You're welcome to try hacking yourself. That's what this project is for.

systemcrash commented 12 months ago

How is this in the latest beta?

ItsEcholot commented 9 months ago

I just tried this project today with YouTube and I too got the SETMAGICCOOKIE error now on iOS 17 public release.

systemcrash commented 9 months ago

Try the latest master 6c343d3679ddb561c61566985acaaf587d0a3bd3. Works for me on iOS 17.0.2.