postlund / pyatv

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

HELP: Is your Apple TV not found? Read this #214

Closed postlund closed 5 years ago

postlund commented 5 years ago

The problem A lot of people are having issues where their devices are not found. You either see a message like this:

ERROR: Could not find any Apple TV on current network

Or just empty results from atvremote scan. The issue can also come and go, so it works from time to time but very unreliably.

I do not know why this happens. I see it sometimes myself, but very seldom, so it's hard to debug. So I am asking for help to solve this once and for all. If you have problems and want to help, continue reading.

Background Apple heavily uses Zero-configuration networking to publish and discover services on a network (they call it Bonjour). This simplifies user experience a lot, since no fiddling with IP-addresses or other network settings are required. Devices, like printers and media players, just "pop-up" when they are available.

The Apple TV works in the same way and pyatv tries to discover four distinct services:

Depending on which services pyatv finds, it will try to figure out the best protocol to use. If for instance both _touch-able._tcp.local. and _appletv-v2._tcp.local. are found, it will use the latter as no additional action is required by the user (i.e. no pairing).

If no service is found for some reason, then pyatv of course will conclude that no device exists. This is what happens for lots of users, including myself. pyatv uses a python library for zeroconf for service discovery and I suspect a bug in that library. By looking at open issues, other people report similar behavior as well.

What can I do? Troubleshooting this is tricky, especially since it's not easily reproducible at all times. One thing I would like to conclude is if python-zeroconf is the culprit. We can do this with some confidence by scanning for Apple TVs with pyatv and also other tools on the same machine and network. If pyatv doesn't find a device but avahi does, then we should suspect python-zeroconf.

So what you can do is:

  1. Scan for devices with atvremote: atvremote scan
  2. If the list is not empty, start over with 1) again a few times. If the device continues to be found, try again later to allow for caches to be flushed, etc.
  3. When no device is found, try scanning with other tools. On Linux you can use avahi-browse like this:
    $ avahi-browse -d local _mediaremotetv._tcp
    +    br0 IPv6 Vardagsrum                                    _mediaremotetv._tcp  local
    +    br0 IPv4 Vardagsrum                                    _mediaremotetv._tcp  local

    or on macOS, you can do this:

    $ dns-sd -B _mediaremotetv._tcp
    Browsing for _mediaremotetv._tcp
    DATE: ---Mon 14 Oct 2019---
    10:50:35.015  ...STARTING...
    Timestamp     A/R    Flags  if Domain               Service Type         Instance Name
    10:50:35.016  Add        2   4 local.               _mediaremotetv._tcp. Vardagsrum

    For Windows I don't know. There probably are tools, but you will have to look that up yourself.

  4. At this stage, if atvremote scan and the other tool you used did not find any device (and you have an Apple TV on your network), then there probably is a legitimate problem. You can report this, it's useful information.
  5. If pyatv did not find a device, but the other tool did, then we can start suspecting python-zeroconf. It would be good if you re-run the commands a few times to get some more entropy.

You can report any combinations you have tried. If you have more than one Apple TV and only one is found, that can be useful as well.

Note: The commands above only looks for MRP, so if you have an ATV3 or earlier and want to help out, change _mediaremotetv._tcp to _touch-able._tcp instead.

What can I do more? Provide additional logging from python-zeroconf during scanning. A simple script like this will scan for devices with debug logging enabled (it is not sufficient to use --debug with atvremote as that doesn't enable debug logging for python-zeroconf):

import logging
import asyncio
import pyatv
import zeroconf

LOOP = asyncio.get_event_loop()

async def scan(loop):
    print(await pyatv.scan_for_apple_tvs(loop, timeout=5))

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    LOOP.run_until_complete(scan(LOOP))

Please do note that the debug printout may contain some sensitive information. No passwords or such should be there, but things like unique identifiers and MAC-addresses might be present. Either you mask sensitive data out (which might be hard) or you just email me the dump (pierre.staahl AT gmail.com). But remember, it is up to you if you want to share the log. I will only use it for debugging.

Great, so anything else? There is another (asyncio) zeroconf library for python that might be interesting to try out. It's called aiozeroconf and is available here:

https://github.com/frawau/aiozeroconf

You could try installing that and scanning for services as well, maybe it works better? It's still based on the same code base as python-zeroconf, so no guarantees.

Instructions:

aiozeroconf -s _mediaremotetv._tcp.local.

Browsing services, press Ctrl-C to exit...

Service Vardagsrum._mediaremotetv._tcp.local. of type _mediaremotetv._tcp.local. state changed: ServiceStateChange.Added
  IPv4 Address: XXX
  IPv6 Address: YYY
  Weight: 0, priority: 0
  Server: Vardagsrum-2.local.
  Properties are:
    ModelName: AppleΒ TV
    AllowPairing: YES

Can I do EVEN more? If you are an experienced user, you can do some packet interception and look the broadcasted data. I have taken dumps with tcpdump (and also looked at zeroconf debug data) when no devices were found by pyatv and made the conclusion that no response was received at all (on network layer) when this happened. It basically means that no response was received by python-zeroconf, so it wasn't just ignored for some unknown reason. It would be interesting to tap in on network traffic from another computer (with wireshark or so) and see if the expected data it received there or not. It would also be interesting to compare what python-zeroconf does, network-wise, and compare to other tools (like avahi and dns-sd, mentioned earlier). Maybe something is not configured correctly?

I leave this as an open bullet for experienced used to fiddle with.

postlund commented 5 years ago

One guess as to why dns-sd and avahi works reliably is caching. Since they both have daemons running they can cache entries over time. It's still however peculiar why devices sometimes don't answer queries.

raufis27 commented 5 years ago

So far what I found out, is that this error valid until I reboot AppleTV. Then it works for some time and stops. Scanning always finds device in the network, I have 6 Apple TVs, different generation.

postlund commented 5 years ago

When you say "it stops", do you mean that the device isn't found by scanning or something else?

A theory I have is that it maybe works if pyatv publishes a zeroconf service itself, so that other nodes start broadcasting their services. No idea if it works, but worth a shot. You simply run this script when a device is not found by atvremote scan:


#!/usr/bin/env python3"
import argparse
import logging
import socket
from time import sleep
from typing import cast

from zeroconf import ServiceInfo, ServiceBrowser, ServiceStateChange, Zeroconf

def on_service_state_change(
    zeroconf: Zeroconf, service_type: str, name: str, state_change: ServiceStateChange
) -> None:
    print("Service %s of type %s state changed: %s" % (name, service_type, state_change))

    if state_change is ServiceStateChange.Added:
        info = zeroconf.get_service_info(service_type, name)
        if info:
            addresses = ["%s:%d" % (socket.inet_ntoa(addr), cast(int, info.port)) for addr in info.addresses]
            print("  Addresses: %s" % ", ".join(addresses))
            print("  Weight: %d, priority: %d" % (info.weight, info.priority))
            print("  Server: %s" % (info.server,))
            if info.properties:
                print("  Properties are:")
                for key, value in info.properties.items():
                    print("    %s: %s" % (key, value))
            else:
                print("  No properties")
        else:
            print("  No info")
        print('\n')

if __name__ == '__main__':
    logging.basicConfig(level=logging.WARN)

    zeroconf = Zeroconf()
    browser = ServiceBrowser(zeroconf, "_mediaremotetv._tcp.local.", handlers=[on_service_state_change])

    info = ServiceInfo(
        "_http._tcp.local.",
        "test._http._tcp.local.",
        addresses=[socket.inet_aton("127.0.0.1")],
        port=80,
        properties={"test":"test"},
        server="testserver.local.",
    )

    print("Press Ctrl-C to exit...")
    zeroconf.register_service(info)
    try:
        while True:
            sleep(0.1)
    except KeyboardInterrupt:
        pass
    finally:
        print("Unregistering...")
        zeroconf.unregister_service(info)
        zeroconf.close()

Hopefully it shows up.

raufis27 commented 5 years ago

Just to clarify, scanning works, there is no problem. When I do pyatv scan, I can see device online, BUT running command against device which is online results : no device found.

postlund commented 5 years ago

Right, then I'm with you. That's just a thing with how atvremote works. I'll see if I can push a better protocol selection method when --protocol isn't specified. It's just a few lines.

postlund commented 5 years ago

I did manage to end up in the situation so that my laptop did not find any Apple TV and by looking at network data (with tcpdump on another machine as well as wireshark on my laptop) I can conclude that the Apple TV did not respond to the lookup. Maybe it doesn't always respond?

postlund commented 5 years ago

According to the scan result, port 56047 is used but you override that with 49152. That's why it doesn't work (you should not specify address nor port, just id or you will likely end up with these kinds of problems).

raufis27 commented 5 years ago

Sorry circled through commands and didn't notice the port option I was trying earlier. Please ignore.

raufis27 commented 5 years ago

Another interesting fact: Apple Remote App has the same problem. It can't find Apple TV sometimes. I see it offline when it is running. But Apple TV widget from control center works fine. So I guess this is TVOS bug.

thowi commented 5 years ago

Hi, glad I found this!

I was happily using this as part of Home Assistant, but recently the integration for my Apple TV stopped working. Possibly after a system update of the Apple TV. I've got an Apple TV HD (A1625) with TVOS 13.0 (17J586). Home Assistant runs on Ubuntu 18.04. I've got a Mac, too.

Here's what I tried:

Browsing services, press Ctrl-C to exit...

Service Apple TV._mediaremotetv._tcp.local. of type _mediaremotetv._tcp.local. state changed: ServiceStateChange.Added IPv4 Address: 192.168.1.101:49152 IPv6 Address: fe80::1499:88f0:8986:3589:49152 Weight: 0, priority: 0 Server: Apple-TV.local. Properties are: ModelName: AppleΒ TV AllowPairing: YES

* Ran the longer debug script from [above](#issuecomment-541824271), which also seems to find it:

$ ./pyatv_debug_scan2.py Press Ctrl-C to exit... Service Apple TV._mediaremotetv._tcp.local. of type _mediaremotetv._tcp.local. state changed: ServiceStateChange.Added Addresses: 192.168.1.101:49152 Weight: 0, priority: 0 Server: Apple-TV.local. Properties are: b'ModelName': b'Apple\xc2\xa0TV' b'AllowPairing': b'YES' b'BluetoothAddress': b'\xac\xbc2j\xb7\xe4' b'macAddress': b'ac:bc:32:6a:b7:e5' b'Name': b'Apple TV' b'UniqueIdentifier': b'D2A803C3-1555-406F-8E24-6FAA75D5D52E' b'SystemBuildVersion': b'17J586' b'LocalAirPlayReceiverPairingIdentity': b'D0052374-93D7-4836-8565-1DBF61D487E5'



Please let me know if there's anything else I can do to help resolve this!

Thanks!
postlund commented 5 years ago

The reason for it not working in Home Assistant is because the support is broken. I need to complete support for MRP in pyatv and fix the integration in HA. The work is progressing at slow pace, but I'm working on it. You can see the progress in all the open issues.

From what I can see in your report, nothing looks anything out of the ordinary. That is good. Thank you for reporting! 😊

thowi commented 5 years ago

From what I can see in your report, nothing looks anything out of the ordinary. That is good.

Well, atvremote scan and the short scan script don't find my ATV. I guess that's not a good sign, is it?

postlund commented 5 years ago

From what I can see in your report, nothing looks anything out of the ordinary. That is good.

Well, atvremote scan and the short scan script don't find my ATV. I guess that's not a good sign, is it?

Yes, you are right. Bad on my part! :wink: But if I understand you correctly, aiozeroconf worked on the same machine as pyatv did not?

thowi commented 5 years ago

Correct, atvremote scan and the short script don't work. While, avahi-browse, aiozeroconf, and the longer script that you posted work. All on Ubuntu 18.04.

postlund commented 5 years ago

Correct, atvremote scan and the short script don't work. While, avahi-browse, aiozeroconf, and the longer script that you posted work. All on Ubuntu 18.04.

Really great input, thanks a lot! πŸ‘

ff4500 commented 5 years ago

Adding my two cents, since I've been trying to figure out what was up with this myself (until I ran across this issue):

Anything I can do to help, I'm happy to jump in to help test. I have 2 ATVs, one an original ATV4 (HD) and an ATV 4k, if it matters. Thanks for looking into this for sure!

The-sultan commented 5 years ago

Just bought an Apple TV 4k. Can't find it with scan. Avahi-browse is finding it (running on same raspi as home assistant) and my mac in same network can also find it with dns-sd. I tried setting home sharing off then on with a restart in the middle to no avail. Let me know if there's anything I can help with (like testing a WIP version of this or giving you any other info). Thanks!

postlund commented 5 years ago

@ff4500 Thank you, great input! That is all I need at the moment! πŸ‘

@The-sultan Awesome! Would be great if you could try the aiozeroconf command explained above as well. Seems like the best shot at the moment.

jconly commented 5 years ago

Latest tvOS, ended up down this road scanning, trying to add to Home Assistant. Single Apple TV

My results:

MacOS

dns-sd -B _mediaremotetv._tcp Browsing for _mediaremotetv._tcp DATE: ---Fri 25 Oct 2019--- 21:45:15.354 ...STARTING... Timestamp A/R Flags if Domain Service Type Instance Name 21:45:15.355 Add 3 15 local. _mediaremotetv._tcp. Justins Apple TV 21:45:15.355 Add 2 22 local. _mediaremotetv._tcp. Justins Apple TV

Ubuntu

avahi-browse -d local _mediaremotetv._tcp

  • enp0s25 IPv4 Justins Apple TV _mediaremotetv._tcp local
  • enp0s25 IPv6 Justins Apple TV _mediaremotetv._tcp local
postlund commented 5 years ago

I took a stab at migrating to aiozeroconf, perhaps it works better. If some of you that have problems try #224 and report back, that would be awesome! 😎

postlund commented 5 years ago

You need to use the code from the PR, it's not on master yet (and avoid specifying --address, --id should suffice).

raufis27 commented 5 years ago

Sorry, what is the command to upgrade from PR ?

postlund commented 5 years ago

Sorry, what is the command to upgrade from PR ?

I guess it depends on how you run. Did you clone from GitHub? If that's the case, it should work with:

git fetch origin
git checkout -b aiozeroconf origin/aiozeroconf
python setup.py develop
postlund commented 5 years ago

I used pip install.

Try this:

pip install git+https://github.com/postlund/pyatv.git@aiozeroconf
postlund commented 5 years ago

The output doesn't match my changes, so you are running the old version. Try pip uninstall pyatv a few time and then install via the command above again.

raufis27 commented 5 years ago

I just updated AppleTV to 13.2, obviously it restarted and so far everything works fine. I'll report back tomorrow. Thank you.

postlund commented 5 years ago

Don't undertans

Looks like update didn't fix the issue. ` atvremote --id XXXXXXXXX --protocol mrp play_state ERROR: Exception in callback _SelectorDatagramTransport._read_ready() handle: <Handle _SelectorDatagramTransport._read_ready()> Traceback (most recent call last): File "/usr/lib/python3.6/asyncio/events.py", line 145, in _run self._callback(*self._args) File "/usr/lib/python3.6/asyncio/selector_events.py", line 1079, in _read_ready self._protocol.datagram_received(data, addr) File "/usr/local/lib/python3.6/dist-packages/aiozeroconf/aiozeroconf.py", line 1124, in datagram_received self.zc.handle_response(msg) File "/usr/local/lib/python3.6/dist-packages/aiozeroconf/aiozeroconf.py", line 2014, in handle_response self.update_record(now, record) File "/usr/local/lib/python3.6/dist-packages/aiozeroconf/aiozeroconf.py", line 1995, in update_record listener.update_record(self, now, rec) File "/usr/local/lib/python3.6/dist-packages/aiozeroconf/aiozeroconf.py", line 1211, in update_record self.listener.remove_service(self.zc, self.type, record.alias) AttributeError: '_ServiceListener' object has no attribute 'remove_service' Traceback (most recent call last): File "/usr/local/lib/python3.6/dist-packages/pyatv/main.py", line 492, in _run_application return await cli_handler(loop) File "/usr/local/lib/python3.6/dist-packages/pyatv/main.py", line 314, in cli_handler return await _handle_commands(args, loop) File "/usr/local/lib/python3.6/dist-packages/pyatv/main.py", line 407, in _handle_commands ret = await _handle_device_command(args, cmd, atv, loop) File "/usr/local/lib/python3.6/dist-packages/pyatv/main.py", line 439, in _handle_device_command playing_resp = await atv.metadata.playing() File "/usr/local/lib/python3.6/dist-packages/pyatv/mrp/init.py", line 250, in playing await self.protocol.start() File "/usr/local/lib/python3.6/dist-packages/pyatv/mrp/protocol.py", line 58, in start await self.connection.connect() File "/usr/lib/python3.6/asyncio/base_events.py", line 783, in create_connection raise exceptions[0] File "/usr/lib/python3.6/asyncio/base_events.py", line 770, in create_connection yield from self.sock_connect(sock, address) File "/usr/lib/python3.6/asyncio/selector_events.py", line 450, in sock_connect return (yield from fut) File "/usr/lib/python3.6/asyncio/selector_events.py", line 480, in _sock_connect_cb raise OSError(err, 'Connect call failed %s' % (address,)) ConnectionRefusedError: [Errno 111] Connect call failed ('10.10.10.10', 50330)

An error occurred, full stack trace above`

atvremote --id xxxxx --protocol mrp play_state ERROR: Could not find any Apple TV on current network

Don't understand why you get connection refused. Can you verify address and port with some other zeroconf tool?

Also, can you try with long timeout: atvremote -i XXX -t 99 --debug --protocol mrp playing

postlund commented 5 years ago

If I don't specify protocol I don't get an error: atvremote --address xxxxxx playing Media type: Unknown Play state: No media Shuffle: False But commands (menu, stop ... ) don't work

Since you have multiple devices and I can't deduct which id you are specifying, I can't really tell what happens. But if you don't specify protocol it will choose MRP if available, otherwise DMAP.

Since play state "No media" is displayed here I can at least say that you are not connected to "Living room". Only DMAP implements that state. It helps if you specify --debug.

raufis27 commented 5 years ago

I am testing Apple TV 4 with TV OS 13 only, all other Apple TVs are Gen 3. Only TV OS 13 has this issue. I think the problem is MRP protocol. Atvremote scan command doesn't detect MRP protocol running on ATV4. If I restart ATV, I see that MRP is available, it works fine for about 2-3 hours then I face this issue again. Thank you so much for your patience, at this point I am ready to give up. It is not mission critical issue for me, I was just trying to help you with troubleshooting. But looks like I am alone with this problem, so don't wanna waste your time. Thank you.

postlund commented 5 years ago

I am testing Apple TV 4 with TV OS 13 only, all other Apple TVs are Gen 3. Only TV OS 13 has this issue. I think the problem is MRP protocol. Atvremote scan command doesn't detect MRP protocol running on ATV4. If I restart ATV, I see that MRP is available, it works fine for about 2-3 hours then I face this issue again. Thank you so much for your patience, at this point I am ready to give up. It is not mission critical issue for me, I was just trying to help you with troubleshooting. But looks like I am alone with this problem, so don't wanna waste your time. Thank you.

I find this to be an interesting issue, likely related to zeroconf problems that a lot of other users see. So I'm very keen on figuring out what is happening 😊 Since you say that it works for a few hours... my guess is that pyatv picks up the wrong port or something. Can't see how that could happen. But that is why it would be good if you could verify what some other browser reports, like Avahi. Does the Remote app work on your phone btw? Just to be certain that it's not completely broken.

If you do a scan with atvremote first to get the MRP port. Then you run:

avahi-browse -prl _mediaremotetv._tcp

You should see the port listed in the output for your ATV. Do they match?

I shall add the missing remove_service method to get rid of that exception.

postlund commented 5 years ago

Just pushed the missing remove_service method, please re-install with pip again.

raufis27 commented 5 years ago

I think I found the problem. I also couldn't get Apple Remote app to work. Unpaired my phone from AppleTV and couldn't add it back. It was acting exactly as atvremote. Using Remote App I could see Apple TV, but as soon as I was trying to pair ATV was disappearing from list. My living room Apple TV is hard wired, so I disconnected it from ethernet and connected to wifi network. After I was able to pair with my phone and atvremote. I switched back to ethernet and everything works as it should, so far. Have to say that this ATV was hardwired from day 1 (2 years now) and nothing has changed in my networking. I faced this issue when ATV was updated to TV OS. So I don't know is it me or Apple. I'll report back in 24 hours. PS. ubuntu server where I have atvremote installed also hardwired.

thowi commented 5 years ago

For me the patched version works better:

$ pip install git+https://github.com/postlund/pyatv.git@aiozeroconf
$ atvremote scan
Scan Results
========================================
       Name: Balcony
    Address: 192.168.1.155
Identifiers:
 - 34:7E:5C:F2:85:18
Services:
 - Protocol: AirPlay, Port: 7000

       Name: Apple TV
    Address: 192.168.1.101
Identifiers:
 - D2A803C3-1555-406F-8E24-6FAA75D5D52E
 - AC:BC:32:6A:B7:E5
Services:
 - Protocol: MRP, Port: 49152, Credentials: None
 - Protocol: AirPlay, Port: 7000
$

"Balcony" is a Sonos speaker (well, IKEA Symfonisk, to be precise). But my Apple TV is now discovered, which is nice!

It is not discovered with the mainline version of atvremote.

raufis27 commented 5 years ago

For me the patched version works better:

$ pip install git+https://github.com/postlund/pyatv.git@aiozeroconf
$ atvremote scan
Scan Results
========================================
       Name: Balcony
    Address: 192.168.1.155
Identifiers:
 - 34:7E:5C:F2:85:18
Services:
 - Protocol: AirPlay, Port: 7000

       Name: Apple TV
    Address: 192.168.1.101
Identifiers:
 - D2A803C3-1555-406F-8E24-6FAA75D5D52E
 - AC:BC:32:6A:B7:E5
Services:
 - Protocol: MRP, Port: 49152, Credentials: None
 - Protocol: AirPlay, Port: 7000
$

"Balcony" is a Sonos speaker (well, IKEA Symfonisk, to be precise). But my Apple TV is now discovered, which is nice!

It is not discovered with the mainline version of atvremote.

Could you please check if you can get playing media title ?

thowi commented 5 years ago
$ atvremote --address AC:BC:32:6A:B7:E5 playing
Media type: Unknown
Play state: Paused
$

I'm not at home until Sunday, so I can't start playing something at the moment, unfortunately.

raufis27 commented 5 years ago

I see. No matter what I play I see same paused message and no title for playing media.

chicaneau commented 5 years ago

I had a similar experience to everyone here. the old atvremote app returned nothing for my apple-tv 4k, however worked for my old apple-tv 3 and always.

After updating with "pip install git+https://github.com/postlund/pyatv.git@aiozeroconf" atvremote now returns as below

Scan Results
========================================
       Name: Loungeroom
    Address: 10.0.3.2
Identifiers:
 - 80FF1339-3458-4FF9-A96E-E6EF8770DDFD
 - 40:CB:C0:B9:93:XX
Services:
 - Protocol: MRP, Port: 49152, Credentials: None
 - Protocol: AirPlay, Port: 7000

       Name: Gym/Spare
    Address: 10.0.0.12
Identifiers:
 - 70:56:81:EF:4A:XX
 - D930EF6660243CC8
Services:
 - Protocol: AirPlay, Port: 7000
 - Protocol: DMAP, Port: 3689, Credentials: 00000000-0c8e-2f07-0bf2-e9b912d84dee

If i try to use --address argument as @thowi did above, i just receive an error. It appears that the new app isn't pulling the credentials.. as you can see none as the result.

I tried with MAC and IP and neither work. I just get

ERROR: Found more than one Apple TV; specify one using --address and --device-credentials

Using -i argument i managed to get a response with no credential, see below

xxx@ubuntuvm2:~$ atvremote -i 40:CB:C0:B9:93:XX playing
Media type: Unknown
Play state: Paused
xxx@ubuntuvm2:~$ atvremote -i 40:CB:C0:B9:93:XX playing
Media type: Unknown
Play state: Playing
postlund commented 5 years ago

I see. No matter what I play I see same paused message and no title for playing media.

The implementation for metadata needs a bit of love, so I wouldn't be surprised if that's the case. Will look into that later once I have the other stuff in place. If you could provide a debug log when something is playing, that would help. I created a new issue for this, #226, that you can report in.

postlund commented 5 years ago

I had a similar experience to everyone here. the old atvremote app returned nothing for my apple-tv 4k, however worked for my old apple-tv 3 and always.

After updating with "pip install git+https://github.com/postlund/pyatv.git@aiozeroconf" atvremote now returns as below

Scan Results
========================================
       Name: Loungeroom
    Address: 10.0.3.2
Identifiers:
 - 80FF1339-3458-4FF9-A96E-E6EF8770DDFD
 - 40:CB:C0:B9:93:XX
Services:
 - Protocol: MRP, Port: 49152, Credentials: None
 - Protocol: AirPlay, Port: 7000

       Name: Gym/Spare
    Address: 10.0.0.12
Identifiers:
 - 70:56:81:EF:4A:XX
 - D930EF6660243CC8
Services:
 - Protocol: AirPlay, Port: 7000
 - Protocol: DMAP, Port: 3689, Credentials: 00000000-0c8e-2f07-0bf2-e9b912d84dee

If i try to use --address argument as @thowi did above, i just receive an error. It appears that the new app isn't pulling the credentials.. as you can see none as the result.

I tried with MAC and IP and neither work. I just get

ERROR: Found more than one Apple TV; specify one using --address and --device-credentials

Using -i argument i managed to get a response with no credential, see below

xxx@ubuntuvm2:~$ atvremote -i 40:CB:C0:B9:93:XX playing
Media type: Unknown
Play state: Paused
xxx@ubuntuvm2:~$ atvremote -i 40:CB:C0:B9:93:XX playing
Media type: Unknown
Play state: Playing

This is actually great! Credentials for MRP is something that you have to provide yourself (it will not be found via a scan), but basic metadata should be available still. The instructions here are wrong, that's why it doesn't work for you πŸ˜‰ I'm in the middle of changing lots of stuff. But using -I is correct, skip specifying address.

postlund commented 5 years ago

I merged the aiozeroconf PR now, so it's on master. Lets try it out for a while and see how it goes. Please feel free to report results back, I'm still interested in how well it works πŸ˜„

nurikk commented 5 years ago

I merged the aiozeroconf PR now, so it's on master. Lets try it out for a while and see how it goes. Please feel free to report results back, I'm still interested in how well it works πŸ˜„

Checked few minutes ago, works for me. But homeassistant integration uses quite outdated version 0.3.13, simple bumping pyatv version to latest(4x) doesn't work due to backward compatibility issues

postlund commented 5 years ago

I merged the aiozeroconf PR now, so it's on master. Lets try it out for a while and see how it goes. Please feel free to report results back, I'm still interested in how well it works πŸ˜„

Checked few minutes ago, works for me. But homeassistant integration uses quite outdated version 0.3.13, simple bumping pyatv version to latest(4x) doesn't work due to backward compatibility issues

Great, thanks for confirmation! 😊 HA integration is documented in #209.

raufis27 commented 5 years ago

My Apple TV stopped responding to remote app and atvremote again. I'll move it to wifi to see if it helps.

chicaneau commented 5 years ago

Hey @postlund I have successfully run atvremote whilst playing a video, here is the debug log for you

Debug Log

postlund commented 5 years ago

Thank you @chicaneau! Nothing really interesting there, will definitely have to look into if new fields have been added to messages and my connection flow.

postlund commented 5 years ago

Hey @postlund I have successfully run atvremote whilst playing a video, here is the debug log for you

Debug Log

I raw-decoded the "big bunch of data" containing SET_STATE_MESSAGE and see a bunch of missing fields:

Raw: 08112000b2010408011001

Decoded
1: 17
4: 0
22 {
  1: 1
  2: 1
}
----------------------------------------
Raw: 080420004ab40112450a04080610010a04080510010a0d081310002100000000000024400a0d08121000210000000000003e400a04080310010a04080110010a04080210010a07082d10018001001a020800300242004a5a0a140801120a4c6f756e6765726f6f6d18cc86bde204121508bf011210636f6d2e706c65786170702e706c65781a2b0a194d6564696152656d6f74652d44656661756c74506c61796572120e44656661756c7420506c61796572591003652194b4c141

Decoded
1: 4
4: 0
9 {
  2 {
    1 {
      1: 6
      2: 1
    }
    1 {
      1: 5
      2: 1
    }
    1 {
      1: 19
      2: 0
      4: 0x4024000000000000
    }
    1 {
      1: 18
      2: 0
      4: 0x403e000000000000
    }
    1 {
      1: 3
      2: 1
    }
    1 {
      1: 1
      2: 1
    }
    1 {
      1: 2
      2: 1
    }
    1 {
      1: 45
      2: 1
      16: 0
    }
  }
  3 {
    1: 0
  }
  6: 2
  8: ""
  9 {
    1 {
      1: 1
      2: "Loungeroom"
      3: 1280262988
    }
    2 {
      1: 191
      2: "com.plexapp.plex"
    }
    3 {
      1: "MediaRemote-DefaultPlayer"
      2: "Default Player"
    }
  }
  11: 0x41c1b49421650310
}
----------------------------------------
Raw: 080420004a930f12001a950e080012f20c0a1c636f6d2e6170706c652e61766b69742e3439312e646339353864333912e8030a1b53313a204531202245766572797468696e672049732046696e652271ac1c5a643b6f9640980101a80101b00101b80100fa010a696d6167652f6a7065679902b26113ba9f238340a80200bd020000803fe2020838303139313835328004029a04e40262706c6973743030d4010203040506070a582476657273696f6e592461726368697665725424746f7058246f626a6563747312000186a05f100f4e534b657965644172636869766572d1080954726f6f748001a50b0c15161755246e756c6cd30d0e0f101214574e532e6b6579735a4e532e6f626a656374735624636c617373a1118002a113800380045f103041564d6564696152656d6f74654d616e616765724e6f77506c6179696e67496e666f4861734465736372697074696f6e1001d218191a1b5a24636c6173736e616d655824636c61737365735f10134e534d757461626c6544696374696f6e617279a31a1c1d5c4e5344696374696f6e617279584e534f626a65637400080011001a00240029003200370049004c005100530059005f0066006e007900800082008400860088008a00bd00bf00c400cf00d800ee00f200ff0000000000000201000000000000001e00000000000000000000000000000108d1049357c3096fb5c141d9042daf48bb3ab5c1419805b99ad6e4fdffffffff012aed0308001a4b08001202656e1a1b7075626c69632e6d61696e2d70726f6772616d2d636f6e74656e742207456e676c6973682a1d456e676c697368205b4f726967696e616c5d2d656e2d456e676c6973681aa50108001202656e1a187075626c69632e617578696c696172792d636f6e74656e741a247075626c69632e6163636573736962696c6974792e6465736372696265732d766964656f221e456e676c697368202d20417564696f204465736372697074696f6e2041442a3d456e676c697368202d20417564696f204465736372697074696f6e2d656e2d456e676c697368202d20417564696f204465736372697074696f6e2041441a3a0800120266721a187075626c69632e617578696c696172792d636f6e74656e7422064672656e63682a104672656e63682d66722d4672656e63681a3a08001202706c1a187075626c69632e617578696c696172792d636f6e74656e742206506f6c6973682a10506f6c6973682d706c2d506f6c6973681a3d0800120265731a187075626c69632e617578696c696172792d636f6e74656e7422075370616e6973682a125370616e6973682d65732d5370616e6973681a3d0800120274721a187075626c69632e617578696c696172792d636f6e74656e7422075475726b6973682a125475726b6973682d74722d5475726b6973682aa90408011a0c080112085f5f4155544f5f5f1aa80108011202656e1a1b7075626c69632e6d61696e2d70726f6772616d2d636f6e74656e741a2e7075626c69632e6163636573736962696c6974792e7472616e736372696265732d73706f6b656e2d6469616c6f671a2e7075626c69632e6163636573736962696c6974792e6465736372696265732d6d757369632d616e642d736f756e64220b456e676c697368205344482a16456e676c6973682d656e2d456e676c697368205344481a6d080112077a682d48616e731a1b7075626c69632e6d61696e2d70726f6772616d2d636f6e74656e7422134368696e6573652c2053696d706c69666965642a2e53696d706c6966696564204368696e6573652d7a682d48616e732d4368696e6573652c2053696d706c69666965641a70080112077a682d48616e741a1b7075626c69632e6d61696e2d70726f6772616d2d636f6e74656e7422144368696e6573652c20547261646974696f6e616c2a30547261646974696f6e616c204368696e6573652d7a682d48616e742d4368696e6573652c20547261646974696f6e616c1a400801120269741a1b7075626c69632e6d61696e2d70726f6772616d2d636f6e74656e7422074974616c69616e2a124974616c69616e2d69742d4974616c69616e1a490801120276691a1b7075626c69632e6d61696e2d70726f6772616d2d636f6e74656e74220a566965746e616d6573652a18566965746e616d6573652d76692d566965746e616d657365324b08001202656e1a1b7075626c69632e6d61696e2d70726f6772616d2d636f6e74656e742207456e676c6973682a1d456e676c697368205b4f726967696e616c5d2d656e2d456e676c697368223d506c61796261636b5175657565496e76616c69646174696f6e31344245354634342d453342372d343931392d384444302d4533334434413544384430382a5d0a140801120a4c6f756e6765726f6f6d18cc86bde204121808eb031213636f6d2e6e6574666c69782e4e6574666c69781a2b0a194d6564696152656d6f74652d44656661756c74506c61796572120e44656661756c7420506c617965722a074e6574666c697830024204080110014a5d0a140801120a4c6f756e6765726f6f6d18cc86bde204121808eb031213636f6d2e6e6574666c69782e4e6574666c69781a2b0a194d6564696152656d6f74652d44656661756c74506c61796572120e44656661756c7420506c6179657259e3fae5126fb5c141

Decoded
1: 4
4: 0
9 {
  2: ""
  3 {
    1: 0
    2 {
      1: "com.apple.avkit.491.dc958d39"
      2 {
        1: "S1: E1 \"Everything Is Fine\""
        14: 0x40966f3b645a1cac
        19: 1
        21: 1
        22: 1
        23: 0
        31: "image/jpeg"
        35: 0x4083239fba1361b2
        37: 0
        39: 0x3f800000
        44: "80191852"
        64: 2
        67: "bplist00\324\001\002\003\004\005\006\007\nX$versionY$archiverT$topX$objects\022\000\001\206\240_\020\017NSKeyedArchiver\321\010\tTroot\200\001\245\013\014\025\026\027U$null\323\r\016\017\020\022\024WNS.keysZNS.objectsV$class\241\021\200\002\241\023\200\003\200\004_\0200AVMediaRemoteManagerNowPlayingInfoHasDescription\020\001\322\030\031\032\033Z$classnameX$classes_\020\023NSMutableDictionary\243\032\034\035\\NSDictionaryXNSObject\000\010\000\021\000\032\000$\000)\0002\0007\000I\000L\000Q\000S\000Y\000_\000f\000n\000y\000\200\000\202\000\204\000\206\000\210\000\212\000\275\000\277\000\304\000\317\000\330\000\356\000\362\000\377\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\036\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\010"
        74: 0x41c1b56f09c35793
        75: 0x41c1b53abb48af2d
        83: 18446744073115372857
      }
      5 {
        1: 0
        3 {
          1: 0
          2: "en"
          3: "public.main-program-content"
          4: "English"
          5: "English [Original]-en-English"
        }
        3 {
          1: 0
          2: "en"
          3: "public.auxiliary-content"
          3: "public.accessibility.describes-video"
          4: "English - Audio Description AD"
          5: "English - Audio Description-en-English - Audio Description AD"
        }
        3 {
          1: 0
          2: "fr"
          3: "public.auxiliary-content"
          4: "French"
          5: "French-fr-French"
        }
        3 {
          1: 0
          2 {
            14: 108
          }
          3: "public.auxiliary-content"
          4: "Polish"
          5: "Polish-pl-Polish"
        }
        3 {
          1: 0
          2: "es"
          3: "public.auxiliary-content"
          4: "Spanish"
          5: "Spanish-es-Spanish"
        }
        3 {
          1: 0
          2: "tr"
          3: "public.auxiliary-content"
          4: "Turkish"
          5: "Turkish-tr-Turkish"
        }
      }
      5 {
        1: 1
        3 {
          1: 1
          2: "__AUTO__"
        }
        3 {
          1: 1
          2: "en"
          3: "public.main-program-content"
          3: "public.accessibility.transcribes-spoken-dialog"
          3: "public.accessibility.describes-music-and-sound"
          4: "English SDH"
          5: "English-en-English SDH"
        }
        3 {
          1: 1
          2: "zh-Hans"
          3: "public.main-program-content"
          4: "Chinese, Simplified"
          5: "Simplified Chinese-zh-Hans-Chinese, Simplified"
        }
        3 {
          1: 1
          2: "zh-Hant"
          3: "public.main-program-content"
          4: "Chinese, Traditional"
          5: "Traditional Chinese-zh-Hant-Chinese, Traditional"
        }
        3 {
          1: 1
          2: "it"
          3: "public.main-program-content"
          4: "Italian"
          5: "Italian-it-Italian"
        }
        3 {
          1: 1
          2: "vi"
          3: "public.main-program-content"
          4: "Vietnamese"
          5: "Vietnamese-vi-Vietnamese"
        }
      }
      6 {
        1: 0
        2: "en"
        3: "public.main-program-content"
        4: "English"
        5: "English [Original]-en-English"
      }
    }
    4: "PlaybackQueueInvalidation14BE5F44-E3B7-4919-8DD0-E33D4A5D8D08"
    5 {
      1 {
        1: 1
        2: "Loungeroom"
        3: 1280262988
      }
      2 {
        1: 491
        2: "com.netflix.Netflix"
      }
      3 {
        1: "MediaRemote-DefaultPlayer"
        2: "Default Player"
      }
    }
  }
  5: "Netflix"
  6: 2
  8 {
    1: 1
    2: 1
  }
  9 {
    1 {
      1: 1
      2: "Loungeroom"
      3: 1280262988
    }
    2 {
      1: 491
      2: "com.netflix.Netflix"
    }
    3 {
      1: "MediaRemote-DefaultPlayer"
      2: "Default Player"
    }
  }
  11: 0x41c1b56f12e5fae3
}
----------------------------------------
Raw: 08372000da03260a2408eb031213636f6d2e6e6574666c69782e4e6574666c697820f5033a074e6574666c6978

Decoded
1: 55
4: 0
59 {
  1 {
    1: 491
    2: "com.netflix.Netflix"
    4: 501
    7: "Netflix"
  }
}
----------------------------------------
Raw: 080420004a8a0512330a0d081310012100000000000024400a0d081210012100000000000024400a04080110010a04080210010a07082d10018001001ae503080012e0030a2437453237344345422d433843302d343345382d423234432d37363545333444393141433312b7030a175332204535202d20546865204b61726d616e204c696e6571000000000020a440980101fa010a696d6167652f6a70656799020000000000000000bd020000803fe2022437453237344345422d433843302d343345382d423234432d3736354533344439314143338004018804049a04850262706c6973743030d4010203040506070a582476657273696f6e592461726368697665725424746f7058246f626a6563747312000186a05f100f4e534b657965644172636869766572d1080954726f6f748001a30b0c1355246e756c6cd30d0e0f101112574e532e6b6579735a4e532e6f626a656374735624636c617373a0a08002d2141516175a24636c6173736e616d655824636c61737365735f10134e534d757461626c6544696374696f6e617279a31618195c4e5344696374696f6e617279584e534f626a65637408111a24293237494c5153575d646c777e7f808287929bb1b5c20000000000000101000000000000001a000000000000000000000000000000cbd104825410266fb5c141d904b98b10266fb5c14182052861633538336462316234353830363137663338303462323736393132383639613533383630353030300142004a5e0a140801120a4c6f756e6765726f6f6d18cc86bde204121908f7021214656d62792e6d656469612e656d62792d74766f731a2b0a194d6564696152656d6f74652d44656661756c74506c61796572120e44656661756c7420506c6179657259e3c40d266fb5c141

Decoded
1: 4
4: 0
9 {
  2 {
    1 {
      1: 19
      2: 1
      4: 0x4024000000000000
    }
    1 {
      1: 18
      2: 1
      4: 0x4024000000000000
    }
    1 {
      1: 1
      2: 1
    }
    1 {
      1: 2
      2: 1
    }
    1 {
      1: 45
      2: 1
      16: 0
    }
  }
  3 {
    1: 0
    2 {
      1: "7E274CEB-C8C0-43E8-B24C-765E34D91AC3"
      2 {
        1: "S2 E5 - The Karman Line"
        14: 0x40a4200000000000
        19: 1
        31: "image/jpeg"
        35: 0x0000000000000000
        39: 0x3f800000
        44: "7E274CEB-C8C0-43E8-B24C-765E34D91AC3"
        64: 1
        65: 4
        67: "bplist00\324\001\002\003\004\005\006\007\nX$versionY$archiverT$topX$objects\022\000\001\206\240_\020\017NSKeyedArchiver\321\010\tTroot\200\001\243\013\014\023U$null\323\r\016\017\020\021\022WNS.keysZNS.objectsV$class\240\240\200\002\322\024\025\026\027Z$classnameX$classes_\020\023NSMutableDictionary\243\026\030\031\\NSDictionaryXNSObject\010\021\032$)27ILQSW]dlw~\177\200\202\207\222\233\261\265\302\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\032\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\313"
        74: 0x41c1b56f26105482
        75: 0x41c1b56f26108bb9
        80: "ac583db1b4580617f3804b276912869a53860500"
      }
    }
  }
  6: 1
  8: ""
  9 {
    1 {
      1: 1
      2: "Loungeroom"
      3: 1280262988
    }
    2 {
      1: 375
      2: "emby.media.emby-tvos"
    }
    3 {
      1: "MediaRemote-DefaultPlayer"
      2: "Default Player"
    }
  }
  11: 0x41c1b56f260dc4e3
}
----------------------------------------
Raw: 082e200092031b0a1908f7021214656d62792e6d656469612e656d62792d74766f73

Decoded
1: 46
4: 0
50 {
  1 {
    1: 375
    2: "emby.media.emby-tvos"
  }
}
----------------------------------------
postlund commented 5 years ago

Here is an example with better definitions as well:

type: SET_STATE_MESSAGE
priority: 0
[setStateMessage] {
  supportedCommands {
  }
  playbackQueue {
    location: 0
    contentItems {
      identifier: "com.apple.avkit.491.dc958d39"
      metadata {
        title: "S1: E1 \"Everything Is Fine\""
        duration: 1435.808
        artworkAvailable: true
        infoAvailable: true
        languageOptionsAvailable: true
        numberOfSections: 0
        artworkMIMEType: "image/jpeg"
        elapsedTime: 612.45299163
        isAlwaysLive: false
        playbackRate: 1.0
        contentIdentifier: "80191852"
        mediaType: 2
        nowPlayingInfoData: "bplist00\324\001\002\003\004\005\006\007\nX$versionY$archiverT$topX$objects\022\000\001\206\240_\020\017NSKeyedArchiver\321\010\tTroot\200\001\245\013\014\025\026\027U$null\323\r\016\017\020\022\024WNS.keysZNS.objectsV$class\241\021\200\002\241\023\200\003\200\004_\0200AVMediaRemoteManagerNowPlayingInfoHasDescription\020\001\322\030\031\032\033Z$classnameX$classes_\020\023NSMutableDictionary\243\032\034\035\\NSDictionaryXNSObject\000\010\000\021\000\032\000$\000)\0002\0007\000I\000L\000Q\000S\000Y\000_\000f\000n\000y\000\200\000\202\000\204\000\206\000\210\000\212\000\275\000\277\000\304\000\317\000\330\000\356\000\362\000\377\000\000\000\000\000\000\002\001\000\000\000\000\000\000\000\036\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\010"
        elapsedTimeTimestamp: 594206227.52611
        inferredTimestamp: 594179446.567846
      }
      currentLanguageOptions {
        type: 0
        characteristics: "\010\000\022\002en\032\033public.main-program-content\"\007English*\035English [Original]-en-English"
        characteristics: "\010\000\022\002en\032\030public.auxiliary-content\032$public.accessibility.describes-video\"\036English - Audio Description AD*=English - Audio Description-en-English - Audio Description AD"
        characteristics: "\010\000\022\002fr\032\030public.auxiliary-content\"\006French*\020French-fr-French"
        characteristics: "\010\000\022\002pl\032\030public.auxiliary-content\"\006Polish*\020Polish-pl-Polish"
        characteristics: "\010\000\022\002es\032\030public.auxiliary-content\"\007Spanish*\022Spanish-es-Spanish"
        characteristics: "\010\000\022\002tr\032\030public.auxiliary-content\"\007Turkish*\022Turkish-tr-Turkish"
      }
      currentLanguageOptions {
        type: 1
        characteristics: "\010\001\022\010__AUTO__"
        characteristics: "\010\001\022\002en\032\033public.main-program-content\032.public.accessibility.transcribes-spoken-dialog\032.public.accessibility.describes-music-and-sound\"\013English SDH*\026English-en-English SDH"
        characteristics: "\010\001\022\007zh-Hans\032\033public.main-program-content\"\023Chinese, Simplified*.Simplified Chinese-zh-Hans-Chinese, Simplified"
        characteristics: "\010\001\022\007zh-Hant\032\033public.main-program-content\"\024Chinese, Traditional*0Traditional Chinese-zh-Hant-Chinese, Traditional"
        characteristics: "\010\001\022\002it\032\033public.main-program-content\"\007Italian*\022Italian-it-Italian"
        characteristics: "\010\001\022\002vi\032\033public.main-program-content\"\nVietnamese*\030Vietnamese-vi-Vietnamese"
      }
    }
    requestId: "PlaybackQueueInvalidation14BE5F44-E3B7-4919-8DD0-E33D4A5D8D08"
  }
  displayName: "Netflix"
  playbackState: 2
  playbackQueueCapabilities {
    requestByRange: true
    requestByIdentifiers: true
  }
  playerPath {
    origin {
      type: 1
      displayName: "Loungeroom"
      identifier: 1280262988
    }
    client {
      processIdentifier: 491
      bundleIdentifier: "com.netflix.Netflix"
    }
    player {
      identifier: "MediaRemote-DefaultPlayer"
      displayName: "Default Player"
    }
  }
  playbackStateTimestamp: 594206245.796719
}
chicaneau commented 5 years ago

@postlund Why do you think so many fields were missing? I was playing via Netflix and appears you were too.. Very strange. Is there anything else you would like me to try?

postlund commented 5 years ago

@postlund Why do you think so many fields were missing? I was playing via Netflix and appears you were too.. Very strange. Is there anything else you would like me to try?

I have only extracted parts of all messages and that was almost two years ago, so Apple has probably introduced both new fields and messages since then. New message definitions will have to be extracted as time goes by. I also believe that Apple changed the way they pushed metadata a bit, so how they did before is probably not how they do it now. That's why the new fields are needed.

Fishairman90 commented 5 years ago

@postlund can you please help me from going even more insane... Been working on this for over a week now. And for the life of me I can't add my ATV...Running Raspbian lite. Ive tried to find my tv the old method... "apple_tv:" and I get nothing. Then I have tried the "Mrp" method and get nothing. So I thought I would get smart and use a port scanner. Found the port, and added the Name, IP and port under apple_tv_mrp... looks like this.

apple_tv_mrp:

- name: Living Room Apple TV

host: 192.168.1.9

port: 49152

This was the most exciting thing ever... I clicked scan and actually got the Apple TV to show up!

I confirmed the IP, and port. And then on to the next step.. Authenticate. this is where I have been stuck now all day. I send the request to authenticate and I get nothing... I have tried rebooting Hass, the whole pi, whole home network, turning off home sharing, rebooting ATV, pulling the power on ATV and then turning back on home sharing, barking like a dog, cussing at it all with no luck. Help?