postlund / pyatv

A client library for Apple TV and AirPlay devices
https://pyatv.dev
MIT License
891 stars 100 forks source link

Add basic implementation of MediaRemoteTV protocol #94

Closed postlund closed 4 years ago

postlund commented 7 years ago

This is a place holder for adding protocol support for MediaRemoteTV. I have not done any work on this at all and I can give no information at this stage if or when it will be supported.

There are some documentation about it here: https://github.com/jeanregisser/mediaremotetv-protocol But I assume that it is no longer complete. As it uses SRP, hopefully most of the work done for device authentication can be re-used.

Some things to consider:

postlund commented 7 years ago

Not sure how far I will get on this without a real device, but it seems like the simulator shipped with Xcode works close enough to a real device. I can use the Remote app with it, so it's possible to sniff traffic. I have started experimenting with this now.

postlund commented 7 years ago

I have managed to hack some code together that can request device information from the simulator:

(pyatv)Pierres-MacBook-Pro:pyatv postlund$ atvremote --debug mrp
Getting device information...
>> 96 01 08 0F 12 24 39 43 30 44 39 44 37 38 2D 46 41 35 42 2D 34 30 32 46 2D 41 31 39 42 2D 41 31 30 33 41 37 37 33 42 33 33 45 20 00 A2 01 69 0A 24 36 46 44 41 44 33 30 39 2D 35 33 33 31 2D 34 37 46 46 2D 42 35 32 35 2D 31 31 35 38 42 42 31 30 35 41 46 30 12 0E 50 69 65 72 72 65 73 20 69 50 68 6F 6E 65 1A 06 69 50 68 6F 6E 65 22 05 31 34 47 36 30 2A 12 63 6F 6D 2E 61 70 70 6C 65 2E 54 56 52 65 6D 6F 74 65 32 06 32 37 33 2E 31 32 38 01 40 2D 48 01 50 01
>> message {
  type: DEVICE_INFO_MESSAGE
  identifier: "9C0D9D78-FA5B-402F-A19B-A103A773B33E"
  priority: 0
  deviceInfoMessage {
    uniqueIdentifier: "6FDAD309-5331-47FF-B525-1158BB105AF0"
    name: "Pierres iPhone"
    localizedModelName: "iPhone"
    systemBuildVersion: "14G60"
    applicationBundleIdentifier: "com.apple.TVRemote"
    applicationBundleVersion: "273.12"
    protocolVersion: 1
    unknown1: 45
    unknown2: 1
    unknown3: 1
  }
}

<< 8E 01 08 0F 12 24 39 43 30 44 39 44 37 38 2D 46 41 35 42 2D 34 30 32 46 2D 41 31 39 42 2D 41 31 30 33 41 37 37 33 42 33 33 45 20 00 A2 01 61 0A 24 31 44 32 35 31 44 31 42 2D 39 38 31 30 2D 34 33 34 46 2D 38 42 44 42 2D 39 45 30 33 32 36 34 39 34 45 33 35 12 0D 69 4F 53 20 53 69 6D 75 6C 61 74 6F 72 1A 03 4D 61 63 22 05 31 36 46 37 33 2A 16 63 6F 6D 2E 61 70 70 6C 65 2E 6D 65 64 69 61 72 65 6D 6F 74 65 64 38 01 40 2D 48 01 50 01
<< message {
  type: DEVICE_INFO_MESSAGE
  identifier: "9C0D9D78-FA5B-402F-A19B-A103A773B33E"
  priority: 0
  deviceInfoMessage {
    uniqueIdentifier: "1D251D1B-9810-434F-8BDB-9E0326494E35"
    name: "iOS Simulator"
    localizedModelName: "Mac"
    systemBuildVersion: "16F73"
    applicationBundleIdentifier: "com.apple.mediaremoted"
    protocolVersion: 1
    unknown1: 45
    unknown2: 1
    unknown3: 1
  }
}

Lots of hacking going on, but it's at least a start. Took some time just to understand the protobuf enoding since there are a few new fields (not documented in the mentioned link) that must be set. I'll see where I end up later today, but I might push a branch if someone else wants to have a look. Going to continue with the pairing process and see what happens. That will probably be quite hard to implement correctly...

postlund commented 7 years ago

Quite a lot of progress has been made and a prototype of all the encryption-related stuff is in the mrp-branch. It doesn't do anything useful yet but pairing works and messages are encrypted/decrypted correctly. My current focus is to refactor and fix the API in pyatv so that MRP can fit alongside current DMAP implementation. It requires a bit of work but I'm slowly getting there. Hopefully I can move most of the prototype code into master branch within the next couple of days, when it's possible to test the code using atvremote and tests.

stigger commented 7 years ago

Hey, looks like we both have made the same reverse-engineering work in parallel: https://github.com/stigger/trakt-for-appletv/tree/control

postlund commented 7 years ago

@stigger It certainly does! Great to see more people interested in this 😄 You should send some PRs with messages updates and details regarding the things you have reversed engineered back to Jeans repo. Would be great to stuff everything we know in there and try to understand the entire protocol. I've started with some things and will continue send new PRs when I have time to do so.

stigger commented 7 years ago

You should send some PRs with messages updates

Yes, I was planning to when I saw your pull requests. Will do when they're accepted, to avoid merge conflicts.

postlund commented 7 years ago

Sounds like a good plan!

ersan commented 6 years ago

Do you happen to know if MediaRemoteTV would be able to launch a specific application on the Apple TV? Based on what I'm seeing the answer is probably no, but I'm not particularly well versed in this sort of thing. I suppose you could send a pre-recorded voice command to Siri via MediaRemoteTV telling it to launch an application?

postlund commented 6 years ago

I have not found any way of doing that, no. That doesn't mean that it's not possible but I haven't found a way. Navigating by sending arrow keys and such is probably the only way of doing that at would likely not be very stable.

bytedealer commented 6 years ago

Great work all in all! Thank you for that!!!

Do you plan any support for swipes?

Here is someone who implemented this. Unfortunately I am not firm in python, have only some PHP skills. https://github.com/stigger/trakt-for-appletv/blob/control/tvremote.py

postlund commented 6 years ago

Thanks! 😊

I've experimented a bit with swipes and I will definitely implement that as well. My experiments are a bit more rough and I will probably base it off the implementation you mentioned. Do you have any specific use cases? Since in most cases it just corresponds to the arrow keys.

bytedealer commented 6 years ago

Hi!

I use a app called Zattoo.

In first screen there is a side menu. Here I can navigate through the "arrow" commands. But when I go to "Live TV" I need a swipe up to start program choice. Zattoo is free, but you need a ATV 4(k).

Is there anyway to support you and your effort? Like PayPal donation or something?

postlund commented 6 years ago

Ok, then I know. I assume it's the same thing as when you change subtitles or audio track? Enabling this menu was my main use case so it is definitely possible to do. Anyway, I have a 4K so I can try it out if necessary.

No worries about that, I do this for fun 😊 I would much rather prefer if donations went to some help organization that need the money more than I do!

stigger commented 6 years ago

Swipes are pretty easy to implement as a series of touch events with phases Began, multiple Moved, and then Ended. I've been using it for a while, works quite well: https://github.com/stigger/trakt-for-appletv/blob/control/tvremote.py#L72

bytedealer commented 6 years ago

Hi again!

Yes, it is the same thing but the other direction (bottom->up). The thing you mention is (top->down).

I like your attitude as developer and as human. Therefore I will look for a help organization in the near and will donate them. 😊

stigger commented 6 years ago

The snippet I referenced should work fine with the other direction, you just need to swap the coordinates.

postlund commented 4 years ago

I consider the basic implementation to be there, so I'll close this now 🎉