airplay-protocol
airplay-protocol copied to clipboard
Device verification forced on Apple TV 4th with latest 10.2 software update
This is the Apple feature that shows a code on the Apple TV that has to be entered on the AirPlay sender by the user (iPhone, iPad).
As far as I know, this exists for a while but has always been an opt-in option. The 10.2 update makes it forced.
Any plans on supporting this?
Looks like the airplay-protocol
doesn't work anymore with the latest tvOS 10.2.
My Apple TV prompt me to use iTunes 11.2 or newer. But changing USER_AGENT
constant in the sources didn't work.
Maybe this project could get some help by Beamer, AirParrot or DoubleTwist? They seem to have managed the hardware verification.
Hey there,
feel free to use my Java-library as a template: https://github.com/funtax/AirPlayAuth
You can simply import the project eg. into "IntelliJ Community Edition" and run the example :)
I'm the developer of two audio AirPlay-apps and can confirm that once the pairing has been done, the ongoing communication with the AirPlay-receiver is done like before.
Also, there seems to be no reliable way to check if pairing is required, beside checking the mdns-data for "appletv" and "pk". Then authentication can also be made on ATVs which have the authentication not enabled, so you can simply always do the pairing in case it's an AppleTV.
Ps. The source of my engineering is a scrambled NodeJS-script (not published) which I could also offer as an unbeautified template. It cointains all parts required for the authentication and could be written well by someone with more Node-knowledge than me. This in combination with the Java-script could solve your issue in a few days.
@funtax thanks! Do you see any difficulties to port AirPlayAuth
to javascript?
Maybe using crypto
this could be tricky:
public static String generateNewAuthToken() {
String clientId = AuthUtils.randomString(16);
return clientId + "@" + net.i2p.crypto.eddsa.Utils.bytesToHex(new KeyPairGenerator().generateKeyPair().getPrivate().getEncoded());
}
@loretoparisi The code has been ported to Python, C and ObjectiveC as far as I know.. so there are several reference-implementations available. I thing porting it into JS should be no major problem. The SRP6a-stuff was the most tricky thing, but one has just to make sure that all the variables do 1:1 the same as in my implementation.
@funtax I tried your project not working for me, after validate pin, I tried play and:
HTTP/1.1 200 OK Date: Sat, 24 Feb 2018 11:57:08 GMT Content-Length: 0 Content-Type: application/octet-stream Server: AirTunes/356.19
Pair Verify finished! HTTP/1.1 400 Bad Request Content-Length: 0 Server: AirTunes/356.19
It fails in AuthUtils.postData(socket, "/play", "text/parameters", content.getBytes("UTF-8"));
Any idea?
Hey @francisco-navarro , did you directly executed my example, or did you use a modified on? I have my ATV not running at the moment and would have to setup it again first to reproduce your issue :)
I run your example with modified parameters (ip and new token created). Then I see in the atv the pin and its pair correctly. But when it does the post /play text/parameters url, I get a 400. I was reading documentation about de api, and I can do a GET with info, but the play doesn't work.
Are you able to open the video in your Browser? I think this issue has nothing to do with the authentication but furthermore with some other issues.
2018-02-24 13:42 GMT+01:00 Paco Navarro [email protected]:
I run your example with modified parameters (ip and new token created). Then I see in the atv the pin and its pair correctly. But when it does the post /play text/parameters url, I get a 400. I was reading documentation about de api, and I can do a GET with info, but the play doesn't work.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/watson/airplay-protocol/issues/7#issuecomment-368225921, or mute the thread https://github.com/notifications/unsubscribe-auth/AAZmMNag7ExVoiy2Y83JGsU-NBk9Q79Xks5tYAOYgaJpZM4MSZhV .
@francisco-navarro, the play request failed with 400 Bad Request Error because the request body must be of type application/x-apple-binary-plist (text parameters are not supported any more).
Thanks @ViktoriiaKh for the information.
@ViktoriiaKh can you check that again as it is giving me 400 bad request even if I use "application/x-apple-binary-plist"
@ingsaurabh, I've just re-checked it on my Apple TV (4th generation) and Apple TV 4K with the latest tvOS 11.2.6 installed. And everything works fine.
CLIENT -> SERVER:
POST /play HTTP/1.1
User-Agent: AirPlay/320.20
Content-Type: application/x-apple-binary-plist
Content-Length: 174
X-Apple-Device-ID: 0x0c5ec9b8179c
<BINARY PLIST DATA>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Content-Location</key>
<string>http://commondatastorage.googleapis.com/gtv-videos-bucket/big_buck_bunny_1080p.mp4</string>
<key>Start-Position</key>
<real>0.1610738</real>
</dict>
</plist>
SERVER -> CLIENT:
HTTP/1.1 200 OK
Date: Mon, 26 Mar 2018 13:09:08 GMT
Server: AirTunes/356.19
Content-Length: 0
@ViktoriiaKh @funtax , I just checked your Xcode version on my Apple TV (4th gen) with the latest tvOS 11.4 installed, it failed to work.. could you please help to check?
If anybody manages to make it work on tvOS 11.4, please help! Thank you!!
@ViktoriiaKh Could you show us your code? I can't get it work with binary plist format (http 500 response). Do I need to include on body "<BINARY PLIST DATA>"?
@funtax Can you update your project with new "application/x-apple-binary-plist" requeriment?
I'm trying to get this working, and had the error 400 before. After switching to a binary plist, I now have an error 500.
NSDictionary plist = new NSDictionary();
plist.put("Content-Location", "http://techslides.com/demos/sample-videos/small.mp4");
plist.put("Start-Position", 0.0);
byte[] contentBytes = BinaryPropertyListWriter.writeToArray(plist);
AuthUtils.postData(socket, "/play", "application/x-apple-binary-plist", contentBytes);
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Content-Location</key>
<string>http://techslides.com/demos/sample-videos/small.mp4</string>
<key>Start-Position</key>
<real>0.0</real>
</dict>
</plist>
Update:
It seems to work every now and then, maybe 10% of the time if a debugger is attached. Some race condition maybe?