trakt-tools / universal-trakt-scrobbler

MIT License
549 stars 54 forks source link

Request: Telia Play #40

Closed schteff closed 3 years ago

schteff commented 3 years ago

Hi! I just found your project while searching for a way to scrobble or sync Telia Play to trakt.tv.

I tried following your development guide but my knowledge of chrome plugin development is non existent and my time is quite limited (parent with small children).

However it seems like Telia has a closed API with many endpoints when inspecting the network requests.

For example this call which fetches all "Continue watching" items: https://ottapi.prod.telia.net/web/se/continuewatching/rest/secure/v2/watchedItems/list/?fromIndex=100&toIndex=199&protocols=dash&resolutions=sd&serviceTypes=SVOD,VOD

Which returns data like:

...
        {
            "mediaId": "1963970510",
            "assetId": "18251879",
            "duration": 2520,
            "position": 0,
            "timestamp": 1601842508186,
            "hidden": false,
            "serviceType": "SVOD",
            "mediaObjectType": "OneCoverObject",
            "mediaObject": {
                "validTo": "2023-04-12T21:59:59Z",
                "validFrom": "2020-04-13T05:00:00Z",
                "type": "VIDEO",
                "totalAssets": 6,
                "title": "03:01 Slowly Slowly Catchy Monkey - Killing Eve",
                "subtitleLanguages": [],
                "storeType": "SVOD",
                "storeName": "HBO Nordic",
                "storeIds": [
                    "8925",
                    "8924",
                    "8959"
                ],
                "storeId": "8925",
                "seriesTitle": "Killing Eve",
                "seriesId": "1489517736",
                "seasonId": "1489517736_03",
                "seasonNumber": 3,
                "renttime": 10800000,
                "productionYear": "2020",
                "portraitImages": [
                    "/HBOFullHD/5803798.jpg",
                    "/HBOHD/5803799.jpg",
                    "/HBO/5803800.jpg"
                ],
                "parentalcontrol": 0,
                "loopId": "1963970510",
                "logoUrl": "/images/logos/hbo_logo_331x38.png",
                "length": 42,
                "language": "swe",
                "landscapeImages": [],
                "episodeNumber": 1,
                "directors": [
                    "Waller-Bridge,Phoebe"
                ],
                "contentproviderName": "HBO",
                "contentproviderId": "2115950840",
                "categoryPaths": [
                    "Serier > Killing Eve"
                ],
                "categories": [
                    "Killing Eve"
                ],
                "cast": [
                    "Oh,Sandra",
                    "Shaw,Fiona",
                    "Comer,Jodie",
                    "Bodnia,Kim"
                ],
                "blockedDevices": [],
                "audioLanguages": [],
                "assets": [
                    {
                        "subtitleLanguages": [],
                        "streamingProtocol": "rtsp",
                        "storeId": "8925",
                        "resolution": "1080p",
                        "protocol": "RTSP",
                        "price": 0,
                        "language": "swe",
                        "is3d": false,
                        "id": "18251879",
                        "hastrailer": false,
                        "format": "rtsp_FullHD",
                        "devicetype": "STB",
                        "codec": "mpeg4",
                        "audioLanguages": [],
                        "attributes": {
                            "externalId": "ABXDN"
                        }
                    }
                ],
                "age": 15,
                "titleId": "1963970510",
                "start": "2020-04-13T05:00:00Z",
                "description_long": "Slowly Slowly Catchy Monkey. Eve försöker bygga upp sitt liv igen efter att ha blivit skjuten av Villanelle. Villanelle försöker också gå vidare, tills hon kontaktas av en gammal fiende. Carolyn blir underminerad på jobbet och Kenny kan inte släppa sin egen utredning av The Twelve."
            }
        },

(Telia has content from HBO and other providers collected in one service).

I think this looks promising for a sync or scrobbling service in your project, but I would need a more in depth guide for continued development on my part.

Would it be possible to point me in the right direction or maybe even add Telia Play to the service list with info provided by me?

Thanks!

rafaelgomesxyz commented 3 years ago

There are examples in the templates folders (https://github.com/trakt-tools/universal-trakt-scrobbler/tree/master/src/streaming-services/scrobbler-template for scrobble and https://github.com/trakt-tools/universal-trakt-scrobbler/tree/master/src/streaming-services/sync-template for sync), and you can also take a look at how other streaming services have been implemented.

But I can definitely add it myself if you don't have the time.

schteff commented 3 years ago

Thanks for replying!

Yes I saw the examples and I looked a bit at the NRK integration to try to make sense of it, but I got stuck after "npm start" because of the lack of detail in the instructions :)

I don't have any previous experience developing browser plugins and i'm not even sure it is possible for Telia Play.

But your reply made me give it another go. And now i figured out how to add the plugin folder to Chrome at least. I'm gonna try spending a couple of hours on it over the coming weeks and see if I can figure the rest out.

If I get stuck can I ask questions in this issue thread or would you prefer some other way?

rafaelgomesxyz commented 3 years ago

It's definitely possible given the info you provided, since it has the title, season, episode and year. That's all you need to match the item on Trakt.

You can ask here or you can also email me at rafael.gssa@gmail.com. Any way you prefer.

schteff commented 3 years ago

I have made quite a bit of progress.

I have parsed the "Continue watching" list and can now see and sync the items in the History interface of the plugin.

The thing is that it is just a "Continue watching" list and not a real "Watched history" list. So it mostly contains the upcoming episodes of the shows i'm currently watching. I'm going to continue snooping the Telia API to see if I can make multiple calls to other API-endpoints to fetch the "Watched history" for all shows that show up in the "Continue watching" list. When going to a show-page on the website I can see which episodes that are played and not, and I guess I can do these API calls one by one and piece together a "Watched history" from that :).

What happens if i sync an item that has 0% progress to Trakt? I'm wondering if I should filter out them or leave them be.

rafaelgomesxyz commented 3 years ago

Great to hear!

It would be better to find an endpoint that offers the complete history, but if they don't have one then building the history manually seems like a good option (although it may lead to a lot of requests). I assume they don't have their API documented? Is there any history page in Telia itself?

The progress is irrelevant to the sync, it's only there to serve as reference for the user. But you can just leave them be, because the idea is to implement a progress filter in the future.

schteff commented 3 years ago

No they don't have a history page. And no documentation for the API from what I can find.

But when going to a shows page I can see the watched progress for each episode. So i'm thinking I can use the "continue watching" data to find shows that are relevant for syncing and fetch the status for all episodes for each show (one request per show).

The most obvious problem with this is that after watching the final episode of a show, the show disappears from the "continue watching" list. So syncing the final episode of a show is not possible using this method.

They have a "my list" page to which I can add any show or movie. They stay there until they are removed manually. Even if they are completely watched.

I could fetch both the "continue watching" list and the "my list" shows and get the status for the episodes of all these shows to maximize the history.

Going to tinker a bit with it now.

schteff commented 3 years ago

My proof of concept seems to work. I haven't gone into pagination because of how the algorithm works.

Basically I collect all shows found in both the "continue watching list" and "my list". Then i do one API request to find all seasons of all shows.

Then i do one request for each season of each show to get all episode IDs (and other metadata).

And last one request to get the "watched" status for all episodes found above.

All in all it is 1 request for the "continue watching" list. 1 request for the "my list" list. 1 request to get the correct series IDs from the "my list" list. 1 request to get all seasons of all found shows. X requests (1 for each found season) to get episode data. 1 request to get all "watched" info for all episodes in one go.

Some episodes are "not found" on Trakt, although the show name and episode number have no problems. When I tried the "Is this wrong"-feature I ran into an issue where the next time I ran the plugin ALL episodes were matched to the episode I corrected. I had to remove and re-add the plugin to Chrome to reset the cache or something to make it work again. Is this a known issue?

I can still see episodes "not found" (see screenshot) after re-adding the plugin.

image

You can see my code here: https://github.com/trakt-tools/universal-trakt-scrobbler/compare/master...schteff:telia-play Haven't dared making a pull request yet.

rafaelgomesxyz commented 3 years ago

The cached corrections are based on the item ID. I see you're getting the ID from mediaObject.titleId, so can you confirm if this is a unique ID for each item?

Upon re-adding the plugin, your local cache no longer exists, so it's normal (at the moment) for you to lose all of your corrections.

schteff commented 3 years ago

Yes, using loopId instead fixed the issue thanks.

Should I make a pull request? Or would you need scrobbling and/or support for movies or other features added before that?

(movies are lost during the "get seasons/explore" step).

rafaelgomesxyz commented 3 years ago

It's not necessary to have both scrobbling and sync, but it would be preferable to support movies as well.

schteff commented 3 years ago

Added support for movies without any more requests. https://github.com/trakt-tools/universal-trakt-scrobbler/compare/master...schteff:telia-play

International movies with Swedish names are "not found" though. But they can be corrected using "Is this wrong?"

rafaelgomesxyz commented 3 years ago

Seems like users will have to do quite a few manual corrections. Can you provide more data examples like the one in the OP so I can mock the API and test it myself, since I can't use Telia Play? Preferably one more from an episode that leads to "Not Found" and another one for a movie as well.

But it looks good, feel free to make a PR!

rafaelgomesxyz commented 3 years ago

Also, just a suggestion (not really important): if all episodes follow the same naming pattern ("S0:E0 Episode Name - Show Name"), it might be better to clean the name so it only has the episode name.

MrMamen commented 3 years ago

As for correction titles: The recommended work around is to translate the title on https://www.themoviedb.org. The search will most likely pickup the correct title unless it is very generic.

schteff commented 3 years ago

I'll try to give you some more examples of JSON responses for mocking in the coming days.

Sadly not all shows follow the same naming pattern. The HBO shows have that pattern, so I could check the "storeName" value and trim the episode names for only HBO, but the shows from other sources (SVT, Kanal 5...) does not use that pattern.

I'll also try adding TmdbApi and see how that changes things. From what I can see you only pull images from it right now, should I add translation/search functions to your TmdbApi class or just try implementing it in the telia-play file?

rafaelgomesxyz commented 3 years ago

Don't worry about it, it's probably better to just keep the name they have in that case.

Keeping things separate is best for reuse, so if you could add those functions to TmdbApi that would be nice. We could potentially use it for other streaming services as well.

MrMamen commented 3 years ago

There is no need use the TmdbApi to find translations. If the title has a translation, trakt syncs these as well. The result in the API search should be the same as a web search: Example: https://trakt.tv/search//?query=lejonkungen The important is that the title is translated on tmdb. For series, it also needs to have tvdb as external id. After that trakt needs to refresh the data, and there could be some delay due to caching.

schteff commented 3 years ago

@MrMamen thanks for clarifying.

schteff commented 3 years ago

The "Not found" episodes can't be reproduces reliably. Maybe it has to do with Trakt api limitations? When i run the sync a seconds time they are mostly matched correctly. But some movies like "Baby-bossen" and "Kapten Kalsong: Filmen" (both searchable on Trakt) are always "Not found".

I have cleaned up the HBO episode names.

Here is a log of all current calls made when I run the sync using my Telia account, and their JSON responses (one on each line). telia-api example.log

Making a pull request soon.

MrMamen commented 3 years ago

Unfortunately most of the JSON-responses in the log-file are invalid, seemingly due to being cut after a certain number of characters. Not sure why the movies are not found in the api-call. Could you paste the actual search, with params, and response here?

Will review pull request shortly.

schteff commented 3 years ago

Sorry about that, I should have checked the endings of the rows. Chrome cut off the log lines in the console.

I logged using console.error instead and manually saved some complete log lines in this file.

telia-api.example.log

schteff commented 3 years ago

Here are the "Not found" movie search calls with responses (I removed the large available_translations arrays):

https://api.trakt.tv/search/movie?query=Baby-Bossen&extended=full

[
    {
        "type": "movie",
        "score": 9.677056,
        "movie": {
            "title": "The Boss Baby",
            "year": 2017,
            "ids": {
                "trakt": 195864,
                "slug": "the-boss-baby-2017",
                "imdb": "tt3874544",
                "tmdb": 295693
            },
            "tagline": "Born leader",
            "overview": "A story about how a new baby's arrival impacts a family, told from the point of view of a delightfully unreliable narrator, a wildly imaginative 7 year old named Tim.",
            "released": "2017-03-31",
            "runtime": 97,
            "country": "us",
            "trailer": "http://youtube.com/watch?v=Ud8j5GaqH3c",
            "homepage": "http://www.dreamworks.com/thebossbaby/",
            "status": "released",
            "rating": 7.33712,
            "votes": 26934,
            "comment_count": 32,
            "updated_at": "2020-11-15T08:04:53.000Z",
            "language": "en",
            "genres": [
                "animation",
                "comedy",
                "family"
            ],
            "certification": "PG"
        }
    }
]

image

https://api.trakt.tv/search/movie?query=Kapten%20Kalsong%3A%20Filmen&extended=full

[
    {
        "type": "movie",
        "score": 4.9297233,
        "movie": {
            "title": "Captain Underpants: The First Epic Movie",
            "year": 2017,
            "ids": {
                "trakt": 166828,
                "slug": "captain-underpants-the-first-epic-movie-2017",
                "imdb": "tt2091256",
                "tmdb": 268531
            },
            "tagline": "",
            "overview": "Two mischievous kids hypnotize their mean elementary school principal and turn him into their comic book creation, the kind-hearted and elastic-banded Captain Underpants.",
            "released": "2017-06-02",
            "runtime": 89,
            "country": "us",
            "trailer": "http://youtube.com/watch?v=zs2SrqLum1M",
            "homepage": "http://www.foxmovies.com/movies/captain-underpants-the-first-epic-movie",
            "status": "released",
            "rating": 7.24793,
            "votes": 6026,
            "comment_count": 17,
            "updated_at": "2020-09-18T08:12:43.000Z",
            "language": "en",
            "genres": [
                "animation",
                "family",
                "comedy",
                "action"
            ],
            "certification": "PG"
        }
    }
]

image

https://api.trakt.tv/search/movie?query=Lego%20Batman%3A%20Lagens%20v%C3%A4ktare&extended=full

[]

image

So the first two are found, but not the Lego Batman one. But in the GUI they are all marked as "Not Found". Weird.

MrMamen commented 3 years ago

It's a bit hard to debug while just watching the code, but if I were to guess, I would say this error is in TraktSearch.ts:152, where the trakt item is supposted to match the telia-item. The matching might need an adjustment.