Skip to content

Issue With Apple Media Service Library #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
smczech opened this issue Oct 2, 2020 · 11 comments · Fixed by #13
Closed

Issue With Apple Media Service Library #8

smczech opened this issue Oct 2, 2020 · 11 comments · Fixed by #13
Labels
bug Something isn't working

Comments

@smczech
Copy link

smczech commented Oct 2, 2020

Hi!

I followed the tutorial Now Playing: Bluetooth Apple Media Service Display and got it working with my Circuit Playground Bluefruit/TFT Gizmo, but it bombs when I play a Blue Oyster Cult song. I get this: RuntimeError: packet too short.

I figured out that it's because it is Blue Öyster Cult with the umlaut above the O. If I modify the code to not display the artist, it works fine so it must be the umlaut. If I print the artist name to the bottom of the editor while it's running I get this: Artist: Blue Ã�yster Cult.

@tannewt
Copy link
Member

tannewt commented Oct 5, 2020

Thanks @smczech! Do you have the full back trace available? That would better point to where we need to update.

@smczech
Copy link
Author

smczech commented Oct 5, 2020

Hi!

This is so weird! I was playing around with this on my MacBook last weekend when I was getting the Blue Oyster Cult error. To give you the traceback, I hooked it up to my iMac and Blue Oyster Cult appeared just fine on the screen with the umlaut! BUT, when I changed to the next track, it bombed just like others are getting in the other issue for this library. It seems to be when you change tracks from the phone where it bombs:

code.py output:
connected
Loading Font Glyphs...
Traceback (most recent call last):
File "code.py", line 141, in
File "adafruit_ble_apple_media.py", line 128, in get
File "adafruit_ble_apple_media.py", line 116, in _update
RuntimeError: packet too short

@evaherrada evaherrada added the bug Something isn't working label Oct 6, 2020
@tannewt
Copy link
Member

tannewt commented Oct 6, 2020

@smczech yay for ble! :-) I think the next step would be to print out the packet before this error occurs to see what it is.

@smczech
Copy link
Author

smczech commented Oct 11, 2020

Hi! I'm sorry I don't know how to print the packet. I do see the packet size is 3 so that's why the error is getting raised. Can you tell me how to properly print the packet?

@smczech
Copy link
Author

smczech commented Oct 11, 2020

I noticed I can re-create the error every time by selecting a different song instead of hitting next or previous track.

@smczech
Copy link
Author

smczech commented Oct 12, 2020

Hi! I took more time with this to print the buffer. I don't really understand how it works. I was playing Machine Gun Kelly - "drunk face", then switched the song to "forget me too". The album name is Tickets to My Downfall.

Packet length: 13
Buffer: ���drunk face�������������������������������������������������������������������������������������������������������������������
Packet length: 25
Buffer: ���Tickets To My Downfall�������������������������������������������������������������������������������������������������������
Packet length: 20
Buffer: ���Machine Gun Kellynfall�������������������������������������������������������������������������������������������������������
Packet length: 15
Buffer: ���1,1.0,82.567Kellynfall�������������������������������������������������������������������������������������������������������
Packet length: 8
Buffer: ���Music,82.567Kellynfall�������������������������������������������������������������������������������������������������������
Packet length: 15
Buffer: ���1,1.0,82.688Kellynfall�������������������������������������������������������������������������������������������������������
Packet length: 15
Buffer: ���1,1.0,87.746Kellynfall�������������������������������������������������������������������������������������������������������
Packet length: 15
Buffer: ���1,1.0,87.799Kellynfall�������������������������������������������������������������������������������������������������������
Packet length: 15
Buffer: ���0,0.0,87.707Kellynfall�������������������������������������������������������������������������������������������������������
Packet length: 3
Buffer: ���0,0.0,87.707Kellynfall�������������������������������������������������������������������������������������������������������
Packet too short: ���0,0.0,87.707Kellynfall�������������������������������������������������������������������������������������������������������
Traceback (most recent call last):
File "code.py", line 159, in
File "/lib/adafruit_ble_apple_media.py", line 160, in get
File "/lib/adafruit_ble_apple_media.py", line 141, in get
File "/lib/adafruit_ble_apple_media.py", line 129, in _update
RuntimeError: ('packet too short: ', 3)

@tannewt
Copy link
Member

tannewt commented Oct 12, 2020

I noticed I can re-create the error every time by selecting a different song instead of hitting next or previous track.

This is a huge first step! Reproducing an error is one of the trickiest parts.

Can you share your edited code on github? I'd like to see how you are printing it off.

I suspect this is an issue where we take the len() of a string instead of the bytes version. String's count in characters and bytes count in... bytes. Emoji and non-latin characters may take more than one byte per character and screw up our math.

@smczech
Copy link
Author

smczech commented Oct 12, 2020

Hi!

I didn't do a whole lot but added a few print statements to the adafruit_ble_apple_media.py file. I bolded/italicized them. I probably should study more about what this is all doing but there's definitely something wrong with this code.

@staticmethod
def _update(obj):
if not obj._buffer:
obj._buffer = bytearray(128)
length_read = obj._entity_update.readinto(obj._buffer)
if length_read > 0:
print("Packet length: ", length_read)
buffer_str = ''.join([chr(b) for b in obj._buffer])
print("Buffer: ", buffer_str)

if length_read < 4:
print("Packet too short: ", buffer_str)
raise RuntimeError("packet too short: ", length_read)
# Even though flags is currently unused, if it were removed, it would cause there to be
# too many values to unpack which would raise a ValueError
(
entity_id,
attribute_id,
flags, # pylint: disable=unused-variable
) = struct.unpack_from("<BBB", obj._buffer)
value = str(obj._buffer[3:length_read], "utf-8")
obj._attribute_cache[(entity_id, attribute_id)] = value

@tannewt
Copy link
Member

tannewt commented Oct 13, 2020

Ok, I suspect this is a quirk of how the media service works. I suspect that it's returning playback info that is empty. The docs say it should be three comma separated values but don't talk about what happens when a song is stopped.

I think if you change the if check to < 3 instead of < 4 it will work by returning an empty string.

@smczech
Copy link
Author

smczech commented Oct 13, 2020

WOW! That worked great! Thanks so much for taking the time to help troubleshoot this!

@tannewt
Copy link
Member

tannewt commented Oct 14, 2020

Great! Would you mind making a PR with the change?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants