Closed postlund closed 4 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.
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.
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.
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.
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.
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?
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).
Sorry circled through commands and didn't notice the port option I was trying earlier. Please ignore.
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.
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:
atvremote scan
10+ times from Ubuntu: No luck.avahi-browse
from Ubuntu, which seems to find it:
$ avahi-browse -d local _mediaremotetv._tcp
$ dns-sd -B _mediaremotetv._tcp
Browsing for _mediaremotetv._tcp
DATE: ---Mon 21 Oct 2019---
23:13:31.517 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
23:13:31.519 Add 2 4 local. _mediaremotetv._tcp. Apple TV
aiozeroconf
from Ubuntu, which also seems to find it:
$ aiozeroconf -s _mediaremotetv._tcp.local.
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!
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! π
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?
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?
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.
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! π
Adding my two cents, since I've been trying to figure out what was up with this myself (until I ran across this issue):
avahi-browse -d local _mediaremotetv._tcp
- ran on ubuntu 18.04, found both ATVs (IPv4 and IPv6 addresses)atvremote scan
- ran on MacOS (Catalina), didn't find either of my two AppleTVs on the networkpyatv_debug_scan.py
script from above - ran on MacOS, didn't find anythingdns-sd -B _mediaremotetv._tcp
- ran on MacOS, found both ATVspython3 -m aiozeroconf -s _mediaremotetv._tcp.local.
- ran on ubuntu 18.04 - found both ATVs, no problemAnything 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!
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!
@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.
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
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! π
You need to use the code from the PR, it's not on master yet (and avoid specifying --address
, --id
should suffice).
Sorry, what is the command to upgrade from PR ?
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
I used pip install.
Try this:
pip install git+https://github.com/postlund/pyatv.git@aiozeroconf
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.
I just updated AppleTV to 13.2, obviously it restarted and so far everything works fine. I'll report back tomorrow. Thank you.
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
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
.
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 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.
Just pushed the missing remove_service
method, please re-install with pip again.
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.
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
.
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 ?
$ 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.
I see. No matter what I play I see same paused message and no title for playing media.
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
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.
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.
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 π
I merged the
aiozeroconf
PR now, so it's onmaster
. 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
I merged the
aiozeroconf
PR now, so it's onmaster
. 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.
My Apple TV stopped responding to remote app and atvremote again. I'll move it to wifi to see if it helps.
Hey @postlund I have successfully run atvremote whilst playing a video, here is the debug log for you
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.
Hey @postlund I have successfully run atvremote whilst playing a video, here is the debug log for you
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"
}
}
----------------------------------------
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
}
@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 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.
@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:
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?
The problem A lot of people are having issues where their devices are not found. You either see a message like this:
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:pyatv
only use this for playing videos based on a URL.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. Ifpyatv
doesn't find a device but avahi does, then we should suspect python-zeroconf.So what you can do is:
atvremote scan
or on macOS, you can do this:
For Windows I don't know. There probably are tools, but you will have to look that up yourself.
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.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):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:
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.