Skip to content
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

Language Options feedback and commands #720

Open
lucasec opened this issue Jun 14, 2020 · 4 comments
Open

Language Options feedback and commands #720

lucasec opened this issue Jun 14, 2020 · 4 comments
Labels
feature mrp Media Remote Protocol

Comments

@lucasec
Copy link
Contributor

lucasec commented Jun 14, 2020

What

The MRP protocol can provide clients with a list of available language options (audio, subtitles). Many apps also support the EnableLanguageOption/DisableLanguageOption commands to select a language option from those lists.

Why

Users may find this valuable in implementing some sort of control interface. At least immediately, a subtitle toggle command seems like the most valuable, particularly for people who watch a lot of international content, or with the volume turned down at night.

How

Getting Language Option information

If a ContentItem has the languageOptionsAvailable = true property in its metadata object, you can request language options for the content. In general the device does not send them automatically. It may send them unsolicited if a subtitle track is currently enabled on the content (whether by default or because it was selected in a previous play session).

To request language options information, send a PlaybackQueueRequest with includeLanguageOptions = true. The device will then respond with a queue and any ContentItem(s) containing the availableLanguageOptions and currentLanguageOptions properties. The schema of those properties should be fairly self-explanatory. There is generally one of each property for each type of language option—e.g. one list for audio options and one list for subtitle options. In general, it seems like the identifier and languageTag are the most important properties when it comes to later selecting a particular option. Not all options have an identifier. Notably the __AUTO__ magic option for subtitles does not.

Keeping information up-to-date

The device sometimes issues updates if another MRP device changes the current language option. Unfortunately, from my finding, these updates seem to be very inconsistent. If the on-screen UI is used on the device to select a language, MRP clients may not get updated at all.

Apple's own implementation in control center suffers from this ailment as well—if you select a language in iOS and the checkmark shortly thereafter snaps back to the previous choice, this is because the device never updated iOS on the new choice. Notably, the dedicated TV Remote app does not exhibit this "snap back" behavior. It just assumes whatever option was selected is the current option, regardless of whether or not it received an update from the device.

Changing the current language option

To select a language option, send the EnableLanguageOption command. The languageOption field in CommandOptions must be filled with a certain binary payload created around a LanguageOption protobuf. In my experience, only the type (audio or subtitle), identifier (if present originally) and languageTag properties need to be sent in the command.

For option types that allow none to be selected (e.g. subtitles), the DisableLanguageOption command can be used. This too requires a wrapped LanguageOption protobuf, but only the type field actually needs to be populated.

The binary payload appears to be Apple's internal marshal object for the protobuf run through NSKeyedArchiver and written to a binary plist. The object just contains a single property which is the encoded protobuf. Why Apple took one binary format and wrapped it in another is beyond me. It's probably easiest to work off the attached sample and pull in a binary plist library.

sample.plist.zip

The subtitle toggle button

The remote widget in iOS control center provides a subtitle toggle button when playing content that has subtitles available.

I don't know exactly how it is implemented, but I assume the widget always requests the language options and uses the same MRP metadata to determine whether to display the button. Assuming it uses the same Enable... command to enable subtitles, how it selects which track to enable is also a mystery. It usually selects the first non-Auto track available, but whether this is influenced by my device or the Apple TV's locale is currently unknown.

@postlund
Copy link
Owner

Sounds great to me! I think it's time to start working on documentation for MRP in general. My initial stance was to not document it at all and push documentation back to https://github.com/jeanregisser/mediaremotetv-protocol (as I have already contributed back to that repo before). But since Jean isn't very active anymore, I want more control and also full documentation for pyatv, adding protocol definitions makes sense. Currently all protocols are clamped into a single page. This should probably be change to one page per protocol.

@postlund
Copy link
Owner

And I wonder... is plistlib compatible with NSKeyedArchiver?

@lucasec
Copy link
Contributor Author

lucasec commented Jun 14, 2020

I suspect it would likely work if you use it to decode the sample plist, then feed it back a dict in a very similar format.

I used this library (in JS) on my project: https://github.com/joeferner/node-bplist-creator/blob/master/bplistCreator.js

@postlund
Copy link
Owner

Yeah, I can give it a try later to see if it works. Hopefully it will.

@postlund postlund added the mrp Media Remote Protocol label Dec 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature mrp Media Remote Protocol
Projects
None yet
Development

No branches or pull requests

2 participants