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

[Bug] ORF ON DRM Streams not working on Android Devices #1585

Open
s0faking opened this issue Jun 19, 2024 · 20 comments
Open

[Bug] ORF ON DRM Streams not working on Android Devices #1585

s0faking opened this issue Jun 19, 2024 · 20 comments
Labels
DRM: Widevine Triage: Confirmed issue has been reproduced by a team member

Comments

@s0faking
Copy link

s0faking commented Jun 19, 2024

Describe the problem

The livestreams for the ORF On Addon cannot be played on Android devices (Tested on Nvidia Shield and Pixel 8 with GrapheneOS). The stream works flawless on Linux/Win

Possible fix

No response

Steps to reproduce

  1. Enable the "Timeshift" option for the ORF ON Addon
  2. Open "Livestream" and "ORF 2"

Alternatively use this in a strm file

#KODIPROP:inputstream=inputstream.adaptive
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
#KODIPROP:inputstream.adaptive.license_url=https://drm.ors.at/acquire-license/widevine
#KODIPROP:inputstream.adaptive.license_key=|Content-Type=application/octet-stream|R{SSM}|R
#KODIPROP:inputstream.adaptive.license_url_append=?BrandGuid=319f2ca9-0d0c-4e5b-bb70-72efae61dad7&userToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJraWQiOlsiKiJdLCJleHAiOjE3MjAwMTc4ODZ9.gcYTr_2cKlQYR-OH9Ca1C6DKKhrFsLbY_VVzetwZ2Bo
https://orf2-247.mdn.ors.at/orf/orf2/drmqxa-247/manifest.mpd?offset=5&begin=20240619T141239|user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36

Debug log

drm_kodi.log

Stream manifest file(s)

manifest.txt

Additional info

The stream has a geolock so it might be hard to debug without an austrian ip. Let me know if I can help with any other logs/files/etc

Operating system(s)

Android

Operating system version(s)

Android 11|Android 14

InputStream Adaptive version(s)

21.4.9

Kodi version(s)

21.0.1

@s0faking s0faking added the Triage: Needed (managed by bot) issue that was just created and needs someone looking at it label Jun 19, 2024
@CastagnaIT
Copy link
Collaborator

in the manifest url
https://orf2-247.mdn.ors.at/orf/orf2/drmqxa-247/manifest.mpd?offset=5&begin=20240619T141239|user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36
you should avoid pipe injection since its not supported by ISAdaptive

you must set the user agent with the appropriate ISA properties
see wiki DRM encrypted video stream example for license: https://github.com/xbmc/inputstream.adaptive/wiki/Integration
and the manifest_headers and stream_headers props

after this
if the situation is the same,
from this

06-19 17:48:09.672  1083  1083 E WVCdm   : [policy_engine.cpp(57):CanDecryptContent] Provided content key is not in license: key_id = 8447520F829A46368344ABFDB257E896
06-19 17:48:09.672  1083  1083 E WVCdm   : Decrypt error in session sid21 during a sample with protected data: 5
06-19 17:48:09.672 25351  6533 E CryptoHalAidl: Failed on decrypt, error description:Status(-8, EX_SERVICE_SPECIFIC): '1: {"cdmError":5,"errorMessage":"Error decrypting data: requested key has not been loaded"}'
06-19 17:48:09.673 25351  6533 I CCodecBufferChannel: [c2.exynos.h264.decoder.secure#591] decrypt failed: result=-2001
06-19 17:48:09.673 25351  6533 W MediaCodec: Log queueSecureInputBuffer error: -2001
06-19 17:48:09.675 25351  6542 D CryptoHalAidl: framework logs size 14; plugin logs size 100
06-19 17:48:09.682 25351  6542 W System.err: android.media.MediaCodec$CryptoException: Error decrypting data: requested key has not been loaded: ERROR_DRM_NO_LICENSE

seem the server dont provide the key,
maybe dont support android platform? i have no idea

@s0faking
Copy link
Author

thanks for the quick reply. i tried it with the headers in place but still the same result on android. with chrome widevine (win/linux) it works either way

#KODIPROP:inputstream=inputstream.adaptive #KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha #KODIPROP:inputstream.adaptive.license_url=https://drm.ors.at/acquire-license/widevine #KODIPROP:inputstream.adaptive.license_key=|Content-Type=application/octet-stream&User-Agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36|R{SSM}|R #KODIPROP:inputstream.adaptive.license_url_append=?BrandGuid=319f2ca9-0d0c-4e5b-bb70-72efae61dad7&userToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJraWQiOlsiKiJdLCJleHAiOjE3MjAwMTc4ODZ9.gcYTr_2cKlQYR-OH9Ca1C6DKKhrFsLbY_VVzetwZ2Bo #KODIPROP:inputstream.adaptive.manifest_headers=User-Agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 #KODIPROP:inputstream.adaptive.stream_headers=User-Agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 https://orf2-247.mdn.ors.at/orf/orf2/drmqxa-247/manifest.mpd

the offical android app for ORF ON uses the same license server and manifest. i decompiled the apk and as far as i can tell the parameters are the same. the app uses exoplayer2, could there be a difference how exoplayer handles the drm stuff? afaik the hardware decoder handles the drm decoding on android, so there shouldn't be a difference, right?

@CastagnaIT
Copy link
Collaborator

the user agent use mozilla on android? usually on android there is a android device user agent

i think should better if you use a web proxy to debug the network while using the official app
this could allow you to see how headers are set on http requests

could there be a difference how exoplayer handles the drm stuff?

exoplayer is much more complex and advanced than ISAdaptive and supports many things not supported here, its not so comparable

from my pov if there is no license key there is something wrong in how you configure the license request

@s0faking
Copy link
Author

s0faking commented Jun 21, 2024

i tried that and appended the correct UA the official app is using but without any luck.

#KODIPROP:inputstream=inputstream.adaptive #KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha #KODIPROP:inputstream.adaptive.license_key=https://drm.ors.at/acquire-license/widevine?BrandGuid=319f2ca9-0d0c-4e5b-bb70-72efae61dad7&userToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJraWQiOlsiKiJdLCJleHAiOjE3MjAxNjc5MjJ9.9d9EfR3uEg1cZa5lI9R1MNVF-yMUKUwuejsotnw7VTw|Content-Type=application/octet-stream&User-Agent=ORF ON/6.0.2-mobile (Linux;Android 14) ExoPlayerLib/2.18.4|R{SSM}| #KODIPROP:inputstream.adaptive.manifest_headers=User-Agent=ORF ON/6.0.2-mobile (Linux;Android 14) ExoPlayerLib/2.18.4 #KODIPROP:inputstream.adaptive.stream_headers=User-Agent=ORF ON/6.0.2-mobile (Linux;Android 14) ExoPlayerLib/2.18.4 https://orf2-247.mdn.ors.at/orf/orf2/drmqxa-247/manifest.mpd

the app requests for license key are exactly the same except for the UA

Screenshot 2024-06-21 122944

shield.log

@mtr81
Copy link

mtr81 commented Jun 22, 2024

I noticed that there are different KIDs for adaptation sets/content types. In Windows ISA gets license for each one, but in Android only for first (in that case - for audio segments). Is this correct behavior?

@s0faking
Copy link
Author

When i change the inputstream.adaptive config to audio only the audio plays fine. Could the different KIDs be the problem as @mtr81 pointed out? Here's a logfile when the audio plays

shield_audio.log

@s0faking
Copy link
Author

i've tried to save a local copy of the manifest and modified it a bit. I've removed the first two adaptionsets (audio tracks) and tried to play it and the video plays fine (without audio of course). it also works vice versa, so when i only keep the first two adaption sets (audio tracks) the audio plays fine.

@CastagnaIT
Copy link
Collaborator

try to see if this test build works:
https://jenkins.kodi.tv/blue/organizations/jenkins/xbmc%2Finputstream.adaptive/detail/PR-1587/1/artifacts
if works please provide a new log (disable Curl debug logging that spam a lot the log)

@mtr81
Copy link

mtr81 commented Jun 25, 2024

First of all ver. 21.4.10 should be fixed because it crashes Kodi.
Last line in log before crash:
2024-06-25 14:21:43.331 T:5412 debug <general>: AddOnLog: inputstream.adaptive: media::CdmAdapter::Initialize: CDM version: 4.10.2710.0
Kodi ver: 21.0 (21.0.0) Git:20240406-60c4500054
System: Windows NT x86 64-bit version 10.0 (0x0A00000B)

@s0faking
Copy link
Author

mille grazie @CastagnaIT :) it works with this version. only tested the android build (on my nvidia shield) though so i can't verify the crash @mtr81 has reported right now. here's the log

shield_update.log

@CastagnaIT
Copy link
Collaborator

CastagnaIT commented Jun 26, 2024

good! this confirm what i found
theproblem is that on android we open only a single drm session shared for all keyid's,
should be opened a drm session for each keyid so that drm will make a license request for each keyid
(but i think it would be possible to avoid opening multiple sessions for the same keyid)

i found that one player do what explained above:
https://players.castlabs.com/android/latest/docs/build/html/drm.html#multi-key-playbacks
and provide also a setting to force a single drm session

explanations on how widevine works are quite fragmentary on the web and i know very little about it too
but i think we should follow castlabs player way
cc @glennguy

no idea about crashes i tested over windows/android with no problems, but there are too many use cases to test so idk atm

@CastagnaIT CastagnaIT added Triage: Confirmed issue has been reproduced by a team member DRM: Widevine and removed Triage: Needed (managed by bot) issue that was just created and needs someone looking at it labels Jun 26, 2024
@glennguy
Copy link
Contributor

I think we've flipped between single/multi a few times now. @matthuisman also knows about this.

Maybe it could be an advanced setting plus Kodi prop for overriding?

@CastagnaIT
Copy link
Collaborator

CastagnaIT commented Jun 26, 2024

what the reason behind to have reverted to one session?

EDIT: ok i found the PR #1165

@matthuisman
Copy link
Contributor

matthuisman commented Jun 26, 2024 via email

@matthuisman
Copy link
Contributor

(or that logic the other way around , but you get the point)

@matthuisman
Copy link
Contributor

Id be keen to try multiple sessions again either way. Pretty sure it fixes some audio issues as well (maybe that guys Disney+ 5.1 audio issues)

If it could be disabled for a Kodi property (or enabled) that would be handy for any add-ons that don't like it

@glennguy
Copy link
Contributor

Ideally getting just separate audio/video sessions will be enough, and this loop ensures that we don't keep going back for keys that we already have (often license requests will return multiple keys):

if (m_decrypter && !defaultKid.empty())
{
LOG::Log(LOGDEBUG, "Initializing stream with KID: %s",
STRING::ToHexadecimal(defaultKid).c_str());
for (size_t i{1}; i < ses; ++i)
{
if (m_decrypter->HasLicenseKey(m_cdmSessions[i].m_cencSingleSampleDecrypter, defaultKid))
{
session.m_cencSingleSampleDecrypter = m_cdmSessions[i].m_cencSingleSampleDecrypter;
session.m_sharedCencSsd = true;
break;
}
}
}

@CastagnaIT
Copy link
Collaborator

CastagnaIT commented Jun 26, 2024

Ideally getting just separate audio/video sessions will be enough, and this loop ensures that we don't keep going back for keys that we already have (often license requests will return multiple keys):

yes but HasLicenseKey method on android return fake value
its needed find a way to solve it

i agree a kodi property its needed for sure

@s0faking
Copy link
Author

any progress on this issue?

@CastagnaIT
Copy link
Collaborator

its required some changes on decrypters and im already working to rework part of decrypters session code, that can solve also this problem, but its a big task that will require not weeks but months, depends how much will be delayed my works

it could be possible add a kind of workaround with a specific property
but even doing this, means spending time on implementation/releasing/documentation
affected addons must apply the changes and make new releases, all this for a temporary solution that at the end more likely will be removed

so from my part i will not work on this until the code rework

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DRM: Widevine Triage: Confirmed issue has been reproduced by a team member
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants