This improves user-experience by allowing set_key_ids to accept more types of Key ID formats directly. This also reduces code duplication because the parse function also checks the validity of the Key IDs list for set_key_ids.
In reality you wouldn't need this for use with pywidevine, but a lot have asked me for this feature so they can use WVDs in other ways or with other software that does not support WVDs.
The previous method was overall fine, but assumed only one PlayReadyHeader was in the PlayReadyObject. It also incorrectly assumed the start data to be garbage data when it's actually the header for the PlayReadyObject.
Previously it would load PlayReadyHeader data under Widevine's SystemId breaking all PlayReady checks.
The actual PlayReadyHeader init_data still needs code to parse it into an object.
OEM Crypto API v16 changed slightly how the Signature algorithm was calculated. The `oemcrypto_core_message` field is now basically prefixed to the full license message for the signature.
This fixes support for devices like Roku OS 11.5.0, among others.
Currently, even though self.version would be 0, it would dump as a version=1 box with key_IDs set to data (where possible).
This is because pymp4 sets the version to 1 if key_IDs is set with data, as that would make it a v1 PSSH box. So effectively .dump() and .dumps() forces a v1 box as output even if you loaded or created a v0 box.
Fixes#16
It seems 16 is the more common limit on moderm OEM Crypto API systems (at least L1). It's also a more reasonable limit.
This also encourages people to .close() their session more. It also makes it quicker to notice if a codebase is forgetting to do a .close() call somewhere as you will reach the limit faster and easier now.
In normal use cases, a limit of 16 sessions will not be a problem as long as the sessions are being closed correctly.
This is for less effort to use the Service Certificate later on. We have no reason to keep the SignedMessage shell as it's just a way to send it as a message from License Acquisition APIs.
The logic of parsing the session's stored service cert to get the provider_id was wrong. It assumed it was a SignedDrmCertificate, when in reality it was a SignedMessage containing a SignedDrmCertificate.
It would also panic if you try to remove a certificate when none was set.
This is so you don't have to do e.g., `from pywidevine.pssh import PSSH` and instead can do `from pywidevine import PSSH`. You can still do it the other way, but now you have the choice.