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

Push progress/watched status to Netflix #80

Closed
3 of 11 tasks
Smeulf opened this issue May 14, 2019 · 41 comments · Fixed by #385
Closed
3 of 11 tasks

Push progress/watched status to Netflix #80

Smeulf opened this issue May 14, 2019 · 41 comments · Fixed by #385
Labels
Enhancement New feature or request Help needed We need the help of other volunteer developers Testers needed To resolve this issue other testers are required

Comments

@Smeulf
Copy link

Smeulf commented May 14, 2019

I'm submitting a ...

  • bug report
  • feature request
  • support request

General information

Not sure if it's a feature request or a bug report...

When you watch an episode from a browser or the netflix app, Netflix remembers the watched status or resume points.

When you browse ie 'My List' and video was already seen, Kodi displays it. But wen you watch something from Kodi, Netflix is not updated.

Would it be possible to send a notification to Netflix when the video is stopped with the watch status/resume point ?

Then it will be possible to continue watching something in the Netflix app that was started on Kodi.

Thanks for your comments.

Addon version used

From sources at commit 8777e02
https://github.com/CastagnaIT/plugin.video.netflix/tree/8777e02a19c3763819d39178b2695dea0a49a03d

Installation

  • I'm using this Netflix Repo
  • I'm using other Netflix Repo (Please specify which)
  • I'm using a different source (Please tell which)

Operating System

  • Linux (x86/x64)
  • OSX (x86/x64)
  • Windows (x86/x64)
  • Linux (ARM)
  • Android

Additional informatin on the environment

LibreELEC 9.0.1

@Smeulf
Copy link
Author

Smeulf commented May 15, 2019

Looks like a feature request : https://github.com/CastagnaIT/plugin.video.netflix/projects/2#card-19070428

There's a MSL endpoint named "pbo_events", with a "events/stop" parameter called after a video is stopped. Could it be the answer ?

@CastagnaIT
Copy link
Owner

days ago i tried to track the logs of the endpoint you specified
but verifying the logs i have not found a behavior that specifies that it is for that functionality
for example i have not found references that are sent to make the server understand that the "stop" is for a certain video running

we should try to understand more deeply in some way

@CastagnaIT CastagnaIT added the Enhancement New feature or request label May 17, 2019
@Smeulf
Copy link
Author

Smeulf commented May 17, 2019

https://www.bountysource.com/issues/46068715-netflix-api-watched-movies-don-t-show-up-in-netflix-web-app-s-viewing-activity

According to asciidisco, it's managed by the 'log' endpoint, he added a payload example.

I don't have the proper tools to decode the payloads myself, so I can't tell what's pushed on the 'event' endpoint, but I tend to trust both of you :)

@CastagnaIT
Copy link
Owner

interesting discussion in the link, summarising
at pbo_events the following requests are submitted:

When video starts:
reqName=events/engage
reqName=events/start

During viewing (often transmitted at every minute or more)
reqName=events/keepAlive

At the end of the video:
reqName=events/stop

to decode it you have to follow the logic on default_crypto
so initially you can decode the data with base64

like asciidisco said this is a complex thing..
first we must try to decode a message sent by the netflix player, maybe creating a separate python software, so based on what we get, understand if we can replicate the requests to be sent at pbo_events

@dm2912
Copy link

dm2912 commented Jun 2, 2019

I think the most crucial thing is the watched status as that is what Netflix relies on for recommendations etc. without it knowing what you have watched, your recommendations are only based on what you add to your list.

@CastagnaIT CastagnaIT added the Help needed We need the help of other volunteer developers label Jul 2, 2019
@yoshimo
Copy link

yoshimo commented Sep 1, 2019

According to asciidisco, it's managed by the 'log' endpoint, he added a payload example.

I think that changed, ichnaea isn't called when i watch movies and progress is still saved.
There are post requests to ​https://www.netflix.com/nq/msl_v1/cadmium/pbo_logblobs/%5E1.0.0/router these days

@CastagnaIT
Copy link
Owner

may be i have no longer followed the situations,
if you are able to help trying to propose something working you are welcome

@Mikau28
Copy link

Mikau28 commented Oct 10, 2019

Would looking at how plex handles this API endpoint aide in resolving this issue? The only reason I ask is that they have a native kodi plugin.

@CastagnaIT
Copy link
Owner

which plex? attach link/documentation

@Mikau28
Copy link

Mikau28 commented Oct 11, 2019

https://forums.plex.tv/t/pms-web-api-documentation/62152

Plex, like Netflix but you host your own media. They offer the same functionality of watched and position markers. I realize they are different but how they work could point towards a better direction.

@CastagnaIT
Copy link
Owner

I don't see any help on this page
and there is not even any source code

@nohajc
Copy link

nohajc commented Nov 4, 2019

like asciidisco said this is a complex thing..
first we must try to decode a message sent by the netflix player, maybe creating a separate python software, so based on what we get, understand if we can replicate the requests to be sent at pbo_events

Hi, I might be able to help. I was playing with the MSL protocol too and I have a mitmproxy plugin which can intercept MSL handshake and decrypt subsequent communication.

The code is really ugly, so I haven't made it public yet, but it works.
It's a classic MitM attack where the proxy will present a different RSA public key to the Netflix server, so it can decrypt the response containing AES key and re-encrypt it with the RSA public key the client is expecting.

All of this is limited to the JWK_RSA (Chrome, Firefox, ...) or JWEJS_RSA (IE) schemes where random keys are generated for each handshake.

WIDEVINE scheme (Android app) uses a device-specific RSA key which is usually protected by L1 DRM. That would be more difficult to deal with (and also questionable from a legal standpoint) but also not necessary for this task, I'd say.

@dagwieers
Copy link
Contributor

Once you have this implemented, you will notice that there's no easy way to update resumepoints in Kodi. See: add-ons/plugin.video.vrt.nu#568

But don't let that stop you, because this functionality is very much wanted, and hopefully we can get that functionality fixed in Kodi as well :-)

@CastagnaIT
Copy link
Owner

this is good news, even if you can only communicate to netflix which movie has been viewed completely is already very good!

take the time you need to clean up the code
here at the moment i am very busy to make the code inter-compatible between py2 - py3

@yoshimo
Copy link

yoshimo commented Nov 4, 2019

very nice to hear @nohajc . I assume once we found the necessary request it can be used across multiple platforms, developers are lazy.
Code can be ugly as long as it gives us the proper info.

@nohajc
Copy link

nohajc commented Nov 6, 2019

I'll release the code soon. I just want to make it easier to use. It's almost done, I only need to persist the negotiated AES key, otherwise browser history has to be cleared every time you restart the mitm script.
I haven't found any better way to force new MSL handshake.

@yoshimo
Copy link

yoshimo commented Nov 6, 2019

With a clean cache, which request sets up the handshake and does it happen right when i log into the website?

@CastagnaIT
Copy link
Owner

CastagnaIT commented Nov 6, 2019

I'll take a look at the code, I don't know what you're doing, but i inform you that all this must work with the session currently opened by the addon (service) not one new

@nohajc
Copy link

nohajc commented Nov 6, 2019

@yoshimo
https://github.com/CastagnaIT/plugin.video.netflix/blob/master/resources/lib/services/msl/msl_handler.py#L107

It should be the first request to manifest endpoint, the only one which will be unencrypted.
It happens some time after login and after choosing a user profile. The MSL session is preserved even after logout though.

@CastagnaIT What I'm doing is a HTTPS proxy which intercepts communication between a real Netflix client (e.g. the cadmium player js library running in browser) and the Netflix server. Normally, you would be able to decrypt TLS with a special CA installed (this is what mitmproxy does by default) but my proxy script also handles MSL decryption.

I will set up a separate repository for this, of course.

@nohajc
Copy link

nohajc commented Nov 6, 2019

All right, the code is up. Anyone is welcome to try it.
https://github.com/nohajc/netflix-mitm-proxy

@yoshimo
Copy link

yoshimo commented Nov 7, 2019

@nohajc i used pip to install pycryptodome, but your script says it can'T find the module on my windows installation. Do you have an idea what goes wrong?

@nohajc
Copy link

nohajc commented Nov 7, 2019

@nohajc i used pip to install pycryptodome, but your script says it can'T find the module on my windows installation. Do you have an idea what goes wrong?

Ah, sorry, I forgot to mention this in the README. Windows installation of mitmproxy uses its own bundled python runtime. The workaround is to install mitmproxy also with pip.

@yoshimo
Copy link

yoshimo commented Nov 12, 2019

Mhm, how do i force a new handshake in this addon?
I deleted the json file to remove the desktop key and broke the proxy and log out and back in doesn't seem to trigger a new handshake.
Has anyone successfully compared logs yet?

@nohajc
Copy link

nohajc commented Nov 12, 2019

Mhm, how do i force a new handshake in this addon?

Yes, logging out does not close the MSL session. The decryption key will stay the same for some time. That's why I cache it in the json file. If you still want a new handshake for some reason, you have to delete all Netflix cookies and local storage or start a new browser profile.

@yoshimo
Copy link

yoshimo commented Nov 12, 2019

  1. does a browser cache reset also need a reset of the decryptor cache?
  2. How would i reset the session in castagna.netflix so that i have two logs of the same format of the same episode to conpare kodi with the website more easily?

@nohajc
Copy link

nohajc commented Nov 12, 2019

1. does a browser cache reset also need a reset of the decryptor cache?

Resetting browser cache should trigger a new handshake, but you don't have to delete the json file of the decryptor. It will be updated automatically with a new key.

2. How would i reset the session in castagna.netflix so that i have two logs of the same format of the same episode to conpare kodi with the website more easily?

I'm not sure but I guess deleting msl_data.json could help: https://github.com/CastagnaIT/plugin.video.netflix/blob/master/resources/lib/services/msl/msl_handler.py#L69

@CastagnaIT
Copy link
Owner

thanks nohajc, i just did a test, you get much information more clearly
i will try to study the situations

@nohajc
Copy link

nohajc commented Dec 18, 2019

thanks nohajc, i just did a test, you get much information more clearly
i will try to study the situations

You're welcome. I noticed you've forked the repository. Feel free to make a pull request, so that I can merge your changes.

@kidforpm
Copy link

kidforpm commented Jan 7, 2020

Is there any progress? Maybe it is possible to split this request into two parts. I think it is possible to sync watched status to kodi, syncing it back to Netflix might be a challenge but that would make the plug-in perfect for me. Now reading and syncing play status from and to kodi seems like a very different story.

@CastagnaIT
Copy link
Owner

the progress can be seen in PR, I have something more in local but not much

I think it is possible to sync watched status to kodi,

it's not easy, you also need to work to find the right compromise with Kodi video management for watched status and resume.

Another obstacle is the Kodi library, i haven't yet researched how to update video watched and resume for each video, without overburdening with too many requests.
At least initially the thing will be confined to work for internal use in the addon and not in the Kodi library.

I also think there's going to be another problem with the cache management, not yet checked.

I'm following the set plan, if it's not followed in perfect order, it's only because things are intrinsically linked

@kidforpm
Copy link

kidforpm commented Jan 8, 2020

Maybe you can use some of the Trakt implementation? They have syncing watched status down pretty reliable both ways. Agreed it is harder to sync watch progress into kodi, but Trakt is also outputting progress at reasonable intervals. I would reckon it is more difficult to read and write that info to Netflix database

@CastagnaIT
Copy link
Owner

i can see how trakt addon update edit the watched/resume status to the Kodi items,
but trakt is another thing, here is not useful

@dagwieers
Copy link
Contributor

AFAICT trakt works using VideoLibrary JSONRPC calls, which does not work for plugin://-type resources. This is making our life quite complicated. It would be much easier if Kodi would support plugin://-type resources from Files.GetFileDetails and Files.SetFileDetails JSONRPC calls.

This means we cannot easily manage/sync playcount and resumetime information between content provider and Kodi :-(

See add-ons/plugin.video.vrt.nu#568 for all the discussions, pull-requests and feature request.

@CastagnaIT
Copy link
Owner

hi dagwieers, thanks for useful info!
interesting the rejected PR, from what i understand the kodi team would only accept the change if you create a new separate function

for now i have other things to complete before get to these changes
this moment will come

@CastagnaIT CastagnaIT linked a pull request Feb 7, 2020 that will close this issue
9 tasks
@CastagnaIT
Copy link
Owner

CastagnaIT commented Feb 7, 2020

@dagwieers I'm trying use this xbmc/xbmc#17202
but i have a problem when i use it, is no longer possible to change the watched status of the menuItem through context menu or keyboard shortcut

happen same thing if i set watched/resume status by: xbmcgui.ListItem
list_item.setProperty('PlayCount', xy)
list_item.setProperty('ResumeTime', xy)

is that normal?

@dagwieers
Copy link
Contributor

@CastagnaIT If you use ListItem properties to set the playcount and resumetime, you are overriding the information from the database. And that is problematic, because if you return to a listing, this information is stale.

With xbmc/xbmc#17202 we no longer need to use ListItem properties, as we can read/write from the database, and rather than set the information in the ListItem, you should update the database and refresh the listing (if necessary).

@CastagnaIT
Copy link
Owner

CastagnaIT commented Feb 9, 2020

i do some tests i was thinking that things are really complicated, i'm not quite sure how to proceed

JSONRPC way, i can not use it when i loading page, this method need a refresh and will result in a Kodi infinite loop ().
-In addition i need to use it before the endOfDirectory(), and can cause a nasty Kodi crash if loading is too fast

In addition even if it works, a user can change the status (via ctx menu or keyboard etc), but there is no kodi callback function, then changes it will not be reflected to netflix service.
(i'm not yet sure if i will can change status on netflix, because it has a very special mode of operation, but this is another story...)

The method: list_item.setProperty('PlayCount', xy) not work in all case...i think has a bug
(e.g. when a item is already watched and you force to set again watched, the override do not work)

The method: list_item.setInfo('video', {'PlayCount': 'xy'}) this works
-But the override, breaks down the Kodi menus (like Reset, mark watched etc...) how remove these menu? then you have to re-implement them all manually? bad..
-In this case i can not use this method in conjunction with JSONRPC, then how do i update the value if I don't have access to the listitem?
-another problem i can not use twice the method setInfo because otherwise delete the previous values and i can't always have direct access to this informations, and there is no getInfo...


I find it a nightmare,
the current situation seem unmanageable

there should now be an opportunity to set/update a initial value when i create an listitem object
without overriding a value in db, Kodi should only insert if value not exist or update the existing value directly

perhaps can be implemented in this way:
add new set in listItem:
setPlayCount()
setResumeTime()

and inside the method addDirectoryItems()
when executing the for each object loop, add a system to insert/update the value to db
by reading setPlayCount/setResumeTime

and after, have a callback way to handle watched/unwatched events when user change manually the value (By Monitor callback)

I think add these two things to Kodi would save a lot of trouble
and JSONRPC method can be used without the problems of the overrided values

opened discussion also to forum: https://forum.kodi.tv/showthread.php?tid=351609

@dagwieers
Copy link
Contributor

It is a nightmare, with a lot of tradeoffs. That is why being able to update the database and no longer needing to add this information to the ListItem is crucial.

It is true that there is no hook for the context menu items (Mark as (un)watched or Reset position) and we haven't looked at how we will simplify our existing implementation for Matrix.

But as you indicated, the process would mostly look like:

  • Update local resumetime/playcount from online when building the ListItem listing
  • Update local and online resumetime/playcount from Player object (start, seek, pause, stop)

To speed up this process and ensure we finish before Kodi refreshes an existing listing, we update locally immediately and online asynchronously.

@CastagnaIT
Copy link
Owner

I'll try making some modifications to Kodi similar described above
then if it works, let's see how to proceed
since Kodi 19 is in alpha we could find a more suitable system

@CastagnaIT
Copy link
Owner

if I find a compromise to use list_item.setInfo('video', {'PlayCount': 'xy'})
you know how to remove these menus?
image

@CastagnaIT CastagnaIT added the Testers needed To resolve this issue other testers are required label Feb 20, 2020
@CastagnaIT
Copy link
Owner

CastagnaIT commented Feb 20, 2020

I'm almost ready to merge it with the master branch!
it would be appreciated if someone would help me run some tests before merge it

for the noobs, test does not mean see if it starts, you must also monitor the log in verbose mode, to ensure that there are no errors

before running the test read also the notes of the PR #385

[plugin.video.netflix_0.17.0_20200220_test1.zip]

!!!WARNING!!!
If you install this test as an upgrade, it may cause problems if you roll back to the previous version
and then update again with future versions, so if necessary make a backup!

I'll add extra protection to safeguard rollbacks before merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement New feature or request Help needed We need the help of other volunteer developers Testers needed To resolve this issue other testers are required
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants